Compartir el nucli SPIP

Procés per compartir el nucli d’SPIP entre diversos llocs.

Compartir el nucli d’SPIP és possible a partir d’SPIP 1.9. Es tracta de poder gestionar diversos llocs SPIP en un sol servidor o allotjament utilitzant només un sol cop els fitxers del nucli d’SPIP.

Això permet un guany d’espai de disc important, així com la possibilitat d’actualitzar SPIP de forma simple en el conjunt de llocs posant al dia només el nucli.

Les evolucions d’SPIP 1.9 simplificaven una mica el procés, però és amb SPIP 1.9.2 i les seves millores [1] que la mutualitzacó esdevé més forta permetent que el nucli d’SPIP es pugui compartir.

Aquest article explica el procés per SPIP 1.9.2, en servidors Apache [2] autoritzant la reescriptura d’url (url_rewriting).

Hi ha diversos mètodes per arribar als mateixos resultats, segons si es desitja configurar directament la mutualització des d’un allotjament o des d’un servidor.

El concepte...

A partir d’SPIP 1.9.2 les carpetes necessàries pel funcionament del nucli SPIP (ecrire, squelettes-dist, oo), i aquelles que marquen l’activitat d’un lloc (config, IMG, tmp, local) són clarament diferents i identificables. És aquesta separació la que permet tenir diversos llocs SPIP autònoms amb un mateix nucli d’SPIP.

Aquesta autonomia es recolza en l’existència d’un grup de quatre carpetes per cada lloc, a dins de les que Spip escriurà les dades que resultin de l’activitat del lloc. Aquests directoris són quatre perquè es distingeixen les dades temporals i permanents per una banda, i les dades accessibles per http i aquelles que no ho són per l’altra. Els dos directoris inaccessibles per http estaran protegits per un .htaccess instal·lat automàticament per SPIP (els administradors del servidor podran també posar aquests directoris a fora de l’arborescència servida per http).

Abans d’SPIP 1.9.2, aquests quatre tipus de dades no es distingien amb claredat, i es trobaven en els directoris IMG, CACHE, ecrire i ecrire/data. Amb SPIP 1.9.2, aquests quatre directoris són diferents i anomenats per les següents constants PHP:

define('_NOM_TEMPORAIRES_INACCESSIBLES', "tmp/");
define('_NOM_TEMPORAIRES_ACCESSIBLES', "local/");
define('_NOM_PERMANENTS_INACCESSIBLES', "config/");
define('_NOM_PERMANENTS_ACCESSIBLES', "IMG/");

En una instal·lació d’Spip no mutualitzada, aquests directoris es creen a l’arrel del lloc, quan s’aplica la funció spip_initialisation sobre els quatre valors indicats més amunt. Per obtenir la mutualització dels recursos d’SPIP, n’hi ha prou sabent associar un URL específic al seu quartet de directoris específics, cridant la funció spip_initialisation sobre uns altres quatre valors, deduïts del URL.

Crear els directoris adequats

Per iniciar la mutualització, fa falta primer de tot partir d’un lloc operatiu. Pels exemples, partirem d’un lloc cridat pel url http://exemple.org/ emmagatzemat físicament a/home/toto/public_html/.

És necessari crear un directori (per exemple anomenat ’llocs’) que contindrà els directoris dels llocs mutualitzats, a l’arrel de la distribució (al mateix nivell que /ecrire).

-  mutualització d’un directori:
Si desitgem que les adreces http://exemple.org/primer_lloc/ i http://exemple.org/segon_lloc/ cridin cadascuna un lloc spip, hem de crear llavors els subdirectoris /primer_lloc i /segon_lloc a dins del directori /llocs, després a dins de cadascun d’ells haurem de crear els directoris /config, /IMG, /tmp, /local. Aquests quatre directoris han de tenir accés d’escriptura. Més tard podrem afegir també un directori /squelettes, al mateix nivell d’aquests directoris.

-  mutualització subdomini i domini (algunes idees) :
Si desitgem que l’adreça http://toto.example.org/, http://exemple.tld/ i http://usuari.exemple.com/ cridin cadascun un lloc spip, podem pensar en crear a dins de /llocs els directoris /toto, /exemple.tld, i /exemple.com/usuari

Comentari: Tots els url han d’apuntar a l’arrel de la distribució SPIP, és a dir a dins de /home/toto/public_html/. És el paper que han de fer o bé un fitxer .htaccess o bé la configuració del servidor Apache explicats més enllà.

Redireccions ben fetes!

Si volem que SPIP reconegui que un lloc està mutualitzat, fa falta que l’script spip.php (cridat per index.php) sigui executat. Aquest buscarà, gràcies a un codi afegit a dins de /config/mes_options.php si el URL cridat correspon a un lloc mutualitzat o no. Per això, fa falta que una adreça http://exemple.org/primer_lloc/ o http://exemple.org/segon_lloc/ sigui redirigit cap a http://exemple.org/ per executar llavors index.php...

És el paper atribuït al fitxer .htaccess (o directament a la configuració del servidor Apache)

Fa falta copiar i reanomenar el fitxer htaccess.txt a l’arrel de la distribució per .htaccess, després modificar-lo:

Per autoritzar la reescriptura del URL (res no canvia normalment): RewriteEngine On

Si la distribució SPIP està a dins d’un subdirectori, modificar rewritebase. En l’exemple el lloc està a l’arrel, per tant: RewriteBase /

Finalment, a dins dels paràmetres personalitzats, afegirem el següent codi per tal que els directoris /primer_lloc , /segon_lloc i /tercer_lloc siguin tractats des de l’arrel de la distribució:

#Mutualisation
RewriteRule ^(primer_lloc|segon_lloc|tercer_lloc)$ /$1/ [R,L]
RewriteRule ^(primer_lloc|segon_lloc|tercer_lloc)/(.*) /$2 [QSA,L]

El primer rewriterule redirigeix les adreces http://exemple.org/primer_lloc cap a http://exemple.org/primer_lloc{{/. La segona redirigeix tot el que hi ha al darrere /primer_lloc/ a l’arrel, per exemple: http://exemple.org/primer_lloc/article112 és redirigit cap a http://exemple.org/article112. (No obstant, aquesta redirecció és transparent, el nom del url no canvia, és encara http://exemple.org/primer_lloc/article112, en concret i sobretot per php!)

I si SPIP es troba en un subdirectori?
En aquest cas, els fitxers d’spip es troben a dins de /home/toto/public_html/spip/, SPIP és cridat per http://exemple.org/spip/, els llocs mutualitzats per http://exemple.org/spip/primer_lloc/ o http://exemple.org/spip/segon_lloc/.

Llavors fa falta posar a dins el fitxer .htaccess :

RewriteEngine On
RewriteBase /spip/

#Mutualisation
RewriteRule ^(primer_lloc|segon_lloc|tercer_lloc)$ /spip/$1/ [R,L]
RewriteRule ^(primer_lloc|segon_lloc|tercer_lloc)/(.*) /spip/$2 [QSA,L]

I per redirigir tots els directoris com a llocs mutualitzats?

És possible, en lloc dels "rewriterules" que hi ha més amunt, utilitzar un codi genèric, utilitzable sigui quin sigui el nom del directori del lloc mutualitzat:

-  a l’arrel

RewriteCond %{REQUEST_URI} !^/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*)
RewriteRule ^[^/]+/(.*) /$1 [QSA,L]

-  o a dins d’una carpeta /spip :

RewriteCond %{REQUEST_URI} !^/spip/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*)
RewriteRule ^[^/]+/(.*) /spip/$1 [QSA,L]

I pels dominis i subdominis?
Per un feliç atzar, aquí no hi ha res a fer ja que ells apunten normalment ja a l’arrel de la distribució SPIP...

Mutualitzar segons el URL gràcies a mes_options.php

És el fitxer /config/mes_options.php a l’arrel de la distribució el que realitzarà la major part del treball: ha de buscar si un URL s’ha de mutualitzar o no, i inicialitzar SPIP en funció d’això.

Es poden presentar nombrosos casos, entre els directoris, els dominis i subdominis. PHP pot utilitzar dues variables per verificar els URLs que han cridat l’script :

$_SERVER['REQUEST_URI']; // conté tot allò que hi ha al darrere del nom de domini: /primer_lloc/article112 per exemple...
$_SERVER['SERVER_NAME']; // conté el nom del domini i subdomini: usuari.exemple.org per exemple

Aquestes són les dues variables que seran comparades a una expressió regular per extreure el nom del directori que conté la mutualització.

Una manera simple de mutualitzar tots els directoris és copiar el següent codi:

<?php 
if ( preg_match(',/([a-zA-Z0-9_-]+)/?,',$_SERVER['REQUEST_URI'],$r)) {

    if (is_dir($e = _DIR_RACINE . 'llocs/' . $r[1]. '/')) {

        $cookie_prefix = $table_prefix = $r[1]; 

        define('_SPIP_PATH',
            $e . ':' .
            _DIR_RACINE .':' .
            _DIR_RACINE .'squelettes-dist/:' .
	    _DIR_RACINE.'prive/:'.
            _DIR_RESTREINT);

        spip_initialisation(
            ($e . _NOM_PERMANENTS_INACCESSIBLES),
            ($e . _NOM_PERMANENTS_ACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_INACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_ACCESSIBLES)
            );

       $GLOBALS['dossier_squelettes'] = $e.'squelettes';

        if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f);
    }
} 
?>

La línia preg_match recupera el nom d’una carpeta a dins l’arborescència del URL, per exemple ’primer_lloc’ a http://exemple.org/primer_lloc/ ... Després l’script prova una mutualització si el directori /llocs/primer_lloc/ existeix.

Si SPIP està a dins d’un directori /spip, fa falta modificar la primera línia per: if (preg_match(',/spip/([a-zA-Z0-9_-]+)/?,', $_SERVER['REQUEST_URI'], $r)) {

Hem de dir a SPIP quin és el prefix de la taula de base de dades utilitzat, i això ho fa $cookie_prefix = $table_prefix = $r[1];
Aquesta línia crearà les taules MySQL amb els prefixes que tinguin el nom del directori que conté el lloc: meu_lloc_article en lloc de spip_article per exemple. Això permet allotjar tots els llocs en una sola i mateixa base de dades. Podeu guardar el prefix per defecte (spip), però fa falta pensar en tenir diverses bases de dades diferents per cada lloc.
Per això, en el seu lloc posarem:

$cookie_prefix = $r[1]; 
$table_prefix='spip';

La funció spip_initialisation admet quatre paràmetres que són l’adreça de cadascun dels directoris necessaris pel funcionament del lloc mutualitzat.

$GLOBALS['dossier_squelettes'] = $e.'squelettes'; defineix l’emplaçament de la carpeta squelettes del lloc mutualitzat.

Finalment, les darreres línies carreguen un eventual llocs/primer_lloc/config/mes_options.php.

Informació:

Tota modificació del fitxer config/mes_options.php del nucli SPIP afectarà les opcions de tots els llocs allotjats.

Per exemple, posar a dins aquest fitxer: $type_urls = ’propres’ ;

Donarà per defecte a tots els llocs aquest tipus d’url.. Però cada lloc el pot canviar a dins del seu propi /llocs/meu_lloc/config/mes_options.php.

Configurar Apache pels dominis i subdominis

La mutualització pel cantó del servidor, en tot allò que fa referència a la gestió dels subdominis o dels dominis és molt simple, però necessita crear algunes redireccions dels URL a dins de la configuració del servidor Apache per tenir en compte aquests llocs.

Heus aquí un exemple de configuració per un servidor anomenat ’exemple..tld’ (aquí un SPIP mutualitzat) utilitzant subdominis (SPIP cridat per http://usuari.exemple.org/spip/).

El nucli SPIP és a dins de ’/home/toto/public_html/spip/’.

He de crear per tant els directoris /llocs/exemple.tld/ , /llocs/exemple.tld/usuari/.

El fitxer de configuració es situa a dins d’Apache 2/linux a /etc/apache2/llocs_disponibles/default (podeu crear també un nou fitxer a dins de la carpeta llocs_disponibles i activar-lo).

# SERVEUR exemple.tld
# SPIP per subdomini...
<VirtualHost *>
        ServerName exemple.tld
	ServerAlias *.exemple.tld

        # Redirecció cal al nucli SPIP
	DocumentRoot "/home/toto/public_html"
	<Directory "/home/toto/public_html/">
		AllowOverride All
		Order allow,deny
		Allow from all
	</Directory>

	# Només l'adreça http://usuari.exemple.tld/spip/* ha de ser redirigida

	# (usuari.exemple.tld/spip/* -> /home/toto/public_html/*)
	RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$
	RewriteRule ^/spip/(.*) /home/toto/public_html/spip/$1 [QSA,L]

	# (usuari.exemple.tld/* -> /home/toto/public_html/llocs/exemple.tld/utilisateur/*)
	RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$
	RewriteRule (.*) /home/toto/public_html/llocs/exemple.tld/%1/$1 [QSA,L]

</VirtualHost>

Per contra, és necessari provar aquestes possibles mutualitzacions a /config/mes_options.php :

<?php
# per usuari.exemple.tld/spip/ 
if ( preg_match(',(.*)\.exemple\.tld/spip/?,',$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'],$r)) {

    if (is_dir($e = _DIR_RACINE . 'llocs/exemple.tld/' . $r[1]. '/')) {

       $cookie_prefix = $table_prefix = $r[1]; 

       define('_SPIP_PATH',
            $e . ':' .
            _DIR_RACINE .':' .
            _DIR_RACINE .'squelettes-dist/:' .
            _DIR_RACINE.'prive/:'.
            _DIR_RESTREINT);

        spip_initialisation(
            ($e . _NOM_PERMANENTS_INACCESSIBLES),
            ($e . _NOM_PERMANENTS_ACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_INACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_ACCESSIBLES)
            );

       $GLOBALS['dossier_squelettes'] = $e.'squelettes';

        if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f);
    }
} 
?>

Nota sobre les salvaguardes i les restauracions

Cada lloc copia els seus fitxers de salvaguardes a dins del directori /llocs/primer_lloc/tmp/dump (o /llocs/primer_lloc/tmp/upload/login per les salvaguardes d’un administrador restringit). Les restauracions es fan per mitjà del mateix directori.

Atenció:

Actualment SPIP enregistra a la base de dades, per allò que fa referència a la carpeta /IMG dels llocs mutualitzats, una adreça llocs/primer_lloc/IMG/* en lloc de IMG/* com per un únic lloc SPIP.

Per tant, una restauració no funcionarà si s’efectua a dins del lloc que ha creat la salvaguarda.

Un truc per restaurar el lloc en una altra banda consisteix en editar el fitxer dump.xml i substituir totes les ocurrències (excepte les de les declaracions dir_img i dir_logo a l’obertura de l’etiqueta spip) :
-  llocs/primer_lloc/IMG/

  • per (SPIP únic) : IMG/
  • o (SPIP mutualitzat): llocs/meu_nou_lloc/IMG/

A la inversa, per passar un SPIP únic a dins d’un directori mutualitzat, fa falta substituir totes les ocurrències de:
-  IMG/
-  per: lloc/meu_lloc/IMG/

(Aquesta dificultat es corregirà a la propera versió d’SPIP)

Notes

[1Nova distribució dels directoris per clarificar la mutualització, correcció dels problemes de logins i dels noms de llocs que es barrejaven algunes vegades entre els llocs compartits, funció més clara d’inicialització d’un lloc per compartir

[2Per informació: aquests processos han estat provats amb Apache 2.0.55 i PHP 5.1.2 en un servidor Ubuntu Dapper Drake i també en PHP 5.1.6 en un servidor Ubuntu Edgy Eft

Autor merce Publié le : Mis à jour : 26/10/12

Traductions : عربي, català, English, Español, français, italiano, Türkçe