Carnet Wiki

PortageV2

Version 28 — Avril 2009 JLuc

Trucs utiles pour le portage d’un plugin vers SPIP version 2.0


définir une fonction qui teste la version

On peut faire appel à la fonction version_compare pour implémenter les fonctionnalités critiques de 2 manières différentes selon la version du core de SPIP. On peut ainsi garder le plugin compatible avec plusieurs versions de SPIP, mais cela allourdit le code.

if (version_compare($GLOBALS['spip_version_code'],'1.9300','<')) { // SPIP <= 1.9.2x 
   ...}
elseif (version_compare($GLOBALS['spip_version_code'],'1.9300','>=')) {	
... // spip V2
};

Ou bien :

if (version_compare($GLOBALS['spip_version_branche'],'2.1.0 dev','<')) 
 {...

Voir aussi la fonction spiplistes_spip_est_inferieur_193() du plugin spipliste.


debut_page

pour thelia il a fallu remplacer :

debut_page(_T("spip_thelia:catalogue_thelia"), "Catalogue Télia", "Catalogue Télia");

par

$commencer_page = charger_fonction('commencer_page', 'inc');
echo $commencer_page(_T("spip_thelia:catalogue_thelia"),_T("spip_thelia:catalogue_thelia"),_T("spip_thelia:catalogue_thelia"));

Pour spip2spip

debut_page(_T('spiptospip:copy_spip2spip'), "administration", "configuration","contenu");
echo "<br / ><br />";

a été remplacé par

$commencer_page = charger_fonction('commencer_page', 'inc');
echo $commencer_page(_T("spiptospip:copy_spip2spip"),_T("spiptospip:copy_spip2spip"),_T("spiptospip:copy_spip2spip"));

debut_gauche, debut_droite, fin_gauche, fin_droite

debut_gauche();
est remplacé par
echo debut_gauche('', true);

il en est de même pour les « fins » qui deviennent par exemple :

echo fin_gauche();
echo fin_page();

attention : fin_droite n’existe pas
pour finir une page correctement le code est
echo fin_gauche().fin_page();


debut_boite_info, fin_boite_info, debut_cadre_relief, fin_cadre_relief

debut_boite_info();
est remplacé par
debut_boite_info(true);

exemple d’emploi de debut_cadre_relief :
echo debut_cadre_relief($icone,true,'',$titre));

fin_cadre_relief(true);
est remplacé par
echo fin_cadre_relief(true);


gros_titre

gros_titre(_T('peuplementldap:titre_page'),'',false);
est remplacé par
echo gros_titre(_T('peuplementldap:titre_page'),'',false);


bouton_block_invisible

la fonction n’existe plus. Il faut l’intégrer via jQuery (class depliant)
Quel est le code exact de remplacement ?


generer_url_xxxx

Remplacer les generer_url_xxxx(’...’) par generer_url_entite($id, ’xxxx’), idem dans les squelettes :
|generer_url_site{...} => |generer_url_entite{site, ...}

Pour un code portable, on teste la version, ce qui fait que pour un portage compatible :
$url = generer_url_article($row['id_article']);
devient :

$url = ( spiplistes_spip_est_inferieur_193()) ? 
                  generer_url_article($row['id_article']) : generer_url_entite($row['id_article'], 'article');

_q (sql_quote)

-  _q est remplacé par sql_quote pour échapper les champs non numeriques dans les syntaxes de requêtes SQL
-  intval est utilisé pour les champs numeriques

-  _q est deprecié et ne doit plus être utilisé
-  les echappements en php peuvent etre faits avec les fonctions php usuelles selon les besoins (addslashes, ...) mais mieux faut utiliser sql_quote pour éviter les problèmes de charset

note@marcimat le 21/01/09 : je ne savais pas que _q est déprécié ? c’est écrit où ça ?
note@erational 21/01/09 : je ne sais mais on dirait que c’est vrai, le core n’utilise quasiment plus _q


spip_query, spip_fetch_array,...

Ces fonctions sont encore définies mais sont depreciée et disparaitront rapidement car elle ne permettent pas la portabilité pour postgresql ou sqlite

Il faut préférer les fonctions en sql_ (cf http://doc.spip.org/spip.php?page=r...)

(idem spip_abstract.., calcule_mysql_in, ...)

Exemples :

selection


-  1) selection : 1 résultat seulement (doc sql_fetsel) :
il existe plusieurs fonctions de sélections (sql_fetsel, sql_select, ...) qui retournent des objets differents. bien choisir celle dont vous avez besoin

        $result = spip_query("SELECT * FROM spip_forms WHERE id_form="._q($id_form));
        if (!$row = spip_fetch_array($result)) return false;

est remplacé par :

        if (!$row = sql_fetsel("multiple","spip_forms","id_form=".intval($id_form)))
                return false;

-  2) selection : compter les résultats :

        $row = spip_fetch_array(spip_query("SELECT COUNT(*) AS tot FROM spip_forms_donnees WHERE id_form=".intval($id_form)." AND confirmation='valide' AND statut<>'poubelle'"));
        if ($row)	$nb_reponses = $row['tot'];

est remplacé par

        $nb_reponses = sql_countsel("spip_forms_donnees","id_form=".intval($id_form)." AND confirmation='valide' AND statut<>'poubelle'");

-  3) selection complexe :
De même,

        $result = spip_query("SELECT r.id_donnee, r.date,r.url, c.champ, c.valeur ".
                "FROM spip_forms_donnees AS r LEFT JOIN spip_forms_donnees_champs AS c USING (id_donnee) ".
                "WHERE id_form=".intval($id_form)." AND confirmation='valide' AND statut<>'poubelle' AND c.id_donnee IS NOT NULL ".
                "ORDER BY date, r.id_donnee");
        while ($row = spip_fetch_array($result)) 
        {...


est remplacé par

     $rows = sql_allfetsel(
                "r.id_donnee, r.date,r.url, c.champ, c.valeur ",
                "spip_forms_donnees AS r LEFT JOIN spip_forms_donnees_champs AS c ON r.id_donnee=c.id_donnee",
                "id_form=".intval($id_form)." AND confirmation='valide' AND statut<>'poubelle' AND c.id_donnee IS NOT NULL ",
                "date, r.id_donnee");
        foreach($rows as $row) 
        {...

-  4 ) selection classique (doc sql_select) :

$result_copie = spip_query("SELECT * FROM ".$table_prefix."_spip2spip ORDER BY site_titre");
while($row_copie  = spip_fetch_array($result_copie)) {  
   ...

est remplacé par

$result = sql_select("*","spip_spip2spip", "", "", "site_titre"); 
 while ($row = sql_fetch($result)) {  

Note sur le code précedent :
préfixe des tables il n’est plus nécessaire d’indiquer les préfixes de tables (cas particulier où l’on possède plusieurs SPIPs sur une même base de données), l’API sql_* se débrouille tout seule
instruction ORDER BY :
$result = sql_select(« * »,« spip_spip2spip ORDER BY site_titre ») ;
n’était pas correct, remplacé par :
$result = sql_select(« * »,« spip_spip2spip », «  », «  », « site_titre ») ; sinon PG ou SQLite ne vont pas du tout aimer (note@marcimat 21/01/09)

-  5) delete :

spip_query("DELETE FROM spip_forms_champs_choix WHERE id_form=3");
est remplacé par
sql_delete("spip_forms_champs_choix","id_form=3");

-  6) Insertions : ( sql_insertq)

        $lsDate = date('Y-m-d H:i:s');
        spip_query("INSERT INTO spip_articles (titre, id_rubrique, texte, date, statut) VALUES ('$titre', '$id_rubrique', '$texte', '$lsDate', 'publie')");
        $id_article = spip_insert_id();


est remplacé par :

        $lsDate = date('Y-m-d H:i:s');
        $id_article = sql_insertq( 'spip_articles', array(
 				'titre'=>$titre, 'id_rubrique'=>$id_rubrique, 
 				'texte'=>$texte, 'statut'=>'publie', 'id_secteur'=>$id_secteur, 
				'date'=> $lsDate, 'accepter_forum'=>'non', 'lang'=>$lang));

-  7) insertions multiples : on pourra également remplacer de multiples appels à spip_query ("INSERT...")
par un unique appel à sql_insertq_multi après avoir préparé les données.

-  8) Mise à jour (update) : ( sql_update)

$sql = "UPDATE spip_spip2spip SET last_syndic = NOW() WHERE id=$current_id LIMIT 1";
spip_query($sql);

remplacé par

sql_update("spip_spip2spip", array('last_syndic' => 'NOW()'), "id=$current_id");

spip_abstract_insert

spip_abstract_insert("spip_forms_donnees","(id_donnee,id_form,date,ip,id_auteur,url,confirmation,statut,maj)","(".intval($id_donnee).",".intval($id_form).", NOW(),"._q($ip).","._q($id_auteur).","._q($url).", 'valide', 'publie', NOW() )");


est remplacé par

$id_donnee = sql_insertq("spip_forms_donnees",
							  array(
							  "id_donnee"=>$id_donnee,
							  "id_form"=>$id_form,
							  "date"=>"NOW()",
							  "ip"=>$ip,
							  "id_auteur"=>$id_auteur,
							  "url"=>$url,
							  "confirmation"=>"valide",
							  "statut"=>'publie',
							  "maj"=>"NOW()"));

spip_abstract_fetch

$row = @spip_abstract_fetch($result,"")
est remplacé par
$row = @sql_fetch($result,"")


spip_abstract_count

spip_abstract_count($result, $verif->sql_serveur)
est remplacé par
sql_count($result,$verif->sql_serveur)


include_ecrire

inclure_ecrire($file)
est remplacé par
inclure_spip($file)


gestion du cron

il faut utiliser le pipeline taches_generales_cron et créer un sous-répertoire genie dans lequel on place les fonctions appelés par le cron. voir en plugin exemple agenda2

Déclarer une tache en CRON


La base de données SPIP

  • la table spip_documents_articles est remplacée par spip_documents_liens

sur les autres tables, beaucoup de champs ont évolué, être prudent donc.


Comment ajouter son plugin version 2 à la liste automatique ?

  1. documenter le plugin en écrire un article sur http://www.spip-contrib.net
  2. ajouter le zip du plugin (éventuellement en document distant depuis la zone)
  3. ajouter à cette article le mot-clé Plugins pour SPIP 2.0

à creuser, du côté des motclés

-  create_groupe a peut être changé de signature.
-  voir ce qu’il en est de create_rubrique_mot ou create_mot_rubrique


Quelques liens utiles

-  Réaliser un premier plugin
-  Compatibilite-des-plugins
-  Les points d’entrée (pipelines)
-  API sql_*
-  [L’interface de SPIP avec SQL sur doc SQL->http://doc .spip.org->http://doc.spip.org/@L-interface-de-SPIP-avec-SQL]
- [L’interface de SPIP avec SQL sur spip.net->http://www.spip.net/fr_article3683.html
-   [changelog SPIP 2..0->http://doc.spip.org/@Suivi-des-ameliorations-pour-SPIP]

-  Romy : porter ses sites en SPIP V2
-  DenisB : Mise à jour d’un site spip 1.9.2 vers spip 2..3