WP File Manager
Current Path:
/
home
/
argothem
/
www
/
log
/
inc
/
cache
/
calcul
/
Name
Action
..
.ok
Edit
00
01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
10
10.cache
Edit
11
12
13
14
15
16
17
18
19
1a
1b
1c
1d
1e
1f
20
21
22
23
24
25
26
27
28
29
2a
2b
2c
2d
2e
2f
30
31
32
33
34
35
36
36.cache
Edit
37
38
39
3a
3b
3c
3d
3e
3f
40
41
41.cache
Edit
42
43
44
45
46
47
48
49
4a
4b
4c
4d
4e
4f
50
51
51.cache
Edit
52
53
54
55
56
57
58
59
5a
5b
5c
5d
5e
5f
60
61
62
63
64
65
66
67
68
69
6a
6b
6c
6d
6e
6f
70
71
72
73
74
75
76
77
78
79
7a
7b
7c
7d
7e
7f
80
81
82
83
84
85
86
87
88
89
8a
8b
8c
8d
8e
8f
90
91
92
93
94
95
96
97
98
99
9a
9b
9c
9d
9e
9f
Chiffrement.php
Edit
Cles-20250623160443.php
Edit
Cles.php
Edit
a0
a1
a2
a3
a4
a5
a6
a7
a8
a9
aa
ab
ac
ad
ad.cache
Edit
ae
af
b0
b1
b2
b3
b4
b5
b6
b7
b8
b9
ba
bb
bc
bd
be
bf
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9
ca
cb
cc
cd
ce
cf
charger_pipelines.php
Edit
charger_plugins_options.php
Edit
d0
d1
d2
d3
d4
d5
d6
d7
d8
d9
da
db
dc
dd
de
df
distant.log-20250625103631.1
Edit
distant.log.1
Edit
distant.log.2
Edit
distant.log.3
Edit
e0
e1
e2
e3
e4
e5
e6
e7
e8
e9
ea
eb
eb.cache
Edit
ec
ec.cache
Edit
ed
ee
ef
f0
f1
f2
f3
f4
f5
f5.cache
Edit
f6
f7
f8
f9
fa
fb
fc
fd
fe
fe.cache
Edit
ff
ff.cache
Edit
modifier.log.1
Edit
mysql.log
Edit
mysql.log-20250623151434.1
Edit
mysql.log-20250623152155.2
Edit
mysql.log-20250623185945.2
Edit
mysql.log.1
Edit
mysql.log.2
Edit
paquet-dist_en.php
Edit
paquet-dist_it.php
Edit
sqlite.log
Edit
svn10000-20250623164814.php
Edit
svn10000-20250623193149.php
Edit
svn10000-20250623205724.php
Edit
svn10000.php
Edit
svp_actionner-20250625103622.php
Edit
svp_actionner.php
Edit
svp_decider.php
Edit
svp_depoter_distant.php
Edit
svp_plugin.php
Edit
v21.php
Edit
v30.php
Edit
v31.php
Edit
Editing: svp_depoter_distant.php
<?php /** * Traitement des dépots distants * * Un dépot distant est une liste de paquets que l'on peut télécharger. * Cette liste est donnée par un fichier XML que l'on peut relire * régulièrement pour actualiser nos informations. Effectivement, chaque * paquet (et plugin) décrit est inséré en base de données pour nous * faciliter les recherches. * * @plugin SVP pour SPIP * @license GPL * @package SPIP\SVP\Depots */ if (!defined('_ECRIRE_INC_VERSION')) { return; } include_spip('inc/plugin'); include_spip('inc/svp_phraser'); /** * Ajout d'un dépot et de son contenu (paquets, plugins) dans la base de données * * Si une erreur survient (syntaxe XML incorrecte, pas de plugin dans le dépot), * son texte est placé dans le paramètre $erreur * * @uses svp_phraser_depot() * @uses svp_actualiser_paquets() * @uses svp_base_supprimer_paquets_locaux() * @param string $url * URL du fichier XML de description du dépot * @param string $erreur * Texte d'un éventuel message d'erreur * @return bool * true si le dépot est ajouté correctement, false sinon */ function svp_ajouter_depot($url, &$erreur = '') { include_spip('inc/distant'); // On considere que l'url a deja ete validee (correcte et nouveau depot) $url = trim($url); // Ajout du depot dans la table spip_depots. Les compteurs de paquets et de plugins // sont mis a jour apres le traitement des paquets // on recupère le XML $fichier_xml = copie_locale($url, 'modif'); if (!$fichier_xml) { $erreur = _T('svp:message_nok_xml_non_recupere', ['fichier' => $url]); return false; } $fichier_xml = _DIR_RACINE . $fichier_xml; // Lire les donnees d'un depot de paquets $infos = svp_phraser_depot($fichier_xml); if (!$infos) { $erreur = _T('svp:message_nok_xml_non_conforme', ['fichier' => $url]); return false; } $titre = filtrer_entites($infos['depot']['titre']); $champs = [ 'titre' => $titre, 'descriptif' => filtrer_entites($infos['depot']['descriptif']), 'type' => $infos['depot']['type'], 'url_serveur' => $infos['depot']['url_serveur'], 'url_brouteur' => $infos['depot']['url_brouteur'], 'url_archives' => $infos['depot']['url_archives'], 'url_commits' => $infos['depot']['url_commits'], 'xml_paquets' => $url, 'sha_paquets' => sha1_file($fichier_xml), 'nbr_paquets' => 0, 'nbr_plugins' => 0, 'nbr_autres' => 0 ]; // verifier avant l'insertion que le depot n'existe pas deja // car la recuperation pouvant etre longue on risque le probleme en cas de concurrence if (sql_countsel('spip_depots', 'xml_paquets=' . sql_quote($url))) { $erreur = _T('svp:message_nok_depot_deja_ajoute', ['url' => $url]); return false; } elseif (!$id_depot = sql_insertq('spip_depots', $champs)) { $erreur = _T('svp:message_nok_sql_insert_depot', ['objet' => "$titre ($url)"]); return false; } // Ajout des paquets dans spip_paquets et actualisation des plugins dans spip_plugins $ok = svp_actualiser_paquets($id_depot, $infos['paquets'], $nb_paquets, $nb_plugins, $nb_autres); if (!$ok or ($nb_paquets == 0)) { // Si une erreur s'est produite, on supprime le depot deja insere sql_delete('spip_depots', 'id_depot=' . sql_quote($id_depot)); if (!$ok) { $erreur = _T('svp:message_nok_xml_non_conforme', ['fichier' => $url]); } else { $erreur = _T('svp:message_nok_aucun_paquet_ajoute', ['url' => $url]); } return false; } // On met à jour le nombre de paquets et de plugins du depot maintenant ! sql_updateq( 'spip_depots', ['nbr_paquets' => $nb_paquets, 'nbr_plugins' => $nb_plugins, 'nbr_autres' => $nb_autres], 'id_depot=' . sql_quote($id_depot) ); // On vide les paquets locaux pour mettre a jour leurs donnees relatives au depot // comme les mises a jour disponibles include_spip('inc/svp_depoter_local'); svp_actualiser_paquets_locaux(true); return true; } /** * Suppression d'un dépot et de son contenu (paquets, plugins) dans la base de données * * Cette suppression entraîne des recalcul comme les versions maximales * des plugins téléchargeables qui peuvent changer. * * @uses svp_actualiser_url_plugins() * @uses svp_nettoyer_apres_suppression() * @uses svp_base_supprimer_paquets_locaux() * * @param int $id * Identifiant du dépot * @return bool * false si le dépot n'est pas trouvé, true sinon */ function svp_supprimer_depot($id) { $id = intval($id); // Pas de depot a cet id ? if (!$id_depot = sql_getfetsel('id_depot', 'spip_depots', 'id_depot=' . sql_quote($id))) { return false; } // on calcule les versions max des plugins heberges par le depot $vmax = []; if ($resultats = sql_allfetsel('id_plugin, version', 'spip_paquets', 'id_depot=' . sql_quote($id))) { foreach ($resultats as $paquet) { $id_plugin = $paquet['id_plugin']; if ( !isset($vmax[$id_plugin]) or (spip_version_compare($vmax[$id_plugin], $paquet['version'], '<')) ) { $vmax[$id_plugin] = $paquet['version']; } } } // On supprime les paquets heberges par le depot sql_delete('spip_paquets', 'id_depot=' . sql_quote($id_depot)); // Si on est pas en mode runtime, on utilise surement l'espace public pour afficher les plugins. // Il faut donc verifier que les urls suivent bien la mise à jour // Donc avant de nettoyer la base des plugins du depot ayant disparus on supprime toutes les urls // associees a ce depot : on les recreera apres le nettoyage if (!_SVP_MODE_RUNTIME) { svp_actualiser_url_plugins(); } // Nettoyer les autres relations à ce dépot svp_nettoyer_apres_suppression($id_depot, $vmax); // 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(); } // On supprime le depot lui-meme sql_delete('spip_depots', 'id_depot=' . sql_quote($id_depot)); // on supprime les paquets locaux pour reactualisation include_spip('inc/svp_depoter_local'); svp_base_supprimer_paquets_locaux(); return true; } /** * Nettoyer la base de données après la suppression d'un dépot * * Supprime * - les liens des plugins avec le dépot (table spip_depots_plugins) * - les plugins dont aucun paquet n'est encore hébergé par un dépot restant (table spip_plugins) * Remet à zéro la version maximale des plugins ayant vu leur paquet en version maximale supprimée * * @param int $id_depot * Identifiant du dépot * @param array $vmax * Tableau de la version maximale des plugins du dépot supprimé * Tableau (id_plugin => version maximale) * @return bool * true toujours. **/ function svp_nettoyer_apres_suppression($id_depot, $vmax) { // On rapatrie la liste des plugins du depot qui servira apres qu'on ait supprime les liens // de la table spip_depots_plugins $liens = sql_allfetsel('id_plugin', 'spip_depots_plugins', 'id_depot=' . sql_quote($id_depot)); $plugins_depot = array_column($liens, 'id_plugin'); // On peut donc supprimer tous ces liens *plugins-depots* du depot sql_delete('spip_depots_plugins', 'id_depot=' . sql_quote($id_depot)); // On verifie pour chaque plugin concerne par la disparition de paquets si c'est la version // la plus elevee qui a ete supprimee. // Si oui, on positionne le vmax a 0, ce qui permettra de remettre a jour le plugin systematiquement // a la prochaine actualisation. // Cette operation est necessaire car on n'impose pas que les informations du plugin soient identiques // pour chaque paquet !!! // On insere, en encapsulant pour sqlite... if (sql_preferer_transaction()) { sql_demarrer_transaction(); } if ($resultats = sql_allfetsel('id_plugin, vmax', 'spip_plugins', sql_in('id_plugin', $plugins_depot))) { foreach ($resultats as $plugin) { if (spip_version_compare($plugin['vmax'], $vmax[$plugin['id_plugin']], '=')) { sql_updateq('spip_plugins', ['vmax' => ''], 'id_plugin=' . sql_quote($plugin['id_plugin'])); } } } if (sql_preferer_transaction()) { sql_terminer_transaction(); } // Maintenant on calcule la liste des plugins du depot qui ne sont pas heberges // par un autre depot => donc a supprimer // - Liste de tous les plugins encore lies a un autre depot // tous les plugins correspondants aux anciens paquets $plugins_restants = sql_allfetsel('DISTINCT(id_plugin)', 'spip_paquets', sql_in('id_plugin', $plugins_depot)); $plugins_restants = array_column($plugins_restants, 'id_plugin'); // - L'intersection des deux tableaux renvoie les plugins a supprimer $plugins_a_supprimer = array_diff($plugins_depot, $plugins_restants); // On supprimer les plugins identifies sql_delete('spip_plugins', sql_in('id_plugin', $plugins_a_supprimer)); return true; } /** * Actualisation des plugins d'un dépot déjà crée * * Actualise les informations uniquement si la signature du fichier * XML de description du dépot a changé * * @uses svp_actualiser_maj_version() * @uses svp_actualiser_paquets() * @uses svp_phraser_depot() * @param int $id * Identifiant du dépot * @return bool * false si erreur, true sinon */ function svp_actualiser_depot($id) { include_spip('inc/distant'); $id = intval($id); // pas de depot a cet id ? if (!$depot = sql_fetsel('*', 'spip_depots', 'id_depot=' . sql_quote($id))) { return false; } $fichier_xml = _DIR_RACINE . copie_locale($depot['xml_paquets'], 'modif'); $sha = sha1_file($fichier_xml); if ($depot['sha_paquets'] == $sha) { // Le fichier n'a pas change (meme sha1) alors on ne fait qu'actualiser la date // de mise a jour du depot en mettant a jour *inutilement* le sha1 spip_log( 'Aucune modification du fichier XML, actualisation non declenchee - id_depot = ' . $depot['id_depot'], 'svp_actions.' . _LOG_INFO ); sql_updateq('spip_depots', ['sha_paquets' => $sha], 'id_depot=' . $id); } else { // Le fichier a bien change il faut actualiser tout le depot $infos = svp_phraser_depot($fichier_xml); if (!$infos) { return false; } // On actualise les paquets dans spip_paquets en premier lieu. // Lors de la mise a jour des paquets, les plugins aussi sont actualises $ok = svp_actualiser_paquets( $depot['id_depot'], $infos['paquets'], $nb_paquets, $nb_plugins, $nb_autres ); // apres la mise a jour des paquets d'un depot, on actualise les informations des paquets locaux // principalement l'info "maj_version" indiquant s'il existe un paquet plus recent include_spip('inc/svp_depoter_local'); svp_actualiser_maj_version(); if ($ok) { // On met à jour : // -- les infos ne pouvant pas etre editees par le formulaire d'edition // d'un depot et extraites du xml // -- le nombre de paquets et de plugins du depot ainsi que le nouveau sha1 // ce qui aura pour effet d'actualiser la date de mise a jour $champs = [ 'url_serveur' => $infos['depot']['url_serveur'], 'url_brouteur' => $infos['depot']['url_brouteur'], 'url_archives' => $infos['depot']['url_archives'], 'url_commits' => $infos['depot']['url_commits'], 'nbr_paquets' => $nb_paquets, 'nbr_plugins' => $nb_plugins, 'nbr_autres' => $nb_autres, 'sha_paquets' => $sha ]; sql_updateq('spip_depots', $champs, 'id_depot=' . sql_quote($depot['id_depot'])); } } return true; } /** * 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. * * @uses svp_supprimer_plugins_orphelins() * @uses svp_corriger_vmax_plugins() * @uses svp_completer_plugins() * @uses eclater_plugin_paquet() * @uses svp_inserer_multi() * @uses svp_completer_plugins_depot() * @uses svp_actualiser_url_plugins() * * @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 = ['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 = []; 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', ['id_depot=' . sql_quote($id_depot), sql_in('signature', $signatures, 'NOT')] ); $anciens_paquets = array_column($anciens_paquets, 'id_paquet'); // 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', ['spip_plugins AS pl', 'spip_paquets AS pa'], ['pl.id_plugin=pa.id_plugin', sql_in('pa.id_paquet', $anciens_paquets)] ); $anciens_plugins = array_column($anciens_plugins, 'id_plugin'); // 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', ['spip_plugins AS pl', 'spip_paquets AS pa'], [ sql_in('pl.id_plugin', $anciens_plugins), 'pl.id_plugin=pa.id_plugin', 'pa.id_depot=' . sql_quote($id_depot) ] ); $plugins_restants = array_column($plugins_restants, 'id_plugin'); // par opposition, on retrouve ceux qui n'en ont plus... $plugins_supprimes = array_diff($anciens_plugins, $plugins_restants); sql_delete( 'spip_depots_plugins', ['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_column($signatures, 'signature'); foreach ($paquets as $cle => $_infos) { if (in_array($_infos['md5'], $signatures)) { unset($paquets[$cle]); } } // tableaux d'actions $insert_paquets = []; $insert_plugins = []; $insert_contribs = []; $prefixes = []; // 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 = []; // 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']; // Le logo est normalement fourni dans les infos de zip if (!empty($_infos['logo'])) { $insert_paquet['logo'] = $depot['url_archives'] . '/' . $_infos['logo']; } elseif ($insert_paquet['logo']) { // Sinon 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 $insert_paquet['logo'] = $depot['url_archives'] . '/' . preg_replace(',\.zip$,i', '', $insert_paquet['nom_archive']) . '.' . pathinfo($insert_paquet['logo'], PATHINFO_EXTENSION); } } 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', [ '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 = [ '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', ['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, ['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 = [ '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', ['spip_plugins AS p', 'spip_depots_plugins AS dp'], ['p.id_plugin=dp.id_plugin', 'dp.id_depot=' . sql_quote($id_depot)] ); $ids = array_column($ids, 'id_plugin'); // inserer les liens avec le depots $insert_dp = []; $news_id = array_diff(array_values($prefixes), $ids); foreach ($news_id as $id) { $insert_dp[] = ['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(); } // 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', ['id_depot=' . sql_quote($id_depot), 'id_plugin=0']); return true; } /** * Insertion en masse de plugins ou de paquets. * * Les paquets peuvent de pas avoir d'info "prefixe" (à transformer en id_plugin) * lorsqu'ils ne proviennent pas de plugin (squelettes...) * * @param array $insert_plugins * Tableau de description de plugins. * Une description est un tableau de couples (colonne sql => valeur) * pour l'insertion en base de données. * @param array $insert_paquets * Tableau de description de paquets. * Une description est un tableau de couples (colonne sql => valeur) * pour l'insertion en base de données. * @param array $insert_contribs * Tableau de description de paquets (contributions non plugins). * Une description est un tableau de couples (colonne sql => valeur) * pour l'insertion en base de données. * @param array $prefixes * Couples de relation (préfixe de plugin => identifiant de plugin) connues, * pour limiter les accès SQL. * @return void **/ function svp_inserer_multi(&$insert_plugins, &$insert_paquets, &$insert_contribs, &$prefixes) { if (count($insert_plugins)) { sql_insertq_multi('spip_plugins', $insert_plugins); $insert_plugins = []; } if (count($insert_paquets)) { // on cherche tous les id_plugin/prefixe que l'on a à récuperer // en une seule requete $prefixes_manquants = []; foreach ($insert_paquets as $p) { // on ne connait que le prefixe if (isset($p['prefixe']) and !isset($prefixes[$p['prefixe']])) { $prefixes_manquants[] = $p['prefixe']; } } // recuperer les nouveaux prefixes : $new = sql_allfetsel(['prefixe', 'id_plugin'], 'spip_plugins', sql_in('prefixe', $prefixes_manquants)); foreach ($new as $p) { $prefixes[$p['prefixe']] = $p['id_plugin']; } // inserer les id_plugin dans les paquets a inserer // inserer le prefixe dans le paquet (pour raccourcis de jointures) foreach ($insert_paquets as $c => $p) { if (isset($p['prefixe'])) { $insert_paquets[$c]['id_plugin'] = $prefixes[$insert_paquets[$c]['prefixe']]; } else { $insert_paquets[$c]['prefixe'] = array_search($p['id_plugin'], $prefixes); } } // on insere tout ! sql_insertq_multi('spip_paquets', $insert_paquets); $insert_paquets = []; } // les contribs n'ont pas le même nombre de champs dans les insertions // et n'ont pas de plugin rattachés. if (count($insert_contribs)) { sql_insertq_multi('spip_paquets', $insert_contribs); $insert_contribs = []; } } /** * Complète les informations des plugins contenus dans un depot * en compilant certaines informations (compatibilités, dates, branches) * * @uses svp_completer_plugins() * @param int $id_depot * Identifiant du depot à actualiser **/ function svp_completer_plugins_depot($id_depot) { // On limite la revue des paquets a ceux des plugins heberges par le depot en cours d'actualisation $ids_plugins = sql_allfetsel('id_plugin', 'spip_depots_plugins', ['id_depot=' . sql_quote($id_depot)]); $ids_plugins = array_column($ids_plugins, 'id_plugin'); if ($ids_plugins) { svp_completer_plugins($ids_plugins); } } /** * Complète les informations des plugins, d'une liste de plugins donnés, * en compilant certaines informations (compatibilités, dates, branches) * * @uses compiler_branches_spip() * @param array $ids_plugin * Liste d'identifiants de plugins * @return bool * false si rien à faire, true sinon **/ function svp_completer_plugins($ids_plugin) { if (!$ids_plugin) { return false; } include_spip('inc/svp_outiller'); // -- on recupere tous les paquets associes aux plugins indiques et on compile les infos if ( $resultats = sql_allfetsel( 'id_plugin, compatibilite_spip, date_crea, date_modif', 'spip_paquets', [sql_in('id_plugin', $ids_plugin), 'id_depot>' . intval(0)], '', 'id_plugin' ) ) { $plugin_en_cours = 0; $inserts = $complements = []; foreach ($resultats as $paquet) { // On finalise le plugin en cours et on passe au suivant if ($plugin_en_cours != $paquet['id_plugin']) { // On met a jour le plugin en cours if ($plugin_en_cours) { // On finalise maintenant les branches de la compatibilite globale du plugin $branches = explode(',', $complements['branches_spip']); $complements['branches_spip'] = implode(',', array_unique($branches)); $inserts[$plugin_en_cours] = $complements; } // On passe au plugin suivant $plugin_en_cours = $paquet['id_plugin']; $complements = ['compatibilite_spip' => '', 'branches_spip' => '', 'date_crea' => 0, 'date_modif' => 0]; } // On compile les compléments du plugin avec le paquet courant if ($paquet['date_modif'] > $complements['date_modif']) { $complements['date_modif'] = $paquet['date_modif']; } if ( ($complements['date_crea'] === 0) or ($paquet['date_crea'] < $complements['date_crea']) ) { $complements['date_crea'] = $paquet['date_crea']; } if ($paquet['compatibilite_spip']) { if (!$complements['compatibilite_spip']) { $complements['compatibilite_spip'] = $paquet['compatibilite_spip']; } else { $complements['compatibilite_spip'] = fusionner_intervalles( $paquet['compatibilite_spip'], $complements['compatibilite_spip'] ); } } if ($branches_paquet = compiler_branches_spip($paquet['compatibilite_spip'])) { $complements['branches_spip'] .= ($complements['branches_spip'] ? ',' : '') . $branches_paquet; } } // On finalise le dernier paquet en cours $branches = explode(',', $complements['branches_spip']); $complements['branches_spip'] = implode(',', array_unique($branches)); $inserts[$plugin_en_cours] = $complements; // On insere, en encapsulant pour sqlite... if (sql_preferer_transaction()) { sql_demarrer_transaction(); } foreach ($inserts as $id_plugin => $complements) { sql_updateq('spip_plugins', $complements, 'id_plugin=' . intval($id_plugin)); } if (sql_preferer_transaction()) { sql_terminer_transaction(); } } return true; } /** * Recrée toutes les URLs propres de plugin * * Supprime toutes les urls de plugin de la table spip_urls puis les régénère. * * @return int * Nombre d'URLs de plugin régénérées **/ function svp_actualiser_url_plugins() { $nb_plugins = 0; // On supprime toutes les urls de plugin sql_delete('spip_urls', ['type=\'plugin\'']); // On recupere les ids des plugins et on regenere les urls if ($ids_plugin = sql_allfetsel('id_plugin', 'spip_plugins')) { $ids_plugin = array_column($ids_plugin, 'id_plugin'); $nb_plugins = count($ids_plugin); foreach ($ids_plugin as $_id) { generer_objet_url($_id, 'plugin', '', '', true); } } return $nb_plugins; } /** * Éclate une description de paquet issu du XML du dépot en deux parties, * une pour le plugin, l'autre pour le paquet * * Sépare en deux une description de champs désignant un paquet, en extrayant : * - la partie plugin, soit ce qui peut être propre à plusieurs paquets. * On trouve dedans le prefixe, nom, slogan, catégorie, tags * - la partie paquet, soit ce qui est propre à ce conteneur là. On trouve * dedans entre autres la description, la version, la compatibilité * à SPIP, les dépendances, etc... * * @param array $champs_aplat * Couples (clé => valeur) d'un paquet issu de l'analyse XML du dépot * @return array * Tableau de 2 index : * - Index 'plugin' : couples (clé=>valeur) relatives au plugin * - Index 'paquet' : couples (clé=>valeur) spécifiques au paquet **/ function eclater_plugin_paquet($champs_aplat) { return [ 'plugin' => [ 'prefixe' => $champs_aplat['prefixe'], 'nom' => $champs_aplat['nom'], 'slogan' => $champs_aplat['slogan'] ], 'paquet' => [ 'logo' => $champs_aplat['logo'], 'description' => $champs_aplat['description'], 'auteur' => $champs_aplat['auteur'], 'credit' => $champs_aplat['credit'], 'version' => $champs_aplat['version'], 'version_base' => $champs_aplat['version_base'], 'compatibilite_spip' => $champs_aplat['compatibilite_spip'], 'branches_spip' => $champs_aplat['branches_spip'], 'etat' => $champs_aplat['etat'], 'etatnum' => $champs_aplat['etatnum'], 'licence' => $champs_aplat['licence'], 'copyright' => $champs_aplat['copyright'], 'lien_doc' => $champs_aplat['lien_doc'], 'lien_demo' => $champs_aplat['lien_demo'], 'lien_dev' => $champs_aplat['lien_dev'], 'dependances' => $champs_aplat['dependances'], 'procure' => $champs_aplat['procure'] ] ]; } /** * Détermine la version max de chaque plugin, c'est à dire * la version maxi d'un des paquets qui lui est lié. * * @param array $plugins Liste d'identifiant de plugins **/ function svp_corriger_vmax_plugins($plugins) { // tous les plugins encore lies a des depots (hors local)... // la vmax est a retablir... if ($plugins) { $p = sql_allfetsel( 'DISTINCT(p.id_plugin)', ['spip_plugins AS p', 'spip_paquets AS pa'], [sql_in('p.id_plugin', $plugins), 'p.id_plugin=pa.id_plugin', 'pa.id_depot>' . intval(0)] ); $p = array_column($p, 'id_plugin'); // pour les autres, on la fixe correctement // On insere, en encapsulant pour sqlite... if (sql_preferer_transaction()) { sql_demarrer_transaction(); } foreach ($p as $id_plugin) { $vmax = ''; if ($pa = sql_allfetsel('version', 'spip_paquets', ['id_plugin=' . $id_plugin, 'id_depot>' . intval(0)])) { foreach ($pa as $v) { if (spip_version_compare($v['version'], $vmax, '>')) { $vmax = $v['version']; } } } sql_updateq('spip_plugins', ['vmax' => $vmax], 'id_plugin=' . intval($id_plugin)); } if (sql_preferer_transaction()) { sql_terminer_transaction(); } } }