Carnet Wiki

Gestion des dossiers /plugins (ou utiliser _DIR_PLUGINS_SUPPL)

Dans le cas d’une mutualisation pour différents domaines, la bidouille suivante permet de disposer à la fois d’un répertoire de plugin “centralisé” (comme c’est le cas général dans la mutualisation) mais également d’un répertoire /plugins pour certaines des instance de mutualisation (i.e. les sites mutualisés pour lesquels on estime pouvoir faire confiance au webmestre...).

Installation

Testé pour le plugin Mutualisation installé pour avoir des sites avec domaines différents avec la configuration suivante:

  • le SPIP “maître” est installé dans /var/www/toto
  • dossier /mutualisation à la racine du SPIP “maître” /var/www/toto/mutualisation
  • les sites mutualisés ont chacun leur nom de domaine et un vhost apache qui pointe sur /var/www/toto
  • chaque site correspond à un sous-dossier de /sites portant le nom de domaine du site: /var/www/toto/sites/mon-site.tld [1]
  • un dossier /plugins (= “central” pour la suite) également à la racine de ce SPIP: celui-ci est utilisé par tous les sites mutualisés (i.e. les plugins dedans sont visibles dans tous les sites) /var/www/toto/plugins
  • la config du apache et des vhost authorise le suivi des liens symboliques (Options FollowSymLinks)

Mise à jour par SVN

« Dans mes mutualisations, j’ai un dossier /plugins/auto dans lequel je mets mes plugins additionels, que je mets à jour par svn.

/plugins/auto se trouve au même niveau que /plungins-dist

Pour chaque site mutualisé, j’active les plugins (qui se trouvent dans le dossier /plugins/auto commun) dont j’ai besoin.

Je ne créé pas de dossier plugins/auto dans chaque dossier de site.

Et donc, je ne mets à jour chaque plugin présent dans /plugins/auto qu’une seule fois par svn, et la mise à jour se fait pour tous les sites mutualisés.

En SPIP 2.0.*: il faut ajouter le plugin Multiplug

Ce plugin (disponible uniquement via SVN: http://zone.spip.org/trac/spip-zone...), permet de déclarer dans le fichier mes_options.php du SPIP central un ensemble de sites autorisés à utiliser leur propre dossier /plugins en plus du dossier /plugins “central” du SPIP central.

La syntaxe est la suivante:

// les sites autorisés à avoir un dossier /plugins supplémentaire (nom du dossier du site)
   $GLOBALS['multiplug_autorise'] = array(
        'mon-site1.tld',
        'ze-site2.tld'
   );

En SPIP 2.1: utilisation de la constante _DIR_PLUGINS_SUPPL

A partir de cette version, chaque SPIP peut déclarer un ensemble de dossiers supplémentaires dans lesquels peuvent êtres placés des plugins.

Pour cela il faut définir _DIR_PLUGINS_SUPPL dans le mes_options.php du site: par exemple pour utiliser le dossier /plugins dans le site mon-site.tld cela donnerait:
(dans les 2 exemples suivants on suppose le site mutualisé installé dans le sous-dossier /sites du SPIP “central”)

define('_DIR_PLUGINS_SUPPL','sites/mon-site.tld/plugins/');

Il est possible d’utiliser plusieurs dossiers avec “:” comme séparateur: Par exemple si on veut utiliser le dossier /plugins du site mon-site.tld et le dossier /le_depot situé à la racine de la mutu cela donnerait:

define('_DIR_PLUGINS_SUPPL','sites/mon-site.tld/plugins/:le_depot/');

Important!: les chemins utilisés dans _DIR_PLUGINS_SUPPL:

  • sont définis relativement à partir de la racine du SPIP
  • doivent se terminer par un / (ainsi que tous les chemins définis dans des constantes SPIP)

A partir de SPIP 3.0.6

Se référer à la documentation : http://www.spip.net/fr_article5296.html

NOTE : pour utiliser un squelette empaqueté en plugin, les deux constantes semblent nécessaires dans le mes_options.php de chaque site mutualisé :

        define('_ROOT_PLUGINS_SUPPL',_DIR_RACINE.'site/'.$site.'/plugins/');
        define('_DIR_PLUGINS_SUPPL',_DIR_RACINE.'site/'.$site.'/plugins/');
        

NB: la suite est obsolète mais conservée à titre d’historique

Pour chaque instance de site mutualisé pour laquelle on veut laisser au webmestre la possibilité d’installer des plugins supplémentaires, on crée un sous-dossier /plugins (= “spécifique” pour la suite) dans le sous-dossier de site correspondant: /var/www/toto/sites/mon-site.tld/plugins. On va alors créer un lien symbolique dans le dossier plugins central qui pointe vers ce sous-dossier, ce lien sera nommé avec le nom de domaine du site:
/var/www/toto/plugins/mon-site.tld(=symlink)—>/var/www/toto/sites/mon-site.tld/plugins
Tel quel on se retrouve donc avec tous les plugins de tous les répertoire “spécifiques” mélangés avec ceux du répertoire “central” donc visibles et disponibles pour tous les sites mutualisés, ce qui n’est pas exactement le but recherché...

Il reste donc à “filtrer” les liens symboliques qui seront suivis en fonction du site: le lien portant le nom de domaine du site, on à donc un moyen simple de “faire le tri”. Ce tri sera fait au niveau de la fonction de SPIP qui scanne le répertoire des plugins: liste_plugin_files() dans le fichier /inc/plugin.php

La seule difficulté pour réaliser cette opération est que cette fonction du core n’est pas surchargeable puisqu’elle n’est pas de la forme nom_de_la_fonction_dist()... Du coup on doit procéder via la surcharge de l’ensemble du fichier /inc/plugin.php ce qui revient à “forker” celui-ci (c’est très mal!).

Pour minimiser la chose et essayer de gérer au mieux les éventuels changements du fichier lors des prochaines versions de SPIP, on peut procéder en faisant une bidouille à base de copie “à la volée” du fichier /inc/plugin.php de la dist et ne modifiant que le strict nécéssaire dans la fonction liste_plugin_files(). Ce qui peut être obtenu de la façon suivante:

  • déclarer /mutualisation dans les répertoires scannés par find_in_path() en l’ajoutant dans les dossiers de squelettes du fichier mes_options.php (après demarrer_site()):
    $GLOBALS['dossier_squelettes'] .= ':mutualisation';
  • créer un sous-dossier /inc dans /mutualisation
  • créer un fichier plugin.php dans ce dossier et mettre dedans le code suivant:
    <?php
    // mutualisation: pour pouvoir utiliser à la fois le rep /plugins central
    // et le rep /plugins du site via un lien symbolique dans /plugins central, 
    // on filtre la liste des ss-reps de plugins retournée par liste_plugin_files() de /inc/plugin.php
    // ce qui nécessite une mauvaise bidouille pour hacker la fonction  
    // et pour ne pas trop galérer avec les mises à jour du core de SPIP 
    // on recrée le fichier à partir de celui de la dist en ne modifiant que le strict minimum
        $inc_plugin_mutu = _DIR_TMP.'inc_plugin_mutu_'.$GLOBALS['spip_version_code'].'.php';
        if (is_file($inc_plugin_mutu)) include($inc_plugin_mutu);
        else {
          // faire le remplacement dans le code de la fonction pour avoir le filtrage
            $a_remplacer = '$plugin_files[]=substr(dirname($plugin), strlen(_DIR_PLUGINS));';
            $code_sup_mutu = '// filtrage des liens symboliques vers les autres sites de mutu'."\r\n";
            $code_sup_mutu .= '$rep_plugin = explode("/",substr(dirname($plugin), strlen(_DIR_PLUGINS)));'."\r\n";
            $code_sup_mutu .= '$rep_plugin = $rep_plugin[0];'."\r\n";
            $code_sup_mutu .= '$site = str_replace("www.", "", $_SERVER["HTTP_HOST"]);'."\r\n";
            $code_sup_mutu .= 'if (is_link(_DIR_PLUGINS.$rep_plugin) AND $rep_plugin != $site) continue;'."\r\n";
            $code_sup_mutu .= $a_remplacer."\r\n";
            $contenu = file_get_contents(_DIR_RESTREINT.'inc/plugin.php');
            $contenu = str_replace($a_remplacer, $code_sup_mutu, $contenu);
     
          // finalement enregistrer le contenu dans /tmp/inc_plugin_mutu_XXX.php puis l'inclure
            if (function_exists('file_put_contents')) {
                if (!file_put_contents($inc_plugin_mutu, $contenu)) include _DIR_RESTREINT.'inc/plugin.php';
                else include $inc_plugin_mutu;
            }
            else {  // php4
                $fic = fopen($inc_plugin_mutu, 'wb');
                if (!fwrite($fic, $contenu)) include _DIR_RESTREINT.'inc/plugin.php';
                else { 
                    fclose($fic);
                    include $inc_plugin_mutu;
                }
            }
        }
    ?>

    Comme on peut le voir en lisant le code, le principe est de créer un fichier inc_plugin_mutu_XXX.php dans le répertoire /tmp du site mutualisé dans lequel on recopie le fichier /inc/plugin.php de la dist en ajoutant le système de filtrage par remplacement d’une ligne de la fonction liste_plugin_files(). Ce fichier est intégré par un include() dans le fichier en cours (i.e. le fichier qui forke l’original). Une fois ce fichier créé il sera réutilisé tel quel les fois suivantes: chaque site mutualisé dispose donc de son fichier “personnalisé” mis en “cache”.

Le XXX correspond à la version du code de SPIP de façon à ce qu’à chaque modification de la version de SPIP le fichier soit régénéré pour être à jour d’une éventuelle modification du fichier original.

[1en vérité c’est un peu plus complexe puisque ces sous-répertoires ne contiennent que des liens symboliques pour IMG,local, tmp et config) qui pointent vers les sous-dossiers correspondants du répertoire spécifique du domaine: l’utilisateur qui gère le site possède donc un accès FTP dans ce répertoire et peut le gérer comme un spip “normal”

cy_altern - Mise à jour :23 June 2018 at 17:56