diff --git a/lizmap/modules/lizmap/lib/Request/OGCRequest.php b/lizmap/modules/lizmap/lib/Request/OGCRequest.php index 5093b92b3d..ee32f39dae 100644 --- a/lizmap/modules/lizmap/lib/Request/OGCRequest.php +++ b/lizmap/modules/lizmap/lib/Request/OGCRequest.php @@ -185,6 +185,78 @@ protected function constructUrl() return Proxy::constructUrl($this->parameters(), $this->services, $url); } + /** + * Generate a string to identify the target of the HTTP request. + * + * @param array $parameters The list of HTTP parameters in the query + * @param int $code The HTTP code of the request + * + * @return string The string to identify the HTTP request, with main OGC parameters first such as MAP, SERVICE... + */ + private function formatHttpErrorString($parameters, $code) + { + // Clone parameters array to perform unset without modify it + $params = array_merge(array(), $parameters); + + // Ordered list of params to fetch first + $mainParamsToLog = array('map', 'repository', 'project', 'service', 'request'); + + $output = array(); + foreach ($mainParamsToLog as $paramName) { + if (array_key_exists($paramName, $params)) { + $output[] = '"'.strtoupper($paramName).'" = '."'".$params[$paramName]."'"; + unset($params[$paramName]); + } + } + + // First implode with main parameters + $message = implode(' & ', $output); + + if ($params) { + // Ideally, we want two lines, one with main parameters, the second one with secondary parameters + // It does not work in jLog + // $message .= '\n'; + $message .= ' & '; + } + + // For remaining parameters in the array, which are not in the main list + $output = array(); + foreach ($params as $key => $value) { + $output[] = '"'.strtoupper($key).'" = '."'".$value."'"; + } + + $message .= implode(' & ', $output); + + return 'HTTP code '.$code.' on '.$message; + } + + /** + * Log if the HTTP code is a 4XX or 5XX error code. + * + * @param int $code The HTTP code of the request + */ + protected function logRequestIfError($code) + { + if ($code < 400) { + return; + } + + $message = 'The HTTP OGC request to QGIS Server ended with an error.'; + + // The master error with MAP parameter + // This user must have an access to QGIS Server logs + $params = $this->parameters(); + \jLog::log($message.' Check logs on QGIS Server. '.$this->formatHttpErrorString($params, $code), 'error'); + + // The admin error without the MAP parameter + // but replaced by REPOSITORY and PROJECT parameters + // This user might not have an access to QGIS Server logs + unset($params['map']); + $params['repository'] = $this->project->getRepository()->getKey(); + $params['project'] = $this->project->getKey(); + \jLog::log($message.' '.$this->formatHttpErrorString($params, $code), 'lizmapadmin'); + } + /** * Request QGIS Server. * @@ -236,11 +308,15 @@ protected function request($post = false, $stream = false) if ($stream) { $response = \Lizmap\Request\Proxy::getRemoteDataAsStream($querystring, $options); + $this->logRequestIfError($response->getCode()); + return new OGCResponse($response->getCode(), $response->getMime(), $response->getBodyAsStream()); } list($data, $mime, $code) = \Lizmap\Request\Proxy::getRemoteData($querystring, $options); + $this->logRequestIfError($code); + return new OGCResponse($code, $mime, $data); } diff --git a/lizmap/modules/lizmap/lib/Request/Proxy.php b/lizmap/modules/lizmap/lib/Request/Proxy.php index 5a912b72f5..de3d433e1f 100644 --- a/lizmap/modules/lizmap/lib/Request/Proxy.php +++ b/lizmap/modules/lizmap/lib/Request/Proxy.php @@ -489,14 +489,14 @@ protected static function fileProxy($url, $options) * @param int $httpCode The HTTP code of the request * @param string $url The URL of the request, for logging */ - public static function logRequestIfError($httpCode, $url) + protected static function logRequestIfError($httpCode, $url) { - $httpCodeClass = substr($httpCode, 0, 1); - // Change to str_starts_with when PHP 8.1 will be minimum version for all maintained version - if ($httpCodeClass == '4' || $httpCodeClass == '5') { - \jLog::log('An HTTP request ended with an error, please check the main error log. Code '.$httpCode, 'lizmapadmin'); - \jLog::log('The HTTP request below ended with an error. Code '.$httpCode.' → '.$url, 'error'); + if ($httpCode < 400) { + return; } + + \jLog::log('An HTTP request ended with an error, please check the main error log. HTTP code '.$httpCode, 'lizmapadmin'); + \jLog::log('The HTTP request ended with an error. HTTP code '.$httpCode.' → '.$url, 'error'); } /** diff --git a/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties b/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties index a50ef2d02c..16a10cad97 100644 --- a/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties +++ b/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties @@ -71,11 +71,15 @@ edition.revertgeom.success=Geometry has been reversed. You can now save the form edition.confirm.launch.child.creation=You are about to create a new child object for the currently edited object. \nPlease check before that you have already saved your changes.\n\nDo you wish to continue? edition.point.coord.crs.layer=Layer edition.point.coord.crs.map=Map +edition.link.pivot.add=The new record will be linked to the feature ID "%f" of "%l" layer +edition.confirm.pivot.unlink=Are you sure you want to unlink the selected feature from "%l" layer? +edition.confirm.pivot.delete=Are you sure you want to delete the selected feature? \n\nThe related links with the following layers:\n %s \n\nwill be also deleted externalsearch.search=Searching externalsearch.notfound=No results externalsearch.mapdata=Map data externalsearch.noquery=Search query is empty +externalsearch.ignlimit=IGN search must contain between 3 and 200 characters timemanager.toolbar.play=Play timemanager.toolbar.pause=Pause @@ -215,11 +219,15 @@ digitizing.toolbar.textLabel=Text digitizing.toolbar.newText=New text digitizing.toolbar.textRotation=Rotation digitizing.toolbar.textScale=Size -digitizing.toolbar.import=Import in GeoJSON, GPX or KML +digitizing.toolbar.import=Import in GeoJSON, GPX, KML, zipped Shapefile or FlatGeobuf digitizing.toolbar.edit=Edit (hold "Shift" to select multiple features) digitizing.toolbar.erase=Delete some features -digitizing.confirme.erase=Are you sure you want to delete this feature? +digitizing.toolbar.erase.all=Delete all features +digitizing.confirm.erase=Are you sure you want to delete this feature? +digitizing.confirm.erase.all=Are you sure you want to delete all features? digitizing.toolbar.save=Save draw in the browser +digitizing.toolbar.save.state=The drawing changes will be saved in the browser +digitizing.toolbar.save.remove=Remove draw from the browser digitizing.toolbar.measure=Measures digitizing.constraint.title=Constraints @@ -227,10 +235,16 @@ digitizing.constraint.details=You can constrain digitizing by setting values for digitizing.constraint.distance=Distance digitizing.constraint.angle=Angle +digitizing.import.fetch.error=Error while fetching projection definition from epsg.io +digitizing.import.metadata.error=No metadata found. Make sure the projection of the fgb file is the same as the current project + switcher.layer.export.title=Export switcher.layer.export.warn=Please select a single layer to export snapping.title=Snapping +snapping.list.title=Snap on +snapping.list.toggle=Toggle snapping for this layer +snapping.list.disabled=This layer is hidden. Turn on the layer on the layer panel to toggle snapping on it mouseposition.hover=Mouse position mouseposition.select=Coordinate unit @@ -244,8 +258,6 @@ mouseposition.removeCenterPoint=Remove center point overviewbar.displayoverview.hover=Display/Hide overview - - action.title=Actions action.choose=Choose an action to run action.close=Close @@ -256,3 +268,22 @@ action.form.button.deactivate.help=Deactivate the active action action.form.select.emptyItem.label=Choose an action action.form.select.help=To run an action, select one in the list and click the Run button action.form.select.warning=You must first select an action in the list + +navbar.pan.hover=Pan map +navbar.zoom.hover=Zoom by rectangle +navbar.zoomextent.hover=Zoom to initial map extent +navbar.zoomin.hover=Zoom in +navbar.slider.hover=Slide to zoom in or out +navbar.zoomout.hover=Zoom out +navbar.previous.hover=Previous +navbar.next.hover=Next + +tooltip.loading.error=An error prevented to load the tooltip data + +featuresTable.item.hover=Click on the feature to display its detailed information +featuresTable.item.active.hover=Click to close the feature information and go back to the list of features +featuresTable.toolbar.previous=Go to the previous feature +featuresTable.toolbar.next=Go to the next feature +featuresTable.toolbar.close=Go back to the list of features +featuresTable.item.draggable.hover=You can drag and drop the feature to move it above or below +featuresTable.item.draggable.dropped=You have successfully moved this feature