Example #1
0
/**
 * Actualisation de la table des paquets pour le dépot choisi
 *
 * Enlève de la base les paquets du dépots qui ne sont plus présents
 * dans la description du XML. Ajoute ou met à jour les autres.
 * 
 * @param int $id_depot
 *     Identifiant du dépot
 * @param array $paquets
 *     Tableau des paquets extraits du fichier XML
 *     L'index est le nom de l'archive (xxxx.zip) et le contenu est
 *     un tableau à deux entrées :
 *     - Index 'plugin' : le tableau des infos du plugin
 *     - Index 'file' : le nom de l'archive .zip
 * @param int $nb_paquets
 *     Nombre de paquets réellement inserés dans la base
 * @param int $nb_plugins
 *     Nombre de plugins parmi les paquets inserés
 * @param int &$nb_autres
 *     Nombre de contributions non issues de plugin parmi les paquets inserés
 * @return bool
 *     false si aucun dépot ou paquets, true sinon
 */
function svp_actualiser_paquets($id_depot, $paquets, &$nb_paquets, &$nb_plugins, &$nb_autres)
{
    // Initialisation des compteurs
    $nb_paquets = 0;
    $nb_plugins = 0;
    $nb_autres = 0;
    // Si aucun depot ou aucun paquet on renvoie une erreur
    if (!$id_depot or !is_array($paquets)) {
        return false;
    }
    // On initialise l'url de base des logos du depot et son type afin de
    // calculer l'url complete de chaque logo
    $select = array('url_archives', 'type');
    $depot = sql_fetsel($select, 'spip_depots', 'id_depot=' . sql_quote($id_depot));
    // On supprime tous les paquets du depot
    // qui ont ete evacues, c'est a dire ceux dont les signatures
    // ne correspondent pas aux nouveaux...
    // et on retablit les vmax des plugins restants...
    $signatures = array();
    foreach ($paquets as $_paquet) {
        $signatures[] = $_paquet['md5'];
    }
    // tous les paquets du depot qui ne font pas parti des signatures
    $anciens_paquets = sql_allfetsel('id_paquet', 'spip_paquets', array('id_depot=' . sql_quote($id_depot), sql_in('signature', $signatures, 'NOT')));
    $anciens_paquets = array_map('array_shift', $anciens_paquets);
    // pour ces vieux paquets, on les nettoie de la base
    if ($anciens_paquets) {
        // tous les plugins correspondants aux anciens paquets
        $anciens_plugins = sql_allfetsel('pl.id_plugin', array('spip_plugins AS pl', 'spip_paquets AS pa'), array('pl.id_plugin=pa.id_plugin', sql_in('pa.id_paquet', $anciens_paquets)));
        $anciens_plugins = array_map('array_shift', $anciens_plugins);
        // suppression des anciens paquets
        sql_delete('spip_paquets', sql_in('id_paquet', $anciens_paquets));
        // suppressions des liaisons depots / anciens plugins
        // on enlève la liaison lorsqu'il n'y a plus aucun paquet lie a un des plugins qui ont vu un paquet enlevé
        // liste des plugins qui ont encore des paquets dans ce depot
        $plugins_restants = sql_allfetsel('pl.id_plugin', array('spip_plugins AS pl', 'spip_paquets AS pa'), array(sql_in('pl.id_plugin', $anciens_plugins), 'pl.id_plugin=pa.id_plugin', 'pa.id_depot=' . sql_quote($id_depot)));
        $plugins_restants = array_map('array_shift', $plugins_restants);
        // par opposition, on retrouve ceux qui n'en ont plus...
        $plugins_supprimes = array_diff($anciens_plugins, $plugins_restants);
        sql_delete('spip_depots_plugins', array('id_depot=' . sql_quote($id_depot), sql_in('id_plugin', $plugins_supprimes)));
        unset($plugins_restants, $plugins_supprimes);
        // supprimer les plugins orphelins
        include_spip('inc/svp_depoter_local');
        svp_supprimer_plugins_orphelins($anciens_plugins);
        // corriger les vmax des plugins
        svp_corriger_vmax_plugins($anciens_plugins);
        // corriger les compats, branches aussi
        svp_completer_plugins($anciens_plugins);
    }
    // on ne garde que les paquets qui ne sont pas presents dans la base
    $signatures = sql_allfetsel('signature', 'spip_paquets', 'id_depot=' . sql_quote($id_depot));
    $signatures = array_map('array_shift', $signatures);
    foreach ($paquets as $cle => $_infos) {
        if (in_array($_infos['md5'], $signatures)) {
            unset($paquets[$cle]);
        }
    }
    // tableaux d'actions
    $insert_paquets = array();
    $insert_plugins = array();
    $insert_contribs = array();
    $prefixes = array();
    // prefixe => id_plugin
    // On met a jour ou on cree chaque paquet a partir du contenu du fichier xml
    // On ne fait pas cas de la compatibilite avec la version de SPIP installee
    // car l'operation doit permettre de collecter tous les paquets
    foreach ($paquets as $_archive => $_infos) {
        $insert_paquet = array();
        // On initialise les informations specifiques au paquet :
        // l'id du depot et les infos de l'archive
        $insert_paquet['id_depot'] = $id_depot;
        $insert_paquet['nom_archive'] = $_archive;
        $insert_paquet['nbo_archive'] = $_infos['size'];
        $insert_paquet['maj_archive'] = date('Y-m-d H:i:s', $_infos['date']);
        $insert_paquet['src_archive'] = $_infos['source'];
        $insert_paquet['date_modif'] = $_infos['last_commit'];
        // On serialise le tableau des traductions par module
        $insert_paquet['traductions'] = serialize($_infos['traductions']);
        // On ajoute la signature
        $insert_paquet['signature'] = $_infos['md5'];
        // On verifie si le paquet est celui d'un plugin ou pas
        // -- Les traitements du XML dependent de la DTD utilisee
        // Formatage des informations extraites du plugin pour insertion dans la base SVP
        $formater = charger_fonction('preparer_sql_' . $_infos['dtd'], 'plugins');
        if ($champs_aplat = $formater($_infos['plugin'])) {
            // Eclater les champs recuperes en deux sous tableaux, un par table (plugin, paquet)
            $champs = eclater_plugin_paquet($champs_aplat);
            $paquet_plugin = true;
            // On complete les informations du paquet et du plugin
            $insert_paquet = array_merge($insert_paquet, $champs['paquet']);
            $insert_plugin = $champs['plugin'];
            // On construit l'url complete du logo
            // Le logo est maintenant disponible a la meme adresse que le zip et porte le nom du zip.
            // Son extension originale est conservee
            if ($insert_paquet['logo']) {
                $insert_paquet['logo'] = $depot['url_archives'] . '/' . basename($insert_paquet['nom_archive'], '.zip') . '.' . pathinfo($insert_paquet['logo'], PATHINFO_EXTENSION);
            }
            // On loge l'absence de categorie ou une categorie erronee et on positionne la categorie
            // par defaut "aucune"
            // Provisoire tant que la DTD n'est pas en fonction
            if (!$insert_plugin['categorie']) {
                spip_log("Categorie absente dans le paquet issu de <" . $insert_paquet['src_archive'] . "> du depot <" . $insert_paquet['id_depot'] . ">\n", 'svp_paquets.' . _LOG_INFO_IMPORTANTE);
                $insert_plugin['categorie'] = 'aucune';
            } else {
                $svp_categories = $GLOBALS['categories_plugin'];
                if (!in_array($insert_plugin['categorie'], $svp_categories)) {
                    spip_log("Categorie &#107;" . $insert_plugin['categorie'] . "&#108; incorrecte dans le paquet issu de <" . $insert_paquet['src_archive'] . "> du depot <" . $insert_paquet['id_depot'] . ">\n", 'svp_paquets.' . _LOG_INFO_IMPORTANTE);
                    $insert_plugin['categorie'] = 'aucune';
                }
            }
        } else {
            $paquet_plugin = false;
        }
        // On teste l'existence du paquet dans la base avec les champs
        // id_depot, nom_archive et src_archive pour être sur de l'unicité.
        // - si le paquet n'existe pas, on le crée,
        // - sinon (et ça ne devrait pas arriver), on ne fait qu'un update
        if (!($paquet = sql_fetsel('*', 'spip_paquets', array('id_depot=' . sql_quote($insert_paquet['id_depot']), 'nom_archive=' . sql_quote($insert_paquet['nom_archive']), 'src_archive=' . sql_quote($insert_paquet['src_archive']))))) {
            // Le paquet n'existe pas encore en base de donnees
            // ------------------------------------------------
            // On positionne la date de creation a celle du dernier commit ce qui est bien le cas
            $insert_paquet['date_crea'] = $insert_paquet['date_modif'];
            // Les collisions ne sont possibles que si on ajoute un nouveau paquet
            $collision = false;
            if ($paquet_plugin) {
                // On est en presence d'un PLUGIN
                // ------------------------------
                // On evite les doublons de paquet
                // Pour determiner un doublon on verifie actuellement :
                // - le prefixe
                // - la version du paquet et de la base
                // - l'etat
                $where = array('t1.id_plugin=t2.id_plugin', 't1.version=' . sql_quote($insert_paquet['version']), 't1.version_base=' . sql_quote($insert_paquet['version_base']), 't1.etatnum=' . sql_quote($insert_paquet['etatnum']), 't1.id_depot>' . intval(0), 't2.prefixe=' . sql_quote($insert_plugin['prefixe']));
                if (!($id_paquet = sql_getfetsel('t1.id_paquet', 'spip_paquets AS t1, spip_plugins AS t2', $where))) {
                    // On traite d'abord le plugin du paquet pour recuperer l'id_plugin
                    // On rajoute le plugin dans la table spip_plugins si celui-ci n'y est pas encore ou on recupere
                    // l'id si il existe deja et on le met a jour si la version du paquet est plus elevee
                    $plugin = sql_fetsel('id_plugin, vmax', 'spip_plugins', array('prefixe=' . sql_quote($insert_plugin['prefixe'])));
                    if (!$plugin and !array_key_exists($insert_plugin['prefixe'], $insert_plugins)) {
                        $insert_plugins[$insert_plugin['prefixe']] = array_merge($insert_plugin, array('vmax' => $insert_paquet['version']));
                    } else {
                        if ($plugin) {
                            $id_plugin = $plugin['id_plugin'];
                            $prefixes[$insert_plugin['prefixe']] = $id_plugin;
                        }
                        if (array_key_exists($insert_plugin['prefixe'], $insert_plugins) and spip_version_compare($insert_plugins[$insert_plugin['prefixe']]['vmax'], $insert_paquet['version'], '<=')) {
                            // attribuer au plugin le nom et le slogan du paquet le plus à jour
                            $insert_plugins[$insert_plugin['prefixe']]['nom'] = $insert_plugin['nom'];
                            $insert_plugins[$insert_plugin['prefixe']]['slogan'] = $insert_plugin['slogan'];
                            $insert_plugins[$insert_plugin['prefixe']]['vmax'] = $insert_paquet['version'];
                        }
                    }
                    // On traite maintenant le paquet connaissant l'id du plugin
                    // temporaire qui sera supprime lors de la connaissance de l'id_paquet
                    $insert_paquet['prefixe'] = $insert_plugin['prefixe'];
                    $insert_paquets[] = $insert_paquet;
                } else {
                    $collision = true;
                }
            } else {
                // On est en presence d'une CONTRIBUTION NON PLUGIN
                // ------------------------------------------------
                $where = array('id_depot=' . sql_quote($insert_paquet['id_depot']), 'nom_archive=' . sql_quote($insert_paquet['nom_archive']));
                if (!($id_paquet = sql_getfetsel('id_paquet', 'spip_paquets', $where))) {
                    // Ce n'est pas un plugin, donc id_plugin=0 et toutes les infos plugin sont nulles
                    $insert_paquet['id_plugin'] = 0;
                    $insert_contribs[] = $insert_paquet;
                } else {
                    $collision = true;
                }
            }
            // On loge le paquet ayant ete refuse dans un fichier a part afin de les verifier
            // apres coup
            if ($collision) {
                spip_log("Collision avec le paquet <" . $insert_paquet['nom_archive'] . " / " . $insert_paquet['src_archive'] . "> du depot <" . $insert_paquet['id_depot'] . ">\n", 'svp_paquets.' . _LOG_INFO_IMPORTANTE);
            }
        } else {
            // Le paquet existe deja en base de donnees
            // ----------------------------------------
            // On ne devrait plus arriver ICI...
            // Code obsolete ?
            spip_log('!!!!!! Passage dans code obsolete (svp/svp_depoter_distant)', 'depoter');
            // on effectue les traitements en attente
            // pour que les updates soient corrects
            svp_inserer_multi($insert_plugins, $insert_paquets, $insert_contribs, $prefixes);
            // On met a jour le paquet en premier lieu qu'il soit un plugin ou une contribution
            sql_updateq('spip_paquets', $insert_paquet, 'id_paquet=' . sql_quote($paquet['id_paquet']));
        }
    }
    // on effectue les traitements en attente
    // pour que les updates soient corrects
    svp_inserer_multi($insert_plugins, $insert_paquets, $insert_contribs, $prefixes);
    // On rajoute le plugin comme heberge par le depot si celui-ci n'est pas encore enregistre comme tel
    $ids = sql_allfetsel('p.id_plugin', array('spip_plugins AS p', 'spip_depots_plugins AS dp'), array('p.id_plugin=dp.id_plugin', 'dp.id_depot=' . sql_quote($id_depot)));
    $ids = array_map('array_shift', $ids);
    // inserer les liens avec le depots
    $insert_dp = array();
    $news_id = array_diff(array_values($prefixes), $ids);
    foreach ($news_id as $id) {
        $insert_dp[] = array('id_depot' => $id_depot, 'id_plugin' => $id);
    }
    if ($insert_dp) {
        sql_insertq_multi('spip_depots_plugins', $insert_dp);
    }
    // on recalcul les vmax des plugins de ce depot.
    svp_corriger_vmax_plugins(array_values($prefixes));
    // On compile maintenant certaines informations des paquets mis a jour dans les plugins
    // (date de creation, date de modif, version spip...)
    svp_completer_plugins_depot($id_depot);
    // Si on est pas en mode runtime, on utilise surement l'espace public pour afficher les plugins.
    // Il faut donc s'assurer que les urls suivent bien la mise à jour
    // - on supprime toutes les urls plugin
    // - on les regenere pour la liste des plugins mise a jour
    if (!_SVP_MODE_RUNTIME) {
        svp_actualiser_url_plugins($id_depot);
    }
    // Calcul des compteurs de paquets, plugins et contributions
    $nb_paquets = sql_countsel('spip_paquets', 'id_depot=' . sql_quote($id_depot));
    $nb_plugins = sql_countsel('spip_depots_plugins', 'id_depot=' . sql_quote($id_depot));
    $nb_autres = sql_countsel('spip_paquets', array('id_depot=' . sql_quote($id_depot), 'id_plugin=0'));
    return true;
}
Example #2
0
/**
 * Actualise les informations en base sur les paquets locaux
 * en ne modifiant que ce qui a changé.
 *
 * @param array $paquets_locaux
 *     Descriptions des paquets (intégrant un hash), stockés par
 *     constante, puis par chemin.
 *     array[_DIR_PLUGIN*][$chemin] = description
**/
function svp_base_modifier_paquets_locaux($paquets_locaux)
{
    include_spip('inc/svp_depoter_distant');
    // On ne va modifier QUE les paquets locaux qui ont change
    // Et cela en comparant les md5 des informations fouries.
    $signatures = array();
    // recuperer toutes les signatures
    foreach ($paquets_locaux as $const_dir => $paquets) {
        foreach ($paquets as $chemin => $paquet) {
            $signatures[$paquet['signature']] = array('constante' => $const_dir, 'chemin' => $chemin, 'paquet' => $paquet);
        }
    }
    // tous les paquets du depot qui ne font pas parti des signatures
    $anciens_paquets = sql_allfetsel('id_paquet', 'spip_paquets', array('id_depot=' . sql_quote(0), sql_in('signature', array_keys($signatures), 'NOT')));
    $anciens_paquets = array_map('array_shift', $anciens_paquets);
    // tous les plugins correspondants aux anciens paquets
    $anciens_plugins = sql_allfetsel('p.id_plugin', array('spip_plugins AS p', 'spip_paquets AS pa'), array('p.id_plugin=pa.id_plugin', sql_in('pa.id_paquet', $anciens_paquets)));
    $anciens_plugins = array_map('array_shift', $anciens_plugins);
    // suppression des anciens paquets
    sql_delete('spip_paquets', sql_in('id_paquet', $anciens_paquets));
    // supprimer les plugins orphelins
    svp_supprimer_plugins_orphelins($anciens_plugins);
    // on ne garde que les paquets qui ne sont pas presents dans la base
    $signatures_base = sql_allfetsel('signature', 'spip_paquets', 'id_depot=' . sql_quote(0));
    $signatures_base = array_map('array_shift', $signatures_base);
    $signatures = array_diff_key($signatures, array_flip($signatures_base));
    // on recree la liste des paquets locaux a inserer
    $paquets_locaux = array();
    foreach ($signatures as $s => $infos) {
        if (!isset($paquets_locaux[$infos['constante']])) {
            $paquets_locaux[$infos['constante']] = array();
        }
        $paquets_locaux[$infos['constante']][$infos['chemin']] = $infos['paquet'];
    }
    svp_base_inserer_paquets_locaux($paquets_locaux);
}