<?php

// -------------------------------------- APPEL PRINCIPAL ------------------------------------------

// Fonction principale appelee par le script empaqueteur.php
// Elle lance successivement:
// 1. la creation des zips et de la base des logos
// 2. le nettoyage des paquets obsoletes
// 3. la creation du fichier xml des paquets
// 4. la creation du fichier des traductions de Salvatore
// 5. la creation d'un index des logos
//
// $url                 : url du repository des sources (ex: svn://zone.spip.org/spip-zone)
// $dir_repo    : repertoire racine des sources extraits du repository (ex: spip-zone)
// $dir_paq             : repertoire de depot des paquets crees (ex: paquets)
// $src                 : nom du fichier listant les archives a creer (ex: archivelist.txt)
// $dest                : nom sans extension du fichier xml recapitulant toutes les archives (ex: archives)
// $dtd_prio    : DTD a utiliser en priorite (plugin ou paquet)
// $nom_vcs             : gestionnaire de versions motorisant le repository concerne (ex: svn)
// $mail_to             : destinataire des mails d'information
// $mail_from   : emetteur des mails d'information
//
// return               : aucun
function empaqueteur($url, $dir_repo, $dir_paq, $src, $dest, $dtd_prio, $nom_vcs, $mail_to, $mail_from) {
        global $erreurs;
        $dir_tmp = $dir_paq.'tmp/';
        require('inc_outils.php');

        // On charge les includes correspondant aux DTD utilisees
        require('empaqueteur_plugin.php');
        require('empaqueteur_paquet.php');

        $erreurs = array();
        $url = trim($url);
        $dir_repo = rtrim($dir_repo ? $dir_repo : basename($url),'/') .'/';
        $dir_paq = rtrim($dir_paq ? $dir_paq : '.','/') .'/';
        
        // 1. creation des zips et de la base des logos
        list($depot, $zips, $logos, $xmls) = empaqueteur_archives($url, $dir_repo, $dir_paq, $src, $nom_vcs, $dtd_prio);
        
        // 2. nettoyage des paquets et logos obsoletes
        if (!$erreurs) {
                $fichiers_a_conserver = array_keys($zips);
                $fichiers_a_conserver = array_merge($fichiers_a_conserver, $logos);
                $fichiers_a_conserver = array_merge($fichiers_a_conserver, $xmls);
                // ne pas nettoyer le fichier archives.xml !
                foreach(is_array($dest) ? $dest : array($dest) as $nom_dest)
                        $fichiers_a_conserver[] = $nom_dest . '.xml';
                // ne pas nettoyer le fichier traductions.txt !
                $fichiers_a_conserver[] = 'traductions.txt';
                // ne pas nettoyer l'index des logos logos.php !
                $fichiers_a_conserver[] = 'logos.php';
                nettoyer_vieux_fichiers($fichiers_a_conserver, $dir_paq . $dir_repo, $dir_tmp);
        }
        elseif ($mail_to) 
                envoyer_mail($erreurs, $mail_to, $mail_from);

        
        // 3. la creation du fichier xml des paquets
        // -- obtention des contenus du fichier xml des paquets et de celui des traductions Salvatore
        list($archives, $salvatore) = empaqueteur_resultats($depot, $zips);
        if ($archives)
                empaqueteur_xml_archives($dest . '.xml', $archives, $dir_paq, $dir_repo);
        else
                echo_trace("Aucun Zip produit");

        // 4. la creation du fichier des traductions de Salvatore
        if ($salvatore)
                empaqueteur_salvatore('traductions.txt', $salvatore, $dir_paq, $dir_repo);
        else
                echo_trace("Aucune traduction avec Salvatore");

        // 5. la creation d'un index des logos
        empaqueteur_index_logos('logos.php', $dir_paq, $dir_repo);
}


// ---------------------------------- CREATION DES ARCHIVES ----------------------------------------

// Fonction de creation des zips et de la base des logos
// Elle lance successivement:
// 1. Creation des repertoires de travail et import initial (uniquement la premiere fois)
// 2. Check-out ou update des sources a archiver
// 3. Lecture de la liste des archives a creer
// 4. Creation de la liste des archives requises
//
// $url                 : url du repository des sources (ex: svn://zone.spip.org/spip-zone)
// $dir_repo    : repertoire racine des sources extraits du repository (ex: spip-zone)
// $dir_paq             : repertoire de depot des paquets crees (ex: paquets)
// $src                 : nom du fichier listant les archives a creer (ex: archivelist.txt)
// $nom_vcs             : gestionnaire de versions motorisant le repository concerne (ex: svn)
// $dtd_prio    : DTD a utiliser en priorite (plugin ou paquet)
//
// return               : tableau des infos du depot et des zips crees
//                                      0 : tableau associatif (info -> valeur) de chaque info collectee sur le depot
//                                      1 : tableau associatif (nom de l'archive -> liste des infos) des zips crees
//                                      2 : tableau de logos crees
//                                      3 : tableau des xml copies
function empaqueteur_archives($url, $dir_repo, $dir_paq, $src, $nom_vcs, $dtd_prio) {
        // Definition des deux sous-repertoires temporaires et definitifs des paquets
        $dir_tmp = $dir_paq.'tmp/';
        $dir_paq .= $dir_repo;

        // 1. Creation des repertoires de travail et import initial
        if (!file_exists($dir_repo)){
                // TODO : refaire
                die("$dir_repo non initialise avec $nom_vcs");
                //preparer_chemin(dirname(rtrim($dir_repo,'/')));
                //if ($url) $vcs("checkout", "$url $dir_repo");
        }
        if (!file_exists($dir_paq))
                preparer_chemin($dir_paq);
        if (!file_exists($dir_tmp))
                preparer_chemin($dir_tmp);

        // 2. Check-out ou update des sources a archiver
        // Si le repo est en file:// on fait un svnsync dessus,
        // le up est fait par un hook post-commit sur ce qui a change uniquement
        // sauf une fois par jour
        if (vcs_smart_update($nom_vcs, $dir_repo, _FORCE_UPDATE)
                and !_FORCE_UPDATE) {
                // fichiers modifies depuis la derniere heure
                $dirs_changed = dirschanged_read($dir_repo, time()-3600);
                if ($dirs_changed) {
                        echo_trace("Dossiers modifies : ".implode(", ",$dirs_changed));
                }
                else {
                        echo_trace("Aucun dossiers modifie");
                }
        }
        else {
                $dirs_changed = null;
        }

        // 3. Lecture de la liste des archives a creer et des informations sur le depot
        list($depot, $paquets) = lister_paquets($dir_repo . $src);

        // 4. Creation de la liste des archives requises
        $zips = $logos = $xmls = array();
        foreach($paquets as $_paquet){
                if ($_paquet['revision']=='HEAD' 
                AND list($infos, $logo, $xml) = creer_paquet($_paquet, $dir_repo, $dir_paq, $dir_tmp, $nom_vcs, $dtd_prio, $dirs_changed)) {
                        $zips[$_paquet['nom'] .".zip"] = $infos;
                        if ($logo) $logos[] = $logo;
                        if ($xml) $xmls[] = $xml;
                        if (intval(_SLEEP_BETWEEN)) usleep(_SLEEP_BETWEEN);
                }
        }
        echo_trace(count($zips) . " trouves");

        return array($depot, $zips, $logos, $xmls);
}


// Lister les paquets demandes dans le fichier des archives
// et compiler les informations sur le depot
//
// $src                 : nom du fichier listant les archives a creer
//
// return               : tableau des infos du depot et des archives a creer
//                                      0 : tableau associatif (info -> valeur) de chaque info collectee sur le depot
//                                      1 : tableau associatif des archives a creer (source, nom, nom_dossier et revision)
function lister_paquets($src) {

        echo_trace("chargement de $src");
        if (!$archivefile=file($src)){
                echo_trace("Erreur : Impossible de lire $src");
                return array();
        }

        $depot = array();
        $paquets = array();
        foreach($archivefile as $ligne=>$lignepaquet){
                //on vire le retour ligne de la fin
                $lignepaquet=rtrim($lignepaquet);
                if (strlen($lignepaquet)) {
                        if (substr($lignepaquet,0,1)!="#") {
                                // C'est une ligne de definition d'un paquet :
                                // - on separe les parametres
                                // - et on fixe ceux manquants
                                $a = explode(";",$lignepaquet);
                                $b = preg_split("/:/",$a[0]);
                                $source = trim($b[0]);
                                $svn_version = empty($b[1]) ?'HEAD' : trim($b[1]);              
                                $nom_paquet = empty($a[1]) ? basename($source) : trim($a[1]);
                                $nom_dossier = empty($a[2]) ? $nom_paquet : trim($a[2]);
                                // Ajout au tableau des paquets a construire
                                $paquets[] = array('source'=>rtrim($source,'/'),
                                                   'nom'=>$nom_paquet,
                                                   'nom_dossier'=>$nom_dossier,
                                                   'revision'=>$svn_version);
                        }
                        else if (preg_match('#@([^=\s]+)\s*=(.+)$#', substr($lignepaquet, 1), $matches)){
                                // C'est une ligne d'information sur le depot
                                // - on stocke le parametre trouve
                                $depot[trim($matches[1])] = trim($matches[2]);
                        }
                }
        }

        echo_trace(count($depot)." informations de depot definies");
        echo_trace(count($paquets)." paquets definis");
        return array($depot, $paquets);
}
        

// Fonction de creation d'un paquet soit :
// - de l'archive des sources (zip actuellement)
// - des informations completes sur le paquet (yc la liste des traductions)
// - et de son logo eventuel
//
// $paquet              : tableau des infos sur l'archive a creer
// $dir_repo    : repertoire racine des sources extraits du repository
// $dir_paq             : repertoire de depot des paquets crees
// $dir_tmp             : repertoire temporaire de depot des archives crees
// $nom_vcs             : methode vcs (git, gitsvn, svn)
// $dtd_prio    : DTD a utiliser en priorite (plugin ou paquet)
// $dirs_changed : repertoires modifies depuis le dernier passage
//
// return               : tableau des infos
//                  0 : paquet cree
//                                              0 : taille du paquet
//                                              1 : date du paquet
//                                              2 : arborescence des sources du paquet (relatif a l'url des sources)
//                                              3 : date du dernier commit
//                                              4 : liste des traductions sous la forme de la balise XML <traductions>
//                                              5 : contenu du fichier xml du plugin
//                                              6 : balises nom, slogan et description en multi tirees des fichiers de langue
//                                              7 : dtd utilisee
//                  1 : logo cree (fichier)
//                  2 : xml recopie (fichier)
function creer_paquet($paquet, $dir_repo, $dir_paq, $dir_tmp, $nom_vcs, $dtd_prio, $dirs_changed=null) {
        // Verifier le repertoire source du paquet a creer
        $dsource = $dir_repo. $paquet['source'];
        if (!file_exists($dsource)){
                echo_trace("Erreur : $dsource inexistant");
                return false;
        }

        $cache = $dir_paq . ".".str_replace("/",".",$paquet['nom']).".cache";
        $zip = $paquet['nom'] .".zip";
        $zippath = $dir_paq.$zip;

        $changed = true;
        if (strpos($paquet['source'], 'tags/') === 0) {
                // un tag ne change jamais : une fois que le zip existe on ne le regenere jamais
                $changed = false;
        }
        else {
                // si on a une liste des repertoires modifies, on sait si le contenu a change ou pas
                if (!is_null($dirs_changed) AND !in_array($dsource,$dirs_changed)) {
                        $changed = false;
                }
        }

        if (!$changed
                AND file_exists($zippath)
                AND file_exists($cache)
                AND $res = file_get_contents($cache)
                AND $res = unserialize($res)
                AND $res[0][2] == $paquet['source']
        ) {

                // rien a faire
                echo_trace("(info) $zippath depuis le cache $cache");
        }
        else {

                // verifier les externals si besoin (concerne le core principalement)
                vcs_externals_smart_update($nom_vcs, $dir_repo, $paquet['source']);

                // Creation de l'archive
                // -- Ajouter le fichier svn.revision dans les fichiers de l'archive pour les besoins de SPIP
                $file_rev = $dsource . "/svn.revision";
                $last_commit = renseigner_revision_paquet($nom_vcs, $dir_repo, $paquet['source'], $file_rev);
                $date_commit = $last_commit[1];
                // -- zipper les sources incluant le fichier svn.revision
                if (!archiver($dsource, $zip, $zippath, $paquet['nom_dossier'], $last_commit, $dir_tmp))
                        return false;
                // -- Traiter le cas de SPIP :
                //    copier le svn.revision de stable/spip.zip qui permet de connaitre la derniere version stable
                if ($zip=="stable/spip.zip") {
                        // necessaire de remettre le fichier a la date actuelle
                        // car il a la date du dernier commit sur ce paquet
                        # touch($dsource."/svn.revision");
                        copie_update($file_rev, $dir_paq.dirname($zip)."/svn.revision");
                }
                // -- supprimer le fichier info revision cree ci-dessus
                @unlink($file_rev);

                // Determination de la dtd a utiliser
                $dtd = '';
                $desc = '';
                $f = $dsource . '/' . $dtd_prio . '.xml';
                if (file_exists($f))
                        $dtd = $dtd_prio;
                else {
                        $autre_dtd = ($dtd_prio == 'plugin') ? 'paquet' : 'plugin';
                        $f = $dsource . '/' . $autre_dtd . '.xml';
                        if (file_exists($f))
                                $dtd = $autre_dtd;
                        else {
                                // Paquet sans xml correspondant a une contribution quelconque
                                echo_trace("(info) Paquet $zip sans fichier XML");
                        }
                }

                $traductions = '';
                $logo = '';
                $multis = '';
                $xml = false;
                $autorisations = '';
                if ($dtd) {
                        // Recuperer le xml qui decrit le plugin et suppression de l'entete XML si elle existe
                        $re = ",<"."\?xml[^>]*\?".">,Uims";
                        $desc = trim(preg_replace($re, '', file_get_contents($f)));

                        // Construire la liste des traductions du plugin
                        $traductions = compiler_traductions($dsource);

                        // Contruire les balises multi du nom, slogan et description qui ne sont plus dans le paquet
                        $f = 'empaqueteur_' . $dtd . '_multi';
                        $multis = !function_exists($f) ? '' : $f($dsource);

                        // Lister les autorisations du plugin
                        // -- détermination de la regexp en fonction de la DTD
                        $regexp = ($dtd == 'plugin')
                                ? "#<pipeline>\s*<nom>\s*autoriser\s*</nom>\s*<inclure>\s*([\w/_.]*)\s*</inclure>#imU"
                                : "#<pipeline\s+nom=['\"]autoriser['\"]\s+inclure=['\"]([\w/_.]*)['\"][^>]*>#imU";
                        // -- récupération des autorisations si elle existe
                        $autorisations = lister_autorisations($regexp, $desc, $dsource);

                        // Creer le logo du paquet
                        $f = 'empaqueteur_' . $dtd . '_logo';
                        $f = !function_exists($f) ? '' : $f($desc, $dsource);
                        if ($f AND file_exists($f) AND preg_match('/[.][^.]*$/', $f, $r)) {
                                $logo = $paquet['nom'] . $r[0];
                                $d = $dir_paq . $logo;
                                copy($f, $d);
                        }

                        // Copier le fichier xml de description du plugin au meme endroit que les logos et zips
                        $xml = $paquet['nom'] . '.xml';
                        if (strlen($desc))
                                file_put_contents($dir_paq . $xml, $desc);
                }

                $res = array(
                                                array(
                                                        filesize($zippath),
                                                        filemtime($zippath),
                                                        $paquet['source'],
                                                        $date_commit,
                                                        $traductions,
                                                        $desc,
                                                        $multis,
                                                        $dtd,
                                                        $autorisations),
                                        $logo,
                                        $xml);

                file_put_contents($cache,serialize($res));
        }
        
        return $res;
}


// Fonction de creation d'une archive des sources contenu dans une arborescence donnee.
// Aujourd'hui l'archive est toujours un zip
//
// $source              : emplacement des sources a archiver
// $zip                 : nom de l'archive a creer
// $zippath             : chemin complet de l'archive a creer
// $nom_dossier : arborescence dans le zip qui sera cree lors du dezippage
// $rev                 : tableau des informations sur le dernier commit (revision, date)
// $dir_tmp             : repertoire temporaire de depot des archives creees
//
// return               : true/false
function archiver($source, $zip, $zippath, $nom_dossier, $rev, $dir_tmp){
        $zipfile = basename($zip);
        list($revision, $date_commit) = $rev;
        $date_paquet = file_exists($zippath) ? filemtime($zippath) : 0;
        // tester si le paquet est a jour
        if (strtotime($date_commit) <= $date_paquet AND !_FORCE_UPDATE) {
                echo_trace("$zip OK : du ".date('Y-m-d H:i:s',$date_paquet)." / dernier commit du $date_commit");
                return true;
        }
        else {
                echo_trace("$zip OLD : du ".date('Y-m-d H:i:s',$date_paquet)." / dernier commit du $date_commit");
                $tmp = $dir_tmp.$nom_dossier;
                preparer_chemin($tmp);
                if (!rename($source,$tmp)) {
                        echo_trace("Erreur : $source --> $tmp");
                        return false;
                } else {
                        $d = getcwd();
                        chdir($dir_tmp);
                        // avant de zipper il faut timestamper le dossier conteneur a la date du dernier commit
                        // pour que le shasum du zip ne change que si le dernier commit change
                        $dp = explode('/', $nom_dossier);
                        $base_dir = reset($dp);
                        $timestamp = strtotime($date_commit);
                        $dirchtime = '';
                        while (count($dp) and $part = array_shift($dp)) {
                                $dirchtime .= "$part/";
                                @touch($dirchtime, $timestamp);
                        }
                        // zipper en prenant la date du fichier le plus recent
                        // comme date du paquet
                        exec_trace("zip -roXq $zipfile $base_dir -x \*/.svn\*");
                        chdir($d);

                        $date_paquet = filemtime($dir_tmp.$zipfile);
                        // cas ou le dernier commit consiste en la suppression de fichiers
                        // du coup le zip est plus ancien que le dernier commit
                        // on corrige manuellement
                        if ($date_paquet<strtotime($date_commit)) {
                                touch($dir_tmp.$zipfile,strtotime($date_commit)+1);
                        }
                        rename($tmp,$source);
                }
                supprimer_chemin($dir_tmp,$nom_dossier);
                copie_update($dir_tmp.$zipfile,$zippath);
                return true;
        }
}


// Fonction de compilation de la liste des traductions d'un plugin sous forme d'une suite
// de balises <traduction>
// On considere que les fichiers de langue ou les rapports de salvatore sont toujours dans
// le sous-repertoire lang/
//
// $source              : emplacement des sources du plugin
//
// return               : chaine composee des balises <traduction>
function compiler_traductions($source){

        // On charge une fois la liste des codes de langues
        if (empty($GLOBALS['codes_langues']));
                include('inc_langues.php');

        $traductions = '';

        // Determination des modules sous salvatore : on cherche les rapports xml
        $modules_salvatore = array();
        if ($rapports = glob($source . '/lang/*.xml')) {
                foreach ($rapports as $_rapport) {
                        $modules_salvatore[] = basename($_rapport, '.xml');
                        $contenu = file_get_contents($_rapport);
                        $traductions .= $contenu;
                }
        }

        // Determination des modules non traduits par salvatore
        // Cette recherche n'est pas totalement deterministe car on est oblige de considerer
        // qu'il existe toujours un fichier module_fr.php pour identifier le nom du module
        if ($fichiers_fr = glob($source . '/lang/*_fr.php')) {
                foreach ($fichiers_fr as $_fichier_fr) {
                        $nom_fichier = basename($_fichier_fr, '.php');
                        // On exclut les fichiers de traduction du paquet.xml
                        if (strpos($nom_fichier, 'paquet-') === false ) {
                                $module = substr($nom_fichier, 0, strlen($nom_fichier)-3);
                                // Si ce module n'a pas ete traite dans un rapport Salvatore on cherche toutes
                                // ses traductions via les fichiers de langue.
                                if (isset($module) && !in_array($module, $modules_salvatore) 
                                AND ($fichiers_langue = glob($source . "/lang/".$module."_*.php"))) {
                                        $liste_langues = '';
                                        foreach ($fichiers_langue as $_fichier_langue) {
                                                $nom_fichier = basename($_fichier_langue, '.php');
                                                $langue = substr($nom_fichier, strlen($module) + 1 - strlen($nom_fichier));
                                                // Si la langue est reconnue, on l'ajoute a la liste des traductions
                                                // Comme on ne connait pas les traducteurs, la balise est donc vide
                                                if (isset($GLOBALS['codes_langues'][$langue]) AND $langue != 'fr')
                                                        $liste_langues .= "\t" . '<langue code="' . $langue . '" />' . "\n";
                                        }
                                        // Le gestionnaire n'est pas precise et la langue de reference est toujours le fr
                                        $traductions .= '<traduction module="' . $module . '" reference="fr">' . "\n" . 
                                                                        $liste_langues .
                                                                        '</traduction>' . "\n";                 
                                }
                        }
                }
        }
        
        // On inclus les balise <traduction> dans une balise <traductions> sans attribut qui
        // facilite le travail du parser
        if ($traductions)
                $traductions = '<traductions>' . "\n" . $traductions . '</traductions>' . "\n"; 
        
        return $traductions;
}


// Fonction de compilation de la liste des autorisations d'un plugin sous forme d'une suite
// de balises <autorisation> incluses dans une balise englobantes <autorisations>
//
// $regexp              : regpex de récupération du pipeline autoriser dans le xml
// $xml                 : contenu de fichier xml du plugin
// $source              : emplacement des sources du plugin
//
// return               : chaine composee des balises <autorisation>
function lister_autorisations($regexp, $xml, $source) {
        $autorisations = '';

        // Recherche du pipeline autoriser dans le xml du plugin
        if (preg_match($regexp, $xml, $matches)) {
                $fichier_autorisations = $source . '/' . $matches[1];
                if (file_exists($fichier_autorisations)) {
                        $contenu = file_get_contents($fichier_autorisations);
                        if (preg_match_all("%function\s+autoriser_([^\(]*)%ims", $contenu, $matches)) {
                                $fonctions = array_map('trim', $matches[1]);
                                foreach($fonctions as $_fonction) {
                                        if (substr($_fonction, -5)=='_dist') {
                                                $dist = 'oui';
                                                $nom = substr($_fonction, 0, strlen($_fonction)-5);
                                        } else {
                                                $dist = 'non';
                                                $nom = $_fonction;
                                        }
                                        $autorisations .= "\t" . '<autorisation nom="' . $nom . '" dist="' . $dist . '" />' . "\n";
                                }
                        }
                }
        }

        return ($autorisations ? "<autorisations>\n$autorisations</autorisations>" : '');
}


// --------------------------- CREATION DES FICHIERS RESULTAT --------------------------------------

// Construit la concatenation des informations essentielles
// contenu dans les fichiers plugin.xml et des informations relatives a chaque paquet
// Construit egalement les informations de traduction par salvatore a destination du fichier traductions.txt
function empaqueteur_resultats($depot, $zips) {
        $xml = '';
        $salvatore = '';
        foreach($zips as $zip => $infos) {
                list($size, $time, $source, $commit, $traductions, $descr_xml, $multis, $dtd, $autorisations) = $infos;
                $f = 'empaqueteur_' . $dtd . '_xml';
                // Bloc d'info du paquet
                $xml .= "<archive id=\"$zip\"" . ($dtd ? " dtd=\"$dtd\"" : "") . ">
<zip>
        <file>$zip</file>
        <size>$size</size>
        <date>$time</date>
        <source>$source</source>
        <last_commit>$commit</last_commit>
</zip>
$traductions
$descr_xml
$multis
$autorisations
\n</archive>\n\n";
                // Bloc d'info pour Salvatore si il existe
                if (preg_match_all("#<salvatore\s+module=['\"](\w*)['\"]\s+reference=['\"](\w*)['\"]\s*/>#i", $descr_xml, $matches)) {
                        foreach ($matches[1] as $_i => $_module) {
                                $salvatore .= rtrim($depot['url_serveur'], '/') . '/' . rtrim($source, '/') . '/lang/;' . 
                                                          $_module . ';' .
                                                          $matches[2][$_i] . "\n";
                        }
                }
        }

        // On complete les archives avec les informations du depot
        // Pour l'instant ce bloc n'implemente pas la nouvelle DTD
        if (!$xml) return '';
        $xml_depot = '';
        foreach ($depot as $_balise => $_valeur) {
                $xml_depot .= "<$_balise>$_valeur</$_balise>\n";
        }
        if ($xml_depot) 
                $xml_depot = "<depot>\n$xml_depot</depot>\n";
        $xml = "$xml_depot
<archives>
$xml
</archives>";

        if($salvatore){
        // On ajoute une en-tete au fichier genere
        $salvatore = 
"# LISTE DES PLUGINS / SQUELETTES UTILISANT SALVATORE
# --------------------------------------------------
# Depot : " . $depot['titre'] . "
# Generation par Smart-Paquets le " . date('d-m-Y H:i') . "
#\n" . $salvatore;
        }
        return array($xml, $salvatore);
}

// Fonction creant le fichier xml recapitulant toutes les archives creees
// et le fichier representant son sha
// 
// Ne pas le reecrire si rien de neuf, c'est + efficace et ca permet
// au detecteur de nouvelle version d'utiliser If-Modified-Since.
//
// Attention, file_put_contents fait ce qu'il veut de certaines lignes vides
// http://fr2.php.net/manual/fr/function.file-put-contents.php
//
// $nom_fichier : nom du fichier xml recapitulant toutes les archives
// $archives    : contenu du nouveau fichier xml resultant des archives creees
// $dir_paq             : repertoire de depot des paquets crees
// $dir_repo    : repertoire racine des sources extraits du repository
//
// return               : aucun
function empaqueteur_xml_archives($nom_fichier, $archives, $dir_paq, $dir_repo)
{
        $taille = strlen($archives);
        $fichier = $dir_paq . $dir_repo . $nom_fichier;
        $fichier_tmp = $fichier . '.last';
        // ecriture du fichier xml dans un fichier archives.xml.last
        file_put_contents($fichier_tmp, $archives);

        // on compare le md5 de archives.xml.last et archives.xml
        // et on update archives.xml uniquement si il a change
        if (!file_exists($fichier) or md5_file($fichier)!==md5_file($fichier_tmp)) {
                @rename($fichier_tmp, $fichier);
                echo_trace("Nouveau $fichier de taille $taille");
        }
        else {
                echo_trace("$fichier non modifie (taille: $taille)");
        }

}


// Fonction creant le fichier des traductions de Salvatore
//
// Ne pas le reecrire si rien de neuf, c'est + efficace et ca permet
// au detecteur de nouvelle version d'utiliser If-Modified-Since.
//
// Attention, file_put_contents fait ce qu'il veut de certaines lignes vides
// http://fr2.php.net/manual/fr/function.file-put-contents.php
//
// $nom_fichier : nom du fichier des traductions
// $salvatore   : contenu du nouveau fichier des traductions Salvatore
// $dir_paq             : repertoire de depot des paquets crees
// $dir_repo    : repertoire racine des sources extraits du repository
//
// return               : aucun
function empaqueteur_salvatore($nom_fichier, $salvatore, $dir_paq, $dir_repo)
{
        $taille = strlen($salvatore);
        $fichier = $dir_paq . $dir_repo . $nom_fichier;
        $old = (file_exists($fichier)) ? trim(file_get_contents($fichier)) : '';
        if ($old != $salvatore) {
                echo_trace("Nouveau $fichier de taille $taille");
                file_put_contents($fichier, $salvatore);
                return;
        }
        echo_trace("$fichier intact (taille: $taille)");
}


// Fonction creant le fichier index des logos permettant d'afficher une page 
// de controle des logos
//
// Le fichier est recree systematiquement
//
// $nom_fichier : nom du fichier index des logos
// $dir_paq             : repertoire de depot des paquets crees
// $dir_repo    : repertoire racine des sources extraits du repository
//
// return               : aucun
function empaqueteur_index_logos($nom_fichier, $dir_paq, $dir_repo)
{
        $contenu = '';
        $logos = array_merge(glob($dir_paq . $dir_repo . '*.png'),
                                                glob($dir_paq . $dir_repo . '*.gif'),
                                                glob($dir_paq . $dir_repo . '*.jpg'));
        foreach($logos as $_logo)
                $contenu .= '<img src="' . basename($_logo) . '" />' . "\n";

        $fichier = $dir_paq . $dir_repo . $nom_fichier;
        if(strlen($contenu)){
                file_put_contents($fichier, $contenu);
                echo_trace("Nouvel index cree : " . count($logos) . " logos");
        }else{
                echo_trace("Aucun logo trouvés, pas d'index créé");
        }
}

?>