<?php

/*******************************************************************************\
 * BIODIV, plugin et squelette pour SPIP - https://www.spip.net/               *
 *         dédié à la gestion d'observations naturalistes                      *
 *                                                                             *
 *         Copyright (C) 2008-2024 Renaud LAURETTE                             *
 *                                                                             *
 * BIODIV a été développé initialement pour le projet Biodiv.Balma de l'APCVEB *
 * (Association de Protection du Cadre de Vie et de l'Environnement balmanais) * 
 *     voir Biodiv.Balma : https://balma.biodiv.fr/                            *
 *     voir APCVEB : http://apcveb.free.fr/                                    *
 *                                                                             *
 *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.         *
 *  Pour plus de détails voir les fichier COPYING.txt et LICENCE-BIODIV.md     *
\*******************************************************************************/

include_spip("inc/autoriser");
include_spip("inc/ordres_biodiv");


function formulaires_importer_biodiv_charger_dist() {

	// Initialisation du formulaire
	$valeurs = array();
	// verifier les droits
	if(!autoriser('ordonner')) {
		$valeurs['editable'] = false;
		return $valeurs;
	}
	
	return $valeurs;
}



function formulaires_importer_biodiv_verifier_dist() 
{
	$erreurs = array();
			
	// vérifier le fichier transmis
	if (isset($_FILES['ordres']) AND $_FILES['ordres']['tmp_name']) {
		$doc=&$_FILES['ordres'];
		// Chargement DOM du XML
		$ordresXml = new DOMDocument();
		if(!$ordresXml->load(realpath($doc['tmp_name']))) {
			$erreurs['message_erreur'] = _T('biodiv:msg_echec_parse_xml');
			spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
		} else {
			// Reception et parsing xml ok
			// Vérification de la source
			libxml_use_internal_errors(true);
			if (!$ordresXml->schemaValidate(find_in_path("xsl/observations.xsd"))) {
				$erreurs['message_erreur'] = _T('biodiv:msg_echec_validation_xml',array('xsd'=>'observations.xsd'));
				$erreurs['message_erreur'] .= erreurs_libxml();
				spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
				return $erreurs;
			}
			// on transforme
			if($f=find_in_path("xsl/observations4spip.xsl")) {
				// transfo XSL trouvée - on la charge comme XML
				$xslDoc = new DOMDocument();
				if($xslDoc->load(realpath($f))) {
					// Transformation
					$proc = new XSLTProcessor();
					if($proc->importStylesheet($xslDoc)) {
						if($proc->setParameter('','source',_request('source'))) {
							if($out = $proc->transformToDoc($ordresXml)) {
								// sauvegarde du resultat dans un fichier temporaire
								$outfile = realpath(tempnam(_NOM_TEMPORAIRES_INACCESSIBLES,"order"));
								$out->save($outfile);
								// Remplacement du fichier chargé par le fichier calculé
								unlink($doc['tmp_name']);
								$doc['tmp_name'] = $outfile;
							} else {
								$erreurs['message_erreur'] = _T('biodiv:msg_echec_transformation');
								spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
							}
						} else {
							$erreurs['message_erreur'] = _T('biodiv:msg_echec_xsl_param',array('p'=>"source=" . _request('source')));
							spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
						}
					} else {
						$erreurs['message_erreur'] = _T('biodiv:msg_echec_load_xsl');
						spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
					}
				} else {
					$erreurs['message_erreur'] = _T('biodiv:msg_echec_load_xsl');
					spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
				}
			} else {
				$erreurs['message_erreur'] = _T('biodiv:no_xsl');
				spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
			}
		}
		
	} else {
		$erreurs['message_erreur'] = _T('biodiv:msg_echec_telechargement');
		spip_log("Importer biodiv -- Verification : ".$erreurs['message_erreur'] , "biodiv.".__LOG_INFO_IMPORTANTE);
	}
	return $erreurs;
}

// Fonction de traitement
// A ce stade, le fichier $_FILES['ordres'] n'est plus le fichier téléchargé, mais le
// résultat de la transformation XSL : c'est devenu un fichier d'ordres précis à traiter.
// Ces ordres vont être traités un par un via SimpleXML

function formulaires_importer_biodiv_traiter_dist() {
	spip_log("Importer biodiv - Traitement : DEBUT", "biodiv");
	$resultat = array();
	$doc=&$_FILES['ordres'];
	$ordresXml = simplexml_load_file($doc['tmp_name']);
	$numOrdre=0;	// Rang de l'ordre dans le fichier
	$avancement="";	// Description des instructions exécutées
	$ignorerUnicite = false;
	if(_request('unicite') == 'ignorer') $ignorerUnicite = true;
	
	foreach($ordresXml->lier as $lier) {
		// Traitement des ordres destinés à lier deux objets
		// Préparation de la description de l'ordre
		$numOrdre++; $avx='';
		foreach($lier->attributes() as $key => $value) { $avx .= ' '.$key.'='.$value; }
		$avancement .= _T('biodiv:msg_ordre_lier',array('num'=> $numOrdre, 'avx' => $avx));
		// On parse l'ordre pour créer une structure exécutable, et on déclenche l'exécution
		$ordre = ordreLier($lier);
		$avancement .= '<br/><pre>'.print_r($ordre,true) . "</pre><br/>\n";
		// On examine le statut retourné par l'exécution
		if($ordre['pret']) {
			// Succès : on enregistre le statut et on continue
			$avancement .= '<br/> --  ok<br/>';
			$resultat['message_ok'] = $avancement;
		} else if ($ordre['skip']) {
			$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_attention',array('e'=>$ordre['erreur'])) . '<br/>';
			$resultat['message_ok'] = $avancement;
		} else {
			// Echec : on enregistre le statut et on interrompt
			$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_fatal',array('e'=>$ordre['erreur'])) . '<br/>';
			$resultat['message_erreur'] = $avancement;
			return $resultat;
		}
	}
	
	foreach($ordresXml->creer as $creer) {
		// TRaitement des ordres de création
		// Préparation de la description de l'ordre
		$numOrdre++; $avx='';
		foreach($creer->attributes() as $key => $value) { $avx .= ' '.$key.'='.$value; }
		$avancement .= _T('biodiv:msg_ordre_creer',array('num'=> $numOrdre, 'avx' => $avx));
		// Controle d'unicité
		if($ignorerUnicite OR controleUnicite($creer)) {
			// Préparation de l'ordre et exécution
			$ordre = ordreCreer($creer);
			$avancement .= '<br/><pre>'.print_r($ordre,true) . "</pre><br/>\n";
			// Traitement du code retour
			if($ordre['pret']) {
				// Succès de l'ordre créer - on enregistre le statut
				$self = $ordre['id'];
				$avancement .= "<br/> --  ok id=$self<br/>";		
				$resultat['message_ok'] = $avancement;
				// Un ordre "créer" peut contenir des sous-ordres "lier" qui se réfèrent à "self"
				// Le "self" correspond à l'objet qui vient d'être créé.
				foreach($creer->lier as $lier) {
					// On parcourt les sous-ordres "lier"
					$numOrdre++; $avx='';
					foreach($lier->attributes() as $key => $value) { $avx .= ' '.$key.'='.$value; }
					$avancement .= $numOrdre . ": Lier $avx ";
					// Préparation de l'ordre et exécution
					$ordre = ordreLier($lier,$self);
					$avancement .= '<br/><pre>'.print_r($ordre,true) . "</pre><br/>\n";
					// Traitement du code retour
					if($ordre['pret']) {
						// Succès du sous-ordre "lier": on enregistre le statut et on continue
						$avancement .= '<br/> --  ok<br/>';
						$resultat['message_ok'] = $avancement;
					} else if ($ordre['skip']) {
						$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_attention',array('e'=>$ordre['erreur'])) . '<br/>';
						$resultat['message_ok'] = $avancement;
					} else {
						// Echec du sous-ordre "lier": on enregistre le statut et on interrompt
						$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_fatal',array('e'=>$ordre['erreur'])) . '<br/>';
						$resultat['message_erreur'] = $avancement;
						return $resultat;
					}
				} // fin des sous-ordres "lier"
			} else {
				// Echec de l'ordre créer : on enregistre le statut et on interrompt
				$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_fatal',array('e'=>$ordre['erreur'])) . '<br/>';
				$resultat['message_erreur'] = $avancement;
				return $resultat;
			}
		} else {
			// L'ordre requiert l'unicité et un objet existe déjà.
			$avancement .= '<br/> --  '. _T('biodiv:msg_ordre_attention',array('e'=>'doublon')) . '<br/>';
		}
	}
	
	// D'autres ordres éventuels devraient être insérés ici
	
	// Tout est fini
	// On détruit le fichier temporaire des ordres et on retourne le résultat
	$avancement.='<br/><b>' . _T('biodiv:msg_succes_ordonner',array('qty'=>$numOrdre)) . '</b><br/>';
	$compteRendu = rapportAvancement($doc['tmp_name'], $avancement,$numOrdre);
	$resultat['message_ok'] = $compteRendu;
	
	// unlink($doc['tmp_name']);
	return $resultat;
}

function rapportAvancement($fname,$avancement,$num) {
	$where = _DIR_RACINE . _NOM_TEMPORAIRES_ACCESSIBLES .'order_'.time();
	$fxml = $where.".xml";
	$fhtml = $where.".html";
	
	rename($fname,$fxml);
	$txt = "<!DOCTYPE html>\n<html>\n<head>\n     <meta charset='UTF-8'>\n</head>\n";
	$txt .= "<h1>Rapport d'exécution</h1>\n";
	$txt .= "<p>Traitement du <a href='".url_absolue($fxml)."' target='_blank'>fichier d'ordre</a></p>\n";
	$txt .= "<h2>Résultat</h2>\n";
	$txt .= $avancement;
	$txt .= "</body>\n</html>\n";
	file_put_contents($fhtml,$txt);
	
	$retour = "<p>Importation terminée. $num ordre(s) traités avec succès.<br/>Consultez le <a href='".url_absolue($fhtml)."' target='_blank'>rapport d'exécution</a>.</p>\n";
	return $retour;
}

?>
