From a82f9ea3e9f37ff4912b197a2b43d487a1df0c2e Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 07:23:48 +0200 Subject: [PATCH 1/6] Remove unusued php-geos package that leads to PHP Warning: GEOSGeometry::__toString() error --- build/resto/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/resto/Dockerfile b/build/resto/Dockerfile index d19c9225..14428879 100644 --- a/build/resto/Dockerfile +++ b/build/resto/Dockerfile @@ -7,6 +7,8 @@ ENV BUILD_DIR=./build/resto \ RESTO_DEBUG=1 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 +RUN apt-get remove -y php-geos + # Copy NGINX configuration COPY ${BUILD_DIR}/container_root/etc/nginx /etc/nginx From 07dddd9139e5a963039ea4f55183a033b12f2cd9 Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 07:24:59 +0200 Subject: [PATCH 2/6] Add comment on previous commit --- build/resto/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/resto/Dockerfile b/build/resto/Dockerfile index 14428879..861a303e 100644 --- a/build/resto/Dockerfile +++ b/build/resto/Dockerfile @@ -7,6 +7,8 @@ ENV BUILD_DIR=./build/resto \ RESTO_DEBUG=1 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=2 +# [TODO] Should be directly removed from jjrom/nginx-fpm +# Avoid "PHP Warning: GEOSGeometry::__toString()" error at startup RUN apt-get remove -y php-geos # Copy NGINX configuration From deb867a249172955aebaa3b675afa338b58e677f Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 09:33:39 +0200 Subject: [PATCH 3/6] Ensure that ltree path character set is limited to alphanumeric --- app/resto/core/utils/RestoUtil.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/resto/core/utils/RestoUtil.php b/app/resto/core/utils/RestoUtil.php index 944b4789..666cefcf 100755 --- a/app/resto/core/utils/RestoUtil.php +++ b/app/resto/core/utils/RestoUtil.php @@ -513,10 +513,12 @@ public static function localhostToDockerhost($url) /** * Convert a unix path (i.e. this/is/my/home ) to LTREE path (i.e. this.is.my.home) + * + * [IMPORTANT] LTREE path can only contains A-Za-z0-9_- characters so replace any other characters with _ */ public static function path2ltree($path) { - return strtolower(str_replace('/', '.', str_replace('.', '_', $path))); + return strtolower(str_replace('/', '.', preg_replace('/[^A-Za-z0-9_\- \/]/', '_', $path))); } /** From 11f87894c7623c1ebd40fb30e51b6b7f52c51067 Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 10:33:30 +0200 Subject: [PATCH 4/6] Ensure to replace non alphanumeric characters from input path search in searchTerms --- .../core/dbfunctions/CatalogsFunctions.php | 6 ++++- .../core/dbfunctions/FiltersFunctions.php | 27 ++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/resto/core/dbfunctions/CatalogsFunctions.php b/app/resto/core/dbfunctions/CatalogsFunctions.php index 4bf7928d..f5d66131 100755 --- a/app/resto/core/dbfunctions/CatalogsFunctions.php +++ b/app/resto/core/dbfunctions/CatalogsFunctions.php @@ -276,7 +276,11 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur $catalogLevel = count(explode('/', $catalog['id'])); // Convert catalogId to LTREE path - first replace dot with underscore $path = RestoUtil::path2ltree($catalog['id']); - + + if ( !isset($catalog['rtype']) ) { + $catalog['rtype'] = null; + } + if ( isset($featureId) && $catalog['rtype'] !== 'collection' && ($catalogLevel > 1 || $catalog['rtype'] === 'catalog') ) { $this->insertIntoCatalogFeature($featureId, $path, $catalog['id'], $collectionId); } diff --git a/app/resto/core/dbfunctions/FiltersFunctions.php b/app/resto/core/dbfunctions/FiltersFunctions.php index 7846bb8b..122d04d2 100755 --- a/app/resto/core/dbfunctions/FiltersFunctions.php +++ b/app/resto/core/dbfunctions/FiltersFunctions.php @@ -651,17 +651,6 @@ private function prepareFilterQueryKeywords($catalogFeatureTableName, $filterNam $searchTerm = ltrim($searchTerm, '-'); } - /* - * Add prefix in front of all elements if needed - * See for instance [eo:instrument] - */ - if (isset($this->model->searchFilters[$filterName]['pathPrefix'])) { - $searchTerm = $this->addPathPrefix($searchTerm, $this->model->searchFilters[$filterName]['pathPrefix']); - } - else { - $searchTerm = '*.' . $searchTerm; - } - $this->terms[] = array_merge($this->processSearchTerms($searchTerm, $filters, $catalogFeatureTableName, $filterName, $exclusion)); } @@ -705,7 +694,21 @@ private function processSearchTerms($searchTerm, &$filters, $catalogFeatureTable $where = array(); for ($j = count($exploded); $j--;) { - $where[] = $catalogFeatureTableName . '.path ~ ' . '\'' . pg_escape_string($this->context->dbDriver->getConnection(), trim($exploded[$j] . '.*')) . '\''; + + $ltreePath = RestoUtil::path2ltree($exploded[$j]); + + /* + * Add prefix in front of all elements if needed + * See for instance [eo:instrument] + */ + if (isset($this->model->searchFilters[$filterName]['pathPrefix'])) { + $ltreePath = $this->addPathPrefix($ltreePath, $this->model->searchFilters[$filterName]['pathPrefix']); + } + else { + $ltreePath = '*.' . $ltreePath; + } + + $where[] = $catalogFeatureTableName . '.path ~ ' . '\'' . pg_escape_string($this->context->dbDriver->getConnection(), trim($ltreePath . '.*')) . '\''; } if ($isOr) { From 4958a9a973945ed164bd1a0323464464dfff6608 Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 11:22:50 +0200 Subject: [PATCH 5/6] Ensure that input catalog identifier has no trailing slash --- app/resto/core/api/STACAPI.php | 2 +- .../core/dbfunctions/CatalogsFunctions.php | 21 ++++++++++++------- .../core/dbfunctions/FeaturesFunctions.php | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/resto/core/api/STACAPI.php b/app/resto/core/api/STACAPI.php index c8d61745..5869e4b2 100644 --- a/app/resto/core/api/STACAPI.php +++ b/app/resto/core/api/STACAPI.php @@ -397,7 +397,7 @@ public function addCatalog($params, $body) RestoLogUtil::httpError(409, 'Catalog ' . $body['id'] . ' already exists'); } $baseUrl = $this->context->core['baseUrl']; - return RestoLogUtil::success('Catalog added', $this->catalogsFunctions->storeCatalog($body, $this->user->profile['id'], $baseUrl, null, null)); + return RestoLogUtil::success('Catalog added', $this->catalogsFunctions->storeCatalog($body, $this->user->profile['id'], $baseUrl, null, null, false)); } diff --git a/app/resto/core/dbfunctions/CatalogsFunctions.php b/app/resto/core/dbfunctions/CatalogsFunctions.php index f5d66131..de0c8135 100755 --- a/app/resto/core/dbfunctions/CatalogsFunctions.php +++ b/app/resto/core/dbfunctions/CatalogsFunctions.php @@ -203,15 +203,20 @@ public function getCatalogItems($catalogId, $baseUrl) * @param string $baseUrl * @param string $collectionId * @param string $featureId - * @param boolean $inTransaction + * @param boolean $inTransaction // True means that already in a begin/commit block */ - public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featureId, $inTransaction = true) + public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featureId, $inTransaction) { // Empty catalog - do nothing if (!isset($catalog)) { return; } + // [IMPORTANT] Catalog identifier should never have a trailing / + if ( substr($catalog['id'], -1) === '/' ) { + $catalog['id'] = rtrim($catalog['id'], '/'); + } + $defaultCount = isset($featureId) ? 1 : 0; $counters = array( 'total' => $defaultCount, @@ -226,7 +231,7 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur try { - if ( $inTransaction ) { + if ( !$inTransaction ) { $this->dbDriver->query('BEGIN'); } @@ -280,7 +285,7 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur if ( !isset($catalog['rtype']) ) { $catalog['rtype'] = null; } - + if ( isset($featureId) && $catalog['rtype'] !== 'collection' && ($catalogLevel > 1 || $catalog['rtype'] === 'catalog') ) { $this->insertIntoCatalogFeature($featureId, $path, $catalog['id'], $collectionId); } @@ -307,13 +312,13 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur ), 500, 'Cannot update catalog feature association for child link ' . $updateCatalogs['id']); } - if ( $inTransaction ) { + if ( !$inTransaction ) { $this->dbDriver->query('COMMIT'); } } catch (Exception $e) { - if ( $inTransaction ) { + if ( !$inTransaction ) { $this->dbDriver->query('ROLLBACK'); } RestoLogUtil::httpError(500, $e->getMessage()); @@ -333,7 +338,7 @@ public function storeCatalog($catalog, $userid, $baseUrl, $collectionId, $featur * @param RestoCollection $collection * @param string $featureId */ - public function storeCatalogs($catalogs, $userid, $collection, $featureId) + public function storeCatalogs($catalogs, $userid, $collection, $featureId, $inTransaction) { // Empty catalogs - do nothing if (!isset($catalogs) || count($catalogs) === 0) { @@ -347,7 +352,7 @@ public function storeCatalogs($catalogs, $userid, $collection, $featureId) $baseUrl = $collection->context->core['baseUrl']; } for ($i = count($catalogs); $i--;) { - $this->storeCatalog($catalogs[$i], $userid, $baseUrl, $collectionId, $featureId); + $this->storeCatalog($catalogs[$i], $userid, $baseUrl, $collectionId, $featureId, $inTransaction); } return $catalogs; diff --git a/app/resto/core/dbfunctions/FeaturesFunctions.php b/app/resto/core/dbfunctions/FeaturesFunctions.php index d2043863..d8f808a0 100755 --- a/app/resto/core/dbfunctions/FeaturesFunctions.php +++ b/app/resto/core/dbfunctions/FeaturesFunctions.php @@ -348,7 +348,7 @@ public function storeFeature($id, $collection, $featureArray) /* * Store catalogs */ - (new CatalogsFunctions($this->dbDriver))->storeCatalogs($keysAndValues['catalogs'], $collection->user->profile['id'], $collection, $result['id']); + (new CatalogsFunctions($this->dbDriver))->storeCatalogs($keysAndValues['catalogs'], $collection->user->profile['id'], $collection, $result['id'], true); /* * Commit everything - rollback if one of the inserts failed @@ -357,7 +357,7 @@ public function storeFeature($id, $collection, $featureArray) } catch (Exception $e) { pg_query($dbh, 'ROLLBACK'); - RestoLogUtil::httpError(500, 'Feature ' . ($featureArray['productIdentifier'] ?? '') . ' cannot be inserted in database'); + RestoLogUtil::httpError(500, 'Feature ' . ($featureArray['properties']['productIdentifier'] ?? '') . ' cannot be inserted in database'); } return array( @@ -507,7 +507,7 @@ public function updateFeature($feature, $collection, $newFeatureArray) $feature->id ) ); - (new CatalogsFunctions($this->dbDriver))->storeCatalogs($keysAndValues['catalogs'], $collection->user->profile['id'], $collection, $feature->id); + (new CatalogsFunctions($this->dbDriver))->storeCatalogs($keysAndValues['catalogs'], $collection->user->profile['id'], $collection, $feature->id, true); /* * Commit From 7302094253b28bd9358a43936960aec644feb6c1 Mon Sep 17 00:00:00 2001 From: jjrom Date: Thu, 10 Oct 2024 11:23:48 +0200 Subject: [PATCH 6/6] Change version to 9.0.0-RC12 --- app/resto/core/RestoConstants.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/resto/core/RestoConstants.php b/app/resto/core/RestoConstants.php index c4ab6dde..0f7a2d79 100644 --- a/app/resto/core/RestoConstants.php +++ b/app/resto/core/RestoConstants.php @@ -20,7 +20,7 @@ class RestoConstants // [IMPORTANT] Starting resto 7.x, default routes are defined in RestoRouter class // resto version - const VERSION = '9.0.0-RC11'; + const VERSION = '9.0.0-RC12'; /* ============================================================ * NEVER EVER TOUCH THESE VALUES