[SPIP] ~v3.2.3-->v3.2.4
[lhc/web/www.git] / www / ecrire / inc / plugin.php
index d88d346..417cb9f 100644 (file)
@@ -3,7 +3,7 @@
 /***************************************************************************\
  *  SPIP, Systeme de publication pour l'internet                           *
  *                                                                         *
- *  Copyright (c) 2001-2017                                                *
+ *  Copyright (c) 2001-2019                                                *
  *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
  *                                                                         *
  *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
@@ -269,6 +269,7 @@ function liste_plugin_valides($liste_plug, $force = false) {
                )
        );
 
+       $invalides = array();
        foreach ($liste_ext as $plug) {
                if (isset($infos['_DIR_PLUGINS_DIST'][$plug])) {
                        plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS_DIST');
@@ -276,7 +277,10 @@ function liste_plugin_valides($liste_plug, $force = false) {
        }
        foreach ($liste_plug as $plug) {
                if (isset($infos['_DIR_PLUGINS'][$plug])) {
-                       plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS');
+                       $r = plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS');
+                       if (is_array($r)) {
+                               $invalides = array_merge($invalides, $r);
+                       }
                }
        }
 
@@ -284,14 +288,20 @@ function liste_plugin_valides($liste_plug, $force = false) {
                $infos['_DIR_PLUGINS_SUPPL'] = $get_infos($liste_plug, false, _DIR_PLUGINS_SUPPL);
                foreach ($liste_plug as $plug) {
                        if (isset($infos['_DIR_PLUGINS_SUPPL'][$plug])) {
-                               plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS_SUPPL');
+                               $r = plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS_SUPPL');
+                               if (is_array($r)) {
+                                       $invalides = array_merge($invalides, $r);
+                               }
                        }
                }
        }
 
        plugin_fixer_procure($liste_non_classee, $infos);
 
-       return array($infos, $liste_non_classee);
+       // les plugins qui sont dans $liste_non_classee ne sont pas invalides (on a trouve un autre version valide)
+       $invalides = array_diff_key($invalides, $liste_non_classee);
+
+       return array($infos, $liste_non_classee, $invalides);
 }
 
 /**
@@ -306,27 +316,34 @@ function liste_plugin_valides($liste_plug, $force = false) {
  * @param string $plug
  * @param array $infos
  * @param string $dir_type
+ * @return string|array
+ *   string prefixe dans $liste si on a accepte le plugin
+ *   array description short si on ne le retient pas (pour memorisation dans une table des erreurs)
  */
 function plugin_valide_resume(&$liste, $plug, $infos, $dir_type) {
        $i = $infos[$dir_type][$plug];
+       $p = strtoupper($i['prefix']);
+       $short_desc = array(
+               'nom' => $i['nom'],
+               'etat' => $i['etat'],
+               'version' => $i['version'],
+               'dir' => $plug,
+               'dir_type' => $dir_type
+       );
        if (isset($i['erreur']) and $i['erreur']) {
-               return;
+               $short_desc['erreur'] = $i['erreur'];
+               return array($p=>$short_desc);
        }
        if (!plugin_version_compatible($i['compatibilite'], $GLOBALS['spip_version_branche'], 'spip')) {
-               return;
+               return array($p=>$short_desc);
        }
-       $p = strtoupper($i['prefix']);
        if (!isset($liste[$p])
                or spip_version_compare($i['version'], $liste[$p]['version'], '>')
        ) {
-               $liste[$p] = array(
-                       'nom' => $i['nom'],
-                       'etat' => $i['etat'],
-                       'version' => $i['version'],
-                       'dir' => $plug,
-                       'dir_type' => $dir_type
-               );
+               $liste[$p] = $short_desc;
        }
+       // ok le plugin etait deja dans la liste ou on a choisi une version plus recente
+       return $p;
 }
 
 /**
@@ -534,7 +551,13 @@ function plugins_erreurs($liste_non_classee, $liste, $infos, $msg = array()) {
 
                $plug = constant($dir_type) . $plug;
                if (!isset($msg[$p])) {
-                       if (!$msg[$p] = plugin_necessite($k['necessite'], $liste, 'necessite')) {
+                       if (isset($resume['erreur']) and $resume['erreur']) {
+                               $msg[$p] = array($resume['erreur']);
+                       }
+                       elseif (!plugin_version_compatible($k['compatibilite'], $GLOBALS['spip_version_branche'], 'spip')) {
+                               $msg[$p] = array(plugin_message_incompatibilite($k['compatibilite'], $GLOBALS['spip_version_branche'], 'SPIP', 'necessite'));
+                       }
+                       elseif (!$msg[$p] = plugin_necessite($k['necessite'], $liste, 'necessite')) {
                                $msg[$p] = plugin_necessite($k['utilise'], $liste, 'utilise');
                        }
                } else {
@@ -663,7 +686,9 @@ function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
        // prendre en compte les erreurs de dépendances à PHP
        // ou à une extension PHP avec des messages d'erreurs dédiés.
        $type = 'plugin';
-       if ($nom === 'PHP') {
+       if ($nom === 'SPIP') {
+               $type = 'spip';
+       } elseif ($nom === 'PHP') {
                $type = 'php';
        } elseif (strncmp($nom, 'PHP:', 4) === 0) {
                $type = 'extension_php';
@@ -807,11 +832,11 @@ function ecrire_plugin_actifs($plugin, $pipe_recherche = false, $operation = 'ra
        // pour ne pas rater l'ajout ou la suppression d'un fichier fonctions/options/administrations
        // pourra etre evite quand on ne supportera plus les plugin.xml
        // en deplacant la detection de ces fichiers dans la compilation ci dessous
-       list($infos, $liste) = liste_plugin_valides($plugin, true);
+       list($infos, $liste, $invalides) = liste_plugin_valides($plugin, true);
        // trouver l'ordre d'activation
        list($plugin_valides, $ordre, $reste) = plugin_trier($infos, $liste);
-       if ($reste) {
-               plugins_erreurs($reste, $liste, $infos);
+       if ($invalides or $reste) {
+               plugins_erreurs(array_merge($invalides, $reste), $liste, $infos);
        }
 
        // Ignorer les plugins necessitant une lib absente
@@ -863,9 +888,6 @@ function ecrire_plugin_actifs($plugin, $pipe_recherche = false, $operation = 'ra
        // generer le fichier _CACHE_PIPELINE
        pipeline_precompile($prepend_code);
 
-       // attendre eventuellement l'invalidation du cache opcode
-       spip_attend_invalidation_opcode_cache();
-
        if (spip_connect()) {
                // lancer et initialiser les nouveaux crons !
                include_spip('inc/genie');
@@ -1319,6 +1341,11 @@ function plugin_est_installe($plug_path) {
  * @uses plugins_installer_dist()
  **/
 function plugin_installes_meta() {
+       if (isset($GLOBALS['fichier_php_compile_recent'])) {
+               // attendre eventuellement l'invalidation du cache opcode
+               spip_attend_invalidation_opcode_cache($GLOBALS['fichier_php_compile_recent']);
+       }
+
        $installer_plugins = charger_fonction('installer', 'plugins');
        $meta_plug_installes = array();
        foreach (unserialize($GLOBALS['meta']['plugin']) as $prefix => $resume) {
@@ -1358,6 +1385,29 @@ function plugin_installes_meta() {
  *     Commentaire : code écrit en tout début de fichier, après la balise PHP ouvrante
 **/
 function ecrire_fichier_php($nom, $contenu, $comment = '') {
-       ecrire_fichier($nom,
-               '<' . '?php' . "\n" . $comment . "\nif (defined('_ECRIRE_INC_VERSION')) {\n" . $contenu . "}\n?" . '>');
+       if (!isset($GLOBALS['fichier_php_compile_recent'])) {
+               $GLOBALS['fichier_php_compile_recent'] = 0;
+       }
+
+       $contenu = '<' . '?php' . "\n" . $comment . "\nif (defined('_ECRIRE_INC_VERSION')) {\n" . $contenu . "}\n?" . '>';
+       // si un fichier existe deja on verifie que son contenu change avant de l'ecraser
+       // si pas de modif on ne touche pas au fichier initial
+       if (file_exists($nom)) {
+               if (substr($nom, -4) == '.php') {
+                       $fichier_tmp = substr($nom, 0, -4) . '.tmp.php';
+               }
+               else {
+                       $fichier_tmp = $nom . '.tmp';
+               }
+               file_put_contents($fichier_tmp, $contenu);
+               if(md5_file($nom) == md5_file($fichier_tmp)) {
+                       $GLOBALS['fichier_php_compile_recent'] = max($GLOBALS['fichier_php_compile_recent'], filemtime($nom));
+                       @unlink($fichier_tmp);
+                       return;
+               }
+               @unlink($fichier_tmp);
+       }
+       ecrire_fichier($nom, $contenu);
+       $GLOBALS['fichier_php_compile_recent'] = max($GLOBALS['fichier_php_compile_recent'], filemtime($nom));
+       spip_clear_opcode_cache(realpath($nom));
 }