<?php
/**
- * Gestion de l'actionneur : il effectue les actions sur les plugins
+ * Gestion de l'actionneur : il effectue les actions sur les plugins
*
* @plugin SVP pour SPIP
* @license GPL
* @package SPIP\SVP\Actionneur
*/
-
-if (!defined("_ECRIRE_INC_VERSION")) return;
+
+if (!defined("_ECRIRE_INC_VERSION")) {
+ return;
+}
/**
* dans un fichier cache et de les effectuer.
*
* @package SPIP\SVP\Actionner
-**/
+ **/
class Actionneur {
/**
* Instance du décideur
- * @var Decideur */
- var $decideur;
+ *
+ * @var Decideur
+ */
+ public $decideur;
/**
* Loguer les différents éléments
- *
+ *
* Sa valeur sera initialisée par la configuration 'mode_log_verbeux' de SVP
- *
- * @var bool */
- var $log = false;
+ *
+ * @var bool
+ */
+ public $log = false;
/**
* Liste des actions à faire
+ *
* @var array
* Tableau identifiant du paquet => type d'action
*/
- var $start = array();
+ public $start = array();
/**
* Actions en cours d'analyse
*
* Chaque sous-tableau est composé d'une description courte du paquet
* auquel est ajouté dans l'index 'todo' le type d'action à faire.
- *
+ *
* @var array
* Index 'off' : les paquets à désactiver (ordre inverse des dépendances)
* Index 'lib' : les librairies à installer
* Index 'on' : les paquets à activer (ordre des dépendances)
* Index 'neutre' : autres actions dont l'ordre a peu d'importance.
*/
- var $middle = array(
+ public $middle = array(
'off' => array(),
'lib' => array(),
'on' => array(),
/**
* Liste des actions à faire
- *
+ *
* Liste de description courtes des paquets + index 'todo' indiquant l'action
- * @var array */
- var $end = array();
+ *
+ * @var array
+ */
+ public $end = array();
/**
* Liste des actions faites
* Liste de description courtes des paquets + index 'todo' indiquant l'action
- * @var array */
- var $done = array(); // faites
+ *
+ * @var array
+ */
+ public $done = array(); // faites
/**
* Actions en cours
* Description courte du paquet + index 'todo' indiquant l'action
- * @var array */
- var $work = array();
+ *
+ * @var array
+ */
+ public $work = array();
/**
* Liste des erreurs
- *
- * @var array Liste des erreurs */
- var $err = array();
+ *
+ * @var array Liste des erreurs
+ */
+ public $err = array();
/**
* Verrou.
* Le verrou est posé au moment de passer à l'action.
+ *
* @var array
* Index 'id_auteur' : Identifiant de l'auteur ayant déclenché des actions
* Indix 'time' : timestamp de l'heure de déclenchement de l'action */
- var $lock = array('id_auteur'=>0, 'time'=>'');
+ public $lock = array('id_auteur' => 0, 'time' => '');
/**
* SVP (ce plugin) est-il à désactiver dans une des actions ?
*
* Dans ce cas, on tente de le désactiver après d'autres plugins à désactiver
* sinon l'ensemble des actions suivantes échoueraient.
- *
+ *
* @var bool
* false si SVP n'est pas à désactiver, true sinon */
- var $svp_off = false;
+ public $svp_off = false;
/**
* Constructeur
*
* Détermine si les logs sont activés et instancie un décideur.
*/
- function Actionneur(){
+ public function __construct() {
include_spip('inc/config');
$this->log = (lire_config('svp/mode_log_verbeux') == 'oui');
*
* @param mixed $quoi
* La chose à logguer (souvent un texte)
- **/
- function log($quoi) {
+ **/
+ public function log($quoi) {
if ($this->log) {
- spip_log($quoi,'actionneur');
+ spip_log($quoi, 'actionneur');
}
}
/**
* Ajoute une erreur
- *
+ *
* Ajoute une erreur à la liste des erreurs présentées au moment
* de traiter les actions.
*
* @param string $erreur
* Le texte de l'erreur
- **/
- function err($erreur) {
+ **/
+ public function err($erreur) {
if ($erreur) {
$this->err[] = $erreur;
}
/**
* Remet à zéro les tableaux d'actions
*/
- function clear() {
+ public function clear() {
$this->middle = array(
'off' => array(),
'lib' => array(),
}
/**
- * Ajoute les actions à faire dans l'actionneur
+ * Ajoute les actions à faire dans l'actionneur
*
* @param array $todo
* Tableau des actions à faire (identifiant de paquet => type d'action)
- **/
- function ajouter_actions($todo) {
- foreach ($todo as $id => $action) {
- $this->start[$id] = $action;
+ **/
+ public function ajouter_actions($todo) {
+ if ($todo) {
+ foreach ($todo as $id => $action) {
+ $this->start[$id] = $action;
+ }
}
$this->ordonner_actions();
}
* @param string $nom Nom de la librairie
* @param string $source URL pour obtenir la librairie
*/
- function add_lib($nom, $source) {
+ public function add_lib($nom, $source) {
if (!$this->decideur->est_presente_lib($nom)) {
if (is_writable(_DIR_LIB)) {
$this->middle['lib'][$nom] = array(
- 'todo'=>'getlib',
- 'n'=>$nom,
- 'p'=>$nom,
- 'v'=>$source,
- 's'=>$source,
+ 'todo' => 'getlib',
+ 'n' => $nom,
+ 'p' => $nom,
+ 'v' => $source,
+ 's' => $source,
);
} else {
// erreur : impossible d'ecrire dans _DIR_LIB !
return false;
}
}
+
return true;
}
* - puis ce qui est a installer (à commencer par les librairies, puis paquets),
* - puis les actions neutres
*/
- function ordonner_actions() {
+ public function ordonner_actions() {
+ $this->log("Ordonner les actions à réaliser");
// nettoyer le terrain
$this->clear();
- foreach ($this->start as $id=>$action) {
- $i = $this->decideur->infos_courtes_id($id);
- $i = $i['i'][$id];
+ // récupérer les descriptions de chaque paquet
+ $this->log("> Récupérer les descriptions des paquets concernés");
+ $infos = array();
+ foreach ($this->start as $id => $action) {
+ // seulement les identifiants de paquets (pas les librairies)
+ if (is_int($id)) {
+ $info = $this->decideur->infos_courtes_id($id);
+ $infos[$id] = $info['i'][$id];
+ }
+ }
+
+ // Calculer les dépendances (nécessite) profondes pour chaque paquet,
+ // si les plugins en questions sont parmis ceux actionnés
+ // (ie A dépend de B qui dépend de C => a dépend de B et C).
+ $infos = $this->calculer_necessites_complets($infos);
+
+ foreach ($this->start as $id => $action) {
+ // infos du paquet. Ne s'applique pas sur librairie ($id = md5)
+ $i = is_int($id) ? $infos[$id] : array();
+
switch ($action) {
case 'getlib':
// le plugin en ayant besoin le fera
break;
case 'up':
// si le plugin est actif
- if ($i['a'] == 'oui') {
+ if ($i['a'] == 'oui') {
$this->on($i, $action);
} else {
$this->neutre($i, $action);
}
}
}
-
+
$this->log("------------");
#$this->log("Fin du tri :");
#$this->log($this->end);
/**
- * Ajoute un paquet à activer
+ * Complète les infos des paquets actionnés pour qu'ils contiennent
+ * en plus de leurs 'necessite' directs, tous les nécessite des
+ * plugins dont ils dépendent, si ceux ci sont aussi actionnés.
+ *
+ * Ie: si A indique dépendre de B, et B de C, la clé
+ * 'dp' (dépendances prefixes). indiquera les préfixes
+ * des plugins B et C
+ *
+ * On ne s'occupe pas des versions de compatibilité ici
+ *
+ * @param array $infos (identifiant => description courte du plugin)
+ * @return array $infos
+ **/
+ public function calculer_necessites_complets($infos) {
+ $this->log("> Calculer les dépendances nécessités sur paquets concernés");
+
+ // prefixe => array(prefixes)
+ $necessites = array();
+
+ // 1) déjà les préfixes directement nécessités
+ foreach ($infos as $i => $info) {
+ if (!empty($info['dn'])) {
+ # à remplacer par array_column($info['dn'], 'nom') un jour
+ $necessites[$info['p']] = array();
+ foreach ($info['dn'] as $n) {
+ $necessites[$info['p']][] = $n['nom'];
+ }
+ }
+ // préparer la clé dp (dépendances préfixes) et 'dmp' (dépendent de moi) vide
+ $infos[$i]['dp'] = array();
+ $infos[$i]['dmp'] = array();
+ }
+
+ if ($nb = count($necessites)) {
+ $this->log(">- $nb plugins ont des nécessités");
+ // 2) ensuite leurs dépendances, récursivement
+ $necessites = $this->calculer_necessites_complets_rec($necessites);
+
+ // 3) intégrer le résultat
+ foreach ($infos as $i => $info) {
+ if (!empty($necessites[$info['p']])) {
+ $infos[$i]['dp'] = $necessites[$info['p']];
+ }
+ }
+
+ // 4) calculer une clé 'dmp' : liste des paquets actionnés qui dépendent de moi
+ foreach ($infos as $i => $info) {
+ $dmp = array();
+ foreach ($necessites as $prefixe => $liste) {
+ if (in_array($info['p'], $liste)) {
+ $dmp[] = $prefixe;
+ }
+ }
+ $infos[$i]['dmp'] = $dmp;
+ }
+ }
+
+ # $this->log($infos);
+
+ return $infos;
+ }
+
+ /**
+ * Fonction récursive pour calculer la liste de tous les préfixes
+ * de plugins nécessités par un autre.
+ *
+ * Avec une liste fermée connue d'avance des possibilités de plugins
+ * (ceux qui seront actionnés)
+ *
+ * @param array prefixe => liste de prefixe dont il dépend
+ * @param bool $profondeur
+ * @return array prefixe => liste de prefixe dont il dépend
+ **/
+ public function calculer_necessites_complets_rec($necessites, $profondeur = 0) {
+ $changement = false;
+ foreach ($necessites as $prefixe => $liste) {
+ $n = count($liste);
+ foreach ($liste as $prefixe_necessite) {
+ // si un des plugins dépendants fait partie des plugins actionnés,
+ // il faut aussi lui ajouter ses dépendances…
+ if (isset($necessites[$prefixe_necessite])) {
+ $liste = array_unique(array_merge($liste, $necessites[$prefixe_necessite]));
+ }
+ }
+ $necessites[$prefixe] = $liste;
+ if ($n !== count($liste)) {
+ $changement = true;
+ }
+ }
+
+ // limiter à 10 les successions de dépendances !
+ if ($changement and $profondeur <= 10) {
+ $necessites = $this->calculer_necessites_complets_rec($necessites, $profondeur++);
+ }
+
+ if ($changement and $profondeur > 10) {
+ $this->log("! Problème de calcul de dépendances complètes : récursion probable. On stoppe.");
+ }
+
+ return $necessites;
+ }
+
+ /**
+ * Ajoute un paquet à activer
*
* À chaque fois qu'un nouveau paquet arrive ici, on le compare
* avec ceux déjà présents pour savoir si on doit le traiter avant
* librairies seront téléchargées avant l'activation des plugins,
* le plugin aura donc sa librairie lorsqu'il sera activé)
*
- *
+ *
* @param array $info
* Description du paquet
* @param string $action
* Action à réaliser (on, upon)
* @return void
- **/
- function on($info, $action) {
+ **/
+ public function on($info, $action) {
$info['todo'] = $action;
$p = $info['p'];
$this->log("ON: $p $action");
// si dependance, il faut le mettre avant !
- $in = $out = $deps = $deps_all = array();
+ $in = $out = $prov = $deps = $deps_all = array();
// raz des cles pour avoir les memes que $out (utile reellement ?)
$this->middle['on'] = array_values($this->middle['on']);
- // ajout des dependance
- foreach ($info['dn'] as $dep) {
- $in[] = $dep['nom'];
+ // ajout des dependances
+ $in = $info['dp'];
+ // $info fourni ses procure
+ if (isset($info['procure']) and $info['procure']) {
+ $prov = array_keys($info['procure']);
}
+ // et se fournit lui meme evidemment
+ array_unshift($prov, $p);
+
// ajout des librairies
foreach ($info['dl'] as $lib) {
// il faudrait gerer un retour d'erreur eventuel !
//
// ainsi que les dependences de ces plugins (deps)
// ie. ces plugins peuvent dependre de ce nouveau a activer.
- foreach ($this->middle['on'] as $inf) {
- $out[] = $inf['p'];
- foreach ($inf['dn'] as $dep) {
- $deps[$inf['p']][] = $dep['nom'];
- $deps_all[] = $dep['nom'];
+ foreach ($this->middle['on'] as $k => $inf) {
+ $out["$k:0"] = $inf['p'];
+ if (isset($inf['procure']) and $inf['procure']) {
+ $i = 1;
+ foreach ($inf['procure'] as $procure => $v) {
+ $out["$k:$i"] = $inf['p'];
+ $i++;
+ }
}
+
+ $deps[$inf['p']] = $inf['dp'];
+ $deps_all = array_merge($deps_all, $inf['dp']);
}
// on place notre action juste apres la derniere dependance
if ($diff = array_intersect($in, $out)) {
$key = array();
- foreach($diff as $d) {$key[] = array_search($d, $out);}
+ foreach ($diff as $d) {
+ $k = array_search($d, $out);
+ $k = explode(":", $k);
+ $key[] = reset($k);
+ }
$key = max($key);
$this->log("- placer $p apres " . $this->middle['on'][$key]['p']);
if ($key == count($this->middle['on'])) {
$this->middle['on'][] = $info;
} else {
- array_splice($this->middle['on'], $key+1, 0, array($info));
+ array_splice($this->middle['on'], $key + 1, 0, array($info));
}
- // intersection = plugin dependant de celui-ci
- // on place notre plugin juste avant la premiere dependance a lui trouvee
- } elseif (in_array($p, $deps_all)) {
- foreach ($deps as $prefix=>$dep) {
- if (in_array($p, $dep)) {
- $key = array_search($prefix, $out);
+ // intersection = plugin dependant de celui-ci
+ // on place notre plugin juste avant la premiere dependance a lui trouvee
+ } elseif (array_intersect($prov, $deps_all)) {
+ foreach ($deps as $prefix => $dep) {
+ if ($diff = array_intersect($prov, $deps_all)) {
+ foreach ($diff as $d) {
+ $k = array_search($d, $out);
+ $k = explode(":", $k);
+ $key[] = reset($k);
+ }
+ $key = min($key);
$this->log("- placer $p avant $prefix qui en depend ($key)");
if ($key == 0) {
array_unshift($this->middle['on'], $info);
}
}
- // rien de particulier, il a des dependances mais les plugins
- // ne sont pas encore la ou les dependances sont deja actives
- // donc on le place tout en bas
+ // rien de particulier, il a des dependances mais les plugins
+ // ne sont pas encore la ou les dependances sont deja actives
+ // donc on le place tout en bas
} else {
$this->log("- placer $p tout en bas");
$this->middle['on'][] = $info;
/**
- * Ajoute un paquet avec une action neutre
+ * Ajoute un paquet avec une action neutre
*
* Ces actions seront traitées en dernier, et peu importe leur
* ordre car elles n'entrent pas en conflit avec des dépendances.
- *
+ *
* @param array $info
* Description du paquet
* @param string $action
* Action à réaliser (kill, get, up (sur plugin inactif))
* @return void
- **/
- function neutre($info, $action) {
+ **/
+ public function neutre($info, $action) {
$info['todo'] = $action;
$this->log("NEUTRE: $info[p] $action");
$this->middle['neutre'][] = $info;
*
* Si le paquet est une dépendance d'un autre plugin, il faut le mettre
* après (pour désactiver avant celui qui en dépend).
- *
+ *
* @param array $info
* Description du paquet
* @param string $action
* Action à réaliser (kill, get, up (sur plugin inactif))
* @return void
- **/
- function off($info, $action) {
+ **/
+ public function off($info, $action) {
$info['todo'] = $action;
$p = $info['p'];
$this->log("OFF: $p $action");
if ($p == 'SVP') {
$this->svp_off = true;
}
-
+
// si dependance, il faut le mettre avant !
$in = $out = array();
// raz des cles pour avoir les memes que $out (utile reellement ?)
$this->middle['off'] = array_values($this->middle['off']);
- foreach ($info['dn'] as $dep) {
- $in[] = $dep['nom'];
- }
- foreach ($this->middle['off'] as $inf) {
+ // in : si un plugin en dépend, il faudra désactiver celui là avant.
+ $in = $info['dp'];
+
+ foreach ($this->middle['off'] as $inf) {
$out[] = $inf['p'];
}
- if (!$in) {
+ if (!$info['dn']) {
// ce plugin n'a pas de dependance, on le met en dernier !
$this->log("- placer $p tout en bas");
$this->middle['off'][] = $info;
} else {
// ce plugin a des dependances,
// on le desactive juste avant elles.
-
+
// intersection = dependance presente aussi
// on place notre action juste avant la premiere dependance
if ($diff = array_intersect($in, $out)) {
$key = array();
- foreach($diff as $d) {$key[] = array_search($d, $out);}
+ foreach ($diff as $d) {
+ $key[] = array_search($d, $out);
+ }
$key = min($key);
$this->log("- placer $p avant " . $this->middle['off'][$key]['p']);
array_splice($this->middle['off'], $key, 0, array($info));
+ // inversement des plugins dépendants de ce plugin sont présents…
+ // on le met juste après le dernier
+ } elseif ($diff = array_intersect($info['dmp'], $out)) {
+ $key = array();
+ foreach ($diff as $d) {
+ $key[] = array_search($d, $out);
+ }
+ $key = max($key);
+ $this->log("- placer $p apres " . $this->middle['off'][$key]['p']);
+ if ($key == count($this->middle['off'])) {
+ $this->middle['off'][] = $info;
+ } else {
+ array_splice($this->middle['off'], $key + 1, 0, array($info));
+ }
} else {
// aucune des dependances n'est a desactiver
// (du moins à ce tour ci),
// on le met en premier !
$this->log("- placer $p tout en haut");
- array_unshift($this->middle['off'], $info); // etait ->middle['on'] ?? ...
+ array_unshift($this->middle['off'], $info);
}
}
unset($diff, $in, $out);
}
+ /**
+ * Retourne le texte qui présente la dernière action qui vient d'être réalisée
+ *
+ * @return string
+ **/
+ public function presenter_derniere_action() {
+ $i = end($this->done);
+ reset($this->done);
+ $texte = '';
+ if ($i) {
+ $ok = ($i['done'] ? true : false);
+ $oks = &$ok;
+ $ok_texte = $ok ? 'ok' : 'fail';
+ $cle_t = 'svp:message_action_finale_' . $i['todo'] . '_' . $ok_texte;
+ $trads = array(
+ 'plugin' => $i['n'],
+ 'version' => denormaliser_version($i['v']),
+ );
+ if (isset($i['maj'])) {
+ $trads['version_maj'] = denormaliser_version($i['maj']);
+ }
+ $texte = _T($cle_t, $trads);
+ if (is_string($i['done'])) {
+ $texte .= " <span class='$ok_texte'>$i[done]</span>";
+ }
+ }
+ return $texte;
+ }
/**
* Retourne un bilan, texte HTML, des actions qui ont été faites
* Si c'est un affichage du bilan de fin, et qu'il reste des actions
* à faire, un lien est proposé pour faire supprimer ces actions restantes
* et le verrou qui va avec.
- *
+ *
* @param bool $fin
* Est-ce un affichage intermédiaire (false) ou le tout dernier (true).
* @return string
* Bilan des actions au format HTML
- **/
- function presenter_actions($fin = false) {
+ **/
+ public function presenter_actions($fin = false) {
$affiche = "";
include_spip('inc/filtres_boites');
-
+
if (count($this->err)) {
$erreurs = "<ul>";
foreach ($this->err as $i) {
$erreurs .= "\t<li class='erreur'>" . $i . "</li>\n";
}
- $erreurs .= "</ul>";
+ $erreurs .= "</ul>";
$affiche .= boite_ouvrir(_T('svp:actions_en_erreur'), 'error') . $erreurs . boite_fermer();
}
$oks = &$ok;
$ok_texte = $ok ? 'ok' : 'fail';
$cle_t = 'svp:message_action_finale_' . $i['todo'] . '_' . $ok_texte;
- $texte = _T($cle_t, array(
+ $trads = array(
'plugin' => $i['n'],
'version' => denormaliser_version($i['v']),
- 'version_maj' => denormaliser_version($i['maj'])));
+ );
+ if (isset($i['maj'])) {
+ $trads['version_maj'] = denormaliser_version($i['maj']);
+ }
+ $texte = _T($cle_t, $trads);
if (is_string($i['done'])) {
$texte .= " <span class='$ok_texte'>$i[done]</span>";
}
- $done .= "\t<li class='$ok_texte'>$texte</li>\n";
+ // si le plugin a ete active dans le meme lot, on remplace le message 'active' par le message 'installe'
+ if ($i['todo'] == 'install' and $ok_texte == 'ok') {
+ $cle_t = 'svp:message_action_finale_' . 'on' . '_' . $ok_texte;
+ $texte_on = _T($cle_t, array(
+ 'plugin' => $i['n'],
+ 'version' => denormaliser_version($i['v']),
+ 'version_maj' => denormaliser_version($i['maj'])
+ ));
+ if (strpos($done, $texte_on) !== false) {
+ $done = str_replace($texte_on, $texte, $done);
+ $texte = "";
+ }
+ }
+ if ($texte) {
+ $done .= "\t<li class='$ok_texte'>$texte</li>\n";
+ }
}
$done .= "</ul>";
$affiche .= boite_ouvrir(_T('svp:actions_realises'), ($oks ? 'success' : 'notice')) . $done . boite_fermer();
if (count($this->end)) {
$todo = "<ul>";
foreach ($this->end as $i) {
- $todo .= "\t<li>"._T('svp:message_action_'.$i['todo'],array(
- 'plugin'=>$i['n'],
- 'version'=>denormaliser_version($i['v']),
- 'version_maj'=>denormaliser_version($i['maj'])))."</li>\n";
+ $todo .= "\t<li>" . _T('svp:message_action_' . $i['todo'], array(
+ 'plugin' => $i['n'],
+ 'version' => denormaliser_version($i['v']),
+ 'version_maj' => denormaliser_version($i['maj'])
+ )) . "</li>\n";
}
$todo .= "</ul>\n";
$titre = ($fin ? _T('svp:actions_non_traitees') : _T('svp:actions_a_faire'));
$date = date('Y-m-d H:i:s', $time);
$todo .= "<br />\n";
$todo .= "<p class='error'>" . _T('svp:erreur_actions_non_traitees', array(
- 'auteur' => sql_getfetsel('nom', 'spip_auteurs', 'id_auteur=' . sql_quote($this->lock['id_auteur'])),
- 'date' => affdate_heure($date)
- )) . "</p>\n";
- $todo .= "<a href='" . parametre_url(self(), 'nettoyer_actions', '1'). "'>" . _T('svp:nettoyer_actions') . "</a>\n";
+ 'auteur' => sql_getfetsel('nom', 'spip_auteurs', 'id_auteur=' . sql_quote($this->lock['id_auteur'])),
+ 'date' => affdate_heure($date)
+ )) . "</p>\n";
+ $todo .= "<a href='" . parametre_url(self(), 'nettoyer_actions',
+ '1') . "'>" . _T('svp:nettoyer_actions') . "</a>\n";
}
$affiche .= boite_ouvrir($titre, 'notice') . $todo . boite_fermer();
}
include_spip('inc/filtres');
$affiche = wrap($affiche, "<div class='svp_retour'>");
}
-
+
return $affiche;
}
+ /**
+ * Retourne le pourcentage de progression des actions
+ * @return int|float
+ */
+ public function progression() {
+ if (count($this->done)) {
+ return count($this->done) / (count($this->done) + count($this->end));
+ }
+ return 0;
+ }
+
/**
* Teste l'existance d'un verrou par un auteur ?
*
* Si un id_auteur est transmis, teste que c'est cet auteur
* précis qui a posé le verrou.
*
- * @see Actionneur::verouiller()
- *
+ * @see Actionneur::verrouiller()
+ *
* @param int|string $id_auteur
* Identifiant de l'auteur, ou vide
* @return bool
* true si un verrou est là, false sinon
- **/
- function est_verrouille($id_auteur = '') {
+ **/
+ public function est_verrouille($id_auteur = '') {
if ($id_auteur == '') {
return ($this->lock['id_auteur'] ? true : false);
}
+
return ($this->lock['id_auteur'] == $id_auteur);
}
* Le verrou est signé par l'id_auteur de l'auteur actuellement identifié.
*
* Le verrou sera sauvegardé en fichier avec la liste des actions
- *
+ *
* @see Actionneur::sauver_actions()
- **/
- function verrouiller() {
+ **/
+ public function verrouiller() {
$this->lock = array(
'id_auteur' => $GLOBALS['visiteur_session']['id_auteur'],
'time' => time(),
/**
* Enlève le verrou
- **/
- function deverrouiller() {
+ **/
+ public function deverrouiller() {
$this->lock = array(
'id_auteur' => 0,
'time' => '',
* les erreurs générées, et le verrouillage.
*
* Le cache peut être lu avec la méthode get_actions()
- *
+ *
* @see Actionneur::get_actions()
- **/
- function sauver_actions() {
+ **/
+ public function sauver_actions() {
$contenu = serialize(array(
'todo' => $this->end,
'done' => $this->done,
'work' => $this->work,
- 'err' => $this->err,
+ 'err' => $this->err,
'lock' => $this->lock,
));
ecrire_fichier(_DIR_TMP . 'stp_actions.txt', $contenu);
*
* Restaure les informations contenues dans le fichier de cache
* et écrites avec la méthode sauver_actions().
- *
+ *
* @see Actionneur::sauver_actions()
- **/
- function get_actions() {
+ **/
+ public function get_actions() {
lire_fichier(_DIR_TMP . 'stp_actions.txt', $contenu);
$infos = unserialize($contenu);
- $this->end = $infos['todo'];
+ $this->end = $infos['todo'];
$this->work = $infos['work'];
$this->done = $infos['done'];
- $this->err = $infos['err'];
+ $this->err = $infos['err'];
$this->lock = $infos['lock'];
}
* Nettoyage des actions et verrou
*
* Remet tout à zéro pour pouvoir repartir d'un bon pied.
- **/
- function nettoyer_actions() {
+ **/
+ public function nettoyer_actions() {
$this->todo = array();
$this->done = array();
$this->work = array();
- $this->err = array();
+ $this->err = array();
$this->deverrouiller();
$this->sauver_actions();
}
* @return bool|array
* False si aucune action à faire,
* sinon tableau de description courte du paquet + index 'todo' indiquant l'action
- **/
- function one_action() {
+ **/
+ public function one_action() {
// s'il reste des actions, on en prend une, et on la fait
// de meme si une action est en cours mais pas terminee (timeout)
// on tente de la refaire...
- if (count($this->end) OR $this->work) {
+ if (count($this->end) or $this->work) {
// on verrouille avec l'auteur en cours pour
// que seul lui puisse effectuer des actions a ce moment la
if (!$this->est_verrouille()) {
$this->deverrouiller();
$this->sauver_actions();
}
+
return $action;
} else {
// on ne devrait normalement plus tomber sur un cas de verrouillage ici
$this->sauver_actions();
}
}
+
return false;
}
* Place dans la clé 'done' de description courte du paquet
* le résultat de l'action (un booléen indiquant si elle s'est bien
* déroulée).
- **/
- function do_action() {
+ **/
+ public function do_action() {
if ($do = $this->work) {
$todo = 'do_' . $do['todo'];
lire_metas(); // avoir les metas a jour
* @return bool
* false si erreur, true sinon.
*/
- function do_geton($info) {
+ public function do_geton($info) {
if (!$this->tester_repertoire_plugins_auto()) {
return false;
}
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($info['i']));
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
if ($dirs = $this->get_paquet_id($i)) {
$this->activer_plugin_dossier($dirs['dossier'], $i);
+
return true;
}
-
- $this->log("GetOn : Erreur de chargement du paquet " .$info['n']);
+
+ $this->log("GetOn : Erreur de chargement du paquet " . $info['n']);
+
return false;
}
* @return bool
* false si erreur, true sinon.
*/
- function do_on($info) {
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($info['i']));
+ public function do_on($info) {
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
// à télécharger ?
- if ($i['id_zone'] > 0) {
+ if (isset($i['id_zone']) and $i['id_zone'] > 0) {
return $this->do_geton($info);
}
-
+
// a activer uniquement
// il faudra prendre en compte les autres _DIR_xx
- if (in_array($i['constante'], array('_DIR_PLUGINS','_DIR_PLUGINS_SUPPL'))) {
+ if (in_array($i['constante'], array('_DIR_PLUGINS', '_DIR_PLUGINS_SUPPL'))) {
$dossier = rtrim($i['src_archive'], '/');
$this->activer_plugin_dossier($dossier, $i, $i['constante']);
+
return true;
}
-
+
return false;
}
* false si erreur,
* description courte du nouveau plugin sinon.
*/
- function do_up($info) {
+ public function do_up($info) {
// ecriture du nouveau
// suppression de l'ancien (si dans auto, et pas au meme endroit)
// OU suppression des anciens fichiers
// $i est le paquet a mettre à jour (donc present)
// $maj est le paquet a telecharger qui est a jour (donc distant)
-
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($info['i']));
+
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
// on cherche la mise a jour...
// c'est a dire le paquet source que l'on met a jour.
if ($maj = sql_fetsel('pa.*',
array('spip_paquets AS pa', 'spip_plugins AS pl'),
array(
- 'pl.prefixe='.sql_quote($info['p']),
- 'pa.version='.sql_quote($info['maj']),
- 'pa.id_plugin = pl.id_plugin',
- 'pa.id_depot>'.sql_quote(0)),
- '', 'pa.etatnum DESC', '0,1')) {
+ 'pl.prefixe=' . sql_quote($info['p']),
+ 'pa.version=' . sql_quote($info['maj']),
+ 'pa.id_plugin = pl.id_plugin',
+ 'pa.id_depot>' . sql_quote(0)
+ ),
+ '', 'pa.etatnum DESC', '0,1')
+ ) {
+
+ // si dans auto, on autorise à mettre à jour depuis auto pour les VCS
+ $dir_actuel_dans_auto = '';
+ if (substr($i['src_archive'], 0, 5) == 'auto/') {
+ $dir_actuel_dans_auto = substr($i['src_archive'], 5);
+ }
- if ($dirs = $this->get_paquet_id($maj)) {
+ if ($dirs = $this->get_paquet_id($maj, $dir_actuel_dans_auto)) {
// Si le plugin a jour n'est pas dans le meme dossier que l'ancien...
// il faut :
// - activer le plugin sur son nouvel emplacement (uniquement si l'ancien est actif)...
// alors que le nouveau est auto/X/Y ...
// il faut prendre en compte ce cas particulier et ne pas ecraser auto/X !
if (substr($i['src_archive'], 0, 5) == 'auto/' and (false === strpos($dirs['dossier'], $i['src_archive']))) {
- if (supprimer_repertoire( constant($i['constante']) . $i['src_archive']) ) {
+ if (supprimer_repertoire(constant($i['constante']) . $i['src_archive'])) {
sql_delete('spip_paquets', 'id_paquet=' . sql_quote($info['i']));
}
}
}
$this->ajouter_plugin_interessants_meta($dirs['dossier']);
+
return $dirs;
}
}
+
return false;
}
* @return bool
* false si erreur, true sinon
*/
- function do_upon($info) {
- $i = sql_fetsel('*', 'spip_paquets', 'id_paquet='.sql_quote($info['i']));
+ public function do_upon($info) {
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
if ($dirs = $this->do_up($info)) {
$this->activer_plugin_dossier($dirs['dossier'], $i, $i['constante']);
+
return true;
}
+
return false;
}
* @return bool
* false si erreur, true sinon
*/
- function do_off($info) {
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($info['i']));
+ public function do_off($info) {
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
// il faudra prendre en compte les autres _DIR_xx
- if (in_array($i['constante'], array('_DIR_PLUGINS','_DIR_PLUGINS_SUPPL'))) {
+ if (in_array($i['constante'], array('_DIR_PLUGINS', '_DIR_PLUGINS_SUPPL'))) {
include_spip('inc/plugin');
$dossier = rtrim($i['src_archive'], '/');
- ecrire_plugin_actifs(array(rtrim($dossier,'/')), false, 'enleve');
- sql_updateq('spip_paquets', array('actif'=>'non', 'installe'=>'non'), 'id_paquet='.sql_quote($info['i']));
+ ecrire_plugin_actifs(array(rtrim($dossier, '/')), false, 'enleve');
+ sql_updateq('spip_paquets', array('actif' => 'non', 'installe' => 'non'), 'id_paquet=' . sql_quote($info['i']));
$this->actualiser_plugin_interessants();
// ce retour est un rien faux...
// il faudrait que la fonction ecrire_plugin_actifs()
// retourne au moins d'eventuels message d'erreur !
return true;
}
+
return false;
}
* @return bool
* false si erreur, true sinon
*/
- function do_stop($info) {
- $i = sql_fetsel('*','spip_paquets','id_paquet=' . sql_quote($info['i']));
+ public function do_stop($info) {
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
// il faudra prendre en compte les autres _DIR_xx
- if (in_array($i['constante'], array('_DIR_PLUGINS','_DIR_PLUGINS_SUPPL'))) {
+ if (in_array($i['constante'], array('_DIR_PLUGINS', '_DIR_PLUGINS_SUPPL'))) {
include_spip('inc/plugin');
- $dossier = rtrim($i['src_archive'],'/');
+ $dossier = rtrim($i['src_archive'], '/');
$installer_plugins = charger_fonction('installer', 'plugins');
// retourne :
// - false : pas de procedure d'install/desinstalle
// - true : operation deja faite
// - tableau : operation faite ce tour ci.
- $infos = $installer_plugins($dossier, 'uninstall');
- if (is_bool($infos) OR !$infos['install_test'][0]) {
+ $infos = $installer_plugins($dossier, 'uninstall', $i['constante']);
+ if (is_bool($infos) or !$infos['install_test'][0]) {
include_spip('inc/plugin');
ecrire_plugin_actifs(array($dossier), false, 'enleve');
- sql_updateq('spip_paquets', array('actif'=>'non', 'installe'=>'non'), 'id_paquet='.sql_quote($info['i']));
+ sql_updateq('spip_paquets', array('actif' => 'non', 'installe' => 'non'), 'id_paquet=' . sql_quote($info['i']));
+
return true;
} else {
// echec
}
}
$this->actualiser_plugin_interessants();
+
return false;
}
* @return bool
* false si erreur, true sinon
*/
- function do_kill($info) {
+ public function do_kill($info) {
// on reverifie que c'est bien un plugin auto !
// il faudrait aussi faire tres attention sur un site mutualise
// cette option est encore plus delicate que les autres...
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($info['i']));
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
+
+ if (in_array($i['constante'], array('_DIR_PLUGINS', '_DIR_PLUGINS_SUPPL'))
+ and substr($i['src_archive'], 0, 5) == 'auto/'
+ ) {
- if (in_array($i['constante'], array('_DIR_PLUGINS','_DIR_PLUGINS_SUPPL'))
- and substr($i['src_archive'], 0, 5) == 'auto/') {
-
$dir = constant($i['constante']) . $i['src_archive'];
if (supprimer_repertoire($dir)) {
$id_plugin = sql_getfetsel('id_plugin', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
}
array_pop($chemins);
}
+
return true;
}
}
* @return bool
* false si erreur, true sinon
*/
- function do_getlib($info) {
+ public function do_getlib($info) {
if (!defined('_DIR_LIB') or !_DIR_LIB) {
$this->err(_T('svp:erreur_dir_dib_indefini'));
$this->log("/!\ Pas de _DIR_LIB defini !");
+
return false;
}
if (!is_writable(_DIR_LIB)) {
- $this->err(_T('svp:erreur_dir_dib_ecriture', array('dir' => _DIR_LIB )));
+ $this->err(_T('svp:erreur_dir_dib_ecriture', array('dir' => _DIR_LIB)));
$this->log("/!\ Ne peut pas écrire dans _DIR_LIB !");
+
return false;
}
- if(!autoriser('plugins_ajouter')){
+ if (!autoriser('plugins_ajouter')) {
$this->err(_T('svp:erreur_auth_plugins_ajouter_lib'));
$this->log("/!\ Pas autorisé à ajouter des libs !");
+
return false;
}
- $this->log("Recuperer la librairie : " . $info['n'] );
+ $this->log("Recuperer la librairie : " . $info['n']);
// on recupere la mise a jour...
include_spip('action/teleporter');
if ($ok === true) {
return true;
}
-
+
$this->err($ok);
$this->log("Téléporteur en erreur : " . $ok);
+
return false;
}
* @return bool
* false si erreur, true sinon
*/
- function do_get($info) {
+ public function do_get($info) {
if (!$this->tester_repertoire_plugins_auto()) {
return false;
}
$i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($info['i']));
-
+
if ($dirs = $this->get_paquet_id($info['i'])) {
$this->ajouter_plugin_interessants_meta($dirs['dossier']);
+
return true;
}
* @return bool
* false si erreur, true sinon
*/
- function do_install($info) {
+ public function do_install($info) {
return $this->installer_plugin($info);
}
/**
- * Activer un plugin
+ * Activer un plugin
*
* @param string $dossier
* Chemin du répertoire du plugin
* @param string $constante
* Constante indiquant le chemin de base du plugin (_DIR_PLUGINS, _DIR_PLUGINS_SUPPL, _DIR_PLUGINS_DIST)
* @return void
- **/
- function activer_plugin_dossier($dossier, $i, $constante='_DIR_PLUGINS') {
+ **/
+ public function activer_plugin_dossier($dossier, $i, $constante = '_DIR_PLUGINS') {
include_spip('inc/plugin');
$this->log("Demande d'activation de : " . $dossier);
-
+
//il faut absolument que tous les fichiers de cache
// soient inclus avant modification, sinon un appel ulterieur risquerait
// de charger des fichiers deja charges par un autre !
// C'est surtout le ficher de fonction le probleme (options et pipelines
// sont normalement deja charges).
- if (@is_readable(_CACHE_PLUGINS_OPT)) {include_once(_CACHE_PLUGINS_OPT);}
- if (@is_readable(_CACHE_PLUGINS_FCT)) {include_once(_CACHE_PLUGINS_FCT);}
- if (@is_readable(_CACHE_PIPELINES)) {include_once(_CACHE_PIPELINES);}
+ if (@is_readable(_CACHE_PLUGINS_OPT)) {
+ include_once(_CACHE_PLUGINS_OPT);
+ }
+ if (@is_readable(_CACHE_PLUGINS_FCT)) {
+ include_once(_CACHE_PLUGINS_FCT);
+ }
+ if (@is_readable(_CACHE_PIPELINES)) {
+ include_once(_CACHE_PIPELINES);
+ }
include_spip('inc/plugin');
ecrire_plugin_actifs(array($dossier), false, 'ajoute');
$installe = $i['version_base'] ? 'oui' : 'non';
if ($installe == 'oui') {
- if(!$i['constante'])
+ if (!$i['constante']) {
$i['constante'] = '_DIR_PLUGINS';
+ }
// installer le plugin au prochain tour
$new_action = array_merge($this->work, array(
- 'todo'=>'install',
- 'dossier'=>rtrim($dossier,'/'),
- 'constante'=>$i['constante'],
- 'v'=>$i['version'], // pas forcement la meme version qu'avant lors d'une mise a jour.
+ 'todo' => 'install',
+ 'dossier' => rtrim($dossier, '/'),
+ 'constante' => $i['constante'],
+ 'v' => $i['version'], // pas forcement la meme version qu'avant lors d'une mise a jour.
));
array_unshift($this->end, $new_action);
$this->log("Demande d'installation de $dossier");
* Décrémente chaque score de plugin présent dans la méta
* 'plugins_interessants' et signifiant que ces plugins
* ont été utilisés récemment.
- *
+ *
* Les plugins atteignant un score de zéro sont évacués ce la liste.
*/
- function actualiser_plugin_interessants() {
+ public function actualiser_plugin_interessants() {
// Chaque fois que l'on valide des plugins,
// on memorise la liste de ces plugins comme etant "interessants",
// avec un score initial, qui sera decremente a chaque tour :
if (!is_array($plugins_interessants)) {
$plugins_interessants = array();
}
-
+
$dossiers = array();
$dossiers_old = array();
- foreach($plugins_interessants as $p => $score) {
+ foreach ($plugins_interessants as $p => $score) {
if (--$score > 0) {
$plugins_interessants[$p] = $score;
- $dossiers[$p.'/'] = true;
+ $dossiers[$p . '/'] = true;
} else {
unset($plugins_interessants[$p]);
- $dossiers_old[$p.'/'] = true;
+ $dossiers_old[$p . '/'] = true;
}
}
// enlever les anciens
if ($dossiers_old) {
// ATTENTION, il faudra prendre en compte les _DIR_xx
- sql_updateq('spip_paquets', array('recent'=>0), sql_in('src_archive', array_keys($dossiers_old)));
+ sql_updateq('spip_paquets', array('recent' => 0), sql_in('src_archive', array_keys($dossiers_old)));
}
- $plugs = sql_allfetsel('src_archive','spip_paquets', 'actif='.sql_quote('oui'));
+ $plugs = sql_allfetsel('src_archive', 'spip_paquets', 'actif=' . sql_quote('oui'));
$plugs = array_map('array_shift', $plugs);
foreach ($plugs as $dossier) {
$dossiers[$dossier] = true;
- $plugins_interessants[ rtrim($dossier, '/') ] = 30; // score initial
+ $plugins_interessants[rtrim($dossier, '/')] = 30; // score initial
}
- $plugs = sql_updateq('spip_paquets', array('recent'=>1), sql_in('src_archive', array_keys($dossiers)));
+ $plugs = sql_updateq('spip_paquets', array('recent' => 1), sql_in('src_archive', array_keys($dossiers)));
ecrire_meta('plugins_interessants', serialize($plugins_interessants));
}
* @param string $dir
* Chemin du répertoire du plugin
*/
- function ajouter_plugin_interessants_meta($dir) {
+ public function ajouter_plugin_interessants_meta($dir) {
$plugins_interessants = @unserialize($GLOBALS['meta']['plugins_interessants']);
if (!is_array($plugins_interessants)) {
$plugins_interessants = array();
* @return bool
* false si erreur, true sinon
*/
- function installer_plugin($info){
+ public function installer_plugin($info) {
// il faut info['dossier'] et info['constante'] pour installer
if ($plug = $info['dossier']) {
$installer_plugins = charger_fonction('installer', 'plugins');
$infos = $installer_plugins($plug, 'install', $info['constante']);
if ($infos) {
// en absence d'erreur, on met a jour la liste des plugins installes...
- if (!is_array($infos) OR $infos['install_test'][0]) {
+ if (!is_array($infos) or $infos['install_test'][0]) {
$meta_plug_installes = @unserialize($GLOBALS['meta']['plugin_installes']);
if (!$meta_plug_installes) {
- $meta_plug_installes=array();
+ $meta_plug_installes = array();
}
$meta_plug_installes[] = $plug;
- ecrire_meta('plugin_installes',serialize($meta_plug_installes),'non');
+ ecrire_meta('plugin_installes', serialize($meta_plug_installes), 'non');
}
if (!is_array($infos)) {
// l'installation avait deja ete faite un autre jour
- return true;
+ return true;
} else {
// l'installation est neuve
list($ok, $trace) = $infos['install_test'];
}
// l'installation est en erreur
$this->err(_T('svp:message_action_finale_install_fail',
- array('plugin' => $info['n'], 'version'=>denormaliser_version($info['v']))) . "<br />" . $trace);
+ array('plugin' => $info['n'], 'version' => denormaliser_version($info['v']))) . "<br />" . $trace);
}
}
}
+
return false;
}
/**
* Télécharge un paquet
- *
+ *
* Supprime les fichiers obsolètes (si présents)
*
* @param int|array $id_or_row
* Identifiant du paquet ou description ligne SQL du paquet
+ * @param string $dest_ancien
+ * Chemin vers l'ancien répertoire (pour les mises à jour par VCS)
* @return bool|array
* False si erreur.
* Tableau de 2 index sinon :
* - dir : Chemin du paquet téléchargé depuis la racine
* - dossier : Chemin du paquet téléchargé, depuis _DIR_PLUGINS
*/
- function get_paquet_id($id_or_row) {
+ public function get_paquet_id($id_or_row, $dest_ancien = "") {
// on peut passer direct le row sql...
if (!is_array($id_or_row)) {
- $i = sql_fetsel('*','spip_paquets','id_paquet='.sql_quote($id_or_row));
+ $i = sql_fetsel('*', 'spip_paquets', 'id_paquet=' . sql_quote($id_or_row));
} else {
$i = $id_or_row;
}
unset($id_or_row);
if ($i['nom_archive'] and $i['id_depot']) {
- $this->log("Recuperer l'archive : " . $i['nom_archive'] );
- if ($adresse = sql_getfetsel('url_archives', 'spip_depots', 'id_depot='.sql_quote($i['id_depot']))) {
- $zip = $adresse . '/' . $i['nom_archive'];
+ $this->log("Recuperer l'archive : " . $i['nom_archive']);
+ // on récupère les informations intéressantes du dépot :
+ // - url des archives
+ // - éventuellement : type de serveur (svn, git) et url de la racine serveur (svn://..../)
+ $adresses = sql_fetsel(array('url_archives', 'type', 'url_serveur'), 'spip_depots',
+ 'id_depot=' . sql_quote($i['id_depot']));
+ if ($adresses and $adresse = $adresses['url_archives']) {
// destination : auto/prefixe/version (sinon auto/nom_archive/version)
$prefixe = sql_getfetsel('pl.prefixe',
array('pa.id_plugin = pl.id_plugin', 'pa.id_paquet=' . sql_quote($i['id_paquet'])));
// prefixe
- $base = ($prefixe ? strtolower($prefixe) : substr($i['nom_archive'], 0, -4) ); // enlever .zip ...
+ $base = ($prefixe ? strtolower($prefixe) : substr($i['nom_archive'], 0, -4)); // enlever .zip ...
// prefixe/version
- $dest = $base . '/v' . denormaliser_version($i['version']);
-
- // si on tombe sur un auto/X ayant des fichiers (et pas uniquement des dossiers)
- // ou un dossier qui ne commence pas par 'v'
- // c'est que auto/X n'était pas chargé avec SVP
- // ce qui peut arriver lorsqu'on migre de SPIP 2.1 à 3.0
- // dans ce cas, on supprime auto X pour mettre notre nouveau paquet.
- $ecraser_base = false;
- if (is_dir(_DIR_PLUGINS_AUTO . $base)) {
- $base_files = scandir(_DIR_PLUGINS_AUTO . $base);
- if (is_array($base_files)) {
- $base_files = array_diff($base_files, array('.', '..'));
- foreach ($base_files as $f) {
- if (($f[0] != '.' and $f[0] != 'v') // commence pas par v
- OR ($f[0] != '.' and !is_dir(_DIR_PLUGINS_AUTO . $base . '/' . $f))) { // commence par v mais pas repertoire
- $ecraser_base = true;
- break;
- }
- }
- }
- }
- if ($ecraser_base) {
+ $dest_future = $base . '/v' . denormaliser_version($i['version']);
+
+ // Nettoyer les vieux formats dans auto/
+ if ($this->tester_repertoire_destination_ancien_format(_DIR_PLUGINS_AUTO . $base)) {
supprimer_repertoire(_DIR_PLUGINS_AUTO . $base);
}
+ // l'url est différente en fonction du téléporteur
+ $teleporteur = $this->choisir_teleporteur($adresses['type']);
+ if ($teleporteur == 'http') {
+ $url = $adresse . '/' . $i['nom_archive'];
+ $dest = $dest_future;
+ } else {
+ $url = $adresses['url_serveur'] . '/' . $i['src_archive'];
+ $dest = $dest_ancien ? $dest_ancien : $dest_future;
+ }
// on recupere la mise a jour...
include_spip('action/teleporter');
$teleporter_composant = charger_fonction('teleporter_composant', 'action');
- $ok = $teleporter_composant('http', $zip, _DIR_PLUGINS_AUTO . $dest);
+ $ok = $teleporter_composant($teleporteur, $url, _DIR_PLUGINS_AUTO . $dest);
if ($ok === true) {
+ // pour une mise à jour via VCS, il faut rebasculer sur le nouveau nom de repertoire
+ if ($dest != $dest_future) {
+ rename(_DIR_PLUGINS_AUTO . $dest, _DIR_PLUGINS_AUTO . $dest_future);
+ }
+
return array(
- 'dir'=> _DIR_PLUGINS_AUTO . $dest,
+ 'dir' => _DIR_PLUGINS_AUTO . $dest,
'dossier' => 'auto/' . $dest, // c'est depuis _DIR_PLUGINS ... pas bien en dur...
);
}
$this->err($ok);
$this->log("Téléporteur en erreur : " . $ok);
} else {
- $this->log("Aucune adresse pour le dépot " . $i['id_depot'] );
+ $this->log("Aucune adresse pour le dépot " . $i['id_depot']);
}
}
+
return false;
}
*
* @return bool
* True si on peut écrire dedans, false sinon
- **/
- function tester_repertoire_plugins_auto() {
+ **/
+ public function tester_repertoire_plugins_auto() {
include_spip('inc/plugin'); // pour _DIR_PLUGINS_AUTO
if (!defined('_DIR_PLUGINS_AUTO') or !_DIR_PLUGINS_AUTO) {
$this->err(_T('svp:erreur_dir_plugins_auto_indefini'));
$this->log("/!\ Pas de _DIR_PLUGINS_AUTO defini !");
+
return false;
}
if (!is_writable(_DIR_PLUGINS_AUTO)) {
- $this->err(_T('svp:erreur_dir_plugins_auto_ecriture', array('dir'=>_DIR_PLUGINS_AUTO)));
+ $this->err(_T('svp:erreur_dir_plugins_auto_ecriture', array('dir' => _DIR_PLUGINS_AUTO)));
$this->log("/!\ Ne peut pas écrire dans _DIR_PLUGINS_AUTO !");
+
return false;
}
+
return true;
}
+ /**
+ * Teste si un répertoire du plugin auto, contenant un plugin
+ * est dans un ancien format auto/prefixe/ (qui doit alors être supprimé)
+ * ou dans un format normal auto/prefixe/vx.y.z
+ *
+ * @example
+ * $this->tester_repertoire_destination_ancien_format(_DIR_PLUGINS_AUTO . $base);
+ *
+ * @param string $dir_dans_auto
+ * Chemin du répertoire à tester
+ * @return bool
+ * true si le répertoire est dans un ancien format
+ */
+ public function tester_repertoire_destination_ancien_format($dir_dans_auto) {
+ // si on tombe sur un auto/X ayant des fichiers (et pas uniquement des dossiers)
+ // ou un dossier qui ne commence pas par 'v'
+ // c'est que auto/X n'était pas chargé avec SVP
+ // ce qui peut arriver lorsqu'on migre de SPIP 2.1 à 3.0
+ // dans ce cas, on supprime auto X pour mettre notre nouveau paquet.
+ if (is_dir($dir_dans_auto)) {
+ $base_files = scandir($dir_dans_auto);
+ if (is_array($base_files)) {
+ $base_files = array_diff($base_files, array('.', '..'));
+ foreach ($base_files as $f) {
+ if (($f[0] != '.' and $f[0] != 'v') // commence pas par v
+ or ($f[0] != '.' and !is_dir($dir_dans_auto . '/' . $f))
+ ) { // commence par v mais pas repertoire
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Teste s'il est possible d'utiliser un téléporteur particulier,
+ * sinon retourne le nom du téléporteur par défaut
+ *
+ * @param string $teleporteur Téléporteur VCS à tester
+ * @param string $defaut Téléporteur par défaut
+ *
+ * @return string Nom du téléporteur à utiliser
+ **/
+ public function choisir_teleporteur($teleporteur, $defaut = 'http') {
+ // Utiliser un teleporteur vcs si possible si demandé
+ if (defined('SVP_PREFERER_TELECHARGEMENT_PAR_VCS') and SVP_PREFERER_TELECHARGEMENT_PAR_VCS) {
+ if ($teleporteur) {
+ include_spip('teleporter/' . $teleporteur);
+ $tester_teleporteur = "teleporter_{$teleporteur}_tester";
+ if (function_exists($tester_teleporteur)) {
+ if ($tester_teleporteur()) {
+ return $teleporteur;
+ }
+ }
+ }
+ }
+
+ return $defaut;
+ }
+
+
/**
* Teste si le plugin SVP (celui-ci donc) a
- * été désinstallé / désactivé dans les actions réalisées
+ * été désinstallé / désactivé dans les actions réalisées
*
* @note
* On ne peut tester sa désactivation que dans le hit où la désinstallation
* est réalisée, puisque après, s'il a été désactivé, au prochain hit
* on ne connaîtra plus ce fichier !
- *
+ *
* @return bool
* true si SVP a été désactivé, false sinon
- **/
- function tester_si_svp_desactive() {
+ **/
+ public function tester_si_svp_desactive() {
foreach ($this->done as $d) {
if ($d['p'] == 'SVP'
- AND $d['done'] == true
- AND in_array($d['todo'], array('off', 'stop'))) {
+ and $d['done'] == true
+ and in_array($d['todo'], array('off', 'stop'))
+ ) {
return true;
}
}
+
return false;
}
-
+
}
* @param string $redirect
* URL de retour
* @return void
-**/
-function svp_actionner_traiter_actions_demandees($actions, &$retour,$redirect=null) {
- $actionneur = new Actionneur();
- $actionneur->ajouter_actions($actions);
- $actionneur->verrouiller();
- $actionneur->sauver_actions();
-
- $redirect = $redirect ? $redirect : generer_url_ecrire('admin_plugin');
- $retour['redirect'] = generer_url_action('actionner', 'redirect='.urlencode($redirect));
- set_request('_todo', '');
- $retour['message_ok'] = _T("svp:action_patienter");
+ **/
+function svp_actionner_traiter_actions_demandees($actions, &$retour, $redirect = null) {
+ $actionneur = new Actionneur();
+ $actionneur->ajouter_actions($actions);
+ $actionneur->verrouiller();
+ $actionneur->sauver_actions();
+
+ $redirect = $redirect ? $redirect : generer_url_ecrire('admin_plugin');
+ $retour['redirect'] = generer_url_action('actionner', 'redirect=' . urlencode($redirect));
+ set_request('_todo', '');
+ $retour['message_ok'] = _T("svp:action_patienter");
}
-?>