From a9453508cbae177f355fc66d04c024ab3d83657f Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 4 Oct 2024 16:23:59 +0200 Subject: [PATCH] QgisProject remove code in read methods --- .../lizmap/lib/Project/QgisProject.php | 523 ++++-------------- .../units/classes/Project/QgisProjectTest.php | 14 +- 2 files changed, 104 insertions(+), 433 deletions(-) diff --git a/lizmap/modules/lizmap/lib/Project/QgisProject.php b/lizmap/modules/lizmap/lib/Project/QgisProject.php index 6c1ae8a159..f032b3b247 100644 --- a/lizmap/modules/lizmap/lib/Project/QgisProject.php +++ b/lizmap/modules/lizmap/lib/Project/QgisProject.php @@ -742,124 +742,13 @@ public function getLayerNameByIdFromConfig($layerId, $layers) */ public function getPrintTemplates() { - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - - return $project->getLayoutsAsKeyArray(); - } - // get restricted composers - $rComposers = array(); - $restrictedComposers = $this->getXml()->xpath('//properties/WMSRestrictedComposers/value'); - if ($restrictedComposers && is_array($restrictedComposers)) { - foreach ($restrictedComposers as $restrictedComposer) { - $rComposers[] = (string) $restrictedComposer; - } + if (!$this->path) { + return array(); } - $printTemplates = array(); - // get layout qgs project version >= 3 - $layouts = $this->getXml()->xpath('//Layout'); - if ($layouts && is_array($layouts)) { - foreach ($layouts as $layout) { - // test restriction - if (in_array((string) $layout['name'], $rComposers)) { - continue; - } - // get page element - $page = $layout->xpath('PageCollection/LayoutItem[@type="65638"]'); - if (!$page) { - continue; - } - $page = $page[0]; - - $pageSize = explode(',', $page['size']); - // init print template element - $printTemplate = array( - 'title' => (string) $layout['name'], - 'width' => (int) $pageSize[0], - 'height' => (int) $pageSize[1], - 'maps' => array(), - 'labels' => array(), - ); - - // store mapping between uuid and id - $mapUuidId = array(); - // get layout maps - $lMaps = $layout->xpath('LayoutItem[@type="65639"]'); - if ($lMaps && is_array($lMaps)) { - // Convert xml to json config - foreach ($lMaps as $lMap) { - $lMapSize = explode(',', $lMap['size']); - $ptMap = array( - 'id' => 'map'.(string) count($printTemplate['maps']), - 'uuid' => (string) $lMap['uuid'], - 'width' => (int) $lMapSize[0], - 'height' => (int) $lMapSize[1], - ); - // store mapping between uuid and id - $mapUuidId[(string) $lMap['uuid']] = 'map'.(string) count($printTemplate['maps']); - - // Overview - $cMapOverviews = $lMap->xpath('ComposerMapOverview'); - foreach ($cMapOverviews as $cMapOverview) { - if ($cMapOverview and (string) $cMapOverview->attributes()->show !== '0' and (string) $cMapOverview->attributes()->frameMap != '-1') { - // frameMap is an uuid - $ptMap['overviewMap'] = (string) $cMapOverview->attributes()->frameMap; - } - } - // Grid - $cMapGrids = $lMap->xpath('ComposerMapGrid'); - foreach ($cMapGrids as $cMapGrid) { - if ($cMapGrid and (string) $cMapGrid->attributes()->show !== '0') { - $ptMap['grid'] = 'True'; - } - } - - $printTemplate['maps'][] = $ptMap; - } - // Modifying overviewMap to id instead of uuid - foreach ($printTemplate['maps'] as $ptMap) { - if (!array_key_exists('overviewMap', $ptMap)) { - continue; - } - if (!array_key_exists($ptMap['overviewMap'], $mapUuidId)) { - unset($ptMap['overviewMap']); - - continue; - } - $ptMap['overviewMap'] = $mapUuidId[$ptMap['overviewMap']]; - } - } - - // get layout labels - $lLabels = $layout->xpath('LayoutItem[@type="65641"]'); - if ($lLabels && is_array($lLabels)) { - foreach ($lLabels as $lLabel) { - if ((string) $lLabel['id'] == '') { - continue; - } - $printTemplate['labels'][] = array( - 'id' => (string) $lLabel['id'], - 'htmlState' => (int) $lLabel['htmlState'], - 'text' => (string) $lLabel['labelText'], - ); - } - } - - // Atlas - $atlas = $layout->xpath('Atlas'); - if ($atlas) { - $atlas = $atlas[0]; - $printTemplate['atlas'] = array( - 'enabled' => (string) $atlas['enabled'], - 'coverageLayer' => (string) $atlas['coverageLayer'], - ); - } - $printTemplates[] = $printTemplate; - } - } + $project = Qgis\ProjectInfo::fromQgisPath($this->path); - return $printTemplates; + return $project->getLayoutsAsKeyArray(); } /** @@ -867,6 +756,10 @@ public function getPrintTemplates() */ public function readLocateByLayer($locateByLayer) { + if (!$this->path) { + return; + } + // collect layerIds $locateLayerIds = array(); foreach ($locateByLayer as $k => $v) { @@ -874,94 +767,49 @@ public function readLocateByLayer($locateByLayer) } // update locateByLayer with project from path - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - - // update locateByLayer with alias and filter information - foreach ($locateByLayer as $k => $v) { - $updateLocate = false; - $layer = $project->getLayerById($v->layerId); - // Get field alias - $alias = $layer->getFieldAlias($v->fieldName); - if ($alias !== null) { - // Update locate with field alias - $v->fieldAlias = $alias; - $updateLocate = true; - } - if (property_exists($v, 'filterFieldName')) { - // Get filter field alias - $filterAlias = $layer->getFieldAlias($v->filterFieldName); - if ($filterAlias !== null) { - // Update locate with filter field alias - $v->filterFieldAlias = $filterAlias; - $updateLocate = true; - } - } - // Get joins - if ($layer->vectorjoins !== null && count($layer->vectorjoins) > 0) { - if (!property_exists($v, 'vectorjoins')) { - // Add joins to locate - $v->vectorjoins = array(); - $updateLocate = true; - } - foreach ($layer->vectorjoins as $vectorjoin) { - if (in_array($vectorjoin->joinLayerId, $locateLayerIds)) { - // Add join info to locate - $v->vectorjoins[] = (object) array( - 'joinFieldName' => $vectorjoin->joinFieldName, - 'targetFieldName' => $vectorjoin->targetFieldName, - 'joinLayerId' => $vectorjoin->joinLayerId, - ); - $updateLocate = true; - } - } - } - if ($updateLocate) { - // Update locate if needed - $locateByLayer->{$k} = $v; - } - } - - return; - } + $project = Qgis\ProjectInfo::fromQgisPath($this->path); // update locateByLayer with alias and filter information foreach ($locateByLayer as $k => $v) { - $xmlLayer = $this->getXmlLayer2($this->getXml(), $v->layerId); - if (is_null($xmlLayer)) { - continue; - } - // aliases - $alias = $xmlLayer->xpath("aliases/alias[@field='".$v->fieldName."']"); - if ($alias && is_array($alias)) { - $alias = $alias[0]; - $v->fieldAlias = (string) $alias['name']; - $locateByLayer->{$k} = $v; + $updateLocate = false; + $layer = $project->getLayerById($v->layerId); + // Get field alias + $alias = $layer->getFieldAlias($v->fieldName); + if ($alias !== null) { + // Update locate with field alias + $v->fieldAlias = $alias; + $updateLocate = true; } if (property_exists($v, 'filterFieldName')) { - $alias = $xmlLayer->xpath("aliases/alias[@field='".$v->filterFieldName."']"); - if ($alias && is_array($alias)) { - $alias = $alias[0]; - $v->filterFieldAlias = (string) $alias['name']; - $locateByLayer->{$k} = $v; + // Get filter field alias + $filterAlias = $layer->getFieldAlias($v->filterFieldName); + if ($filterAlias !== null) { + // Update locate with filter field alias + $v->filterFieldAlias = $filterAlias; + $updateLocate = true; } } - // vectorjoins - $vectorjoins = $xmlLayer->xpath('vectorjoins/join'); - if ($vectorjoins && is_array($vectorjoins)) { + // Get joins + if ($layer->vectorjoins !== null && count($layer->vectorjoins) > 0) { if (!property_exists($v, 'vectorjoins')) { + // Add joins to locate $v->vectorjoins = array(); + $updateLocate = true; } - foreach ($vectorjoins as $vectorjoin) { - $joinLayerId = (string) $vectorjoin['joinLayerId']; - if (in_array($joinLayerId, $locateLayerIds)) { + foreach ($layer->vectorjoins as $vectorjoin) { + if (in_array($vectorjoin->joinLayerId, $locateLayerIds)) { + // Add join info to locate $v->vectorjoins[] = (object) array( - 'joinFieldName' => (string) $vectorjoin['joinFieldName'], - 'targetFieldName' => (string) $vectorjoin['targetFieldName'], - 'joinLayerId' => (string) $vectorjoin['joinLayerId'], + 'joinFieldName' => $vectorjoin->joinFieldName, + 'targetFieldName' => $vectorjoin->targetFieldName, + 'joinLayerId' => $vectorjoin->joinLayerId, ); + $updateLocate = true; } } + } + if ($updateLocate) { + // Update locate if needed $locateByLayer->{$k} = $v; } } @@ -972,29 +820,11 @@ public function readLocateByLayer($locateByLayer) */ public function readEditionLayers($editionLayers) { - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - foreach ($editionLayers as $key => $obj) { - // Improve performance by getting provider directly from config - // Available for lizmap plugin >= 3.3.2 - if (property_exists($obj, 'provider')) { - if ($obj->provider == 'spatialite') { - unset($editionLayers->{$key}); - } - - continue; - } - // check for embedded layers - $layer = $project->getLayerById($obj->layerId); - if ($layer->provider == 'spatialite') { - unset($editionLayers->{$key}); - } - } - + if (!$this->path) { return; } - $embeddedEditionLayers = array(); + $project = Qgis\ProjectInfo::fromQgisPath($this->path); foreach ($editionLayers as $key => $obj) { // Improve performance by getting provider directly from config // Available for lizmap plugin >= 3.3.2 @@ -1006,21 +836,8 @@ public function readEditionLayers($editionLayers) continue; } // check for embedded layers - $qgisProject = $this->getEmbeddedQgisProject($obj, $embeddedEditionLayers); - if ($qgisProject) { - $xml = $qgisProject->getXml(); - } else { - $xml = $this->getXml(); - } - - // Read layer property from QGIS project XML - $layerXml = $this->getXmlLayer2($xml, $obj->layerId); - if (is_null($layerXml)) { - continue; - } - $provider = $layerXml->xpath('provider'); - $provider = (string) $provider[0]; - if ($provider == 'spatialite') { + $layer = $project->getLayerById($obj->layerId); + if ($layer->provider == 'spatialite') { unset($editionLayers->{$key}); } } @@ -1032,42 +849,25 @@ public function readEditionLayers($editionLayers) */ public function readEditionForms($editionLayers, $proj = null) { - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - foreach ($editionLayers as $key => $obj) { - $layer = $project->getLayerById($obj->layerId); - if ($layer === null) { - continue; - } - if ($layer->type !== 'vector') { - continue; - } - - /** @var Qgis\Layer\VectorLayer $layer */ - $formControls = $layer->getFormControls(); - if ($proj) { - $proj->getCacheHandler()->setEditableLayerFormCache($obj->layerId, $formControls); - } - } - + if (!$this->path) { return; } - $embeddedEditionLayers = array(); + + $project = Qgis\ProjectInfo::fromQgisPath($this->path); foreach ($editionLayers as $key => $obj) { - // check for embedded layers - $qgisProject = $this->getEmbeddedQgisProject($obj, $embeddedEditionLayers); - if ($qgisProject) { - $xml = $qgisProject->getXml(); - } else { - $xml = $this->getXml(); + $layer = $project->getLayerById($obj->layerId); + if ($layer === null) { + continue; } - - $layerXml = $this->getXmlLayer2($xml, $obj->layerId); - if (is_null($layerXml)) { + if ($layer->type !== 'vector') { continue; } - $formControls = $this->readFormControls($layerXml, $obj->layerId, $proj); - $proj->getCacheHandler()->setEditableLayerFormCache($obj->layerId, $formControls); + + /** @var Qgis\Layer\VectorLayer $layer */ + $formControls = $proj->getCacheHandler()->getEditableLayerFormCache($obj->layerId); + if (!$formControls && $proj) { + $proj->getCacheHandler()->setEditableLayerFormCache($obj->layerId, $layer->getFormControls()); + } } } @@ -1116,80 +916,37 @@ public function getEmbeddedQgisProject($editionLayer, &$embeddedEditionLayers = * * This concerns fields with ValueMap, ValueRelation & RelationReference config * - * @param array $layerIds List of layer identifiers - * @param Project $proj + * @param array $layerIds List of layer identifiers + * @param null|Project $proj */ - public function readLayersLabeledFieldsConfig($layerIds, $proj) + public function readLayersLabeledFieldsConfig($layerIds, $proj = null) { // Get QGIS form fields configurations for each layer $layersLabeledFieldsConfig = array(); - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - foreach ($layerIds as $layerId) { - $layer = $project->getLayerById($layerId); - if ($layer === null) { - continue; - } - if ($layer->type !== 'vector') { - continue; - } - - /** @var Qgis\Layer\VectorLayer $layer */ - $formControls = $layer->getFormControls(); - - $fields_config = array(); - foreach ($formControls as $fieldName => $control) { - $editType = $control->getFieldEditType(); - if (!in_array($editType, array('ValueMap', 'ValueRelation', 'RelationReference'))) { - continue; - } - $fields_config[$fieldName] = array( - 'type' => $editType, - ); - if ($editType == 'ValueMap') { - $valueMap = $control->getValueMap(); - if ($valueMap) { - $fields_config[$fieldName]['data'] = $valueMap; - } - } elseif ($editType == 'ValueRelation') { - $valueRelationData = $control->getValueRelationData(); - $fields_config[$fieldName]['source_layer_id'] = $valueRelationData['layer']; - $fields_config[$fieldName]['source_layer'] = $valueRelationData['layerName']; - $fields_config[$fieldName]['code_field'] = $valueRelationData['key']; - $fields_config[$fieldName]['label_field'] = $valueRelationData['value']; - $fields_config[$fieldName]['exp_filter'] = $valueRelationData['filterExpression']; - } else { - // RelationReference - // We need to get the relation properties - $relationReferenceData = $control->getRelationReference(); - $relation = $relationReferenceData['relation']; - $referencedLayerId = $relationReferenceData['referencedLayerId']; - if (!array_key_exists($referencedLayerId, $this->relations)) { - continue; - } - $fields_config[$fieldName]['relation'] = $relation; - $fields_config[$fieldName]['source_layer_id'] = $referencedLayerId; - $fields_config[$fieldName]['source_layer'] = $relationReferenceData['referencedLayerName']; - $fields_config[$fieldName]['code_field'] = $this->relations[$referencedLayerId][0]['referencedField']; - $fields_config[$fieldName]['label_field'] = $this->relations[$referencedLayerId][0]['previewField']; - $fields_config[$fieldName]['exp_filter'] = $relationReferenceData['filterExpression']; - } - } - $layersLabeledFieldsConfig[$layer->layername] = $fields_config; - } - + if (!$this->path) { return $layersLabeledFieldsConfig; } + $project = Qgis\ProjectInfo::fromQgisPath($this->path); foreach ($layerIds as $layerId) { - $layerXml = $this->getXmlLayer2($this->getXml(), $layerId); - if (is_null($layerXml)) { + $layer = $project->getLayerById($layerId); + if ($layer === null) { continue; } - $formControls = $this->readFormControls($layerXml, $layerId, $proj); - $getLayer = $this->getLayer($layerId, $proj); - $layerName = $getLayer->getName(); + if ($layer->type !== 'vector') { + continue; + } + + /** @var Qgis\Layer\VectorLayer $layer */ + $formControls = array(); + if ($proj) { + $formControls = $proj->getCacheHandler()->getEditableLayerFormCache($layerId); + } + if (!$formControls) { + $formControls = $layer->getFormControls(); + } + $fields_config = array(); foreach ($formControls as $fieldName => $control) { $editType = $control->getFieldEditType(); @@ -1228,8 +985,7 @@ public function readLayersLabeledFieldsConfig($layerIds, $proj) $fields_config[$fieldName]['exp_filter'] = $relationReferenceData['filterExpression']; } } - - $layersLabeledFieldsConfig[$layerName] = $fields_config; + $layersLabeledFieldsConfig[$layer->layername] = $fields_config; } return $layersLabeledFieldsConfig; @@ -1240,23 +996,11 @@ public function readLayersLabeledFieldsConfig($layerIds, $proj) */ public function readAttributeLayers($attributeLayers) { - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - // Get field order & visibility - foreach ($attributeLayers as $key => $obj) { - // Improve performance by getting custom_config status directly from config - // Available for lizmap plugin >= 3.3.3 - if (property_exists($obj, 'custom_config') && $obj->custom_config != 'True') { - continue; - } - - $layer = $project->getLayerById($obj->layerId); - $obj->attributetableconfig = $layer->attributetableconfig->toKeyArray(); - } - + if (!$this->path) { return; } + $project = Qgis\ProjectInfo::fromQgisPath($this->path); // Get field order & visibility foreach ($attributeLayers as $key => $obj) { // Improve performance by getting custom_config status directly from config @@ -1265,21 +1009,8 @@ public function readAttributeLayers($attributeLayers) continue; } - // Read layer property from QGIS project XML - $layerXml = $this->getXmlLayer2($this->getXml(), $obj->layerId); - if (is_null($layerXml)) { - continue; - } - $attributetableconfigXml = $layerXml->xpath('attributetableconfig'); - if (count($attributetableconfigXml) == 0) { - continue; - } - $attributetableconfig = str_replace( - '@', - '', - json_encode($attributetableconfigXml[0]) - ); - $obj->attributetableconfig = json_decode($attributetableconfig); + $layer = $project->getLayerById($obj->layerId); + $obj->attributetableconfig = $layer->attributetableconfig->toKeyArray(); } } @@ -1291,85 +1022,23 @@ public function readAttributeLayers($attributeLayers) public function readLayersOrder($layers) { $layersOrder = array(); - if ($this->path) { - $project = Qgis\ProjectInfo::fromQgisPath($this->path); - $customOrder = $project->layerTreeRoot->customOrder; - if (!$customOrder->enabled) { - return $layersOrder; - } - $lo = 0; - foreach ($customOrder->items as $layerI) { - // Get layer name from config instead of XML for possible embedded layers - $name = $this->getLayerNameByIdFromConfig($layerI, $layers); - if ($name) { - $layersOrder[$name] = $lo; - } - ++$lo; - } - } elseif ($this->qgisProjectVersion >= 30000) { // For QGIS >=3.0, custom-order is in layer-tree-group - $customOrder = $this->getXml()->xpath('layer-tree-group/custom-order'); - if (count($customOrder) == 0) { - return $layersOrder; - } - $customOrderZero = $customOrder[0]; - if (intval($customOrderZero->attributes()->enabled) == 1) { - $items = $customOrderZero->xpath('//item'); - $lo = 0; - foreach ($items as $layerI) { - // Get layer name from config instead of XML for possible embedded layers - $name = $this->getLayerNameByIdFromConfig($layerI, $layers); - if ($name) { - $layersOrder[$name] = $lo; - } - ++$lo; - } - } else { - return $layersOrder; - } - } elseif ($this->qgisProjectVersion >= 20400) { // For QGIS >=2.4, new item layer-tree-canvas - $customOrder = $this->getXml()->xpath('//layer-tree-canvas/custom-order'); - if (count($customOrder) == 0) { - return $layersOrder; - } - $customOrderZero = $customOrder[0]; - if (intval($customOrderZero->attributes()->enabled) == 1) { - $items = $customOrderZero->xpath('//item'); - $lo = 0; - foreach ($items as $layerI) { - // Get layer name from config instead of XML for possible embedded layers - $name = $this->getLayerNameByIdFromConfig($layerI, $layers); - if ($name) { - $layersOrder[$name] = $lo; - } - ++$lo; - } - } else { - $items = $this->getXml()->xpath('layer-tree-group//layer-tree-layer'); - $lo = 0; - foreach ($items as $layerTree) { - // Get layer name from config instead of XML for possible embedded layers - $name = $this->getLayerNameByIdFromConfig($layerTree->attributes()->id, $layers); - if ($name) { - $layersOrder[$name] = $lo; - } - ++$lo; - } - } - } else { - $legend = $this->getXml()->xpath('//legend'); - if (count($legend) == 0) { - return $layersOrder; - } - $legendZero = $legend[0]; - $updateDrawingOrder = (string) $legendZero->attributes()->updateDrawingOrder; - if ($updateDrawingOrder == 'false') { - $layers = $this->getXml()->xpath('//legendlayer'); - foreach ($layers as $layer) { - if ($layer->attributes()->drawingOrder && intval($layer->attributes()->drawingOrder) >= 0) { - $layersOrder[(string) $layer->attributes()->name] = (int) $layer->attributes()->drawingOrder; - } - } - } + if (!$this->path) { + return $layersOrder; + } + + $project = Qgis\ProjectInfo::fromQgisPath($this->path); + $customOrder = $project->layerTreeRoot->customOrder; + if (!$customOrder->enabled) { + return $layersOrder; + } + $lo = 0; + foreach ($customOrder->items as $layerI) { + // Get layer name from config instead of XML for possible embedded layers + $name = $this->getLayerNameByIdFromConfig($layerI, $layers); + if ($name) { + $layersOrder[$name] = $lo; + } + ++$lo; } return $layersOrder; diff --git a/tests/units/classes/Project/QgisProjectTest.php b/tests/units/classes/Project/QgisProjectTest.php index 7c772b59af..df0e5baed7 100644 --- a/tests/units/classes/Project/QgisProjectTest.php +++ b/tests/units/classes/Project/QgisProjectTest.php @@ -1,10 +1,12 @@ editionLayers; $testProj = new qgisProjectForTests(); - $testProj->setXmlForTest(simplexml_load_file($file)); + $testProj->setPath($file); $testProj->readEditionLayersForTest($eLayers); $this->assertEquals($expectedELayer, $eLayers); } @@ -435,15 +437,15 @@ public function testReadAttributeLayer()