source: spip-zone/_plugins_/n-core/trunk/inc/ncore_noisette.php @ 113624

Last change on this file since 113624 was 113624, checked in by eric@…, 4 months ago

Correction PHPDoc

  • Property svn:eol-style set to native
File size: 30.6 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'API N-Core de gestion des noisettes, c'est-à-dire les instances paramétrées
4 * de types de noisette affectées à un conteneur.
5 *
6 * @package SPIP\NCORE\NOISETTE\API
7 */
8if (!defined('_ECRIRE_INC_VERSION')) {
9        return;
10}
11
12
13/**
14 * Ajoute dans un conteneur, à un rang donné ou en dernier rang, une noisette d'un type donné.
15 * La fonction met à jour les rangs des autres noisettes si nécessaire.
16 *
17 * @api
18 * @uses type_noisette_lire()
19 * @uses ncore_conteneur_verifier()
20 * @uses ncore_conteneur_identifier()
21 * @uses ncore_conteneur_construire()
22 * @uses ncore_conteneur_est_noisette()
23 * @uses ncore_noisette_decrire()
24 * @uses ncore_noisette_completer()
25 * @uses ncore_noisette_lister()
26 * @uses ncore_noisette_ranger()
27 * @uses ncore_noisette_stocker()
28 *
29 * @param string $plugin
30 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
31 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
32 * @param string $type_noisette
33 *        Identifiant du type de noisette à ajouter au squelette.
34 * @param array  $conteneur
35 *        Identifiant du conteneur accueillant la noisette qui prend soit la forme d'un tableau soit celui d'un id.
36 * @param int    $rang
37 *        Rang dans le conteneur où insérer la noisette. Si l'argument n'est pas fourni ou est égal à 0
38 *        on insère la noisette en fin de conteneur.
39 * @param string $stockage
40 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
41 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
42 *        fournissant le service de stockage souhaité.
43 *
44 * @return int|string|bool
45 *        Retourne l'identifiant de la nouvelle instance de noisette créée ou `false` en cas d'erreur.
46 **/
47function noisette_ajouter($plugin, $type_noisette, $conteneur, $rang = 0, $stockage = '') {
48
49        // Initialisation de la valeur de sortie.
50        $noisette_ajoutee = false;
51
52        if ($type_noisette) {
53                // On récupère les paramètres du type de noisette.
54                include_spip('inc/ncore_type_noisette');
55                $champs = type_noisette_lire(
56                        $plugin,
57                        $type_noisette,
58                        'parametres',
59                        false,
60                        $stockage
61                );
62
63                // Et on leur associe des valeurs par défaut.
64                include_spip('inc/saisies');
65                $parametres = saisies_lister_valeurs_defaut($champs);
66
67                // On charge les services de N-Core.
68                // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
69                include_spip('ncore/ncore');
70
71                // Suivant que le conteneur est passé au format tableau ou id on complète les deux identifiants
72                $id_conteneur = '';
73                if (is_array($conteneur)) {
74                        // -- Vérification des index du conteneur.
75                        $conteneur = ncore_conteneur_verifier($plugin, $conteneur, $stockage);
76                        // -- Calcul de l'id
77                        if ($conteneur) {
78                                $id_conteneur = ncore_conteneur_identifier($plugin, $conteneur, $stockage);
79                        }
80                } elseif (is_string($conteneur)) {
81                        $id_conteneur = $conteneur;
82                        $conteneur = ncore_conteneur_construire($plugin, $id_conteneur, $stockage);
83                }
84
85                // On initialise la description de la noisette à ajouter et en particulier on stocke le tableau et l'id du
86                // conteneur pour simplifier les traitements par la suite.
87                if ($id_conteneur) {
88                        // -- Initialisation par défaut
89                        $description = array(
90                                'plugin'        => $plugin,
91                                'type_noisette' => $type_noisette,
92                                'conteneur'     => serialize($conteneur),
93                                'id_conteneur'  => $id_conteneur,
94                                'rang_noisette' => intval($rang),
95                                'est_conteneur' => type_noisette_lire($plugin, $type_noisette, 'conteneur', false, $stockage),
96                                'parametres'    => serialize($parametres),
97                                'encapsulation' => 'defaut',
98                                'css'           => '',
99                                'profondeur'    => 0
100                        );
101                        // -- Pour les noisettes conteneur pas de capsule englobante.
102                        if ($description['est_conteneur'] == 'oui') {
103                                $description['encapsulation'] = 'non';
104                        }
105
106                        // -- Pour une noisette incluse dans un conteneur noisette on calcule la profondeur.
107                        if (ncore_conteneur_est_noisette($plugin, $conteneur, $stockage)) {
108                                $description_conteneur = ncore_noisette_decrire($plugin, $conteneur['id_noisette'], $stockage);
109                                $description['profondeur'] = $description_conteneur['profondeur'] + 1;
110                        }
111
112                        // Complément à la description par défaut, spécifique au plugin utilisateur, si nécessaire.
113                        $description = ncore_noisette_completer($plugin, $description, $stockage);
114
115                        // On récupère les noisettes déjà affectées au conteneur sous la forme d'un tableau indexé
116                        // par le rang de chaque noisette.
117                        $noisettes = ncore_noisette_lister($plugin, $id_conteneur, '', 'rang_noisette', $stockage);
118
119                        // On calcule le rang max déjà utilisé.
120                        $rang_max = $noisettes ? max(array_keys($noisettes)) : 0;
121
122                        if (!$rang or ($rang and ($rang > $rang_max))) {
123                                // Si, le rang est nul ou si il est strictement supérieur au rang_max, on positionne la noisette
124                                // à ajouter au rang max + 1.
125                                // En effet, si le rang est supérieur au rang max c'est que la nouvelle noisette est ajoutée
126                                // après les noisettes existantes, donc cela revient à insérer la noisette en fin de liste.
127                                // Postionner le rang à max + 1 permet d'éviter d'avoir des trous dans la liste des rangs.
128                                $description['rang_noisette'] = $rang_max + 1;
129                        } else {
130                                // Si le rang est non nul et inférieur ou égal au rang max c'est qu'on insère la noisette dans la liste
131                                // existante : il faut décaler d'un rang les noisettes de rang supérieur ou égal si elle existent pour
132                                // libérer la position de la nouvelle noisette.
133                                if ($rang <= $rang_max) {
134                                        krsort($noisettes);
135                                        foreach ($noisettes as $_rang => $_description) {
136                                                if ($_rang >= $rang) {
137                                                        ncore_noisette_ranger($plugin, $_description, $_rang + 1, $stockage);
138                                                }
139                                        }
140                                }
141                        }
142
143                        // La description de la nouvelle noisette est prête à être stockée à sa position.
144                        $noisette_ajoutee = ncore_noisette_stocker($plugin, $description, $stockage);
145                }
146        }
147
148        return $noisette_ajoutee;
149}
150
151/**
152 * Met à jour les paramètres éditables d'une noisette donnée.
153 * La fonction contrôle la liste des champs modifiables.
154 *
155 * @api
156 * @uses ncore_noisette_decrire()
157 * @uses ncore_noisette_stocker()
158 *
159 * @param string $plugin
160 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
161 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
162 * @param mixed  $noisette
163 *        Identifiant de la noisette qui peut prendre soit la forme d'un entier ou d'une chaine unique, soit la forme
164 *        d'un couple (id conteneur, rang).
165 * @param array  $modifications
166 *        Tableau des couples (champ, valeur) à mettre à jour pour la noisette spécifiée.
167 *        La fonction contrôle la liste des champs éditables en filtrant les champs standard comme `parametres`,
168 *        `balise`, `css` et éventuellement ceux spécifiquement définis par le plugin utilisateur dans
169 *        l'argument $editables_specifiques.
170 * @param array  $editables_specifiques
171 *        Liste de champs éditables spécifiques au plugin utilisateur ou tableau vide sinon. Le tableau possède deux
172 *        index, l'un pour les noisettes conteneur `conteneur`, l'autre pour les noisettes non conteneur `non_conteneur`.
173 * @param string $stockage
174 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
175 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
176 *        fournissant le service de stockage souhaité.
177 *
178 * @return bool
179 */
180function noisette_parametrer($plugin, $noisette, $modifications, $editables_specifiques = array(), $stockage = '') {
181
182        // Initialisation du retour
183        $noisette_parametree = false;
184
185        // On charge les services de N-Core.
186        // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
187        include_spip('ncore/ncore');
188
189        // L'identifiant d'une noisette peut être fourni de deux façons :
190        // - par une valeur unique, celle créée lors de l'ajout et qui peut-être un entier (id d'une table SPIP) ou
191        //   une chaine unique par exemple générée par uniqid().
192        // - ou par un tableau à deux entrées fournissant le conteneur et le rang dans le conteneur
193        //   (qui est unique pour un conteneur donné).
194        if (!empty($noisette) and (is_string($noisette) or is_numeric($noisette) or is_array($noisette))) {
195                // On récupère la description complète de la noisette avant de modifier les champs éditables spécifiés.
196                $description = ncore_noisette_decrire($plugin, $noisette, $stockage);
197
198                // On contrôle les champs éditables et on met à jour la description de la noisette.
199                // Pour une noisette conteneur les champs encapsulation et css ne sont pas éditables
200                if ($description['est_conteneur'] == 'oui') {
201                        $parametres = array_merge(
202                                array('parametres'),
203                                (isset($editables_specifiques['conteneur']) ? $editables_specifiques['conteneur'] : array())
204                        );
205                } else {
206                        $parametres = array_merge(
207                                array('parametres', 'encapsulation', 'css'),
208                                (isset($editables_specifiques['non_conteneur']) ? $editables_specifiques['non_conteneur'] : array())
209                        );
210                }
211                $modifications = array_intersect_key($modifications, array_flip($parametres));
212                $description = array_merge($description, $modifications);
213
214                // La description est prête à être stockée en remplacement de l'existante.
215                if (ncore_noisette_stocker($plugin, $description, $stockage)) {
216                        $noisette_parametree = true;
217                }
218        }
219
220        return $noisette_parametree;
221}
222
223/**
224 * Supprime une noisette donnée du conteneur auquel elle est associée et, si cette noisette est un conteneur,
225 * le vide de ses noisettes au préalable.
226 * La fonction met à jour les rangs des autres noisettes si nécessaire.
227 *
228 * @api
229 * @uses ncore_noisette_decrire()
230 * @uses ncore_noisette_destocker()
231 * @uses ncore_noisette_lister()
232 * @uses ncore_noisette_ranger()
233 *
234 * @param string $plugin
235 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
236 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
237 * @param mixed  $noisette
238 *        Identifiant de la noisette qui peut prendre soit la forme d'un entier ou d'une chaine unique, soit la forme
239 *        d'un couple (id conteneur, rang).
240 * @param string $stockage
241 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
242 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
243 *        fournissant le service de stockage souhaité.
244 *
245 * @return bool
246 */
247function noisette_supprimer($plugin, $noisette, $stockage = '') {
248
249        // Initialisation du retour
250        $noisette_supprimee = false;
251
252        // On charge les services de N-Core.
253        // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
254        include_spip('ncore/ncore');
255
256        // L'identifiant d'une noisette peut être fourni de deux façons :
257        // - par une valeur unique, celle créée lors de l'ajout et qui peut-être un entier (id d'une table SPIP) ou
258        //   une chaine unique par exemple générée par uniqid().
259        // - ou par un tableau à deux entrées fournissant le conteneur et le rang dans le conteneur
260        //   (qui est unique pour un conteneur donné).
261        if (!empty($noisette) and (is_string($noisette) or is_numeric($noisette) or is_array($noisette))) {
262                // Avant de supprimer la noisette on sauvegarde sa description.
263                // Cela permet de conserver le rang et l'id du conteneur indépendamment de l'identifiant
264                // utilisé pour spécifier la noisette.
265                $description = ncore_noisette_decrire($plugin, $noisette, $stockage);
266
267                // Si la noisette est de type conteneur, il faut d'abord vider le conteneur qu'elle représente
268                // et ce de façon récursive. La récursivité est gérée par la fonction de service ncore_conteneur_destocker().
269                $conteneur_destocke = true;
270                if ($description['est_conteneur'] == 'oui') {
271                        // Inutile de redéfinir un conteneur car la description de la noisette contient les deux champs
272                        // essentiels, à savoir, type_noisette et id_noisette.
273                        $conteneur_destocke = ncore_conteneur_destocker($plugin, $description, $stockage);
274                }
275
276                // Suppression de la noisette. On passe la description complète ce qui permet à la fonction de
277                // destockage de choisir la méthode d'identification la plus adaptée.
278                if ($conteneur_destocke and ncore_noisette_destocker($plugin, $description, $stockage)) {
279                        // On récupère les noisettes restant affectées au conteneur sous la forme d'un tableau indexé par rang.
280                        $autres_noisettes = ncore_noisette_lister(
281                                $plugin,
282                                $description['id_conteneur'],
283                                '',
284                                'rang_noisette',
285                                $stockage
286                        );
287
288                        // Si il reste des noisettes, on tasse d'un rang les noisettes qui suivaient la noisette supprimée.
289                        if ($autres_noisettes) {
290                                // On lit les noisettes restantes dans l'ordre décroissant pour éviter d'écraser une noisette.
291                                ksort($autres_noisettes);
292                                foreach ($autres_noisettes as $_rang => $_autre_description) {
293                                        if ($_rang > $description['rang_noisette']) {
294                                                ncore_noisette_ranger($plugin, $_autre_description, $_autre_description['rang_noisette'] - 1, $stockage);
295                                        }
296                                }
297                        }
298
299                        $noisette_supprimee = true;
300                }
301        }
302
303        return $noisette_supprimee;
304}
305
306/**
307 * Retourne, pour une noisette donnée, la description complète ou seulement un champ précis.
308 * Les champs textuels peuvent subir un traitement typo si demandé.
309 *
310 * @api
311 * @uses ncore_noisette_decrire()
312 *
313 * @param string  $plugin
314 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
315 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
316 * @param mixed   $noisette
317 *        Identifiant de la noisette qui peut prendre soit la forme d'un entier ou d'une chaine unique, soit la forme
318 *        d'un couple (id conteneur, rang).
319 * @param string  $information
320 *        Information spécifique à retourner ou vide pour retourner toute la description.
321 * @param boolean $traiter_typo
322 *        Indique si les données textuelles doivent être retournées brutes ou si elles doivent être traitées
323 *        en utilisant la fonction typo. Par défaut l'indicateur vaut `false`.
324 *        Les champs sérialisés sont eux toujours désérialisés.
325 *        Pour l'instant il n'y a pas de champ textuel directement associé à une noisette.
326 * @param string  $stockage
327 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
328 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
329 *        fournissant le service de stockage souhaité.
330 *
331 * @return array|string|int
332 *        La description complète ou champ précis demandé pour une noisette donnée. Les champs
333 *        de type tableau sont systématiquement désérialisés et si demandé, les champs textuels peuvent être
334 *        traités avec la fonction typo().
335 */
336function noisette_lire($plugin, $noisette, $information = '', $traiter_typo = false, $stockage = '') {
337
338        // On indexe le tableau des descriptions par le plugin appelant en cas d'appel sur le même hit
339        // par deux plugins différents.
340        // En outre, on gère un tableau par type d'identification, id noisette ou couple (id conteneur, rang).
341        static $description_noisette_par_id = array();
342        static $description_noisette_par_rang = array();
343
344        // Initialisation de la description en sortie.
345        $noisette_lue = array();
346
347        if (!empty($noisette) and (is_string($noisette) or is_numeric($noisette) or is_array($noisette))) {
348                // On charge les services de N-Core.
349                // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
350                include_spip('ncore/ncore');
351
352                // On vérifie si la noisette est valide et si la description n'a pas déjà été enregistrée dans le tableau adéquat.
353                $description_existe = false;
354                $noisette_invalide = false;
355                if (!is_array($noisette)) {
356                        $description_existe = isset($description_noisette_par_id[$plugin][$noisette]) ? true : false;
357                } elseif (isset($noisette['id_conteneur'], $noisette['rang_noisette'])) {
358                        $description_existe = isset($description_noisette_par_rang[$plugin][$noisette['id_conteneur']][$noisette['rang_noisette']])
359                                ? true
360                                : false;
361                } else {
362                        $noisette_invalide = true;
363                }
364
365                if (!$noisette_invalide) {
366                        if (!$description_existe) {
367                                // Lecture de toute la configuration de la noisette: les données retournées sont brutes.
368                                $description = ncore_noisette_decrire($plugin, $noisette, $stockage);
369
370                                // Traitements des champs tableaux sérialisés si nécessaire
371                                if ($description) {
372                                        if (isset($description['parametres']) and is_string($description['parametres'])) {
373                                                $description['parametres'] = unserialize($description['parametres']);
374                                        }
375                                        if (isset($description['conteneur']) and is_string($description['conteneur'])) {
376                                                $description['conteneur'] = unserialize($description['conteneur']);
377                                        }
378                                }
379
380                                // Sauvegarde de la description de la noisette pour une consultation ultérieure dans le même hit
381                                // en suivant le type d'identification.
382                                if (!is_array($noisette)) {
383                                        $description_noisette_par_id[$plugin][$noisette] = $description;
384                                } else {
385                                        $description_noisette_par_rang[$plugin][$noisette['id_conteneur']][$noisette['rang_noisette']] = $description;
386                                }
387                        }
388
389                        if ($information) {
390                                if ((!is_array($noisette) and isset($description_noisette_par_id[$plugin][$noisette][$information]))
391                                        or (is_array($noisette)
392                                                and isset($description_noisette_par_rang[$plugin][$noisette['id_conteneur']][$noisette['rang_noisette']][$information]))) {
393                                        $noisette_lue = is_array($noisette)
394                                                ? $description_noisette_par_rang[$plugin][$noisette['id_conteneur']][$noisette['rang_noisette']][$information]
395                                                : $description_noisette_par_id[$plugin][$noisette][$information];
396                                } else {
397                                        $noisette_lue = '';
398                                }
399                        } else {
400                                $noisette_lue = is_array($noisette)
401                                        ? $description_noisette_par_rang[$plugin][$noisette['id_conteneur']][$noisette['rang_noisette']]
402                                        : $description_noisette_par_id[$plugin][$noisette];
403                        }
404                }
405        }
406
407        return $noisette_lue;
408}
409
410/**
411 * Déplace une noisette donnée au sein d’un même conteneur ou dans un autre conteneur.
412 * La fonction met à jour les rangs des autres noisettes si nécessaire.
413 *
414 * @api
415 *
416 * @uses ncore_noisette_decrire()
417 * @uses ncore_conteneur_verifier()
418 * @uses ncore_conteneur_identifier()
419 * @uses ncore_noisette_lister()
420 * @uses ncore_conteneur_construire()
421 * @uses ncore_conteneur_est_noisette()
422 * @uses ncore_noisette_changer_conteneur()
423 * @uses ncore_noisette_ranger()
424 *
425 * @param string       $plugin
426 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
427 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
428 * @param mixed        $noisette
429 *        Identifiant de la noisette qui peut prendre soit la forme d'un entier ou d'une chaine unique, soit la forme
430 *        d'un couple (id conteneur, rang).
431 * @param array|string $conteneur_destination
432 *        Identifiant du conteneur destination qui prend soit la forme d'un tableau soit celui d'un id.
433 * @param int          $rang_destination
434 *        Entier représentant le rang où repositionner la noisette dans le squelette contextualisé.
435 * @param string       $stockage
436 *        Identifiant du service de stockage à utiliser si précisé.
437 *
438 * @return bool
439 *         Renvoie `false` si la noisette n'est pas déplacée à cause d'une erreur de traitement ou parce que le
440 *         rang destination est identique au rang origine, sinon `true`.
441 */
442function noisette_deplacer($plugin, $noisette, $conteneur_destination, $rang_destination, $stockage = '') {
443
444        // Initialisation du retour
445        $noisette_deplacee = false;
446
447        // On charge les services de N-Core.
448        // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
449        include_spip('ncore/ncore');
450
451        // L'identifiant d'une noisette peut être fourni de deux façons :
452        // - par une valeur unique, celle créée lors de l'ajout et qui peut-être un entier (id d'une table SPIP) ou
453        //   une chaine unique par exemple générée par uniqid().
454        // - ou par un tableau à deux entrées fournissant le conteneur et le rang
455        //   (qui est unique pour un conteneur donné).
456        if (!empty($noisette) and (is_string($noisette) or is_numeric($noisette) or is_array($noisette))) {
457                // Avant de déplacer la noisette on sauvegarde sa description, son id conteneur et son rang.
458                $description = ncore_noisette_decrire($plugin, $noisette, $stockage);
459                $id_conteneur_origine = $description['id_conteneur'];
460                $rang_origine = $description['rang_noisette'];
461
462                // On détermine l'id du conteneur destination en fonction du mode d'identification fourni par l'argument.
463                $id_conteneur_destination = '';
464                if (is_array($conteneur_destination)) {
465                        // -- Vérification des index du conteneur.
466                        $conteneur_destination = ncore_conteneur_verifier($plugin, $conteneur_destination, $stockage);
467                        // -- Calcul de l'id
468                        if ($conteneur_destination) {
469                                $id_conteneur_destination = ncore_conteneur_identifier(
470                                        $plugin,
471                                        $conteneur_destination,
472                                        $stockage
473                                );
474                        }
475                } elseif (is_string($conteneur_destination)) {
476                        $id_conteneur_destination = $conteneur_destination;
477                }
478
479                // Si le conteneur destination est différent du conteneur origine, la première opération consiste à
480                // transférer la noisette en fin du conteneur destination, ce qui est toujours possible.
481                // Ensuite on tasse le conteneur d'origine.
482                if ($id_conteneur_destination) {
483                        if ($id_conteneur_destination != $id_conteneur_origine) {
484                                // On recherche le dernier rang utilisé dans le conteneur destination et on se positionne après.
485                                $rangs = ncore_noisette_lister(
486                                        $plugin,
487                                        $id_conteneur_destination,
488                                        'rang_noisette',
489                                        'id_noisette',
490                                        $stockage
491                                );
492                                $rang_conteneur_destination = $rangs ? max($rangs) + 1 : 1;
493
494                                // Pour éviter que chaque plugin ait à gérer la profondeur, N-Core calcule la profondeur de la noisette à son
495                                // nouvel emplacement avant de déplacer celle-ci et la fournit à la fonction de changement de conteneur.
496                                if (!is_array($conteneur_destination)) {
497                                        $conteneur_destination = ncore_conteneur_construire($plugin, $id_conteneur_destination, $stockage);
498                                }
499                                if (ncore_conteneur_est_noisette($plugin, $conteneur_destination, $stockage)) {
500                                        $description_conteneur = ncore_noisette_decrire($plugin, $conteneur_destination['id_noisette'], $stockage);
501                                        $profondeur_destination = $description_conteneur['profondeur'] + 1;
502                                } else {
503                                        $profondeur_destination = 0;
504                                }
505
506                                // On transfère la noisette vers le conteneur destination à la position calculée (max + 1).
507                                $description = ncore_noisette_changer_conteneur(
508                                        $plugin,
509                                        $description,
510                                        $id_conteneur_destination,
511                                        $rang_conteneur_destination,
512                                        $profondeur_destination,
513                                        $stockage
514                                );
515
516                                // Il faut maintenant tasser les noisettes du conteneur d'origine qui a perdu une noisette.
517                                // -- On récupère les noisettes restant affectées au conteneur origine sous la forme d'un tableau
518                                //    indexé par rang.
519                                $autres_noisettes = ncore_noisette_lister(
520                                        $plugin,
521                                        $id_conteneur_origine,
522                                        '',
523                                        'rang_noisette',
524                                        $stockage
525                                );
526
527                                // Si il reste des noisettes, on tasse d'un rang les noisettes qui suivaient la noisette supprimée.
528                                if ($autres_noisettes) {
529                                        // On lit les noisettes restantes dans l'ordre décroissant pour éviter d'écraser une noisette.
530                                        ksort($autres_noisettes);
531                                        foreach ($autres_noisettes as $_rang => $_autre_description) {
532                                                if ($_rang > $rang_origine) {
533                                                        ncore_noisette_ranger($plugin, $_autre_description, $_autre_description['rang_noisette'] - 1, $stockage);
534                                                }
535                                        }
536                                }
537
538                                // Le rang origine devient donc le nouveau rang de la noisette dans le conteneur destination.
539                                $rang_origine = $description['rang_noisette'];
540                        }
541
542                        // A partir de là, le déplacement est un déplacement à l'intérieur d'un conteneur.
543                        // Si les rangs origine et destination sont identiques on ne fait rien !
544                        if ($rang_destination != $rang_origine) {
545                                // On récupère les noisettes affectées au même conteneur sous la forme d'un tableau indexé par le rang.
546                                $noisettes = ncore_noisette_lister(
547                                        $plugin,
548                                        $description['id_conteneur'],
549                                        '',
550                                        'rang_noisette',
551                                        $stockage
552                                );
553
554                                // On vérifie que le rang destination est bien compris entre 1 et le rang max, sinon on le force à l'une
555                                // des bornes.
556                                $rang_destination = max(1, $rang_destination);
557                                $rang_max = $noisettes ? max(array_keys($noisettes)) : 0;
558                                $rang_destination = min($rang_max, $rang_destination);
559
560                                // Suivant la position d'origine et de destination de la noisette déplacée on trie les noisettes
561                                // du conteneur.
562                                if ($rang_destination < $rang_origine) {
563                                        krsort($noisettes);
564                                } else {
565                                        ksort($noisettes);
566                                }
567
568                                // On déplace les noisettes impactées à l'exception de la noisette concernée par le déplacement
569                                // afin de créer une position libre.
570                                foreach ($noisettes as $_rang => $_description) {
571                                        if ($rang_destination < $rang_origine) {
572                                                // On "descend" les noisettes du rang destination au rang origine non compris.
573                                                if (($_rang >= $rang_destination) and ($_rang < $rang_origine)) {
574                                                        ncore_noisette_ranger($plugin, $_description, $_rang + 1, $stockage);
575                                                }
576                                        } else {
577                                                // On "remonte" les noisettes du rang destination au rang origine non compris.
578                                                if (($_rang <= $rang_destination) and ($_rang > $rang_origine)) {
579                                                        ncore_noisette_ranger($plugin, $_description, $_rang - 1, $stockage);
580                                                }
581                                        }
582                                }
583
584                                // On positionne le rang de la noisette à déplacer au rang destination.
585                                // On met le rang à zéro pour indiquer que l'emplacement d'origine n'est plus occupé par la
586                                // noisette et qu'il ne faut pas le supprimer lors du rangement.
587                                $description['rang_noisette'] = 0;
588                                if (ncore_noisette_ranger($plugin, $description, $rang_destination, $stockage)) {
589                                        $noisette_deplacee = true;
590                                }
591                        }
592                }
593        }
594
595        return $noisette_deplacee;
596}
597
598/**
599 * Duplique une noisette donnée dans un conteneur destination et, si cette noisette est un conteneur, duplique aussi
600 * les noisettes contenues de façon récursive.
601 *
602 * @api
603 * @uses ncore_noisette_decrire()
604 * @uses noisette_ajouter()
605 * @uses noisette_parametrer()
606 * @uses ncore_noisette_lister()
607 * @uses noisette_dupliquer()
608 *
609 * @param string       $plugin
610 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
611 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
612 * @param mixed        $noisette
613 *        Identifiant de la noisette qui peut prendre soit la forme d'un entier ou d'une chaine unique, soit la forme
614 *        d'un couple (id conteneur, rang).
615 * @param array|string $conteneur
616 *        Identifiant du conteneur destination qui prend soit la forme d'un tableau soit celui d'un id.
617 * @param int    $rang
618 *        Rang dans le conteneur destination où insérer la noisette dupliquée. Si l'argument n'est pas fourni ou
619 *        est égal à 0 on insère la noisette en fin de conteneur.
620 * @param array        $parametrage
621 *        Tableau indiquant les champs éditables de la noisette source à copier dans la noisette dupliquée.
622 * @param string       $stockage
623 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
624 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
625 *        fournissant le service de stockage souhaité.
626 *
627 * @return bool
628 */
629function noisette_dupliquer($plugin, $noisette, $conteneur, $rang = 0, $parametrage = array(), $stockage = '') {
630
631        // Initialisation du retour
632        $noisette_dupliquee = false;
633
634        // On charge les services de N-Core.
635        // Ce sont ces fonctions qui aiguillent ou pas vers un service spécifique du plugin.
636        include_spip('ncore/ncore');
637
638        // L'identifiant d'une noisette peut être fourni de deux façons :
639        // - par une valeur unique, celle créée lors de l'ajout et qui peut-être un entier (id d'une table SPIP) ou
640        //   une chaine unique par exemple générée par uniqid().
641        // - ou par un tableau à deux entrées fournissant le conteneur et le rang dans le conteneur
642        //   (qui est unique pour un conteneur donné).
643        if (!empty($noisette) and (is_string($noisette) or is_numeric($noisette) or is_array($noisette))) {
644                // Avant de dupliquer la noisette on sauvegarde sa description car il faudra utiliser ses paramètres
645                // d'affichage, d'encapsulation et de style pour la duplication.
646                $description = ncore_noisette_decrire($plugin, $noisette, $stockage);
647
648                // On ajoute la noisette à la fin du conteneur destination : la noisette est créée par défaut.
649                if ($id_noisette = noisette_ajouter($plugin, $description['type_noisette'], $conteneur, $rang, $stockage)) {
650                        // Suivant le paramétrage demandé on copie les champs idoines de la noisette source.
651                        if ($parametrage) {
652                                $modifications = array();
653                                foreach ($parametrage as $_champ) {
654                                        if (($description['est_conteneur'] == 'non')
655                                        or (($description['est_conteneur'] == 'oui') and (($_champ == 'encapsulation') or ($_champ == 'css')))) {
656                                                $modifications[$_champ] = $description[$_champ];
657                                        }
658                                }
659
660                                if ($modifications) {
661                                        noisette_parametrer($plugin, $id_noisette, $modifications, array(), $stockage);
662                                }
663                        }
664
665                        // Si la noisette est de type conteneur, il faut aussi dupliquer les noisettes éventuellement contenues
666                        // et ce de façon récursive.
667                        if ($description['est_conteneur'] == 'oui') {
668                                // On récupère les noisettes incluses dans la noisette origine qui est un conteneur.
669                                $autres_noisettes = ncore_noisette_lister(
670                                        $plugin,
671                                        array('type_noisette' => $description['type_noisette'], 'id_noisette' => $description['id_noisette']),
672                                        '',
673                                        'rang_noisette',
674                                        $stockage
675                                );
676
677                                // Si il reste des noisettes, on tasse d'un rang les noisettes qui suivaient la noisette supprimée.
678                                if ($autres_noisettes) {
679                                        // On calcule l'id conteneur de la noisette conteneur venant d'être dupliquée pour y dupliquer les
680                                        // noisettes incluses.
681                                        $conteneur_noisette_dupliquee = array(
682                                                'type_noisette' => $description['type_noisette'],
683                                                'id_noisette' => $id_noisette
684                                        );
685
686                                        // On lit les noisettes incluses et on appelle la fonction dupliquer récursivement.
687                                        ksort($autres_noisettes);
688                                        foreach ($autres_noisettes as $_rang => $_autre_description) {
689                                                noisette_dupliquer(
690                                                        $plugin,
691                                                        $_autre_description['id_noisette'],
692                                                        $conteneur_noisette_dupliquee,
693                                                        $parametrage,
694                                                        $stockage
695                                                );
696                                        }
697                                }
698                        }
699
700                        $noisette_dupliquee = true;
701                }
702        }
703
704        return $noisette_dupliquee;
705}
Note: See TracBrowser for help on using the repository browser.