<?php
/**
 * Ce script définit la classe *app_om_import*.
 *
 * @package opencimetiere
 * @version SVN : $Id$
 */

require_once "../obj/om_import_override.class.php";

/**
 * Définition de la classe *app_om_import* (om_import).
 *
 * Cette classe permet la surcharge de certaines méthodes de
 * la classe om_import du framework pour des besoins spécifiques
 * de l'application.
 */
class app_om_import extends import {
    function get_import_form_display__specific_geojson($obj) {
        // Enclenchement de la tamporisation de sortie
        ob_start();
        //
        echo "\n<div id=\"form-geojson-import\" class=\"formulaire\">\n";
        $this->f->layout->display__form_container__begin(array(
            "action" => OM_ROUTE_MODULE_IMPORT."&obj=".$obj,
            "name" => "f2",
        ));
        //
        $champs = array(
            "fic1",
            "table",
            "primarykey_fieldname",
            "geom_fieldname",
            "primarykey_propertyname",
        );
        //
        $form = $this->f->get_inst__om_formulaire(array(
            "validation" => 0,
            "maj" => 0,
            "champs" => $champs,
        ));
        //
        $form->setLib("fic1", __("Fichier GEOJSON"));
        $form->setType("fic1", "upload2");
        $form->setTaille("fic1", 64);
        $form->setMax("fic1", 30);
        $form->setSelect("fic1", array(
            "constraint" => array(
                "size_max" => 8,
                "extension" => ".geojson"
            ),
        ));
        //
        $form->setLib("table", __("Table"));
        $form->setType("table", "text");
        $form->setTaille("table", 60);
        $form->setMax("table", 100);
        //
        $form->setLib("primarykey_fieldname", __("Clé primaire - Nom de la colonne dans la table"));
        $form->setType("primarykey_fieldname", "text");
        $form->setTaille("primarykey_fieldname", 60);
        $form->setMax("primarykey_fieldname", 100);
        //
        $form->setLib("geom_fieldname", __("Champ géométrique - Nom de la colonne dans la table"));
        $form->setType("geom_fieldname", "text");
        $form->setTaille("geom_fieldname", 60);
        $form->setMax("geom_fieldname", 100);
        //
        $form->setLib("primarykey_propertyname", __("Clé primaire - Nom de la propriété dans le fichier GEOJson"));
        $form->setType("primarykey_propertyname", "text");
        $form->setTaille("primarykey_propertyname", 60);
        $form->setMax("primarykey_propertyname", 100);
        //
        $form->entete();
        $form->afficher($champs, 0, false, false);
        $form->enpied();
        $this->f->layout->display__form_controls_container__begin(array(
            "controls" => "bottom",
        ));
        $this->f->layout->display__form_input_submit(array(
            "name" => "submit-geojson-import",
            "value" => __("Importer"),
            "class" => "boutonFormulaire",
        ));
        $this->f->layout->display_lien_retour(array(
            "href" => OM_ROUTE_MODULE_IMPORT,
        ));
        $this->f->layout->display__form_controls_container__end();
        $this->f->layout->display__form_container__end();
        echo "</div>\n";
        // Affecte le contenu courant du tampon de sortie a $output puis l'efface
        $output = ob_get_clean();
        return $output;
    }
    function get_import_helper_display__specific_geojson($obj) {
        $output = sprintf(
            'Exemple de fichier GEOJson :<pre>{
    "type": "FeatureCollection",
    "name": "import-geojson-01",
    "crs": { 
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
        }
    },
    "features": [
        {
            "type": "Feature",
            "properties": {
                "id": 14,
                "id_conc": 1
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [ [ [ [ 2.162269863532345, 43.932334982006239 ], [ 2.162260449410437, 43.932339379625539 ], [ 2.162275324305131, 43.932356010074727 ], [ 2.162284738428571, 43.932351612454198 ], [ 2.162269863532345, 43.932334982006239 ] ] ] ]
            }
        },
        {   
            "type": "Feature",
            "properties": {
                "id": 22,
                "id_conc": 2
            },
            "geometry": null
        },
        {
            "type": "Feature",
            "properties": {
                "id": 33,
                "id_conc": 3
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [ [ [ [ 2.162269863532345, 43.932334982006239 ], [ 2.162260449410437, 43.932339379625539 ], [ 2.162275324305131, 43.932356010074727 ], [ 2.162284738428571, 43.932351612454198 ], [ 2.162269863532345, 43.932334982006239 ] ] ] ]
            }
        }
    ]
}
</pre>'
        );
        return $output;
    }
    function treatment_import__specific_geojson($obj) {
        // On vérifie que le formulaire a bien été validé
        if (!isset($_POST['submit-geojson-import'])) {
            return false;
        }
        $this->log(__METHOD__." - begin");
        // On vérifie que le fichier a bien été posté et qu'il n'est pas vide
        $message_check = "";
        if (isset($_POST['fic1']) !== true
            || (isset($_POST['fic1']) && $_POST['fic1'] == "")) {
            //
            $message_check .= __('Le champ').' <span class="bold">Fichier GEOJson</span> '.__('est obligatoire');
        }
        if (isset($_POST['table']) !== true
            || (isset($_POST['table']) && $_POST['table'] == "")) {
            //
            $message_check .= "<br/>".__('Le champ').' <span class="bold">Table</span> '.__('est obligatoire');
        }
        if (isset($_POST['primarykey_fieldname']) !== true
            || (isset($_POST['primarykey_fieldname']) && $_POST['primarykey_fieldname'] == "")) {
            //
            $message_check .= "<br/>".__('Le champ').' <span class="bold">Clé primaire - Nom de la colonne dans la table</span> '.__('est obligatoire');
        }
        if (isset($_POST['geom_fieldname']) !== true
            || (isset($_POST['geom_fieldname']) && $_POST['geom_fieldname'] == "")) {
            //
            $message_check .= "<br/>".__('Le champ').' <span class="bold">Champ géométrique - Nom de la colonne dans la table</span> '.__('est obligatoire');
        }
        if (isset($_POST['primarykey_propertyname']) !== true
            || (isset($_POST['primarykey_propertyname']) && $_POST['primarykey_propertyname'] == "")) {
            //
            $message_check .= "<br/>".__('Le champ').' <span class="bold">Clé primaire - Nom de la propriété dans le fichier GEOJson</span> '.__('est obligatoire');
        }
        if ($message_check !== "") {
            $this->f->displayMessage(
                "error",
                $message_check
            );
            $this->log(__METHOD__." - ".$message_check);
            $this->log(__METHOD__." - end");
            return false;
        }
        //
        $fichier_tmp = str_replace("tmp|", "", $_POST['fic1']);
        // On récupère le chemin vers le fichier
        $path = $this->f->storage->storage->temporary_storage->getPath($fichier_tmp);
        // On vérifie que le fichier peut être récupéré
        if (!file_exists($path)) {
            $class = "error";
            $message = __("Le fichier n'existe pas.");
            $this->f->displayMessage($class, $message);
            $this->log(__METHOD__." - ".$message);
            $this->log(__METHOD__." - end");
            return false;
        }
        $json = file_get_contents($path);
        $data = json_decode($json, TRUE);
        //
        if (is_array($data) !== true
            || array_key_exists("features", $data) !== true
            || is_array($data["features"]) !== true) {
            //
            $message = __("Le fichier GeoJSON n'est pas valide.");
            $this->f->displayMessage("error", $message);
            $this->log(__METHOD__." - ".$message);
            $this->log(__METHOD__." - end");
            return false;
        }
        $table = $_POST['table'];
        $id_fieldname = $_POST['primarykey_fieldname'];
        $id_propertyname = $_POST['primarykey_propertyname'];
        $geom_fieldname = $_POST['geom_fieldname'];
        $this->log(sprintf(
            '%s - table = %s - id_fieldname = %s - id_propertyname = %s - geom_fieldname = %s',
            __METHOD__,
            $table,
            $id_fieldname,
            $id_propertyname,
            $geom_fieldname
        ));
        // On instancie l'utilitaire de génération
        $g = $this->f->get_inst__om_gen();
        // On récupère la liste de toutes les tables de la base de données
        $tables = $g->get_all_tables_from_database();
        // On vérifie que la table passée en paramètre existe
        if (!in_array($table, $tables)) {
            $message = __("Le champ *Table* passé en paramètre n'existe pas.");
            $this->f->displayMessage("error", $message);
            $this->log(__METHOD__." - ERROR - ".$message);
            $this->log(__METHOD__." - end");
            return false;
        }
        // On vérifie que la clé primaire passée en paramètre existe
        if ($g->get_primary_key($table) !== $id_fieldname) {
            $message = __("Le champ *Clé primaire - Nom de la colonne dans la table* passé en paramètre n'existe pas.");
            $this->f->displayMessage("error", $message);
            $this->log(__METHOD__." - ERROR - ".$message);
            $this->log(__METHOD__." - end");
            return false;
        }
        
        $counters = array(
            "errors" => 0,
            "ok" => 0,
            "total" => 0,
        );
        foreach ($data["features"] as $key => $feature) {
            $counters["total"] += 1;
            //
            if (is_array($feature) !== true
                || array_key_exists("properties", $feature) !== true
                || is_array($feature["properties"]) !== true
                || array_key_exists($id_propertyname, $feature["properties"]) !== true) {
                //
                $message = sprintf(
                    'L\'élément JSON est mal formé'
                );
                $this->log(__METHOD__." - ERROR - ".$message);
                $this->f->db->rollback();
                $counters["errors"] += 1;
                continue;
            }
            // On désactive l'auto-commit
            $this->f->db->autoCommit(false);
            //
            $id_value = $feature["properties"][$id_propertyname];
            // Si les coordonnées transmis sont vides on souhaite vider le champ
            if ($feature["geometry"] === null) {
                $geom_value = "NULL";
            } else {
                $geom_value = sprintf(
                    'ST_Transform(ST_GeomFromGeoJSON(\'%s\'),2154)',
                    json_encode($feature["geometry"])
                );
            }
            $query = sprintf(
                'UPDATE %1$s%2$s SET %5$s=%6$s WHERE %2$s.%3$s=%4$s;',
                DB_PREFIXE,
                $table,
                $id_fieldname,
                $id_value,
                $geom_fieldname,
                $geom_value
            );
            $res = $this->f->db->query($query);
            $this->addToLog(
                __METHOD__."(): db->query(\"".$query."\");",
                VERBOSE_MODE
            );
            if ($this->f->isDatabaseError($res, true)) {
                $message = __("Erreur SQL pour l'id")." ".$id_value." ".$res->getDebugInfo()."\n";
                $this->log(__METHOD__." - ERROR - ".$message);
                $this->f->db->rollback();
                $counters["errors"] += 1;
                continue;
            }
            $affected_rows = $this->f->db->affectedRows();
            if ($affected_rows == 0) {
                $this->log(sprintf(
                    '%s - ERROR - Aucun enregistrement correspondant à id_value = %s',
                    __METHOD__,
                    $id_value
                ));
                $this->f->db->rollback();
                $counters["errors"] += 1;
                continue;
            }
            if ($affected_rows > 1) {
                $this->log(sprintf(
                    '%s - ERROR - Trop d\'enregistrements correspondants à id_value = %s',
                    __METHOD__,
                    $id_value
                ));
                $this->f->db->rollback();
                $counters["errors"] += 1;
                continue;
            }
            $counters["ok"] += 1;
            $this->log(sprintf(
                '%s - id_value = %s - geom_value = %s',
                __METHOD__,
                $id_value,
                $geom_value
            ));
            $this->f->db->commit();
        }
        //
        $this->log(__METHOD__." - Traitement terminé - ".print_r($counters, true));
        $this->f->displayMessage(
            "ok",
            __("Le traitement d'import est terminé.")." ".sprintf('%s éléments importés avec succès sur %s.', $counters["ok"], $counters["total"])
        );
        $this->log(__METHOD__." - end");
    }
}
