<?php
// WebJaxe, Observatoire de Paris, licence GPL
// encodage : UTF-8

//--------------------------------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------- requetes SQL -------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------

// Sélectionne un ou tous les projets
function requete_lire_projets($lien_bdd=false, $id_projet=false, $titre_projet=false, $id_projet_parent=false)
{
    $requete = "SELECT * FROM projets";
    $where = '';
    if ($id_projet != false)
        $where .= "id='$id_projet'";
    if ($titre_projet != false) {
        if ($where != '')
            $where .= " AND ";
        $where .= "titre='$titre_projet'";
    }
    if ($id_projet_parent != false) {
        if ($where != '')
            $where .= " AND ";
        $where .= "id_projet_parent='$id_projet_parent'";
    }
    if ($where != '')
        $requete .= " WHERE ".$where;
    $requete .= " ORDER BY titre";
    $resultat = executer_requete($requete, $lien_bdd);
    return($resultat);
}

// Créer une nouvelle ligne de la table des projets
function requete_creer_projet($lien_bdd, $titre_projet, $id_projet_parent=false)
{
    if ($id_projet_parent == false)
        $requete = "INSERT INTO projets (titre) VALUES ('$titre_projet')";
    else
        $requete = "INSERT INTO projets (titre, id_projet_parent) VALUES ('$titre_projet', '$id_projet_parent')";
    $resultat = executer_requete($requete, $lien_bdd);
    return($resultat);
}

// Supprime la ligne de la table projets avec l'id donné
// (et retire la référence vers ce projet pour les projets qui l'ont comme projet parent)
function requete_supprimer_projet($id)
{
    $lien_bdd = connexion();
    $requete = "DELETE FROM projets WHERE id = '$id'";
    $resultat = executer_requete($requete, $lien_bdd);
    if (!tester_resultat($resultat)) {
        deconnecte_base($lien_bdd);
        return($resultat);
    }
    $requete = "UPDATE projets SET id_projet_parent=NULL WHERE id_projet_parent='$id'";
    $resultat = executer_requete($requete, $lien_bdd);
    deconnecte_base($lien_bdd);
    return($resultat);
}

// retire le lien vers le projet parent
function requete_supprimer_projet_parent($id_projet) {
    if ($id_projet == false)
        return(false);
    $requete = "UPDATE projets SET id_projet_parent=NULL WHERE id='$id_projet' ";
    $resultat = executer_requete($requete);
    return($resultat);
}

function requete_ajouter_participant($id_projet, $id_utilisateur) {
    $requete = "INSERT INTO participants (id_utilisateur,id_projet) VALUES ('$id_utilisateur','$id_projet')";
    $resultat = executer_requete($requete);
    return($resultat);
}

function requete_supprimer_participants($id_projet, $id_utilisateur=false)
{
    if ($id_projet!=false && $id_utilisateur==false)
    {
        $requete = "DELETE FROM participants WHERE participants.id_projet = '$id_projet'";
    }
    else if ($id_projet!=false && $id_utilisateur!=false)
    {
        $requete = "DELETE FROM participants WHERE id_projet='$id_projet' AND id_utilisateur='$id_utilisateur'";
    }
    else if ($id_projet==false && $id_utilisateur!=false)
    {
        $requete ="DELETE FROM participants WHERE id_utilisateur = '$id_utilisateur'";
    }
    $resultat = executer_requete($requete);
    return($resultat);
}

// renvoie utilisateurs.* correspondants au projet et éventuellement à l'utilisateur
function requete_lire_participants($lien_bdd, $id_projet, $id_utilisateur=false)
{
    if ($id_projet != false && $id_utilisateur == false)
        $requete ="SELECT utilisateurs.* FROM participants, utilisateurs WHERE participants.id_projet='$id_projet' AND utilisateurs.id=participants.id_utilisateur";
    else if ($id_projet != false && $id_utilisateur != false)
        $requete ="SELECT utilisateurs.* FROM participants, utilisateurs WHERE participants.id_projet='$id_projet' AND participants.id_utilisateur='$id_utilisateur' AND utilisateurs.id=participants.id_utilisateur";
    
    $resultat = executer_requete($requete, $lien_bdd);
    return($resultat);
}

// Requête renvoyant tous les champs des projets correspondant à un utilisateur dont on donne l'id
function requete_projets_utilisateur($id_utilisateur)
{
    $requete = "SELECT projets.* FROM participants, projets WHERE participants.id_utilisateur='$id_utilisateur' AND projets.id=participants.id_projet ORDER BY titre";
    $resultat = executer_requete($requete);
    return($resultat);
}

// Requête renvoyant tous les champs des contributions correspondant à un projet dont on donne l'id
function requete_contributions_projet($lien_bdd, $id_projet)
{
    $requete = "SELECT * FROM contributions WHERE id_projet='$id_projet' ORDER BY nom";
    $resultat = executer_requete($requete, $lien_bdd);
    return($resultat);
}

function requete_modifier_projet($id_projet, $titre, $id_projet_parent=false)
{
    if ($id_projet == false || ($titre == false && $id_projet_parent == false))
        return(false);
    $requete = "UPDATE projets";
    if ($titre != false)
        $requete .= " SET titre='$titre'";
    if ($id_projet_parent != false) {
        if ($titre != false)
            $requete .= ", ";
        else
            $requete .= " SET ";
        $requete .= "id_projet_parent='$id_projet_parent'";
    }
    $requete .= " WHERE id='$id_projet'";
    $resultat = executer_requete($requete);
    return($resultat);
}


//--------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------- fonctions -----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------

// Renvoie un tableau de tous les projets, avec un tableau des champs pour chaque projet,
// ou FALSE s'il n'y a pas de projet
function liste_des_projets()
{
   $resultat_requete = requete_lire_projets(false);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_LISTE_PROJETS);
    $liste = lire_le_resultat($resultat_requete);
    return($liste);
}

// Crée un nouveau projet à partir de son titre
// renvoie l'id du nouveau projet
function creer_projet($titre_projet, $id_projet_parent=false)
{
    $lien_bdd = connexion();
    verifie_titre_projet($titre_projet);
    $resultat_requete = requete_creer_projet($lien_bdd, $titre_projet, $id_projet_parent);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_CREATION_PROJET);
    $id = dernier_id($lien_bdd);
    deconnecte_base($lien_bdd);
    return($id);
}

// Supprime le projet avec l'id en paramètre
// (en supposant qu'aucune contribution n'est liée)
function supprimer_projet($id)
{
    $resultat_requete = requete_supprimer_participants($id);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_SUPPRESSION_PROJET);
    $resultat_requete = requete_supprimer_projet($id);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_SUPPRESSION_PROJET);
    return(true);
}

function projet_existe($titre_projet) {
    $resultat_requete = requete_lire_projets(false, false, $titre_projet);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    return(nombre_de_lignes($resultat_requete) > 0);
}

// retourne un tableau avec les champs du projet
function projet($id_projet)
{
    $resultat_requete = requete_lire_projets(false, $id_projet);
    if (!tester_resultat($resultat_requete))
        erreur(PROJET_EXISTE_PAS);
    $projet = lire_premier_resultat($resultat_requete) ;
    return($projet);
}

// paramètre : un numero id de projet
// sortie : une chaine de caracteres avec le titre du projet
function titre_projet($id_projet)
{
    $resultat_requete = requete_lire_projets(false, $id_projet);
    if (!tester_resultat($resultat_requete))
        erreur(PROJET_EXISTE_PAS);
    $titre = lire_premier_resultat($resultat_requete, 'titre') ;
    return($titre);
}

// Renvoie un tableau de tous les sous-projets d'un projet, avec un tableau des champs pour chaque sous-projet,
// ou FALSE s'il n'y a pas de sous-projet dans ce projet
function liste_sous_projets($id_projet, $lien_bdd=false) {
   $resultat_requete = requete_lire_projets($lien_bdd, false, false, $id_projet);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    $liste = lire_le_resultat($resultat_requete);
    return($liste);
}

// Renvoie un tableau de tous les sous-projets, sous-sous-projets, etc... d'un projet,
// avec un tableau des champs pour chaque projet descendant,
// ou FALSE s'il n'y a pas de projet correspondant
function liste_projets_descendants($id_projet, $lien_bdd=false) {
    // fonction récursive
    // on évite les boucles infinies en s'assurant qu'elles ne sont pas créées dans ajouter_sous_projet
    // remarque : cette solution n'est pas rapide, il faut plusieurs requêtes SQL...
    // utiliser une table des ancêtres pourrait résoudre ce problème, mais ce n'est pas nécessaire ici
    // (les arbres ne sont pas profonds)
    if ($lien_bdd == false)
        $lien = connexion();
    else
        $lien = $lien_bdd;
    $liste = liste_sous_projets($id_projet, $lien);
    if ($liste != false) {
        $liste1 = $liste;
        foreach ($liste1 as $projet) {
            $liste2 = liste_projets_descendants($projet['id'], $lien);
            if ($liste2 != false)
                $liste = array_merge($liste, $liste2);
        }
    }
    if ($lien_bdd == false)
        deconnecte_base($lien);
    return($liste);
}

// renvoie un tableau de tous les projets ancêtres d'un projet (projet parent, parent de parent, etc...)
// avec un tableau des champs pour chaque projet descendant,
// ou FALSE s'il n'y a pas de projet correspondant
function liste_projets_ancetres($id_projet) {
    // pour ne pas faire trop de requêtes, on récupère carrément la liste de tous les projets pour construire la liste
    $tous_les_projets = liste_des_projets();
    $le_projet = NULL;
    foreach ($tous_les_projets as $projet) {
        if ($projet['id'] == $id_projet) {
            $le_projet = $projet;
            break;
        }
    }
    if ($le_projet == NULL)
        return(false);
    $liste = array();
    while ($le_projet != NULL && $le_projet['id_projet_parent'] != NULL) {
        $projet_parent = NULL;
        $id_parent = $le_projet['id_projet_parent'];
        foreach ($tous_les_projets as $projet) {
            if ($projet['id'] == $id_parent) {
                $projet_parent = $projet;
                break;
            }
        }
        if ($projet_parent != NULL)
            $liste[] = $projet_parent;
        $le_projet = $projet_parent;
    }
    return($liste);
}

// renvoie true si le 2ème projet est bien sous-projet du 1er
function est_sous_projet($id_projet_parent, $id_sous_projet) {
    $resultat_requete = requete_lire_projets(false, $id_projet_parent, false, $id_sous_projet);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    if ( nombre_de_lignes($resultat_requete) > 0 )
        return(true);
    return(false);
}

// renvoie true si le projet parent est bien un ancêtre du sous-projet
function est_projet_descendant($id_projet_parent, $id_sous_projet) {
    $liste = liste_projets_descendants($id_projet_parent);
    if ($liste == false)
        return(false);
    foreach ($liste as $projet) {
        if ($projet['id'] == $id_sous_projet)
            return(true);
    }
    return(false);
}

// ajouter un sous-projet à un projet
// paramètres : une numero id de projet, un numero id de sous-projet
// sortie : la valeur booléenne true en cas de réussite de l'operation
function ajouter_sous_projet($id_projet, $id_sous_projet)
{
    // le projet est-il déjà un sous-projet ?
    if (est_sous_projet($id_projet, $id_sous_projet))
        erreur(DEJA_SOUS_PROJET);
    
    // ou l'inverse ? (il faut éviter les boucles !)
    if (est_projet_descendant($id_sous_projet, $id_projet))
        erreur(DEJA_PROJET_PARENT);
    
    // ajout du lien
    $resultat_requete = requete_modifier_projet($id_sous_projet, false, $id_projet);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    
    return(true);
}

// supprime un lien projet - sous-projet
// paramètres : un id de projet et un id de sous-projet
// sortie : la valeur booléenne true en cas de réussite
function supprimer_sous_projet($id_projet, $id_sous_projet)
{
    $resultat_requete = requete_supprimer_projet_parent($id_sous_projet);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    return(true);
}


// liste des participants à un projet (sans prendre en compte les sous-projets)
// paramètres : id du projet
// sortie : liste des tuples de la table utilisateur des utilisateurs concernés par le projet
function liste_participants($id_projet)
{
    $resultat_requete = requete_lire_participants(false, $id_projet, false);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    $liste = lire_le_resultat($resultat_requete);
    return($liste);
}

// ajouter un participant à un projet
// paramètres : une numero id de projet, un numero id d'utilisateur
// sortie : la valeur booléenne true en cas de réussite de l'operation
function ajouter_participant($id_projet, $id_utilisateur)
{
    // l'utilisateur est-il déjà associé à ce projet ?
    if (est_participant($id_projet, $id_utilisateur))
        erreur(CONTRIBUTEUR_EXISTANT);
    
    // ajout du lien
    $resultat_requete = requete_ajouter_participant($id_projet, $id_utilisateur);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    
    return(true);
}

// supprime un participant
// paramètres : un id de projet et un id d'utilisateur
// sortie : la valeur booléenne true en cas de réussite
function supprimer_participant($id_projet, $id_utilisateur)
{
    $resultat_requete = requete_supprimer_participants($id_projet, $id_utilisateur);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    return(true);
}

// liste des id des projets
// sortie : un tableau avec la liste des id des projets, ou FALSE s'il n'y en a pas
function liste_id_projets()
{
    $resultat_requete = requete_lire_projets(false);
    if (!tester_resultat($resultat_requete))
        erreur(REQUETE_LISTE_CONTRIBUTION);
    $liste = lire_le_resultat($resultat_requete, 'id');
    return($liste);
}

// liste des projets pour un utilisateur dont on donne l'id
// sortie : retourne un tableau aves la liste des projets de l'utilisateur et leurs sous-projets,
// ou FALSE s'il n'y en a pas
function liste_des_projets_utilisateur($id_utilisateur, $avec_sous_projets = true)
{
    $resultat_requete = requete_projets_utilisateur($id_utilisateur);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    $liste = lire_le_resultat($resultat_requete);
    if ($liste != false && $avec_sous_projets) {
        $liste1 = $liste;
        // ajout récursif des sous-projets
        for ($i=0; $i<count($liste1); $i++) {
            $projet = $liste1[$i];
            $liste2 = liste_projets_descendants($projet['id']);
            if ($liste2 != false) {
                // les projets descendants peuvent être déjà liés à l'utilisateur
                for ($j=0; $j<count($liste2); $j++) {
                    $sous_projet = $liste2[$j];
                    $dejala = false;
                    for ($k=0; $k<count($liste); $k++) {
                        if ($liste[$k]['id'] == $sous_projet['id']) {
                            $dejala = true;
                            break;
                        }
                    }
                    if (!$dejala)
                        $liste[] = $sous_projet;
                }
            }
        }
    }
    return($liste);
}

// liste des contributions pour un projet dont on donne l'id
// sortie : retourne un tableau aves la liste des contributions, ou FALSE s'il n'y en a pas
function liste_des_contributions_projet($id_projet, $lien_bdd=false)
{
    if ($lien_bdd == false)
        $lien = connexion();
    else
        $lien = $lien_bdd;
    $resultat_requete = requete_contributions_projet($lien, $id_projet);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    $liste = lire_le_resultat($resultat_requete);
    if ($lien_bdd == false)
        deconnecte_base($lien);
    return($liste);
}

// liste des contributions pour un projet dont on donne l'id, et tous ses projets descendants
// sortie : retourne un tableau aves la liste des contributions, ou FALSE s'il n'y en a pas
function liste_des_contributions_projet_et_sous_projets($id_projet)
{
    $lien = connexion();
    $liste = liste_des_contributions_projet($id_projet, $lien);
    $sous_projets = liste_projets_descendants($id_projet, $lien);
    if ($sous_projets != false) {
        foreach ($sous_projets as $sous_projet) {
            $liste2 = liste_des_contributions_projet($sous_projet['id'], $lien);
            if ($liste2 != false) {
                if ($liste != false)
                    $liste = array_merge($liste, $liste2);
                else
                    $liste = $liste2;
            }
        }
    }
    deconnecte_base($lien);
    return($liste);
}

// liste des id des contributions pour un projet dont on donne l'id
// sortie : retourne un tableau aves la liste des id des contributions, ou FALSE s'il n'y en a pas
function liste_id_contributions_projet($id_projet)
{
    $resultat_requete = requete_contributions_projet(false, $id_projet);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    $liste = lire_le_resultat($resultat_requete, 'id');
    return($liste);
}

// renvoie true si l'utilisateur participe au projet
function est_participant($id_projet, $id_utilisateur) {
    $resultat_requete = requete_lire_participants(false, $id_projet, $id_utilisateur);
    if (!tester_resultat($resultat_requete)) 
        erreur(ECHEC_REQUETE);
    if ( nombre_de_lignes($resultat_requete) > 0 )
        return(true);
    return(false);
}

// permet de changer le titre d'un projet
function modifier_projet($id_projet, $titre) {
    verifie_titre_projet($titre);
    $resultat_requete = requete_modifier_projet($id_projet, $titre);
    if (!tester_resultat($resultat_requete))
        erreur(ECHEC_REQUETE);
    return(true);
}

// Export en zip de toutes les contributions d'un projet
function exporter_projet($id_projet) {
    $nom_projet = strtr(utf8_decode(titre_projet($id_projet)), utf8_decode('éèàêïë '), 'eeaeie_');
    $sep = DIRECTORY_SEPARATOR;
    $racine = realpath(getcwd().$sep.'..'.$sep.'..'.$sep).$sep;
    $dossier_temp = $racine.'tmp';
    $tmpzip = tempnam($dossier_temp, 'tmpzip_'.$nom_projet);
    $archive = new PclZip($tmpzip);
    $contrib_xml = $racine.'contribXML';
    $liste_projets = array(projet($id_projet));
    $liste_projets_d = liste_projets_descendants($id_projet);
    if ($liste_projets_d != false)
        $liste_projets = array_merge($liste_projets, $liste_projets_d);
    $liste_contributions = liste_des_contributions_projet_et_sous_projets($id_projet);
    $chemins_contribs = construire_chemins_contributions($liste_projets, $liste_contributions);
    $liste_noms_contributions = array();
    for ($i=0; $i<count($liste_contributions); $i++) {
        $contribution = $liste_contributions[$i];
        $nom_contribution = $contribution['nom'];
        $liste_noms_contributions[] = $contrib_xml.$sep.$nom_contribution;
    }
    $_SESSION['chemins-contribs'] = $chemins_contribs; // pour le filtre
    $v_list = $archive->add($liste_noms_contributions, PCLZIP_OPT_REMOVE_PATH, $contrib_xml,
        PCLZIP_CB_PRE_ADD, 'filtre_export_projets');
    unset($_SESSION['chemins-contribs']);
    if ($v_list == 0)
        erreur($archive->errorInfo(true));
    if (!file_exists($tmpzip))
        erreur(CONTACTER_ADMIN);
    
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.$nom_projet.'.zip');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($tmpzip));
    lire_un_fichier($tmpzip);
    unlink($tmpzip);
}

// construit un tableau nom_contribution => chemin_complet (avec les noms des projets)
function construire_chemins_contributions($liste_projets, $liste_contributions) {
    $liste = array();
    foreach ($liste_contributions as $contribution) {
        $chemin = construire_chemin_projet($contribution['id_projet'], $liste_projets).'/'.$contribution['nom'];
        $liste[$contribution['nom']] = $chemin;
    }
    return($liste);
}

function construire_chemin_projet($id_projet, $liste_projets) {
    foreach ($liste_projets as $projet) {
        if ($projet['id'] == $id_projet) {
            $nom_projet = strtr(utf8_decode($projet['titre']), utf8_decode('éèàêïë '), 'eeaeie_');
            $chemin = $nom_projet;
            if ($projet['id_projet_parent'] != NULL) {
                $chemin_parent = construire_chemin_projet($projet['id_projet_parent'], $liste_projets);
                if ($chemin_parent != NULL)
                    $chemin = $chemin_parent.'/'.$chemin;
            }
            return($chemin);
        }
    }
    return(NULL); // le parent n'est pas dans la liste
}

function filtre_export_projets($p_event, &$p_header) {
    $info = pathinfo($p_header['stored_filename']);
    $nom = $info['basename'];
    if ($nom == '__MACOSX' || $nom[0] == '.' || $nom == 'Thumbs.db')
        return(0);
    $chemin = $p_header['stored_filename'];
    $p = strpos($chemin, '/');
    if ($p == -1) {
        $nom_contribution = $chemin;
        $suite = '';
    } else {
        $nom_contribution = substr($chemin, 0, $p);
        $suite = substr($chemin, $p);
    }
    $chemins_contribs = $_SESSION['chemins-contribs'];
    if (!isset($chemins_contribs[$nom_contribution]) || $chemins_contribs[$nom_contribution] == NULL)
        return(0);
    $nouveau_chemin = $chemins_contribs[$nom_contribution].$suite;
    $p_header['stored_filename'] = $nouveau_chemin;
    return(1);
}

// import d'un projet entier à partir d'un fichier ZIP
// renvoie true si l'import est un succès, sinon une erreur est lancée
function importer_projet($nom_fichier_zip, $config) {
    if (!file_exists($nom_fichier_zip)) {
        erreur(ZIP_NON_TROUVE);
        return(false);
    }
    $zip = new PclZip($nom_fichier_zip);
    if (($list = $zip->listContent()) == 0) {
        erreur(CONTENU_ZIP_PROJET);
        return(false);
    }
    
    $chemins_contribs = array();
    $arbre = array();
    
    for ($i=0; $i<sizeof($list); $i++) {
        $chemin_i = str_replace('\\', '/', $list[$i]['filename']);
        if (!($list[$i]['folder']) && substr_count($chemin_i, '/') >= 2 && strpos($chemin_i, '__MACOSX') === false &&
                substr($chemin_i, strlen($chemin_i) - 4) == '.xml') {
            ajouter_chemin_arbre($chemin_i, $arbre);
        }
    }
    if (!isset($arbre['nom-projet']) || (!isset($arbre['sous-projets']) && !isset($arbre['contributions']))) {
        erreur(CONTENU_ZIP_PROJET);
        return(false);
    }
    
    $id_utilisateur = $_SESSION['id_utilisateur'];
    creer_projets_et_contribs($arbre, $id_utilisateur, $config);
    
    $sep = DIRECTORY_SEPARATOR;
    $racine = realpath(getcwd().$sep.'..'.$sep.'..'.$sep).$sep;
    $contrib_xml = $racine.'contribXML';
    $_SESSION['arbre-projets'] = $arbre; // pour le filtre
    if ($zip->extract(PCLZIP_OPT_PATH, $contrib_xml, PCLZIP_CB_PRE_EXTRACT, 'filtre_import_projets') == 0) {
        unset($_SESSION['arbre-projets']);
        erreur($zip->errorInfo(true));
    }
    unset($_SESSION['arbre-projets']);
    return(true);
}

// ajoute à partir du chemin d'un fichier les projets et contributions dans un arbre
// ayant pour chaque noeud projet les éléments possibles : nom-projet, sous-projets, contributions
function ajouter_chemin_arbre($chemin, &$arbre) {
    $noms = explode('/', $chemin);
    if (count($noms) < 3)
        return;
    $nm1 = $noms[count($noms)-1];
    $nm2 = $noms[count($noms)-2];
    if ($nm1 == $nm2.'.xml') {
        $projet_parent = null;
        for ($i=0; $i<count($noms)-1; $i++) {
            if ($i < count($noms)-2) {
                $nom_projet = $noms[$i];
                if ($projet_parent == null) {
                    if (!isset($arbre))
                        $arbre = array();
                    if (!isset($arbre['nom-projet'])) {
                        if (projet_existe($nom_projet))
                            erreur(PROJET_EXISTE_DEJA.$nom_projet);
                        $arbre['nom-projet'] = $nom_projet;
                        $ce_projet = &$arbre;
                    } else if ($arbre['nom-projet'] == $nom_projet)
                        $ce_projet = &$arbre;
                    else
                        erreur('Deuxième projet de 1er niveau : '.$nom_projet.' ???');
                } else {
                    unset($ce_projet);
                    $ce_projet = null;
                    if (!isset($projet_parent['sous-projets']))
                        $projet_parent['sous-projets'] = array();
                    $sous_projets = &$projet_parent['sous-projets'];
                    for ($j=0; $j < count($sous_projets); $j++) {
                        $sous_projet = &$sous_projets[$j];
                        if ($sous_projet['nom-projet'] == $nom_projet) {
                            $ce_projet = &$sous_projet;
                            break;
                        }
                    }
                    if ($ce_projet == null) {
                        if (projet_existe($nom_projet))
                            erreur(PROJET_EXISTE_DEJA.$nom_projet);
                        $ce_projet = array('nom-projet' => $nom_projet);
                        $sous_projets[] = &$ce_projet;
                    }
                }
                $projet_parent = &$ce_projet;
            } else {
                $nom_contribution = $noms[$i];
                if (contribution_existe($nom_contribution))
                    erreur(CONTRIB_MEME_NOM.' : '.$nom_contribution);
                if ($projet_parent != null) {
                    if (!isset($projet_parent['contributions']))
                        $projet_parent['contributions'] = array();
                    if (!in_array($nom_contribution, $projet_parent['contributions']))
                        $projet_parent['contributions'][] = $nom_contribution;
                } else
                    erreur('Contribution sans projet parent : '.$nom_contribution.' ???');
            }
        }
    }
}

function creer_projets_et_contribs($arbre, $id_utilisateur, $config, $id_projet_parent=false) {
    $titre_projet = preg_replace("/[^-_a-zA-Zàâéèêëîïôöüùç 0-9]/","", $arbre['nom-projet']);
    $titre_projet = str_replace('_', ' ', $titre_projet);
    $id_projet = creer_projet($titre_projet, $id_projet_parent);
    if ($id_projet_parent == false)
        ajouter_participant($id_projet, $id_utilisateur);
    if (isset($arbre['sous-projets'])) {
        foreach ($arbre['sous-projets'] as $sous_projet) {
            creer_projets_et_contribs($sous_projet, $id_utilisateur, $config, $id_projet);
        }
    }
    if (isset($arbre['contributions'])) {
        foreach ($arbre['contributions'] as $nom_contribution) {
            creer_contribution($nom_contribution, $id_projet, $config);
        }
    }
}

function filtre_import_projets($p_event, &$p_header) {
    $chemin_absolu = $p_header['filename'];
    $chemin_dans_archive = $p_header['stored_filename'];
    $info = pathinfo($chemin_absolu);
    $nom = $info['basename'];
    if ($nom == '__MACOSX' || $nom[0] == '.' || $nom == 'Thumbs.db')
        return(0);
    $nouveau_chemin = retirer_dossiers_projets($chemin_dans_archive, $_SESSION['arbre-projets'], true);
    if ($nouveau_chemin == NULL)
        return(0);
    $p = strpos($chemin_absolu, $chemin_dans_archive);
    if ($p === FALSE)
        return(0);
    $debut = substr($chemin_absolu, 0, $p);
    $chemin_absolu = $debut.$nouveau_chemin;
    $p_header['filename'] = $chemin_absolu;
    return(1);
}

// retire du chemin d'un fichier les noms des projets
// renvoie NULL si le fichier ne semble pas être dans une contribution
function retirer_dossiers_projets($chemin, $arbre, $premier) {
    $p = strpos($chemin, '/');
    if ($p == -1)
        return(NULL);
    $nom = substr($chemin, 0, $p);
    if ($premier) {
        if ($nom != $arbre['nom-projet'])
            return(NULL);
        $arbre2 = $arbre;
    } else {
        $arbre2 = NULL;
        if (isset($arbre['sous-projets'])) {
            foreach ($arbre['sous-projets'] as $sous_projet) {
                if ($sous_projet['nom-projet'] == $nom) {
                    $arbre2 = $sous_projet;
                    break;
                }
            }
        }
        if ($arbre2 == NULL) {
            if (isset($arbre['contributions'])) {
                foreach ($arbre['contributions'] as $nom_contribution) {
                    if ($nom_contribution == $nom)
                        return($chemin);
                }
            }
            return(NULL);
        }
    }
    $chemin2 = substr($chemin, $p + 1);
    return(retirer_dossiers_projets($chemin2, $arbre2, false));
}

// renvoie une forêt des projets à partir d'une liste plate, en utilisant les relations entre les projets
// (une forêt est une liste d'arbres)
function construire_foret_projets($liste_projets) {
    $racines = array();
    for ($i=0; $i<count($liste_projets); $i++) {
        $projet = $liste_projets[$i];
        if ($projet['id_projet_parent'] == NULL)
            $racines[] = $projet;
        else {
            $parent_trouve = false;
            for ($j=0; $j<count($liste_projets); $j++) {
                if ($liste_projets[$j]['id'] == $projet['id_projet_parent']) {
                    $parent_trouve = true;
                    break;
                }
            }
            if (!$parent_trouve)
                $racines[] = $projet;
        }
    }
    $arbre = array();
    foreach ($racines as $projet) {
        $sous_projets = chercher_sous_projets($projet['id'], $liste_projets);
        $arbre[] = array(
            'projet' => $projet,
            'sous-projets' => $sous_projets
        );
    }
    return($arbre);
}

function chercher_sous_projets($id_projet_parent, $liste_projets) {
    $arbre = array();
    foreach ($liste_projets as $projet) {
        if ($projet['id_projet_parent'] == $id_projet_parent) {
            $sous_projets = chercher_sous_projets($projet['id'], $liste_projets);
            $arbre[] = array(
                'projet' => $projet,
                'sous-projets' => $sous_projets
            );
        }
    }
    return($arbre);
}

?>
