Créer des champs extras depuis un plugin perso avec l’aide de Saisies

Note : n’oubliez pas de remplacer prefixe par le préfixe de votre plugin.

Créer la fonction qui va déclarer les nouveaux champs

Dans cette première partie, on ajoute simplement un champ date aux articles du secteur 1 et un champ textarea aux rubriques de la branche 5. Pour voir d’autres types de champs, rendez-vous dans la partie Déclarer d’autres types de champs extras.

Créer un fichier /base/prefixe.php contenant le code suivant :

<?php

// Sécurité
if (!defined("_ECRIRE_INC_VERSION")) return;

function prefixe_declarer_champs_extras($champs = array()) {

    // SAISIE DATE SUR L'OBJET ARTICLE DU SECTEUR 1
    $champs['spip_articles']['date_diffusion'] = array(
        // Le type de saisie
        'saisie' => 'date',
        'options' => array(
            // Le nom du champ dans la base de données
            'nom' => 'date_diffusion', 
            // Le label affiché dans l'espace privé du site
            'label' => _T('prefixe:chaine_de_langue_date_diffusion'),
            // L'explication affichée dans l'espace privé du site
            'explication' => _T('prefixe:chaine_de_langue_date_diffusion_explication'),
            // Le type d'info attendue
            'sql' => "datetime DEFAULT '0000-00-00 00:00:00' NOT NULL",
            // La valeur par défaut
            'defaut' => '',
            // Le champ est obligatoire
            'obligatoire' => 'oui',
            // Afficher ce champ uniquement pour les articles du secteur n°1
            'restrictions'=>array(
                        'secteur' => '1'
            ),
       ),
        // Vérifier et normaliser les infos saisies avant de les insérer dans la base
        'verifier' => array(
            'type' => 'date',
            'options' => array(
                'normaliser' => 'datetime',
            )
        )
    );

    // SAISIE TEXTEAREA SUR L'OBJET RUBRIQUE DE LA BRANCHE N°5
    $champs['spip_rubriques']['infos_complementaires'] = array(
        'saisie' => 'textarea',
        'options' => array(
            'nom' => 'infos_complementaires',
            'label' => _T('prefixe:chaine_de_langue_infos_complementaires'), 
            'defaut' => '',
            // Nombre de ligne du champ dans l'espace privé
            'rows' => 10,
            // Insérer la barre d'outils type forum
            'inserer_barre' => 'forum',
            // Appliquer les traitements typographiques et raccourcis SPIP à l'affichage du champ
            'traitements' => '_TRAITEMENT_RACCOURCIS',
            'sql' => "text DEFAULT '' NOT NULL",
            // Afficher ce champ uniquement pour les articles de la branche n°5
            'restrictions'=>array(
                        'branche' => '5'
            ),
        )
    );
    return $champs;        
}

Indiquer au plugin de mettre à jour la base

Créer un fichier /prefixe_administrations.php contenant le code suivant :

<?php
if (!defined("_ECRIRE_INC_VERSION")) return;

// Inclure l'API Champs Extras
include_spip('inc/cextras');
// Inclure les champs déclarés à l'étape précédente
include_spip('base/prefixe');

function prefixe_upgrade($nom_meta_base_version,$version_cible) {

        $maj = array();

        // Première déclaration à l'installation du plugin
        cextras_api_upgrade(prefixe_declarer_champs_extras(), $maj['create']);

        include_spip('base/upgrade');
        maj_plugin($nom_meta_base_version, $version_cible, $maj);

}

// Désinstaller proprement le plugin en supprimant les champs de la base de données
function prefixe_vider_tables($nom_meta_base_version) {
        cextras_api_vider_tables(prefixe_declarer_champs_extras());
        effacer_meta($nom_meta_base_version);
}

Si vous ajoutez des champs extras une fois votre plugin installé et en fonctionnement, vous devez déclarer ces mises à jour en ajoutant au code ci-dessus (après la première déclaration $maj['create']) :

        // Ajout d'un nouveau ou plusieurs champs
        cextras_api_upgrade(prefixe_declarer_champs_extras(), $maj['0.1.1']);
        
        // Encore un ajout de nouveaux champs
        cextras_api_upgrade(prefixe_declarer_champs_extras(), $maj['0.1.2']);

Si vous supprimez des champs, par exemple la date, indiquer à votre plugin de les supprimer de la base :

// Supprimer des champs
	cextras_api_upgrade(prefixe_declarer_champs_extras(), $maj['1.2.0']);
	$maj['1.2.0'][] = array('sql_alter',"TABLE spip_articles DROP date_nom");

Note : la valeur $maj['0.1.1'] doit correspondre avec le schema déclaré plus loin dans paquet.xml.

Dans votre paquet.xml

Dernière étape : pour que tout ça soit pris en compte, vous devez modifier votre fichier paquet.xml.

Indiquer que le plugin doit mettre à jour la base

Ajouter schema="0.1.0" dans la balise <paquet> afin que votre plugin mette à jour la base de données.
Puis, à chaque ajout ou surpression d’un champ, monter d’une version que le changement soit pris en compte.

Déclarer le pipeline champs extras

Enfin, déclarer le pipeline declarer_champs_extras :

        <pipeline nom="declarer_champs_extras" inclure="base/prefixe.php" />

Déclarer les dépendances

Pour que ça fonctionne, votre plugin nécessite désormais 3 autres plugins :

  • Champs Extras 3 pour gérer les champs en base
  • Saisies pour gérer les saisies (interface avec la base)
  • Vérifier pour vérifier les infos saisies avant de les rentrer en base

Ajouter ces nécessites :

<necessite nom="cextras" compatibilite="[3.0.5;]" />	
	<necessite nom="saisies" compatibilite="[3.2.0;]" />
	<necessite nom="verifier" compatibilite="[1.8.0;]" />

Note : l’article ayant été écrit en mai/juin 2020, il sera peut-être nécessaire de mettre à jour les compatibilite.

Récapitulatif paquet.xml

Votre fichier paquet.xml doit désormais ressembler à ça :

<paquet
	prefix="prefixe"
	categorie="squelette"
	version="1.0.0"
	etat="stable"
	compatibilite="[3.2.0;3.3.*]"
	logo="prive/themes/spip/images/prefixe-32.png"
	documentation="https://www.domaine.net"
	schema="0.1.0"
>

	<nom>Nom de votre Plugin</nom>

	<pipeline nom="declarer_champs_extras" inclure="base/prefixe.php" />

	<necessite nom="cextras" compatibilite="[3.0.5;]" />	
	<necessite nom="saisies" compatibilite="[3.2.0;]" />
	<necessite nom="verifier" compatibilite="[1.8.0;]" />

</paquet>

Déclarer d’autres types de champs extras

Voici un exemple plus complet :

<?php
 
if (!defined("_ECRIRE_INC_VERSION")) return;
 
function prefixe_declarer_champs_extras($champs = array()) {

    // SAISIE RADIO SUR L'OBJET ARTICLE
    $champs['spip_articles']['type_structure'] = array(
        'saisie' => 'radio',
        'options' => array(
            'nom' => 'structure', 
            'label' => _T('prefixe:type_structure_label'),
            'explication' => _T('prefixe:type_structure_explication'),
            'sql' => "varchar(30) NOT NULL DEFAULT ''",
            'defaut' => '',
            // Les cases radio
            'datas' => array(
                '' =>  _T('prefixe:champ_vide'), 
                'structure_adherente' =>  _T('prefixe:type_structure_adherente'), 
                'structure_non_adherente' =>  _T('prefixe:type_structure_non_adherente'), 
            ),
        )
    );

    // SAISIE CHECKBOX SUR L'OBJET RUBRIQUE DE LA BRANCHE N°1 
    $champs['spip_rubriques']['jour_de_diffusion'] = array(
        'saisie' => 'checkbox',
        'options' => array(
            'nom' => 'jour_diffusion_emission',
            'label' => _T('prefixe:jour_de_diffusion'), 
            'sql' => "text DEFAULT '' NOT NULL",
            'defaut' => '',
            'restrictions'=>array(
                'branche' => '1',
                // Autorisation : Tous les auteurs peuvent voir ce champ
                'voir' => array('auteur' => ''),
                // Autorisation : Seuls les admins complets peuvent le modifier
                'modifier' => array('auteur' => 'admin_complet')
            ),
            // Les cases checkbox
            'datas'=>array(
                'lundi' => 'Lundi',
                'mardi' => 'Mardi',
                'mercredi' => 'Mercredi',
                'jeudi' => 'Jeudi',
                'vendredi' => 'Vendredi',
                'samedi' => 'Samedi',
                'dimanche' => 'Dimanche'
            ),
        )
	);
 
    // 2 SAISIES DANS UN FIELDSET POUR L'OBJET AUTEUR
    $champs['spip_auteurs']['fieldset_numeros'] = array(
        'saisie' => 'fieldset',
        'options' => array(
            'nom' => "fieldset_numeros",
            'label' => _T('prefixe:chaine_de_langue_fieldset_numeros')
        ),
        'saisies' => array(
            // SAISIE INPUT SUR L'OBJET AUTEUR 
            'telephone' => array(
                'saisie' => 'input',
                'options' => array(
                    'nom' => 'telephone', 
                    'label' => _T('prefixe:chaine_de_langue_telephone'),
                    // Texte indicatif
                    'placeholder' => _T('prefixe:chaine_de_langue_placeholder'), 
                    // Limiter ce champ à 30 caractères
                    'sql' => "varchar(30) NOT NULL DEFAULT ''",
                    'defaut' => '',
                ),
                // Vérifier que les données saisies correspondent à un numéro de téléphone
                'verifier' => array(
                    'type' => 'telephone'
                )
            ),
            'fax' => array(
                'saisie' => 'input',
                'options' => array(
                    'nom' => 'fax', 
                    'label' => _T('prefixe:chaine_de_langue_fax'), 
                    // Limiter ce champ à 30 caractères
                    'sql' => "varchar(30) NOT NULL DEFAULT ''",
                    'defaut' => '',
                ),
                // Vérifier que les données saisies correspondent à un numéro de téléphone
                'verifier' => array(
                    'type' => 'telephone'
                )
            )
        )
    );
    // SAISIE SÉLECTEUR D'ARTICLE
    $champs['spip_articles']['voir_aussi'] = array(
        'saisie' => 'selecteur_article',
        'options' => array(
            'nom' => 'voir_aussi', 
            'label' => _T('prefixe:voir_aussi_label'),
            'explication' => _T('prefixe:voir_aussi_explication'),
            'sql' => "varchar(30) NOT NULL DEFAULT ''",
            // Possibilité de choisir plusieurs articles
            'multiple' => true,
        )
    );

    return $champs;	
}

Pour aller plus loin