/** * Save all layers and their depending classes in the database * of distinct layers and not distinct layers. * Distinct layers do not share the same name. * * $layers [array] : an array of layers * * TODO: This function became huge overtime. It could be split * into multiple functions but it's not an easy task and I lacked * time to do it. * */ private function save($data, $igoContexte = null) { $this->db->begin(); //Create a contexte if IgoContexte is defined if ($igoContexte) { $this->igoContexteSave($igoContexte); } //Create an associative array of all the possible non-multi geometry types //This way, we dont need to issue a sql request for each layer $geometryTypes = array(); //TODO Déterminer pourquoi on ne veut pas les multi $allGeometryTypes = IgoGeometrieType::find("NOT nom ilike '%multi%'"); foreach ($allGeometryTypes as $geometryType) { $geometryTypes[$geometryType->layer_type] = $geometryType->id; } //Create an empty array that will be used to store the group IDs $groups = array(); $layerIndex = 1; try { $igoCouches = array(); foreach ($data as $d) { $igoConnexion = null; if ($d['connection'] && isset($d['connection']['connectionString']) && isset($d['connection']['type'])) { //Check if connexion exists already in the database $igoConnexion = $this->getConnection($d['connection']['connectionString'], $d['connection']['type']); } foreach ($d['layers'] as $layer) { if (isset($layer['connection']) && isset($layer['connectiontype']) && trim($layer['connection']) && trim($layer['connectiontype'])) { //Check if connexion exists already in the database $igoConnexion = $this->getConnection($layer['connection'], $layer['connectiontype']); } $groupeCoucheId = null; $groupID = null; $layer['currentGroup'] = null; //If geometry type doesn't exist, create it if (!array_key_exists($layer['type'], $geometryTypes)) { $igoGeometrieType = new IgoGeometrieType(); $igoGeometrieType->layer_type = $layer['type']; $igoGeometrieType->nom = $layer['type']; $this->igoGeometrieTypeSave($igoGeometrieType); //Store the new geometry type id in an array and refer to it //for the following layers with the same geometry type $geometryTypes[$layer['type']] = $igoGeometrieType->id; } $layerQuery = 'mf_layer_name="' . $layer['name'] . '"'; $igoLayer = IgoCouche::findFirst($layerQuery); $layerSaveSuccessful = false; if ($layer['action'] == 'insert') { if ($igoLayer) { //If a layer with the same name exists already //Find its geometry if ($igoLayer->geometrie_id) { $geometryQuery = 'id="' . $igoLayer->geometrie_id . '"'; $igoGeometrie = IgoGeometrie::findFirst($geometryQuery); } else { $igoGeometrie = new IgoGeometrie(); } //Find it's classe d'entité if ($igoGeometrie && $igoGeometrie->classe_entite_id) { $classeEntiteQuery = 'id="' . $igoGeometrie->classe_entite_id . '"'; $igoClasseEntite = IgoClasseEntite::findFirst($classeEntiteQuery); } else { $igoClasseEntite = null; } //Find its classes if ($igoLayer->id) { $classesQuery = 'couche_id="' . $igoLayer->id . '"'; $igoClasses = IgoClasse::find($classesQuery); } else { $igoClasses = null; } } else { //If a layer with the same name doesn't exist //Create a new layer $igoLayer = new IgoCouche(); //Create a new geometry $igoGeometrie = new IgoGeometrie(); //Set some variables to null $igoClasseEntite = null; $igoClasses = null; } $groupID = null; if ($layer['wms_group_title']) { //Create a new group only if no context are to be created or if the layer has no group already if (!$igoContexte || !$layer['currentGroup']) { //Find all the sub-groups $groupNames = preg_split("/\\//", $layer['wms_group_title']); $fullGroupName = ''; $parent_groupe_id = null; foreach ($groupNames as $groupName) { //Build the full group name by appending the group name to the previous //full name. The full group name is used to store the ids of the //groups parsed already (but not yet commited) in order to create them only once //Exemple of two diffrent groups: //Vigilance/Inondation != MTQ/Inondation $fullGroupName .= '/' . $groupName; //Check if the group has been parsed already (from another layer) and retrieve its ID $found = false; foreach ($groups as $group) { if ($group['name'] == $fullGroupName) { $groupID = $group['id']; $found = true; break; } } //If the groups has not been created already, create it if (!$found) { //Check if this group exists in the database already $igoGroupe = IgoGroupe::findFirst('nom="' . $groupName . '"'); if ($igoGroupe) { //If it exists already, retrieve it's id $groupID = $igoGroupe->id; } else { //If it doesn't exist, create it and retrieve it's id $igoGroupe = new IgoGroupe(); $igoGroupe->nom = $groupName; $igoGroupe->est_exclu_arbre = 'FALSE'; if (!$igoGroupe->save()) { foreach ($igoGroupe->getMessages() as $message) { throw new Exception($message); } $this->db->rollback(); } $groupID = $igoGroupe->id; } $igoGroupe->specifie_parent($parent_groupe_id); //Store the id of the newly created group in the groups array $groups[] = array('name' => $fullGroupName, 'id' => $groupID); } $parent_groupe_id = $groupID; } } } //This array is used to define a couche_contexte for each excluded attribute $excludedAttributes = array(); if (!$igoClasseEntite) { //If the classe d'entité doesn't exist, create a new one $igoClasseEntite = new IgoClasseEntite(); //Else, set the classe d'entité name to the layer name $igoClasseEntite->nom = $layer['name']; // TODO : presentement on prend le premier catalogue du bord. Il faudra penser à une meilleure solution. $igoCatalogueCsw = IgoCatalogueCsw::findFirst(); if ($igoCatalogueCsw) { $igoClasseEntite->catalogue_csw_id = $igoCatalogueCsw->id; } if (!$igoClasseEntite->save()) { foreach ($igoClasseEntite->getMessages() as $message) { throw new Exception($message); } $this->db->rollback(); } } //if (!$igoClasseEntite) { // //Update or set the geometry attributes $igoGeometrie->mf_layer_projection = $layer['projection']; $igoGeometrie->mf_layer_data = $layer['data']; $igoGeometrie->connexion_id = $igoConnexion ? $igoConnexion->id : $igoGeometrie->connexion_id; $igoGeometrie->geometrie_type_id = $geometryTypes[$layer['type']]; $igoGeometrie->classe_entite_id = $igoClasseEntite->id; $igoGeometrie->vue_defaut = $layer['vue_defaut']; $igoGeometrie->acces = "L"; // Définir l'indice d'inclusion... $indice_inclusion = "T"; // T=Tous, E=Exclusion I=Inclusion foreach ($layer['attributes'] as $attribute) { if ($attribute['est_inclu']) { $indice_inclusion = "I"; break; } else { $indice_inclusion = "E"; break; } } $igoGeometrie->ind_inclusion = $indice_inclusion; if ($igoGeometrie->save(false) == false) { $this->db->rollback(); foreach ($igoGeometrie->getMessages() as $message) { throw new Exception($message); } } //Insert or update attributes foreach ($layer['attributes'] as $attribute) { $attributeQuery = 'geometrie_id="' . $igoGeometrie->id . '" AND colonne="' . $attribute['colonne'] . '"'; $igoAttribute = IgoAttribut::findFirst($attributeQuery); $update = false; if (!$igoAttribute) { $igoAttribute = new IgoAttribut(); $update = true; } else { if ($igoAttribute && !$igoContexte) { $update = true; } } if ($update) { $igoAttribute->colonne = $attribute['colonne']; $igoAttribute->est_cle = $attribute['est_cle'] ? 'TRUE' : 'FALSE'; $igoAttribute->est_inclu = $attribute['est_inclu'] ? 'TRUE' : 'FALSE'; $igoAttribute->geometrie_id = $igoGeometrie->id; if (!$igoAttribute->save(false)) { foreach ($igoAttribute->getMessages() as $message) { throw new Exception($message); } $this->db->rollback(); } } else { if ($igoContexte && !$attribute['est_inclu']) { if ($igoAttribute->est_inclu == 'TRUE') { $excludedAttributes[] = $igoAttribute->id; } } } } // Création ou mise à jour de la couche $igoLayer->type = $layer['location']; $igoLayer->geometrie_id = $igoGeometrie->id; $igoLayer->mf_layer_name = $layer['name']; $igoLayer->mf_layer_group = $layer['group']; $igoLayer->mf_layer_meta_name = $layer['wms_name']; $igoLayer->mf_layer_meta_attribution_title = $layer['wms_attribution_title']; $igoLayer->mf_layer_meta_title = $layer['wms_title']; $igoLayer->mf_layer_meta_group_title = $layer['wms_group_title']; $igoLayer->mf_layer_filtre = $layer['filter']; $igoLayer->mf_layer_opacity = $layer['opacity']; $igoLayer->mf_layer_minscale_denom = $layer['minscaledenom'] == -1 ? null : $layer['minscaledenom']; $igoLayer->mf_layer_maxscale_denom = $layer['maxscaledenom'] == -1 ? null : $layer['maxscaledenom']; $igoLayer->mf_layer_labelitem = $layer['labelitem']; $igoLayer->mf_layer_labelminscale_denom = $layer['labelminscaledenom'] == -1 ? null : $layer['labelminscaledenom']; $igoLayer->mf_layer_labelmaxscale_denom = $layer['labelmaxscaledenom'] == -1 ? null : $layer['labelmaxscaledenom']; $igoLayer->mf_layer_def = $layer['layer_def']; $igoLayer->mf_layer_meta_def = $layer['meta_def']; if (isset($layer['wfs_maxfeatures']) && is_numeric($layer['wfs_maxfeatures'])) { $igoLayer->mf_layer_meta_wfs_max_feature = $layer['wfs_maxfeatures']; } // Assignation du champ fiche_csw_id tel que décrit dans issue 39 $igoLayer->fiche_csw_id = $layer['name']; if (isset($layer['msp_classe_meta'])) { $igoLayer->fiche_csw_id = $layer['msp_classe_meta']; } //Check if some attributes should be overwritten in igoCoucheContexte $coucheContexteName = null; if ($igoContexte && $igoLayer->mf_layer_meta_name && $igoLayer->mf_layer_meta_name != $layer['wms_name']) { $coucheContexteName = $layer['wms_name']; } else { $igoLayer->mf_layer_meta_name = isset($layer['wms_name']) ? $layer['wms_name'] : $layer['name']; } $coucheContexteTitle = null; if ($igoContexte && $igoLayer->mf_layer_meta_title && $igoLayer->mf_layer_meta_title != $layer['wms_title']) { $coucheContexteTitle = $layer['wms_title']; } else { $igoLayer->mf_layer_meta_title = $layer['wms_title']; } $coucheContexteFilter = null; if ($igoContexte && $igoLayer->mf_layer_filtre && $igoLayer->mf_layer_filtre != $layer['filter']) { $coucheContexteFilter = $layer['filter']; } else { $igoLayer->mf_layer_filtre = $layer['filter']; } //If the new group is different than the current group, assign the new group the the context instead //of changing the group itself if ($layer['currentGroup'] && $layer['currentGroup'] != $layer['wms_group_title']) { $igoCoucheContexte->mf_layer_meta_group_title = $layer['wms_group_title']; } if (!$igoLayer->save(false)) { foreach ($igoLayer->getMessages() as $message) { throw new Exception($message); } $this->db->rollback(); } else { $layerSaveSuccessful = true; //If the layer has some classes defined already, delete them and re-insert them //We need to delete them and re-insert since it is not possible to update them //(they don't have a name on which we can query) if ($igoClasses) { foreach ($igoClasses as $igoClass) { if ($igoClass->delete() == false) { foreach ($igoClass->getMessages() as $message) { throw new Exception($message); } } } } //Save each classes and assign them a z order $mf_class_z_order = 0; foreach ($layer['classes'] as $class) { $igoClass = new IgoClasse(); $igoClass->mf_class_def = $class; $igoClass->couche_id = $igoLayer->id; $igoClass->mf_class_z_order = $mf_class_z_order; $igoClass->save(false); if ($igoLayer->save(false) == false) { foreach ($igoClass->getMessages() as $message) { throw new Exception($message); } $this->db->rollback(); } $mf_class_z_order++; } if ($groupID) { $igoGroupeeCouche = IgoGroupeCouche::findFirst('couche_id=' . $igoLayer->id . ' AND groupe_id=' . $groupID); if (!$igoGroupeeCouche) { $igoGroupeeCouche = new IgoGroupeCouche(); $igoGroupeeCouche->groupe_id = $groupID; $igoGroupeeCouche->couche_id = $igoLayer->id; $igoGroupeeCouche->save(); } } else { echo "La couche {$layer['name']} est dans aucun groupe.<br>"; } } } //Conserver = softinsert, Insérer/remplacer = insert if ($layer['action'] == 'softinsert' || $layer['action'] == 'insert' && $layerSaveSuccessful) { if (!isset($excludedAttributees)) { $excludedAttributes = array(); } if ($igoContexte) { //If no attributes are excluded, append a null value to the excluded attributes //array. This way a couche_contexte with no excluded attribute will be created if (count($excludedAttributes) == 0) { $excludedAttributes[] = null; } foreach ($excludedAttributes as $excludedAttribute) { $igoCoucheContexte = new IgoCoucheContexte(); $igoCoucheContexte->contexte_id = $igoContexte->id; $igoCoucheContexte->couche_id = $igoLayer->id; $igoCoucheContexte->layer_a_order = $layerIndex++; $nomComplet = str_replace("'", "_", $layer['wms_group_title']); while (!empty($nomComplet)) { // Fix pour que le groupe existe la première fois. $igoVueGroupesRecursif = IgoVueGroupesRecursif::findFirst("nom_complet like '%{$nomComplet}'"); $groupe_id = $igoVueGroupesRecursif ? $igoVueGroupesRecursif->groupe_id : $groupID; if ($groupe_id && $igoVueGroupesRecursif) { $arbre_id = $igoVueGroupesRecursif->grp; $igoCoucheContexteGroupe = IgoCoucheContexte::findFirst("contexte_id={$igoContexte->id} and couche_id IS NULL and arbre_id='{$arbre_id}'"); if (!$igoCoucheContexteGroupe) { $igoCoucheContexteGroupe = new IgoCoucheContexte(); $igoCoucheContexteGroupe->contexte_id = $igoContexte->id; $igoCoucheContexteGroupe->couche_id = null; $igoCoucheContexteGroupe->groupe_id = $groupe_id; $igoCoucheContexteGroupe->arbre_id = $arbre_id; $igoCoucheContexteGroupe->mf_layer_meta_name = $igoVueGroupesRecursif->nom; $igoCoucheContexteGroupe->mf_layer_meta_title = $igoVueGroupesRecursif->nom_complet; $a = explode("/", $igoVueGroupesRecursif->nom_complet); $s = array_pop($a); $igoCoucheContexteGroupe->mf_layer_meta_title = $s; $igoCoucheContexteGroupe->mf_layer_meta_group_title = $s; $igoCoucheContexteGroupe->layer_a_order = $layerIndex++; $igoCoucheContexteGroupe->est_visible = 'TRUE'; $igoCoucheContexteGroupe->ind_fond_de_carte = 'D'; $igoCoucheContexteGroupe->save(); } } $t = explode('/', $nomComplet); array_pop($t); $nomComplet = implode('/', $t); } $igoCoucheContexte->groupe_id = $groupe_id; $igoVueGroupesRecursif = IgoVueGroupesRecursif::findFirst("nom_complet like '%" . str_replace("'", "_", $layer['wms_group_title']) . "'"); $igoCoucheContexte->arbre_id = $igoVueGroupesRecursif ? $igoVueGroupesRecursif->grp : $groupe_id; $igoCoucheContexte->mf_layer_meta_name = $layer['wms_name']; $igoCoucheContexte->mf_layer_meta_title = $layer['wms_title']; $a = explode("/", $layer['wms_title']); $s = array_pop($a); $igoCoucheContexte->mf_layer_meta_title = $s; $igoCoucheContexte->mf_layer_meta_group_title = $s; $igoCoucheContexte->mf_layer_meta_z_order = $layer['zIndex']; $igoCoucheContexte->est_visible = 'TRUE'; $igoCoucheContexte->ind_fond_de_carte = 'D'; //Check if some attributes should be overwritten in igoCoucheContexte $coucheContexteName = null; if ($igoContexte && $igoLayer->mf_layer_meta_name && $igoLayer->mf_layer_meta_name != $layer['wms_name']) { $coucheContexteName = $layer['wms_name']; } else { $igoLayer->mf_layer_meta_name = $layer['wms_name'] ? $layer['wms_name'] : $layer['name']; } $coucheContexteTitle = null; if ($igoContexte && $igoLayer->mf_layer_meta_title && $igoLayer->mf_layer_meta_title != $layer['wms_title']) { $coucheContexteTitle = $layer['wms_title']; } else { $igoLayer->mf_layer_meta_title = $layer['wms_title']; } $coucheContexteFilter = null; if ($igoContexte && $igoLayer->mf_layer_filtre && $igoLayer->mf_layer_filtre != $layer['filter']) { $coucheContexteFilter = $layer['filter']; } else { $igoLayer->mf_layer_filtre = $layer['filter']; } if ($coucheContexteName) { $igoCoucheContexte->mf_layer_meta_name = $coucheContexteName; } if ($coucheContexteTitle) { $igoCoucheContexte->mf_layer_meta_title = $coucheContexteTitle; } if ($coucheContexteFilter) { $igoCoucheContexte->mf_layer_filtre = $coucheContexteFilter; } if ($excludedAttribute) { $igoCoucheContexte->attribut_id = $excludedAttribute; $igoCoucheContexte->est_exclu = 'TRUE'; } //If the new group is different than the current group, assign the new group the the context instead //of changing the group itself if ($layer['currentGroup'] && $layer['currentGroup'] != $layer['wms_group_title']) { $igoCoucheContexte->mf_layer_meta_group_title = $layer['wms_group_title']; } $this->igoCoucheContexteSave($igoCoucheContexte); } } } $igoCouches[] = $igoLayer; } } $this->db->commit(); if ($igoContexte !== null) { $igoContexte->saveMapFile(); } foreach ($igoCouches as $igoCouche) { $igoCouche->saveMapFile(false); } } catch (Exception $e) { error_log(json_encode($e)); throw $e; } }