Gestion des blocs conteneurs

- création d'une table de liaisons blocktype -> blocktype, avec un role [parent|enfant]
- mise à jour des rôles sur la page d'édition d'un blocktype et contrainte d'intégrité (si un blocktype A ne peut être contenu que dans un blocktype B, alors le blocktype B peut forcément contenir le blocktype A)
- chaines de langue
master
nicod_ 1 week ago
parent 1ac4c60a2d
commit 22209ed41c

@ -99,12 +99,22 @@ function blocks_declarer_tables_objets_sql($tables) {
'PRIMARY KEY' => 'id_blocktype',
'UNIQUE KEY identifiant' => 'identifiant',
],
'titre' => 'titre AS titre, "" AS lang',
'champs_editables' => ['titre', 'description', 'saisies', 'objets', 'identifiant'],
'champs_versionnes' => ['titre', 'description', 'saisies', 'objets', 'identifiant'],
'rechercher_champs' => ["titre" => 10, 'description' => 5, 'identifiant' => 5],
'tables_jointures' => [],
'page' => false,
'titre' => 'titre AS titre, "" AS lang',
'champs_editables' => ['titre', 'description', 'saisies', 'objets', 'identifiant'],
'champs_versionnes' => ['titre', 'description', 'saisies', 'objets', 'identifiant'],
'rechercher_champs' => ["titre" => 10, 'description' => 5, 'identifiant' => 5],
'tables_jointures' => [],
'roles_titres' => [
'enfant' => _T('blocktype:role_enfant'),
'parent' => _T('blocktype:role_parent'),
],
'roles_objets' => [
'blocktypes' => [
'choix' => ['enfant', 'parent'],
'defaut' => '',
],
],
'page' => false,
];
// jointure potentielle avec tous les objets
@ -138,5 +148,20 @@ function blocks_declarer_tables_auxiliaires($tables) {
],
];
// table de liaison entre blocktypes enfants / parents
$tables['spip_blocktypes_liens'] = [
'field' => [
'id_blocktype' => 'bigint(21) DEFAULT "0" NOT NULL',
'id_objet' => 'bigint(21) DEFAULT "0" NOT NULL',
'objet' => 'varchar(25) DEFAULT "" NOT NULL',
'rang_lien' => 'int(4) DEFAULT "0" NOT NULL',
'role' => 'varchar(25) DEFAULT "" NOT NULL', // [enfant|parent]
],
'key' => [
'PRIMARY KEY' => 'id_blocktype,id_objet,objet,role',
'KEY id_blocktype' => 'id_blocktype',
],
];
return $tables;
}

@ -26,7 +26,7 @@ function blocks_upgrade($nom_meta_base_version, $version_cible) {
$maj = [];
$maj['create'] = [
['maj_tables', ['spip_blocks', 'spip_blocks_liens', 'spip_blocktypes']],
['maj_tables', ['spip_blocks', 'spip_blocks_liens', 'spip_blocktypes', 'spip_blocktypes_liens']],
['blocks_installe_config'],
];
@ -35,12 +35,8 @@ function blocks_upgrade($nom_meta_base_version, $version_cible) {
['maj_tables', ['spip_blocks', 'spip_blocks_liens', 'spip_blocktypes']],
];
$maj['1.1.1'] = [
['maj_tables', ['spip_blocks']],
];
$maj['1.1.2'] = [
['maj_tables', ['spip_blocktypes']],
$maj['1.2.0'] = [
['maj_tables', ['spip_blocks', 'spip_blocktypes', 'spip_blocktypes_liens']],
];
include_spip('base/upgrade');

@ -54,6 +54,42 @@ function formulaires_editer_blocktype_saisies_dist($id_blocktype = 'new', $retou
],
],
[
'saisie' => 'case',
'options' => [
'nom' => 'conteneur_enfants',
'label_case' => _T('blocktype:champ_conteneur_enfants_label'),
],
],
[
'saisie' => 'blocktypes',
'options' => [
'nom' => 'blocktypes_enfants',
'label' => _T('blocktype:champ_blocktypes_enfants_label'),
'afficher_si' => '@conteneur_enfants@ == "on"',
'multiple' => 'oui',
'titre_court' => 'oui',
'exclus' => [$id_blocktype],
],
],
[
'saisie' => 'case',
'options' => [
'nom' => 'conteneur_parents',
'label_case' => _T('blocktype:champ_conteneur_parents_label'),
],
],
[
'saisie' => 'blocktypes',
'options' => [
'nom' => 'blocktypes_parents',
'label' => _T('blocktype:champ_blocktypes_parents_label'),
'afficher_si' => '@conteneur_parents@ == "on"',
'multiple' => 'oui',
'titre_court' => 'oui',
'exclus' => [$id_blocktype],
],
],
[
'saisie' => 'input',
'options' => [
@ -61,7 +97,6 @@ function formulaires_editer_blocktype_saisies_dist($id_blocktype = 'new', $retou
'obligatoire' => 'oui',
'label' => _T('blocktype:champ_identifiant_label'),
'explication' => _T('blocktype:champ_identifiant_explication'),
],
],
];
@ -128,6 +163,17 @@ function formulaires_editer_blocktype_identifier_dist($id_blocktype = 'new', $re
function formulaires_editer_blocktype_charger_dist($id_blocktype = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$valeurs = formulaires_editer_objet_charger('blocktype', $id_blocktype, '', $lier_trad, $retour, $config_fonc, $row, $hidden);
$valeurs['objets'] = blocks_deserialize($valeurs['objets']);
if ($blocktypes_enfants = objet_trouver_liens(['blocktype' => $id_blocktype], ['blocktype' => '*'], ['role' => 'enfant'])) {
$valeurs['blocktypes_enfants'] = array_column($blocktypes_enfants, 'id_objet');
$valeurs['conteneur_enfants'] = 'on';
}
if ($blocktypes_parents = objet_trouver_liens(['blocktype' => $id_blocktype], ['blocktype' => '*'], ['role' => 'parent'])) {
$valeurs['blocktypes_parents'] = array_column($blocktypes_parents, 'id_objet');
$valeurs['conteneur_parents'] = 'on';
}
$valeurs['saisies'] = call_user_func_array('formulaires_editer_blocktype_saisies_dist', func_get_args());
return $valeurs;
}
@ -181,11 +227,40 @@ function formulaires_editer_blocktype_verifier_dist($id_blocktype = 'new', $reto
*
*/
function formulaires_editer_blocktype_traiter_dist($id_blocktype = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$creation = (int)$id_blocktype ? false : true;
set_request('objets', blocks_serialize(_request('objets')));
$retours = formulaires_editer_objet_traiter('blocktype', $id_blocktype, '', $lier_trad, $retour, $config_fonc, $row, $hidden);
if (!(int)$id_blocktype) {
if ($id_blocktype = $retours['id_blocktype']) {
// mettre à jour les rôles
objet_dissocier(['blocktype' => $id_blocktype], ['blocktype' => '*'], ['role' => 'enfant']);
if ($blocktypes_enfants = _request('blocktypes_enfants')) {
foreach ($blocktypes_enfants as $blocktype_enfant) {
objet_associer(['blocktype' => $id_blocktype], ['blocktype' => $blocktype_enfant], ['role' => 'enfant']);
}
}
objet_dissocier(['blocktype' => $id_blocktype], ['blocktype' => '*'], ['role' => 'parent']);
if ($blocktypes_parents = _request('blocktypes_parents')) {
foreach ($blocktypes_parents as $blocktype_parent) {
objet_associer(['blocktype' => $id_blocktype], ['blocktype' => $blocktype_parent], ['role' => 'parent']);
objet_associer(['blocktype' => $blocktype_parent], ['blocktype' => $id_blocktype], ['role' => 'enfant']);
}
}
// réassigner le role enfant pour les roles parents existants
if ($blocktypes_parents = objet_trouver_liens(['blocktype' => '*'], ['blocktype' => '*'], ['role' => 'parent'])) {
foreach ($blocktypes_parents as $blocktype_parent) {
objet_associer(['blocktype' => $blocktype_parent['id_objet']], ['blocktype' => $blocktype_parent['id_blocktype']], ['role' => 'enfant']);
}
}
}
if ($creation) {
// en cas de création d'un type de block, rediriger vers la configuration des champs
$retours['redirect'] = generer_url_ecrire('blocktype_edit_champs', 'id_blocktype=' . $retours['id_blocktype']);
}
return $retours;
}

@ -14,6 +14,10 @@ $GLOBALS[$GLOBALS['idx_lang']] = [
// C
'champ_identifiant_label' => 'Identifiant',
'champ_identifiant_explication' => 'Unique, composé de lettres en minuscules, chiffres ou souligné <code>_</code><br>Cet identifiant servira aussi à trouver le squelette qui affichera ce type de bloc : <code>squelettes/blocks/identifiant.html</code></code>',
'champ_conteneur_enfants_label' => 'Ce bloc peut contenir des blocs',
'champ_blocktypes_enfants_label' => 'Quels types de blocs peuvent être ajoutés dans ce bloc',
'champ_conteneur_parents_label' => 'Ce bloc ne peut être contenu que dans certains blocs',
'champ_blocktypes_parents_label' => 'Dans quels types de blocs',
'champ_saisies_label' => 'Paramètres de ce type de bloc',
'champ_titre_label' => 'Titre',
'champ_description_label' => 'Description',
@ -34,6 +38,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = [
// R
'retirer_lien_blocktype' => 'Retirer ce type de bloc',
'retirer_tous_liens_blocktypes' => 'Retirer tous les types de blocs',
'role_enfant' => 'Peut contenir',
'role_parent' => 'Ne peut être contenu que dans',
// S
'supprimer_blocktype' => 'Supprimer cet type de bloc',

@ -5,7 +5,7 @@
compatibilite="[4.2.0;4.2.*]"
logo="prive/themes/spip/images/blocks-xx.svg"
documentation=""
schema="1.1.2"
schema="1.2.0"
>
<nom>Blocks</nom>

@ -3,13 +3,34 @@
[(#DESCRIPTION|propre)]
#BOITE_OUVRIR
<p>
<strong class="label"><:blocktype:champ_identifiant_label:/> : </strong>#IDENTIFIANT
</p>
<B>
<p><strong class="label"><:blocktype:champ_conteneur_enfants_label:/> : </strong></p>
<ul class="spip">
<BOUCLE(spip_blocktypes_liens){id_blocktype}{role=enfant}>
<li>#INFO_TITRE{blocktype,#ID_OBJET}</li>
</BOUCLE>
</ul>
</B>
<B>
<p><strong class="label"><:blocktype:champ_conteneur_parents_label:/> : </strong></p>
<ul class="spip">
<BOUCLE(spip_blocktypes_liens){id_blocktype}{role=parent}>
<li>#INFO_TITRE{blocktype,#ID_OBJET}</li>
</BOUCLE>
</ul>
</B>
[<p>
<strong class="label"><:blocktype:champ_objets_label:/> : </strong>
(#INCLURE{fond=saisies-vues/blocks_objets, valeur=#OBJETS})
</p>]
<p>
<strong class="label"><:blocktype:texte_squelette_public:/> : </strong>
#SET{skel, #IDENTIFIANT|blocks_trouver_squelette{1,1,0}}
@ -17,6 +38,7 @@
[(#GET{skel}|oui) #ALERTE_MESSAGE{#GET{skel}, '', success} ]
[(#GET{skel}|non) [(#ALERTE_MESSAGE{#GET{skeldist}, <:blocktype:info_blocktypes_sans_squelette:/>, notice})] ]
</p>
<p>
<strong class="label"><:blocktype:texte_squelette_prive:/> : </strong>
#SET{skel, #IDENTIFIANT|blocks_trouver_squelette{0,1,0}}
@ -24,6 +46,7 @@
[(#GET{skel}|oui) #ALERTE_MESSAGE{#GET{skel}, '', success} ]
[(#GET{skel}|non) [(#ALERTE_MESSAGE{#GET{skeldist}, <:blocktype:info_blocktypes_sans_squelette:/>, notice})] ]
</p>
#BOITE_FERMER
#SET{saisies, #SAISIES|blocks_deserialize{1}}

Loading…
Cancel
Save