....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 213.186.33.2  /  Your IP : 216.73.216.250
Web Server : Apache
System : Linux webd003.cluster102.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : uneseuleoc ( 96096)
PHP Version : 7.4.33
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/uneseuleoc/www/plugins-dist/porte_plume/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/uneseuleoc/www/plugins-dist/porte_plume//porte_plume_fonctions.php
<?php

/**
 * Fonctions utiles pour le Porte Plume
 *
 * @plugin Porte Plume pour SPIP
 * @license GPL
 * @package SPIP\PortePlume\BarreOutils
 */

if (!defined('_ECRIRE_INC_VERSION')) {
	return;
}

/**
 * Objet contenant les différents paramètres definissant une barre d'outils
 * Markitup et permettant d'agir dessus
 *
 * @example
 *     $barre = new Barre_Outil($description);
 *
 * @package SPIP\PortePlume\BarreOutils
 */
class Barre_outils {
	/**
	 * Identifiant HTML de la barre
	 *
	 * @todo À supprimer car non utilisé !
	 * @var string
	 */
	public $id = '';

	/**
	 * Nom de la barre d'outil
	 *
	 * @var string
	 */
	public $nameSpace = '';

	/**
	 * Langue
	 *
	 * @todo À supprimer car non utilisé !
	 * @var string
	 */
	public $lang = '';

	/**
	 * Option de markitup : rafraîchir la prévisu ?
	 *
	 * @todo À supprimer car non utilisé !
	 * @var bool
	 */
	public $previewAutoRefresh = false;

	/**
	 * Option de markitup : nom de la fonction de prévisu
	 *
	 * @todo À supprimer car on le redéfini dans l'appel javascript !
	 * @var bool
	 */
	public $previewParserPath = '';

	/**
	 * Option de markitup : que faire sur l'appuie de Entrée ?
	 *
	 * @var array
	 */
	public $onEnter = [];

	/**
	 * Option de markitup : que faire sur l'appuie de Shift+Entrée ?
	 *
	 * @example array('keepDefault'=>false, 'replaceWith'=>"\n_ ")
	 * @var array
	 */
	public $onShiftEnter = [];

	/**
	 * Option de markitup : que faire sur l'appuie de Control+Entrée ?
	 *
	 * @var array
	 */
	public $onCtrlEnter = [];

	/**
	 * Option de markitup : que faire sur l'appuie d'une tabulation ?
	 *
	 * @var array
	 */
	public $onTab = [];

	/**
	 * Option de markitup : Code JS à exécuter avant une insertion
	 *
	 * @var string
	 */
	public $beforeInsert = '';

	/**
	 * Option de markitup : Code JS à exécuter après une insertion
	 *
	 * @var string
	 */
	public $afterInsert = '';

	/**
	 * Description des outils/boutons et leurs sous boutons éventuels
	 *
	 * @var array
	 */
	public $markupSet = [];

	/**
	 * Fonctions JS supplémentaires à écrire après la déclaration JSON
	 * des outils. Ces fonctions peuvent servir aux boutons.
	 *
	 * @var string
	 */
	public $functions = '';

	/**
	 * Liste des paramètres valides pour une description d'outils (markupSet)
	 */
	private array $_liste_params_autorises = [

		'replaceWith',
		'openWith',
		'closeWith',
		'openBlockWith',
		// sur multiline, avant les lignes selectionnees
		'closeBlockWith',
		// sur multiline, apres les lignes selectionnees
		'placeHolder',
		// remplace par ce texte lorsqu'il n'y a pas de selection

		'beforeInsert',
		// avant l'insertion
		'afterInsert',
		// apres l'insertion
		'beforeMultiInsert',
		'afterMultiInsert',

		'dropMenu',
		// appelle un sous menu

		'name',
		// nom affiche au survol
		'key',
		// raccourcis clavier
		'className',
		// classe css utilisee
		'lang',
		// langues dont le bouton doit apparaitre - array
		'lang_not',
		// langues dont le bouton ne doit pas apparaitre - array
		'selectionType',
		// '','word','line' : type de selection (normale, aux mots les plus proches, a la ligne la plus proche)
		'multiline',
		// open/close sur chaque ligne (mais replace est applique sur l'ensemble de la selection)
		'forceMultiline',
		// pour faire comme si on faisait systematiquement un control+shift
		// (et replace est applique sur chaque ligne de la selection)

		'separator',

		'call',
		'keepDefault',

		// cacher ou afficher facilement des boutons
		'display',
		// donner un identifiant unique au bouton (pour le php)
		'id',
	];

	/**
	 * Constructeur
	 *
	 * Initialise la barre avec les paramètres transmis
	 * en n'adressant que les paramètres effectivement valides
	 *
	 * @api
	 * @param array $params Paramètres de la barre d'outil
	 * @return void
	 */
	public function __construct($params = []) {
		foreach ($params as $p => $v) {
			if (isset($this->$p)) {
				// si tableau, on verifie les entrees
				if (is_array($v)) {
					$v = $this->verif_params($p, $v);
				}
				$this->$p = $v;
			}
		}
	}


	/**
	 * Vérifie que les paramètres d'une clé existent
	 * et retourne un tableau des paramètres valides
	 *
	 * @param string $nom
	 *     Clé à vérifier (ex: 'markupSet')
	 * @param array $params
	 *     Paramètres de cette clé (description des boutons ou sous boutons)
	 * @return array
	 *     Paramètres, soustrait de ceux qui ne sont pas valides
	 */
	public function verif_params($nom, $params = []) {
		// si markupset, on boucle sur les items
		if (stripos($nom, 'markupSet') !== false) {
			foreach ($params as $i => $v) {
				$params[$i] = $this->verif_params($i, $v);
			}
		} // sinon on teste la validite
		else {
			foreach ($params as $p => $v) {
				if (!in_array($p, $this->_liste_params_autorises)) {
					unset($params[$p]);
				}
			}
		}

		return $params;
	}

	/**
	 * Permet d'affecter des paramètres à un élément de la barre
	 *
	 * La fonction retourne les paramètres, de sorte qu'on peut s'en servir
	 * pour simplement récupérer ceux-ci.
	 *
	 * Il est possible d'affecter des paramètres avant/après l'élément trouvé
	 * en definisant une valeur différente pour le $lieu : 'dedans','avant','apres'
	 * par defaut 'dedans' (modifie l'élément trouvé).
	 *
	 * Lorsqu'on demande d'insérer avant ou après, la fonction retourne
	 * les paramètres inserés
	 *
	 * @param array $tableau
	 *     Tableau ou chercher les elements (sert pour la recursion)
	 * @param string $identifiant
	 *     Identifiant du bouton a afficher
	 * @param array $params
	 *     Paramètres à affecter à la trouvaille (ou avant ou après).
	 *     Peut être un tableau clé/valeur ou un tableau de tableaux
	 *     clé/valeur (sauf pour $lieu = dedans)
	 * @param string $lieu
	 *     Lieu d'affectation des paramètres (dedans, avant, apres)
	 * @param bool $plusieurs
	 *     Définit si $params est une forme simple (tableau cle/valeur)
	 *     ou comporte plusieurs boutons (tableau de tableaux cle/valeur).
	 * @return array|bool
	 *     Paramètres de l'élément modifié ou paramètres ajoutés
	 *     False si l'identifiant cherché n'est pas trouvé
	 */
	public function affecter(&$tableau, $identifiant, $params = [], $lieu = 'dedans', $plusieurs = false) {
		static $cle_de_recherche = 'id'; // ou className ?

		if ($tableau === null) {// utile ?
			$tableau = &$this->markupSet;
		}

		if (!in_array($lieu, ['dedans', 'avant', 'apres'])) {
			$lieu = 'dedans';
		}

		// present en premiere ligne ?
		$trouve = false;
		foreach ($tableau as $i => $v) {
			if (isset($v[$cle_de_recherche]) and ($v[$cle_de_recherche] == $identifiant)) {
				$trouve = $i;
				break;
			}
		}
		// si trouve, affectations
		if (($trouve !== false)) {
			if ($params) {
				// verifier que les insertions sont correctes
				$les_params = ($plusieurs ? $params : [$params]);
				foreach ($les_params as $i => $un_params) {
					$les_params[$i] = $this->verif_params($identifiant, $un_params);
				}

				// dedans on merge ($params uniquement tableau cle/valeur)
				if ($lieu == 'dedans' && !$plusieurs) {
					return $tableau[$trouve] = array_merge($tableau[$trouve], $les_params[0]);
				} // avant ou apres, on insere ($params peut etre tableau cle/valeur ou tableau de tableaux cle/valeur)
				elseif ($lieu == 'avant') {
					array_splice($tableau, $trouve, 0, $les_params);

					return $params;
				} elseif ($lieu == 'apres') {
					array_splice($tableau, $trouve + 1, 0, $les_params);

					return $params;
				}
			}

			return $tableau[$trouve];
		}

		// recursivons sinon !
		foreach ($tableau as $i => $v) {
			if (is_array($v)) {
				foreach ($v as $m => $n) {
					if (
						is_array($n)
						and ($r = $this->affecter($tableau[$i][$m], $identifiant, $params, $lieu, $plusieurs))
					) {
						return $r;
					}
				}
			}
		}

		return false;
	}


	/**
	 * Permet d'affecter des paramètres à tous les éléments de la barre
	 * ou à une liste d'identifiants d'éléments indiqués.
	 *
	 * @param array $tableau
	 *     Tableau où chercher les éléments
	 * @param array $params
	 *     Paramètres à affecter aux éléments
	 * @param array $ids
	 *     Tableau d'identifiants particuliers à qui on affecte les paramètres.
	 *     Si vide, tous les identifiants seront modifiés
	 * @return bool
	 *     false si aucun paramètre à affecter, true sinon.
	 */
	public function affecter_a_tous(&$tableau, $params = [], $ids = []) {
		if (!$params) {
			return false;
		}

		if ($tableau === null) {
			$tableau = &$this->markupSet;
		}

		$params = $this->verif_params('divers', $params);

		// merge de premiere ligne
		foreach ($tableau as $i => &$v) {
			if (!$ids or in_array($v['id'], $ids)) {
				$tableau[$i] = array_merge($tableau[$i], $params);
			}
			// recursion si sous-menu
			if (isset($tableau[$i]['dropMenu'])) {
				$this->affecter_a_tous($tableau[$i]['dropMenu'], $params, $ids);
			}
		}

		return true;
	}


	/**
	 * Affecte les valeurs des paramètres indiqués au bouton demandé
	 * et retourne l'ensemble des paramètres du bouton (sinon false)
	 *
	 * @api
	 * @param string|array $identifiant
	 *     Identifiant du ou des boutons.
	 * @param array $params
	 *     Paramètres de l'ajout (tableau paramètre=>valeur)
	 * @return bool|array
	 *     false si l'identifiant n'a pas été trouvé
	 *     true si plusieurs identifiants,
	 *     array sinon : description de l'identifiant cherché.
	 */
	public function set($identifiant, $params = []) {
		// prudence tout de meme a pas tout modifier involontairement (si array)
		if (!$identifiant) {
			return false;
		}

		if (is_string($identifiant)) {
			return $this->affecter($this->markupSet, $identifiant, $params);
		} elseif (is_array($identifiant)) {
			return $this->affecter_a_tous($this->markupSet, $params, $identifiant);
		}

		return false;
	}

	/**
	 * Retourne les parametres du bouton demande
	 *
	 * @api
	 * @param string|array $identifiant
	 *     Identifiant du ou des boutons.
	 * @return bool|array
	 *     false si l'identifiant n'est pas trouvé
	 *     array sinon : Description de l'identifiant cherché.
	 */
	public function get($identifiant) {
		if ($a = $this->affecter($this->markupSet, $identifiant)) {
			return $a;
		}

		return false;
	}


	/**
	 * Affiche le ou les boutons demandés
	 *
	 * @api
	 * @param string|array $identifiant
	 *     Identifiant du ou des boutons
	 * @return bool|array
	 *     false si l'identifiant n'a pas été trouvé
	 *     true si plusieurs identifiants,
	 *     array sinon : description de l'identifiant cherché.
	 */
	public function afficher($identifiant) {
		return $this->set($identifiant, ['display' => true]);
	}


	/**
	 * Cache le ou les boutons demandés
	 *
	 * @api
	 * @param string|array $identifiant
	 *     Identifiant du ou des boutons
	 * @return bool|array
	 *     false si l'identifiant n'a pas été trouvé
	 *     true si plusieurs identifiants,
	 *     array sinon : description de l'identifiant cherché.
	 */
	public function cacher($identifiant) {
		return $this->set($identifiant, ['display' => false]);
	}


	/**
	 * Affiche tous les boutons
	 *
	 * @api
	 * @return bool
	 *     false si aucun paramètre à affecter, true sinon.
	 */
	public function afficherTout() {
		return $this->affecter_a_tous($this->markupSet, ['display' => true]);
	}

	/**
	 * Cache tous les boutons
	 *
	 * @api
	 * @return bool
	 *     false si aucun paramètre à affecter, true sinon.
	 */
	public function cacherTout() {
		return $this->affecter_a_tous($this->markupSet, ['display' => false]);
	}


	/**
	 * Ajoute un bouton ou quelque chose, avant un autre déjà présent
	 *
	 * @api
	 * @param string $identifiant
	 *     Identifiant du bouton où l'on doit se situer
	 * @param array $params
	 *     Paramètres de l'ajout.
	 *     Description d'un bouton (tableau clé/valeurs).
	 * @return array|bool
	 *     Paramètres ajoutés avant
	 *     False si l'identifiant cherché n'est pas trouvé
	 */
	public function ajouterAvant($identifiant, $params) {
		return $this->affecter($this->markupSet, $identifiant, $params, 'avant');
	}

	/**
	 * Ajoute plusieurs boutons, avant un autre déjà présent
	 *
	 * @api
	 * @param string $identifiant
	 *     Identifiant du bouton où l'on doit se situer
	 * @param array $tableau_params
	 *     Paramètres de l'ajout.
	 *     Description de plusieurs boutons (tableau de tableaux clé/valeurs).
	 * @return array|bool
	 *     Paramètres ajoutés avant
	 *     False si l'identifiant cherché n'est pas trouvé
	 */
	public function ajouterPlusieursAvant($identifiant, $tableau_params) {
		return $this->affecter($this->markupSet, $identifiant, $tableau_params, 'avant', true);
	}

	/**
	 * Ajoute un bouton ou quelque chose, après un autre déjà présent
	 *
	 * @api
	 * @param string $identifiant
	 *     Identifiant du bouton où l'on doit se situer
	 * @param array $params
	 *     Paramètres de l'ajout.
	 *     Description d'un bouton (tableau clé/valeurs).
	 * @return array|bool
	 *     Paramètres ajoutés après
	 *     False si l'identifiant cherché n'est pas trouvé
	 */
	public function ajouterApres($identifiant, $params) {
		return $this->affecter($this->markupSet, $identifiant, $params, 'apres');
	}

	/**
	 * Ajoute plusieurs boutons, après un autre déjà présent
	 *
	 * @api
	 * @param string $identifiant
	 *     Identifiant du bouton où l'on doit se situer
	 * @param array $tableau_params
	 *     Paramètres de l'ajout.
	 *     Description de plusieurs boutons (tableau de tableaux clé/valeurs).
	 * @return array|bool
	 *     Paramètres ajoutés après
	 *     False si l'identifiant cherché n'est pas trouvé
	 */
	public function ajouterPlusieursApres($identifiant, $tableau_params) {
		return $this->affecter($this->markupSet, $identifiant, $tableau_params, 'apres', true);
	}

	/**
	 * Ajoute une fonction JS qui pourra être utilisée par les boutons
	 *
	 * @api
	 * @param string $fonction Code de la fonction JS
	 * @return void
	 */
	public function ajouterFonction($fonction) {
		if (false === strpos($this->functions, $fonction)) {
			$this->functions .= "\n" . $fonction . "\n";
		}
	}

	/**
	 * Supprimer les éléments non affichés (display:false)
	 * Et les séparateurs (li vides) selon la configuration
	 *
	 * @param array $tableau Tableau de description des outils
	 * @return void
	 */
	public function enlever_elements_non_affiches(&$tableau) {
		if ($tableau === null) { // utile ?
			$tableau = &$this->markupSet;
		}

		foreach ($tableau as $p => &$v) {
			if (isset($v['display']) and !$v['display']) {
				unset($tableau[$p]);
				// remettre les cles automatiques sinon json les affiche et ça plante.
				$tableau = array_values($tableau);
			} else {
				// sinon, on lance une recursion sur les sous-menus
				if (isset($v['dropMenu']) and is_array($v['dropMenu'])) {
					$this->enlever_elements_non_affiches($tableau[$p]['dropMenu']);
					// si le sous-menu est vide
					// on enleve le sous menu.
					// mais pas le parent ($tableau[$p]), qui peut effectuer une action.
					if (empty($tableau[$p]['dropMenu'])) {
						unset($tableau[$p]['dropMenu']);
					}
				}
			}
		}
	}

	/**
	 * Enlève les séparateurs pour améliorer l'accessibilité
	 * au détriment du stylage possible de ces séparateurs.
	 *
	 * Le bouton précédent le séparateur reçoit une classe CSS 'separateur_avant'
	 * Celui apres 'separateur_apres'
	 *
	 * @param array $tableau
	 *     Tableau de description des outils
	 * @return void
	 **/
	public function enlever_separateurs(&$tableau) {
		if ($tableau === null) { // utile ?
			$tableau = &$this->markupSet;
		}


		foreach ($tableau as $p => &$v) {
			if (isset($v['separator']) and $v['separator']) {
				if (isset($tableau[$p - 1])) {
					if (!isset($tableau[$p - 1]['className'])) {
						$tableau[$p - 1]['className'] = '';
					}
					$tableau[$p - 1]['className'] .= ' separateur_avant';
				}
				if (isset($tableau[$p + 1])) {
					if (!isset($tableau[$p + 1]['className'])) {
						$tableau[$p + 1]['className'] = '';
					}
					$tableau[$p + 1]['className'] .= " separateur separateur_apres $v[id]";
				}
				unset($tableau[$p]);
				// remettre les cles automatiques sinon json les affiche et ça plante.
				$tableau = array_values($tableau);
			}
		}
	}

	/**
	 * Supprime les éléments vides (uniquement à la racine de l'objet)
	 * et uniquement si chaîne ou tableau.
	 *
	 * Supprime les paramètres privés
	 * Supprime les paramètres inutiles a markitup/json dans les paramètres markupSet
	 * (id, display, icone)
	 */
	public function enlever_parametres_inutiles() {
		foreach ($this as $p => $v) {
			if ($p == 'markupSet') {
				continue;
			}
			if (!$v) {
				if (is_array($v) or is_string($v)) {
					unset($this->$p);
				}
			} elseif ($p == 'functions') {
				unset($this->$p);
			}
		}
		foreach ($this->markupSet as $p => $v) {
			foreach ($v as $n => $m) {
				if (in_array($n, ['id', 'display'])) {
					unset($this->markupSet[$p][$n]);
				}
			}
		}
		unset($this->_liste_params_autorises);
	}

	public function echapper_appels_fonctions(&$tableau, &$rappels = []) {
		static $i = 0;
		foreach ($tableau as $p => $v) {
			if (is_array($v)) {
				foreach ($v as $k => $w) {
					if ($k === 'dropMenu' and is_array($tableau[$p][$k])) {
						$this->echapper_appels_fonctions($tableau[$p][$k], $rappels);
					} elseif (is_string($w) and substr($w, 0, 8) == 'function') {
						$echap = "%function$i%";
						$i++;
						$rappels["\"$echap\""] = $w;
						$tableau[$p][$k] = $echap;
					}
				}
			}
		}
		return $rappels;
	}


	/**
	 * Crée la sortie json pour le javascript des paramètres de la barre
	 *
	 * @return string Déclaration json de la barre
	 */
	public function creer_json() {
		$barre = $this;
		$type = $barre->nameSpace;
		$fonctions = $barre->functions;

		$barre->enlever_elements_non_affiches($this->markupSet);
		$barre->enlever_separateurs($this->markupSet);
		$barre->enlever_parametres_inutiles();
		$appels_fonctions = $barre->echapper_appels_fonctions($this->markupSet);
		$json = json_encode($barre, JSON_PRETTY_PRINT);
		$json = str_replace(array_keys($appels_fonctions), $appels_fonctions, $json);

		// on lance la transformation des &chose; en veritables caracteres
		// sinon markitup restitue &laquo; au lieu de « directement
		// lorsqu'on clique sur l'icone
		include_spip('inc/charsets');
		$json = unicode2charset(html2unicode($json));

		return "\n\nbarre_outils_$type = " . $json . "\n\n $fonctions";
	}
}


/**
 * Crée le code CSS pour les images des icones des barres d'outils
 *
 * S'appuie sur la description des jeux de barres disponibles et cherche
 * une fonction barre_outils_($barre)_icones pour chaque barre et
 * l'exécute si existe, attendant alors en retour un tableau de couples :
 * nom de l'outil => nom de l'image
 *
 * @pipeline_appel porte_plume_lien_classe_vers_icone
 *
 * @return string Déclaration CSS des icones
 */
function barre_outils_css_icones() {
	// recuperer la liste, extraire les icones
	$css = '';

	// liste des barres
	if (!$barres = barre_outils_liste()) {
		return null;
	}

	// liste des classes css et leur correspondance avec une icone
	$classe2icone = [];
	foreach ($barres as $barre) {
		include_spip('barre_outils/' . $barre);
		if ($f = charger_fonction($barre . '_icones', 'barre_outils', true)) {
			if (is_array($icones = $f())) {
				$classe2icone = array_merge($classe2icone, $icones);
			}
		}
	}

	/**
	 * Permettre aux plugins d'étendre les icones connues du porte plume
	 *
	 * On passe la liste des icones connues au pipeline pour ceux qui
	 * ajoutent de simples icones à des barres existantes
	 *
	 * @pipeline_appel porte_plume_lien_classe_vers_icone
	 * @var array $classe2icone
	 *     Couples identifiant de bouton => nom de l'image (ou tableau)
	 *     Dans le cas d'un tableau, cela indique une sprite : (nom de l'image , position haut, position bas)
	 *     Exemple : 'outil_header1' => array('spt-v1.png','-10px -226px')
	 */
	$classe2icone = pipeline('porte_plume_lien_classe_vers_icone', $classe2icone);

	// passage en css
	foreach ($classe2icone as $n => $i) {
		$pos = '';
		if (is_array($i)) {
			$pos = 'background-position:' . end($i);
			$i = reset($i);
		}
		if (file_exists($i)) {
			$file = $i;
		} else {
			$file = find_in_path("icones_barre/$i");
		}
		if ($file) {
			$css .= "\n.markItUp .$n>a>em {background-image:url(" . protocole_implicite(url_absolue($file)) . ");$pos}";
		}
	}

	return $css;
}


/**
 * Retourne une instance de Barre_outils
 * crée à partir du type de barre demandé
 *
 * Une fonction barre_outils_{type}_dist() retournant la barre doit
 * donc exister.
 *
 * @param string $set
 *     Type de barre (ex: 'edition')
 * @return Barre_Outils|bool
 *     La barre d'outil si la fonction a été trouvée, false sinon
 */
function barre_outils_initialiser($set) {
	if ($f = charger_fonction($set, 'barre_outils')) {
		// retourne une instance de l'objet Barre_outils
		return $f();
	}

	return false;
}

/**
 * Retourne la liste des barres d'outils connues
 *
 * @return array|bool
 *     Tableau des noms de barres d'outils trouvées
 *     False si on ne trouve aucune barre.
 */
function barre_outils_liste() {
	static $sets = -1;
	if ($sets !== -1) {
		return $sets;
	}

	// on recupere l'ensemble des barres d'outils connues
	if (
		!$sets = find_all_in_path('barre_outils/', '.*[.]php')
		or !is_array($sets)
	) {
		spip_log("[Scandale] Porte Plume ne trouve pas de barre d'outils !");
		$sets = false;

		return $sets;
	}

	foreach ($sets as $fichier => $adresse) {
		$sets[$fichier] = substr($fichier, 0, -4); // juste le nom
	}

	return $sets;
}

/**
 * Filtre appliquant les traitements SPIP d'un champ
 *
 * Applique les filtres prévus sur un champ (et eventuellement un type d'objet)
 * sur un texte donné. Sécurise aussi le texte en appliquant safehtml().
 *
 * Ce mécanisme est à préférer au traditionnel #TEXTE*|propre
 *
 * traitements_previsu() consulte la globale $table_des_traitements et
 * applique le traitement adequat. Si aucun traitement n'est trouvé,
 * alors propre() est appliqué.
 *
 * @package SPIP\PortePlume\Fonctions
 * @see champs_traitements() dans public/references.php
 * @global table_des_traitements
 *
 * @param string $texte
 *     Texte source
 * @param string $nom_champ
 *     Nom du champ (nom de la balise, en majuscules)
 * @param string $type_objet
 *     L'objet a qui appartient le champ (en minuscules)
 * @param string $connect
 *     Nom du connecteur de base de données
 * @return string
 *     Texte traité avec les filtres déclarés pour le champ.
 */
function traitements_previsu($texte, $nom_champ = '', $type_objet = '', $connect = null) {
	include_spip('public/interfaces'); // charger les traitements

	global $table_des_traitements;
	if (!strlen($nom_champ) || !isset($table_des_traitements[$nom_champ])) {
		$texte = propre($texte, $connect);
	} else {
		include_spip('base/abstract_sql');
		$table = table_objet($type_objet);
		$ps = $table_des_traitements[$nom_champ];
		if (is_array($ps)) {
			$ps = $ps[(strlen($table) && isset($ps[$table])) ? $table : 0];
		}
		if (!$ps) {
			$texte = propre($texte, $connect);
		} else {
			// [FIXME] Éviter une notice sur le eval suivant qui ne connait
			// pas la Pile ici. C'est pas tres joli...
			$Pile = [0 => []];
			// remplacer le placeholder %s par le texte fourni
			eval('$texte=' . str_replace('%s', '$texte', $ps) . ';');
		}
	}

	// si il y a du PHP issu de modeles, il faut l'eval ici, car on aura pas de eval final contrairement aux pages SPIP
	if (defined('_PROTEGE_PHP_MODELES')) {
		$texte = echappe_retour($texte, 'php' . _PROTEGE_PHP_MODELES, 'traitements_previsu_php_modeles_eval');
	}

	// il faut toujours securiser le texte prévisualisé car il peut contenir n'importe quoi
	// et servir de support a une attaque xss ou vol de cookie admin
	// on ne peut donc se fier au statut de l'auteur connecté car le contenu ne vient pas
	// forcément de lui
	return safehtml($texte);
}


/**
 * Evaluer le PHP des modèles dans la previsu
 * @param $php
 * @return false|string
 */
function traitements_previsu_php_modeles_eval($php) {
	ob_start();
	try {
		$res = eval('?' . '>' . $php);
		$texte = ob_get_contents();
	} catch (\Throwable $e) {
		$texte = '<!-- Erreur -->';
	}
	ob_end_clean();
	return $texte;
}

/**
 * Retourne la définition de la barre markitup désignée.
 * (cette déclaration est au format json)
 *
 * Deux pipelines 'porte_plume_pre_charger' et 'porte_plume_charger'
 * permettent de récuperer l'objet de classe Barre_outil
 * avant son export en json pour modifier des elements.
 *
 * @pipeline_appel porte_plume_barre_pre_charger
 *     Charge des nouveaux boutons au besoin
 * @pipeline_appel porte_plume_barre_charger
 *     Affiche ou cache certains boutons
 *
 * @return string Déclaration json
 */
function porte_plume_creer_json_markitup() {
	// on recupere l'ensemble des barres d'outils connues
	include_spip('porte_plume_fonctions');
	if (!$sets = barre_outils_liste()) {
		return null;
	}

	// 1) On initialise tous les jeux de barres
	$barres = [];
	foreach ($sets as $set) {
		if (($barre = barre_outils_initialiser($set)) and is_object($barre)) {
			$barres[$set] = $barre;
		}
	}

	// 2) Préchargement

	/**
	 * Charger des nouveaux boutons au besoin
	 *
	 * @example
	 *     $barre = &$flux['spip'];
	 *     $barre->ajouterApres('bold',array(params));
	 *     $barre->ajouterAvant('bold',array(params));
	 *
	 *     $bold = $barre->get('bold');
	 *     $bold['id'] = 'bold2';
	 *     $barre->ajouterApres('italic',$bold);
	 * @pipeline_appel porte_plume_barre_pre_charger
	 */
	$barres = pipeline('porte_plume_barre_pre_charger', $barres);


	// 3) Chargement

	/**
	 * Cacher ou afficher certains boutons au besoin
	 *
	 * @example
	 *     $barre = &$flux['spip'];
	 *     $barre->afficher('bold');
	 *     $barre->cacher('bold');
	 *
	 *     $barre->cacherTout();
	 *     $barre->afficher(array('bold','italic','header1'));
	 * @pipeline_appel porte_plume_barre_charger
	 */
	$barres = pipeline('porte_plume_barre_charger', $barres);


	// 4 On crée les jsons
	$json = '';
	foreach ($barres as $set => $barre) {
		$json .= $barre->creer_json();
	}

	return $json;
}

Youez - 2016 - github.com/yon3zu
LinuXploit