1 | <?php |
---|
2 | /** |
---|
3 | * Fonctions utiles pour le Porte Plume |
---|
4 | * |
---|
5 | * @plugin Porte Plume pour SPIP |
---|
6 | * @license GPL |
---|
7 | * @package SPIP\PortePlume\BarreOutils |
---|
8 | */ |
---|
9 | |
---|
10 | if (!defined("_ECRIRE_INC_VERSION")) return; |
---|
11 | |
---|
12 | /** |
---|
13 | * Objet contenant les différents paramètres definissant une barre d'outils |
---|
14 | * Markitup et permettant d'agir dessus |
---|
15 | * |
---|
16 | * @example |
---|
17 | * $barre = new Barre_Outil($description); |
---|
18 | * |
---|
19 | * @package SPIP\PortePlume\BarreOutils |
---|
20 | */ |
---|
21 | class Barre_outils{ |
---|
22 | /** |
---|
23 | * Identifiant HTML de la barre |
---|
24 | * @todo À supprimer car non utilisé ! |
---|
25 | * @var string */ |
---|
26 | public $id = ""; |
---|
27 | |
---|
28 | /** |
---|
29 | * Nom de la barre d'outil |
---|
30 | * @var string */ |
---|
31 | public $nameSpace = ""; |
---|
32 | |
---|
33 | /** |
---|
34 | * Langue |
---|
35 | * @todo À supprimer car non utilisé ! |
---|
36 | * @var string */ |
---|
37 | public $lang = ""; |
---|
38 | |
---|
39 | /** |
---|
40 | * Option de markitup : rafraîchir la prévisu ? |
---|
41 | * @todo À supprimer car non utilisé ! |
---|
42 | * @var bool */ |
---|
43 | public $previewAutoRefresh = false; |
---|
44 | |
---|
45 | /** |
---|
46 | * Option de markitup : nom de la fonction de prévisu |
---|
47 | * @todo À supprimer car on le redéfini dans l'appel javascript ! |
---|
48 | * @var bool */ |
---|
49 | public $previewParserPath = ""; |
---|
50 | |
---|
51 | /** |
---|
52 | * Option de markitup : que faire sur l'appuie de Entrée ? |
---|
53 | * @var array */ |
---|
54 | public $onEnter = array(); |
---|
55 | |
---|
56 | /** |
---|
57 | * Option de markitup : que faire sur l'appuie de Shift+Entrée ? |
---|
58 | * @example array('keepDefault'=>false, 'replaceWith'=>"\n_ ") |
---|
59 | * @var array */ |
---|
60 | public $onShiftEnter = array(); |
---|
61 | |
---|
62 | /** |
---|
63 | * Option de markitup : que faire sur l'appuie de Control+Entrée ? |
---|
64 | * @var array */ |
---|
65 | public $onCtrlEnter = array(); |
---|
66 | |
---|
67 | /** |
---|
68 | * Option de markitup : que faire sur l'appuie d'une tabulation ? |
---|
69 | * @var array */ |
---|
70 | public $onTab = array(); |
---|
71 | |
---|
72 | /** |
---|
73 | * Option de markitup : Code JS à exécuter avant une insertion |
---|
74 | * @var string */ |
---|
75 | public $beforeInsert = ""; |
---|
76 | |
---|
77 | /** |
---|
78 | * Option de markitup : Code JS à exécuter après une insertion |
---|
79 | * @var string */ |
---|
80 | public $afterInsert = ""; |
---|
81 | |
---|
82 | /** |
---|
83 | * Description des outils/boutons et leurs sous boutons éventuels |
---|
84 | * @var array */ |
---|
85 | public $markupSet = array(); |
---|
86 | |
---|
87 | /** |
---|
88 | * Fonctions JS supplémentaires à écrire après la déclaration JSON |
---|
89 | * des outils. Ces fonctions peuvent servir aux boutons. |
---|
90 | * @var string */ |
---|
91 | public $functions = ""; |
---|
92 | |
---|
93 | /** |
---|
94 | * Liste des paramètres valides pour une description d'outils (markupSet) |
---|
95 | * @var array */ |
---|
96 | private $_liste_params_autorises = array( |
---|
97 | |
---|
98 | 'replaceWith', |
---|
99 | 'openWith', |
---|
100 | 'closeWith', |
---|
101 | 'openBlockWith', // sur multiline, avant les lignes selectionnees |
---|
102 | 'closeBlockWith', // sur multiline, apres les lignes selectionnees |
---|
103 | 'placeHolder', // remplace par ce texte lorsqu'il n'y a pas de selection |
---|
104 | |
---|
105 | 'beforeInsert', // avant l'insertion |
---|
106 | 'afterInsert', // apres l'insertion |
---|
107 | 'beforeMultiInsert', |
---|
108 | 'afterMultiInsert', |
---|
109 | |
---|
110 | 'dropMenu', // appelle un sous menu |
---|
111 | |
---|
112 | 'name', // nom affiche au survol |
---|
113 | 'key', // raccourcis clavier |
---|
114 | 'className', // classe css utilisee |
---|
115 | 'lang', // langues dont le bouton doit apparaitre - array |
---|
116 | 'lang_not', // langues dont le bouton ne doit pas apparaitre - array |
---|
117 | 'selectionType', // '','word','line' : type de selection (normale, aux mots les plus proches, a la ligne la plus proche) |
---|
118 | 'multiline', // open/close sur chaque ligne (mais replace est applique sur l'ensemble de la selection) |
---|
119 | 'forceMultiline', // pour faire comme si on faisait systematiquement un control+shift (et replace est applique sur chaque ligne de la selection) |
---|
120 | |
---|
121 | 'separator', |
---|
122 | |
---|
123 | 'call', |
---|
124 | 'keepDefault', |
---|
125 | |
---|
126 | // cacher ou afficher facilement des boutons |
---|
127 | 'display', |
---|
128 | // donner un identifiant unique au bouton (pour le php) |
---|
129 | 'id', |
---|
130 | ); |
---|
131 | |
---|
132 | /** |
---|
133 | * Constructeur |
---|
134 | * |
---|
135 | * Initialise la barre avec les paramètres transmis |
---|
136 | * en n'adressant que les paramètres effectivement valides |
---|
137 | * |
---|
138 | * @api |
---|
139 | * @param array $params Paramètres de la barre d'outil |
---|
140 | * @return void |
---|
141 | */ |
---|
142 | function __construct($params = array()){ |
---|
143 | foreach ($params as $p=>$v) { |
---|
144 | if (isset($this->$p)) { |
---|
145 | // si tableau, on verifie les entrees |
---|
146 | if (is_array($v)) { |
---|
147 | $v = $this->verif_params($p,$v); |
---|
148 | } |
---|
149 | $this->$p = $v; |
---|
150 | } |
---|
151 | } |
---|
152 | } |
---|
153 | |
---|
154 | |
---|
155 | /** |
---|
156 | * Vérifie que les paramètres d'une clé existent |
---|
157 | * et retourne un tableau des paramètres valides |
---|
158 | * |
---|
159 | * @param string $nom |
---|
160 | * Clé à vérifier (ex: 'markupSet') |
---|
161 | * @param array $params |
---|
162 | * Paramètres de cette clé (description des boutons ou sous boutons) |
---|
163 | * @return array |
---|
164 | * Paramètres, soustrait de ceux qui ne sont pas valides |
---|
165 | */ |
---|
166 | function verif_params($nom, $params = array()) { |
---|
167 | // si markupset, on boucle sur les items |
---|
168 | if (stripos($nom, 'markupSet')!==false) { |
---|
169 | foreach ($params as $i=>$v) { |
---|
170 | $params[$i] = $this->verif_params($i, $v); |
---|
171 | } |
---|
172 | } |
---|
173 | // sinon on teste la validite |
---|
174 | else { |
---|
175 | foreach ($params as $p=>$v) { |
---|
176 | if (!in_array($p, $this->_liste_params_autorises)) { |
---|
177 | unset($params[$p]); |
---|
178 | } |
---|
179 | } |
---|
180 | } |
---|
181 | return $params; |
---|
182 | } |
---|
183 | |
---|
184 | /** |
---|
185 | * Permet d'affecter des paramètres à un élément de la barre |
---|
186 | * |
---|
187 | * La fonction retourne les paramètres, de sorte qu'on peut s'en servir |
---|
188 | * pour simplement récupérer ceux-ci. |
---|
189 | * |
---|
190 | * Il est possible d'affecter des paramètres avant/après l'élément trouvé |
---|
191 | * en definisant une valeur différente pour le $lieu : 'dedans','avant','apres' |
---|
192 | * par defaut 'dedans' (modifie l'élément trouvé). |
---|
193 | * |
---|
194 | * Lorsqu'on demande d'insérer avant ou après, la fonction retourne |
---|
195 | * les paramètres inserés |
---|
196 | * |
---|
197 | * @param array $tableau |
---|
198 | * Tableau ou chercher les elements (sert pour la recursion) |
---|
199 | * @param string $identifiant |
---|
200 | * Identifiant du bouton a afficher |
---|
201 | * @param array $params |
---|
202 | * Paramètres à affecter à la trouvaille (ou avant ou après). |
---|
203 | * Peut être un tableau clé/valeur ou un tableau de tableaux |
---|
204 | * clé/valeur (sauf pour $lieu = dedans) |
---|
205 | * @param string $lieu |
---|
206 | * Lieu d'affectation des paramètres (dedans, avant, apres) |
---|
207 | * @param bool $plusieurs |
---|
208 | * Définit si $params est une forme simple (tableau cle/valeur) |
---|
209 | * ou comporte plusieurs boutons (tableau de tableaux cle/valeur). |
---|
210 | * @return array|bool |
---|
211 | * Paramètres de l'élément modifié ou paramètres ajoutés |
---|
212 | * False si l'identifiant cherché n'est pas trouvé |
---|
213 | */ |
---|
214 | function affecter(&$tableau, $identifiant, $params = array(), $lieu = 'dedans', $plusieurs = false){ |
---|
215 | static $cle_de_recherche = 'id'; // ou className ? |
---|
216 | |
---|
217 | if ($tableau === null) // utile ? |
---|
218 | $tableau = &$this->markupSet; |
---|
219 | |
---|
220 | if (!in_array($lieu, array('dedans','avant','apres'))) |
---|
221 | $lieu = 'dedans'; |
---|
222 | |
---|
223 | // present en premiere ligne ? |
---|
224 | $trouve = false; |
---|
225 | foreach ($tableau as $i => $v){ |
---|
226 | if (isset($v[$cle_de_recherche]) and ($v[$cle_de_recherche] == $identifiant)) { |
---|
227 | $trouve = $i; |
---|
228 | break; |
---|
229 | } |
---|
230 | } |
---|
231 | // si trouve, affectations |
---|
232 | if (($trouve !== false)) { |
---|
233 | if ($params) { |
---|
234 | // verifier que les insertions sont correctes |
---|
235 | $les_params = ($plusieurs ? $params : array($params)); |
---|
236 | foreach ($les_params as $i=>$un_params) { |
---|
237 | $les_params[$i] = $this->verif_params($identifiant, $un_params); |
---|
238 | } |
---|
239 | |
---|
240 | // dedans on merge ($params uniquement tableau cle/valeur) |
---|
241 | if ($lieu == 'dedans' && !$plusieurs) { |
---|
242 | return $tableau[$trouve] = array_merge($tableau[$trouve], $les_params[0]); |
---|
243 | } |
---|
244 | // avant ou apres, on insere ($params peut etre tableau cle/valeur ou tableau de tableaux cle/valeur) |
---|
245 | elseif ($lieu == 'avant') { |
---|
246 | array_splice($tableau, $trouve, 0, $les_params); |
---|
247 | return $params; |
---|
248 | } |
---|
249 | elseif ($lieu == 'apres') { |
---|
250 | array_splice($tableau, $trouve+1, 0, $les_params); |
---|
251 | return $params; |
---|
252 | } |
---|
253 | } |
---|
254 | return $tableau[$trouve]; |
---|
255 | } |
---|
256 | |
---|
257 | // recursivons sinon ! |
---|
258 | foreach ($tableau as $i => $v){ |
---|
259 | if (is_array($v)) { |
---|
260 | foreach ($v as $m => $n) { |
---|
261 | if (is_array($n) AND ($r = $this->affecter($tableau[$i][$m], $identifiant, $params, $lieu, $plusieurs))) |
---|
262 | return $r; |
---|
263 | } |
---|
264 | } |
---|
265 | } |
---|
266 | return false; |
---|
267 | } |
---|
268 | |
---|
269 | |
---|
270 | /** |
---|
271 | * Permet d'affecter des paramètres à tous les éléments de la barre |
---|
272 | * ou à une liste d'identifiants d'éléments indiqués. |
---|
273 | * |
---|
274 | * @param array $tableau |
---|
275 | * Tableau où chercher les éléments |
---|
276 | * @param array $params |
---|
277 | * Paramètres à affecter aux éléments |
---|
278 | * @param array $ids |
---|
279 | * Tableau d'identifiants particuliers à qui on affecte les paramètres. |
---|
280 | * Si vide, tous les identifiants seront modifiés |
---|
281 | * @return bool |
---|
282 | * false si aucun paramètre à affecter, true sinon. |
---|
283 | */ |
---|
284 | function affecter_a_tous(&$tableau, $params = array(), $ids = array()){ |
---|
285 | if (!$params) |
---|
286 | return false; |
---|
287 | |
---|
288 | if ($tableau === null) |
---|
289 | $tableau = &$this->markupSet; |
---|
290 | |
---|
291 | $params = $this->verif_params('divers', $params); |
---|
292 | |
---|
293 | // merge de premiere ligne |
---|
294 | foreach ($tableau as $i => &$v){ |
---|
295 | if (!$ids OR in_array($v['id'], $ids)) { |
---|
296 | $tableau[$i] = array_merge($tableau[$i], $params); |
---|
297 | } |
---|
298 | // recursion si sous-menu |
---|
299 | if (isset($tableau[$i]['dropMenu'])) { |
---|
300 | $this->affecter_a_tous($tableau[$i]['dropMenu'], $params, $ids); |
---|
301 | } |
---|
302 | } |
---|
303 | return true; |
---|
304 | } |
---|
305 | |
---|
306 | |
---|
307 | /** |
---|
308 | * Affecte les valeurs des paramètres indiqués au bouton demandé |
---|
309 | * et retourne l'ensemble des paramètres du bouton (sinon false) |
---|
310 | * |
---|
311 | * @api |
---|
312 | * @param string|array $identifiant |
---|
313 | * Identifiant du ou des boutons. |
---|
314 | * @param array $params |
---|
315 | * Paramètres de l'ajout (tableau paramètre=>valeur) |
---|
316 | * @return bool|array |
---|
317 | * false si l'identifiant n'a pas été trouvé |
---|
318 | * true si plusieurs identifiants, |
---|
319 | * array sinon : description de l'identifiant cherché. |
---|
320 | */ |
---|
321 | function set($identifiant, $params = array()) { |
---|
322 | // prudence tout de meme a pas tout modifier involontairement (si array) |
---|
323 | if (!$identifiant) return false; |
---|
324 | |
---|
325 | if (is_string($identifiant)) { |
---|
326 | return $this->affecter($this->markupSet, $identifiant, $params); |
---|
327 | } |
---|
328 | elseif (is_array($identifiant)) { |
---|
329 | return $this->affecter_a_tous($this->markupSet, $params, $identifiant); |
---|
330 | } |
---|
331 | return false; |
---|
332 | } |
---|
333 | |
---|
334 | /** |
---|
335 | * Retourne les parametres du bouton demande |
---|
336 | * |
---|
337 | * @api |
---|
338 | * @param string|array $identifiant |
---|
339 | * Identifiant du ou des boutons. |
---|
340 | * @return bool|array |
---|
341 | * false si l'identifiant n'est pas trouvé |
---|
342 | * array sinon : Description de l'identifiant cherché. |
---|
343 | */ |
---|
344 | function get($identifiant) { |
---|
345 | if ($a = $this->affecter($this->markupSet, $identifiant)) { |
---|
346 | return $a; |
---|
347 | } |
---|
348 | return false; |
---|
349 | } |
---|
350 | |
---|
351 | |
---|
352 | /** |
---|
353 | * Affiche le ou les boutons demandés |
---|
354 | * |
---|
355 | * @api |
---|
356 | * @param string|array $identifiant |
---|
357 | * Identifiant du ou des boutons |
---|
358 | * @return bool|array |
---|
359 | * false si l'identifiant n'a pas été trouvé |
---|
360 | * true si plusieurs identifiants, |
---|
361 | * array sinon : description de l'identifiant cherché. |
---|
362 | */ |
---|
363 | function afficher($identifiant){ |
---|
364 | return $this->set($identifiant,array('display'=>true)); |
---|
365 | } |
---|
366 | |
---|
367 | |
---|
368 | /** |
---|
369 | * Cache le ou les boutons demandés |
---|
370 | * |
---|
371 | * @api |
---|
372 | * @param string|array $identifiant |
---|
373 | * Identifiant du ou des boutons |
---|
374 | * @return bool|array |
---|
375 | * false si l'identifiant n'a pas été trouvé |
---|
376 | * true si plusieurs identifiants, |
---|
377 | * array sinon : description de l'identifiant cherché. |
---|
378 | */ |
---|
379 | function cacher($identifiant){ |
---|
380 | return $this->set($identifiant, array('display'=>false)); |
---|
381 | } |
---|
382 | |
---|
383 | |
---|
384 | /** |
---|
385 | * Affiche tous les boutons |
---|
386 | * |
---|
387 | * @api |
---|
388 | * @return bool |
---|
389 | * false si aucun paramètre à affecter, true sinon. |
---|
390 | */ |
---|
391 | function afficherTout(){ |
---|
392 | return $this->affecter_a_tous($this->markupSet, array('display'=>true)); |
---|
393 | } |
---|
394 | |
---|
395 | /** |
---|
396 | * Cache tous les boutons |
---|
397 | * |
---|
398 | * @api |
---|
399 | * @return bool |
---|
400 | * false si aucun paramètre à affecter, true sinon. |
---|
401 | */ |
---|
402 | function cacherTout(){ |
---|
403 | return $this->affecter_a_tous($this->markupSet, array('display'=>false)); |
---|
404 | } |
---|
405 | |
---|
406 | |
---|
407 | /** |
---|
408 | * Ajoute un bouton ou quelque chose, avant un autre déjà présent |
---|
409 | * |
---|
410 | * @api |
---|
411 | * @param string $identifiant |
---|
412 | * Identifiant du bouton où l'on doit se situer |
---|
413 | * @param array $params |
---|
414 | * Paramètres de l'ajout. |
---|
415 | * Description d'un bouton (tableau clé/valeurs). |
---|
416 | * @return array|bool |
---|
417 | * Paramètres ajoutés avant |
---|
418 | * False si l'identifiant cherché n'est pas trouvé |
---|
419 | */ |
---|
420 | function ajouterAvant($identifiant, $params){ |
---|
421 | return $this->affecter($this->markupSet, $identifiant, $params, 'avant'); |
---|
422 | } |
---|
423 | |
---|
424 | /** |
---|
425 | * Ajoute plusieurs boutons, avant un autre déjà présent |
---|
426 | * |
---|
427 | * @api |
---|
428 | * @param string $identifiant |
---|
429 | * Identifiant du bouton où l'on doit se situer |
---|
430 | * @param array $tableau_params |
---|
431 | * Paramètres de l'ajout. |
---|
432 | * Description de plusieurs boutons (tableau de tableaux clé/valeurs). |
---|
433 | * @return array|bool |
---|
434 | * Paramètres ajoutés avant |
---|
435 | * False si l'identifiant cherché n'est pas trouvé |
---|
436 | */ |
---|
437 | function ajouterPlusieursAvant($identifiant, $tableau_params){ |
---|
438 | return $this->affecter($this->markupSet, $identifiant, $tableau_params, 'avant', true); |
---|
439 | } |
---|
440 | |
---|
441 | /** |
---|
442 | * Ajoute un bouton ou quelque chose, après un autre déjà présent |
---|
443 | * |
---|
444 | * @api |
---|
445 | * @param string $identifiant |
---|
446 | * Identifiant du bouton où l'on doit se situer |
---|
447 | * @param array $params |
---|
448 | * Paramètres de l'ajout. |
---|
449 | * Description d'un bouton (tableau clé/valeurs). |
---|
450 | * @return array|bool |
---|
451 | * Paramètres ajoutés après |
---|
452 | * False si l'identifiant cherché n'est pas trouvé |
---|
453 | */ |
---|
454 | function ajouterApres($identifiant, $params){ |
---|
455 | return $this->affecter($this->markupSet, $identifiant, $params, 'apres'); |
---|
456 | } |
---|
457 | |
---|
458 | /** |
---|
459 | * Ajoute plusieurs boutons, après un autre déjà présent |
---|
460 | * |
---|
461 | * @api |
---|
462 | * @param string $identifiant |
---|
463 | * Identifiant du bouton où l'on doit se situer |
---|
464 | * @param array $tableau_params |
---|
465 | * Paramètres de l'ajout. |
---|
466 | * Description de plusieurs boutons (tableau de tableaux clé/valeurs). |
---|
467 | * @return array|bool |
---|
468 | * Paramètres ajoutés après |
---|
469 | * False si l'identifiant cherché n'est pas trouvé |
---|
470 | */ |
---|
471 | function ajouterPlusieursApres($identifiant, $tableau_params){ |
---|
472 | return $this->affecter($this->markupSet, $identifiant, $tableau_params, 'apres', true); |
---|
473 | } |
---|
474 | |
---|
475 | /** |
---|
476 | * Ajoute une fonction JS qui pourra être utilisée par les boutons |
---|
477 | * |
---|
478 | * @api |
---|
479 | * @param string $fonction Code de la fonction JS |
---|
480 | * @return void |
---|
481 | */ |
---|
482 | function ajouterFonction($fonction){ |
---|
483 | if (false === strpos($this->functions, $fonction)){ |
---|
484 | $this->functions .= "\n" . $fonction . "\n"; |
---|
485 | } |
---|
486 | } |
---|
487 | |
---|
488 | /** |
---|
489 | * Supprimer les éléments non affichés (display:false) |
---|
490 | * Et les séparateurs (li vides) selon la configuration |
---|
491 | * |
---|
492 | * @param array $tableau Tableau de description des outils |
---|
493 | * @return void |
---|
494 | */ |
---|
495 | function enlever_elements_non_affiches(&$tableau){ |
---|
496 | if ($tableau === null) { // utile ? |
---|
497 | $tableau = &$this->markupSet; |
---|
498 | } |
---|
499 | |
---|
500 | foreach ($tableau as $p => &$v) { |
---|
501 | if (isset($v['display']) AND !$v['display']) { |
---|
502 | unset($tableau[$p]); |
---|
503 | $tableau = array_values($tableau); // remettre les cles automatiques sinon json les affiche et ça plante. |
---|
504 | } |
---|
505 | // sinon, on lance une recursion sur les sous-menus |
---|
506 | else { |
---|
507 | if (isset($v['dropMenu']) and is_array($v['dropMenu'])) { |
---|
508 | $this->enlever_elements_non_affiches($tableau[$p]['dropMenu']); |
---|
509 | // si le sous-menu est vide |
---|
510 | // on enleve le sous menu. |
---|
511 | // mais pas le parent ($tableau[$p]), qui peut effectuer une action. |
---|
512 | if (empty($tableau[$p]['dropMenu'])) { |
---|
513 | unset($tableau[$p]['dropMenu']); |
---|
514 | } |
---|
515 | } |
---|
516 | } |
---|
517 | } |
---|
518 | } |
---|
519 | |
---|
520 | /** |
---|
521 | * Enlève les séparateurs pour améliorer l'accessibilité |
---|
522 | * au détriment du stylage possible de ces séparateurs. |
---|
523 | * |
---|
524 | * Le bouton précédent le séparateur reçoit une classe CSS 'separateur_avant' |
---|
525 | * Celui apres 'separateur_apres' |
---|
526 | * |
---|
527 | * @param array $tableau |
---|
528 | * Tableau de description des outils |
---|
529 | * @return void |
---|
530 | **/ |
---|
531 | function enlever_separateurs(&$tableau) { |
---|
532 | if ($tableau === null) { // utile ? |
---|
533 | $tableau = &$this->markupSet; |
---|
534 | } |
---|
535 | |
---|
536 | |
---|
537 | foreach ($tableau as $p => &$v) { |
---|
538 | if (isset($v['separator']) and $v['separator']) { |
---|
539 | if (isset($tableau[$p-1])) { |
---|
540 | if (!isset($tableau[$p-1]['className'])) { |
---|
541 | $tableau[$p-1]['className'] = ""; |
---|
542 | } |
---|
543 | $tableau[$p-1]['className'] .= " separateur_avant"; |
---|
544 | } |
---|
545 | if (isset($tableau[$p+1])) { |
---|
546 | if (!isset($tableau[$p+1]['className'])) { |
---|
547 | $tableau[$p+1]['className'] = ""; |
---|
548 | } |
---|
549 | $tableau[$p+1]['className'] .= " separateur separateur_apres $v[id]"; |
---|
550 | } |
---|
551 | unset($tableau[$p]); |
---|
552 | $tableau = array_values($tableau); // remettre les cles automatiques sinon json les affiche et ça plante. |
---|
553 | } |
---|
554 | // sinon, on lance une recursion sur les sous-menus |
---|
555 | else { |
---|
556 | if (isset($v['dropMenu']) and is_array($v['dropMenu'])) { |
---|
557 | #$this->enlever_separateurs($tableau[$p]['dropMenu']); |
---|
558 | } |
---|
559 | } |
---|
560 | } |
---|
561 | } |
---|
562 | |
---|
563 | /** |
---|
564 | * Supprime les éléments vides (uniquement à la racine de l'objet) |
---|
565 | * et uniquement si chaîne ou tableau. |
---|
566 | * |
---|
567 | * Supprime les paramètres privés |
---|
568 | * Supprime les paramètres inutiles a markitup/json dans les paramètres markupSet |
---|
569 | * (id, display, icone) |
---|
570 | */ |
---|
571 | function enlever_parametres_inutiles() { |
---|
572 | foreach($this as $p=>$v){ |
---|
573 | if (!$v) { |
---|
574 | if (is_array($v) or is_string($v)) { |
---|
575 | unset($this->$p); |
---|
576 | } |
---|
577 | } elseif ($p == 'functions') { |
---|
578 | unset($this->$p); |
---|
579 | } |
---|
580 | } |
---|
581 | foreach($this->markupSet as $p=>$v) { |
---|
582 | foreach ($v as $n=>$m) { |
---|
583 | if (in_array($n, array('id', 'display'))) { |
---|
584 | unset($this->markupSet[$p][$n]); |
---|
585 | } |
---|
586 | } |
---|
587 | } |
---|
588 | unset ($this->_liste_params_autorises); |
---|
589 | } |
---|
590 | |
---|
591 | |
---|
592 | /** |
---|
593 | * Crée la sortie json pour le javascript des paramètres de la barre |
---|
594 | * |
---|
595 | * @return string Déclaration json de la barre |
---|
596 | */ |
---|
597 | function creer_json(){ |
---|
598 | $barre = $this; |
---|
599 | $type = $barre->nameSpace; |
---|
600 | $fonctions = $barre->functions; |
---|
601 | |
---|
602 | $barre->enlever_elements_non_affiches($this->markupSet); |
---|
603 | $barre->enlever_separateurs($this->markupSet); |
---|
604 | $barre->enlever_parametres_inutiles(); |
---|
605 | |
---|
606 | $json = Barre_outils::json_export($barre); |
---|
607 | |
---|
608 | // on lance la transformation des &chose; en veritables caracteres |
---|
609 | // sinon markitup restitue « au lieu de « directement |
---|
610 | // lorsqu'on clique sur l'icone |
---|
611 | include_spip('inc/charsets'); |
---|
612 | $json = unicode2charset(html2unicode($json)); |
---|
613 | return "\n\nbarre_outils_$type = ".$json . "\n\n $fonctions"; |
---|
614 | } |
---|
615 | |
---|
616 | /** |
---|
617 | * Transforme une variable PHP dans un équivalent javascript (json) |
---|
618 | * |
---|
619 | * Copié depuis ecrire/inc/json, mais modifié pour que les fonctions |
---|
620 | * JavaScript ne soient pas encapsulées dans une chaîne (string) |
---|
621 | * |
---|
622 | * @access private |
---|
623 | * @param mixed $var the variable |
---|
624 | * @return string|boolean |
---|
625 | * - string : js script |
---|
626 | * - boolean false if error |
---|
627 | */ |
---|
628 | function json_export($var) { |
---|
629 | $asso = false; |
---|
630 | switch (true) { |
---|
631 | case is_null($var) : |
---|
632 | return 'null'; |
---|
633 | case is_string($var) : |
---|
634 | if (strtolower(substr(ltrim($var),0,8))=='function') |
---|
635 | return $var; |
---|
636 | return '"' . addcslashes($var, "\"\\\n\r") . '"'; |
---|
637 | case is_bool($var) : |
---|
638 | return $var ? 'true' : 'false'; |
---|
639 | case is_scalar($var) : |
---|
640 | return $var; |
---|
641 | case is_object( $var) : |
---|
642 | $var = get_object_vars($var); |
---|
643 | $asso = true; |
---|
644 | case is_array($var) : |
---|
645 | $keys = array_keys($var); |
---|
646 | $ikey = count($keys); |
---|
647 | while (!$asso && $ikey--) { |
---|
648 | $asso = $ikey !== $keys[$ikey]; |
---|
649 | } |
---|
650 | $sep = ''; |
---|
651 | if ($asso) { |
---|
652 | $ret = '{'; |
---|
653 | foreach ($var as $key => $elt) { |
---|
654 | $ret .= $sep . '"' . $key . '":' . Barre_outils::json_export($elt); |
---|
655 | $sep = ','; |
---|
656 | } |
---|
657 | return $ret ."}\n"; |
---|
658 | } else { |
---|
659 | $ret = '['; |
---|
660 | foreach ($var as $elt) { |
---|
661 | $ret .= $sep . Barre_outils::json_export($elt); |
---|
662 | $sep = ','; |
---|
663 | } |
---|
664 | return $ret ."]\n"; |
---|
665 | } |
---|
666 | } |
---|
667 | return false; |
---|
668 | } |
---|
669 | |
---|
670 | } |
---|
671 | |
---|
672 | |
---|
673 | /** |
---|
674 | * Crée le code CSS pour les images des icones des barres d'outils |
---|
675 | * |
---|
676 | * S'appuie sur la description des jeux de barres disponibles et cherche |
---|
677 | * une fonction barre_outils_($barre)_icones pour chaque barre et |
---|
678 | * l'exécute si existe, attendant alors en retour un tableau de couples : |
---|
679 | * nom de l'outil => nom de l'image |
---|
680 | * |
---|
681 | * @pipeline_appel porte_plume_lien_classe_vers_icone |
---|
682 | * |
---|
683 | * @return string Déclaration CSS des icones |
---|
684 | */ |
---|
685 | function barre_outils_css_icones(){ |
---|
686 | // recuperer la liste, extraire les icones |
---|
687 | $css = ""; |
---|
688 | |
---|
689 | // liste des barres |
---|
690 | if (!$barres = barre_outils_liste()) |
---|
691 | return null; |
---|
692 | |
---|
693 | // liste des classes css et leur correspondance avec une icone |
---|
694 | $classe2icone = array(); |
---|
695 | foreach ($barres as $barre) { |
---|
696 | include_spip('barre_outils/' . $barre); |
---|
697 | if ($f = charger_fonction($barre . '_icones', 'barre_outils', true)) { |
---|
698 | if (is_array($icones = $f())) { |
---|
699 | $classe2icone = array_merge($classe2icone, $icones); |
---|
700 | } |
---|
701 | } |
---|
702 | } |
---|
703 | |
---|
704 | /** |
---|
705 | * Permettre aux plugins d'étendre les icones connues du porte plume |
---|
706 | * |
---|
707 | * On passe la liste des icones connues au pipeline pour ceux qui |
---|
708 | * ajoutent de simples icones à des barres existantes |
---|
709 | * |
---|
710 | * @pipeline_appel porte_plume_lien_classe_vers_icone |
---|
711 | * @var array $classe2icone |
---|
712 | * Couples identifiant de bouton => nom de l'image (ou tableau) |
---|
713 | * Dans le cas d'un tableau, cela indique une sprite : (nom de l'image , position haut, position bas) |
---|
714 | * Exemple : 'outil_header1' => array('spt-v1.png','-10px -226px') |
---|
715 | */ |
---|
716 | $classe2icone = pipeline('porte_plume_lien_classe_vers_icone', $classe2icone); |
---|
717 | |
---|
718 | // passage en css |
---|
719 | foreach ($classe2icone as $n=>$i) { |
---|
720 | $pos=""; |
---|
721 | if (is_array($i)){ |
---|
722 | $pos = "background-position:".end($i); |
---|
723 | $i = reset($i); |
---|
724 | } |
---|
725 | if (file_exists($i)) |
---|
726 | $file = $i; |
---|
727 | else |
---|
728 | $file = find_in_path("icones_barre/$i"); |
---|
729 | if ($file) |
---|
730 | $css .= "\n.markItUp .$n>a>em {background-image:url(".protocole_implicite(url_absolue($file)).");$pos}"; |
---|
731 | } |
---|
732 | |
---|
733 | return $css; |
---|
734 | } |
---|
735 | |
---|
736 | |
---|
737 | /** |
---|
738 | * Retourne une instance de Barre_outils |
---|
739 | * crée à partir du type de barre demandé |
---|
740 | * |
---|
741 | * Une fonction barre_outils_{type}_dist() retournant la barre doit |
---|
742 | * donc exister. |
---|
743 | * |
---|
744 | * @param string $set |
---|
745 | * Type de barre (ex: 'edition') |
---|
746 | * @return Barre_Outils|bool |
---|
747 | * La barre d'outil si la fonction a été trouvée, false sinon |
---|
748 | */ |
---|
749 | function barre_outils_initialiser($set){ |
---|
750 | if ($f = charger_fonction($set, 'barre_outils')) { |
---|
751 | // retourne une instance de l'objet Barre_outils |
---|
752 | return $f(); |
---|
753 | } |
---|
754 | return false; |
---|
755 | } |
---|
756 | |
---|
757 | /** |
---|
758 | * Retourne la liste des barres d'outils connues |
---|
759 | * |
---|
760 | * @return array|bool |
---|
761 | * Tableau des noms de barres d'outils trouvées |
---|
762 | * False si on ne trouve aucune barre. |
---|
763 | */ |
---|
764 | function barre_outils_liste(){ |
---|
765 | static $sets = -1; |
---|
766 | if ($sets !== -1) |
---|
767 | return $sets; |
---|
768 | |
---|
769 | // on recupere l'ensemble des barres d'outils connues |
---|
770 | if (!$sets = find_all_in_path('barre_outils/','.*[.]php') |
---|
771 | or !is_array($sets)) { |
---|
772 | spip_log("[Scandale] Porte Plume ne trouve pas de barre d'outils !"); |
---|
773 | $sets = false; |
---|
774 | return $sets; |
---|
775 | } |
---|
776 | |
---|
777 | foreach($sets as $fichier=>$adresse) { |
---|
778 | $sets[$fichier] = substr($fichier,0,-4); // juste le nom |
---|
779 | } |
---|
780 | return $sets; |
---|
781 | } |
---|
782 | |
---|
783 | /** |
---|
784 | * Filtre appliquant les traitements SPIP d'un champ |
---|
785 | * |
---|
786 | * Applique les filtres prévus sur un champ (et eventuellement un type d'objet) |
---|
787 | * sur un texte donné. Sécurise aussi le texte en appliquant safehtml(). |
---|
788 | * |
---|
789 | * Ce mécanisme est à préférer au traditionnel #TEXTE*|propre |
---|
790 | * |
---|
791 | * traitements_previsu() consulte la globale $table_des_traitements et |
---|
792 | * applique le traitement adequat. Si aucun traitement n'est trouvé, |
---|
793 | * alors propre() est appliqué. |
---|
794 | * |
---|
795 | * @package SPIP\PortePlume\Fonctions |
---|
796 | * @see champs_traitements() dans public/references.php |
---|
797 | * @global table_des_traitements |
---|
798 | * |
---|
799 | * @param string $texte |
---|
800 | * Texte source |
---|
801 | * @param string $nom_champ |
---|
802 | * Nom du champ (nom de la balise, en majuscules) |
---|
803 | * @param string $type_objet |
---|
804 | * L'objet a qui appartient le champ (en minuscules) |
---|
805 | * @param string $connect |
---|
806 | * Nom du connecteur de base de données |
---|
807 | * @return string |
---|
808 | * Texte traité avec les filtres déclarés pour le champ. |
---|
809 | */ |
---|
810 | function traitements_previsu($texte, $nom_champ = '', $type_objet = '', $connect = null) { |
---|
811 | include_spip('public/interfaces'); // charger les traitements |
---|
812 | |
---|
813 | global $table_des_traitements; |
---|
814 | if (!strlen($nom_champ) || !isset($table_des_traitements[$nom_champ])) { |
---|
815 | $texte = propre($texte, $connect); |
---|
816 | } |
---|
817 | else { |
---|
818 | include_spip('base/abstract_sql'); |
---|
819 | $table = table_objet($type_objet); |
---|
820 | $ps = $table_des_traitements[$nom_champ]; |
---|
821 | if (is_array($ps)) { |
---|
822 | $ps = $ps[(strlen($table) && isset($ps[$table])) ? $table : 0]; |
---|
823 | } |
---|
824 | if (!$ps) { |
---|
825 | $texte = propre($texte, $connect); |
---|
826 | } else { |
---|
827 | // [FIXME] Éviter une notice sur le eval suivant qui ne connait |
---|
828 | // pas la Pile ici. C'est pas tres joli... |
---|
829 | $Pile = array( 0 => array() ); |
---|
830 | // remplacer le placeholder %s par le texte fourni |
---|
831 | eval('$texte=' . str_replace('%s', '$texte', $ps) . ';'); |
---|
832 | } |
---|
833 | } |
---|
834 | // il faut toujours securiser le texte prévisualisé car il peut contenir n'importe quoi |
---|
835 | // et servir de support a une attaque xss ou vol de cookie admin |
---|
836 | // on ne peut donc se fier au statut de l'auteur connecté car le contenu ne vient pas |
---|
837 | // forcément de lui |
---|
838 | return safehtml($texte); |
---|
839 | } |
---|