[SPIP] +spip v3.0.17
[lhc/web/clavette_www.git] / www / plugins-dist / svp / plugins / preparer_sql_plugin.php
1 <?php
2
3 /**
4 * Fichier permettant de calculer les données SQL à insérer
5 * à partir d'une arbre de description originaire d'un plugin.xml
6 *
7 * @plugin SVP pour SPIP
8 * @license GPL
9 * @package SPIP\SVP\Plugins
10 **/
11
12 if (!defined('_ECRIRE_INC_VERSION')) return;
13
14 /**
15 * Pour une description de plugin donnée (issue de la dtd de plugin.xml),
16 * prépare les données à installer en bdd
17 *
18 * Les données sont parfois sérialisées, parfois transcodées, parfois compilées
19 * pour tenir compte des spécificités de cette DTD et du stockage en bdd.
20 *
21 * @param array $plugin
22 * Description de plugin
23 * @return array
24 * Couples clés => valeurs de description du paquet
25 **/
26 function plugins_preparer_sql_plugin($plugin)
27 {
28 include_spip('inc/svp_outiller');
29
30 $champs = array();
31 if (!$plugin)
32 return $champs;
33
34 // On initialise les champs ne necessitant aucune transformation
35 $champs['categorie'] = (isset($plugin['categorie']) and $plugin['categorie']) ? $plugin['categorie'] : '';
36 $champs['etat'] = (isset($plugin['etat']) and $plugin['etat']) ? $plugin['etat'] : '';
37 $champs['version'] = $plugin['version'] ? normaliser_version($plugin['version']) : '';
38 $champs['version_base'] = (isset($plugin['schema']) and $plugin['schema']) ? $plugin['schema'] : '';
39
40 // Renommage de certains champs
41 $champs['logo'] = (isset($plugin['logo']) and $plugin['logo']) ? $plugin['logo'] : '';
42 $champs['lien_doc'] = (isset($plugin['documentation']) and $plugin['documentation']) ? normaliser_lien($plugin['documentation']) : '';
43 // On passe le prefixe en lettres majuscules comme ce qui est fait dans SPIP
44 // Ainsi les valeurs dans la table spip_plugins coincideront avec celles de la meta plugin
45 $champs['prefixe'] = strtoupper($plugin['prefix']);
46
47 // Indicateurs d'etat numerique (pour simplifier la recherche des maj de STP)
48 static $num = array('stable'=>4, 'test'=>3, 'dev'=>2, 'experimental'=>1);
49 $champs['etatnum'] = (isset($plugin['etat']) and isset($num[$plugin['etat']])) ? $num[$plugin['etat']] : 0;
50
51 // Tags : liste de mots-cles
52 $champs['tags'] = (isset($plugin['tags']) and $plugin['tags']) ? serialize($plugin['tags']) : '';
53
54 // On passe en utf-8 avec le bon charset les champs pouvant contenir des entites html
55 $champs['description'] = entite2charset($plugin['description']);
56
57 // Traitement des auteurs, credits, licences et copyright
58 // -- on extrait les auteurs, licences et copyrights sous forme de tableaux
59 // -- depuis le commit 18294 du core la balise auteur est renvoyee sous forme de tableau mais
60 // contient toujours qu'un seul index
61 $balise_auteur = entite2charset($plugin['auteur'][0]);
62 $auteurs = normaliser_auteur_licence($balise_auteur, 'auteur');
63 $balise_licence = isset($plugin['licence'][0]) ? entite2charset($plugin['licence'][0]) : '';
64 $licences = normaliser_auteur_licence($balise_licence, 'licence');
65 // -- on merge les tableaux recuperes dans auteur et licence
66 $champs['auteur'] = $champs['licence'] = $champs['copyright'] = '';
67 if ($t = array_merge($auteurs['auteur'], $licences['auteur']))
68 $champs['auteur'] = serialize($t);
69 if ($t = array_merge($auteurs['licence'], $licences['licence']))
70 $champs['licence'] = serialize($t);
71 if ($t = array_merge($auteurs['copyright'], $licences['copyright']))
72 $champs['copyright'] = serialize($t);
73
74 // Extrait d'un nom et un slogan normalises
75 // Slogan : si vide on ne fait plus rien de special, on traitera ça a l'affichage
76 $champs['slogan'] = $plugin['slogan'] ? entite2charset($plugin['slogan']) : '';
77 // Nom : on repere dans le nom du plugin un chiffre en fin de nom
78 // et on l'ampute de ce numero pour le normaliser
79 // et on passe tout en unicode avec le charset du site
80 $champs['nom'] = trim(entite2charset($plugin['nom']));
81
82 // Extraction de la compatibilite SPIP et construction de la liste des branches spip supportees
83 $champs['compatibilite_spip'] = ($plugin['compatibilite']) ? $plugin['compatibilite'] : '';
84 $champs['branches_spip'] = ($plugin['compatibilite']) ? compiler_branches_spip($plugin['compatibilite']) : '';
85
86 // Construction du tableau des dependances necessite, lib et utilise
87 $dependances['necessite'] = $plugin['necessite'];
88 $dependances['librairie'] = $plugin['lib'];
89 $dependances['utilise'] = $plugin['utilise'];
90 $champs['dependances'] = serialize($dependances);
91
92 // Champs non supportes par la DTD plugin et ne pouvant etre deduits d'autres balises
93 $champs['lien_demo'] = '';
94 $champs['lien_dev'] = '';
95 $champs['credit'] = '';
96
97 return $champs;
98 }
99
100
101 /**
102 * Normalise un nom issu d'un plugin.xml
103 *
104 * @todo Supprimer cette fonction qui ne sert nulle part ?
105 *
106 * @param string $nom
107 * Le nom
108 * @param string $langue
109 * La langue à extraire
110 * @param bool $supprimer_numero
111 * Supprimer les numéros ?
112 * @return string
113 * Le nom
114 **/
115 function normaliser_nom($nom, $langue='', $supprimer_numero=true) {
116 include_spip('inc/texte');
117
118 // On extrait les traductions de l'eventuel multi
119 // Si le nom n'est pas un multi alors le tableau renvoye est de la forme '' => 'nom'
120 $noms = extraire_trads(str_replace(array('<multi>', '</multi>'), array(), $nom, $nbr_replace));
121 $multi = ($nbr_replace > 0 AND !$langue) ? true : false;
122
123 $nouveau_nom = '';
124 foreach ($noms as $_lang => $_nom) {
125 $_nom = trim($_nom);
126 if (!$_lang)
127 $_lang = 'fr';
128 if ($supprimer_numero)
129 $nbr_matches = preg_match(',(.+)(\s+[\d._]*)$,Um', $_nom, $matches);
130 else
131 $nbr_matches = 0;
132 if (!$langue OR $langue == $_lang OR count($noms) == 1)
133 $nouveau_nom .= (($multi) ? '[' . $_lang . ']' : '') .
134 (($nbr_matches > 0) ? trim($matches[1]) : $_nom);
135 }
136
137 if ($nouveau_nom)
138 // On renvoie un nouveau nom multi ou pas sans la valeur de la branche
139 $nouveau_nom = (($multi) ? '<multi>' : '') . $nouveau_nom . (($multi) ? '</multi>' : '');
140
141 return $nouveau_nom;
142 }
143
144
145 /**
146 * Normalise un lien issu d'un plugin.xml
147 *
148 * Éliminer les textes superflus dans les liens (raccourcis [XXX->http...])
149 * et normaliser l'esperluete pour éviter l'erreur d'entité indéfinie
150 *
151 * @param string $url
152 * URL à normaliser
153 * @return string
154 * URL normalisée
155 */
156 function normaliser_lien($url) {
157 if (!preg_match(',https?://[^]\s]+,', $url, $r))
158 return '';
159 $url = str_replace('&', '&amp;', str_replace('&amp;', '&', $r[0]));
160 return $url;
161 }
162
163
164 /**
165 * Normalise un auteur ou une licence issue d'un plugin.xml
166 *
167 * - Élimination des multi (exclus dans la nouvelle version)
168 * - Transformation en attribut des balises A
169 * - Interprétation des balises BR et LI et de la virgule et du
170 * espace+tiret comme séparateurs
171 *
172 * @param string $texte
173 * Texte de la balise
174 * @param string $balise
175 * Nom de la balise (auteur | licence)
176 * @return array
177 * Tableau listant les auteurs, licences et copyright trouvés
178 */
179 function normaliser_auteur_licence($texte, $balise) {
180 include_spip('inc/filtres');
181 include_spip('inc/lien');
182 include_spip('inc/svp_outiller');
183
184 // On extrait le multi si besoin et on selectionne la traduction francaise
185 $t = normaliser_multi($texte);
186
187 $res = array('auteur' => array(), 'licence' => array(),'copyright' => array());
188 foreach(preg_split('@(<br */?>)|<li>|,|\s-|\n_*\s*|&amp;| & | et @', $t['fr']) as $v) {
189 // On detecte d'abord si le bloc texte en cours contient un eventuel copyright
190 // -- cela generera une balise copyright et non auteur
191 $copy = '';
192 if (preg_match('/(?:\&#169;|©|copyright|\(c\)|&copy;)[\s:]*([\d-]+)/i', $v, $r)) {
193 $copy = trim($r[1]);
194 $v = str_replace($r[0], '', $v);
195 $res['copyright'][] = $copy;
196 }
197
198 // On detecte ensuite un lien eventuel d'un auteur
199 // -- soit sous la forme d'une href d'une ancre
200 // -- soit sous la forme d'un raccourci SPIP
201 // Dans les deux cas on garde preferentiellement le contenu de l'ancre ou du raccourci
202 // si il existe
203 $href = $mail = '';
204 if (preg_match('@<a[^>]*href=(\W)(.*?)\1[^>]*>(.*?)</a>@', $v, $r)) {
205 $href = $r[2];
206 $v = str_replace($r[0], $r[3], $v);
207 }
208 elseif (preg_match(_RACCOURCI_LIEN,$v, $r)) {
209 if (preg_match('/([^\w\d._-]*)(([\w\d._-]+)@([\w\d.-]+))/', $r[4], $m)) {
210 $mail = $r[4];
211 }
212 else {
213 $href = $r[4];
214 }
215 $v = ($r[1]) ? $r[1] : str_replace($r[0], '', $v);
216 } else
217 $href = '';
218
219 // On detecte ensuite un mail eventuel
220 if (!$mail AND preg_match('/([^\w\d._-]*)(([\w\d._-]+)@([\w\d.-]+))/', $v, $r)) {
221 $mail = $r[2];
222 $v = str_replace($r[2], '', $v);
223 if (!$v) {
224 // On considere alors que la premiere partie du mail peut faire office de nom d'auteur
225 if (preg_match('/(([\w\d_-]+)[.]([\w\d_-]+))@/', $r[2], $s))
226 $v = ucfirst($s[2]) . ' ' . ucfirst($s[3]);
227 else
228 $v = ucfirst($r[3]);
229 }
230 }
231
232 // On detecte aussi si le bloc texte en cours contient une eventuelle licence
233 // -- cela generera une balise licence et non auteur
234 // cette heuristique n'est pas deterministe car la phrase de licence n'est pas connue
235 $licence = array();
236 if (preg_match('/\b((gnu|free|creative\s+common|cc)*[\/|\s|-]*(apache|lgpl|agpl|gpl|fdl|mit|bsd|art\s+|attribution|by)(\s+licence|\-sharealike|-nc-nd|-nc-sa|-sa|-nc|-nd)*\s*v*(\d*[\.\d+]*))\b/i', $v, $r)) {
237 if ($licence = definir_licence($r[2], $r[3], $r[4], $r[5])) {
238 $res['licence'][] = $licence;
239 }
240 }
241
242 // On finalise la balise auteur ou licence si on a pas trouve de licence prioritaire
243 if ($href)
244 $href = !preg_match(',https?://,', $href, $matches) ? "http://" . $href : $href;
245 $v = trim(textebrut($v));
246 if ((strlen($v) > 2) AND !$licence)
247 if ($balise == 'auteur')
248 $res['auteur'][] = array('nom' => $v, 'url' => $href, 'mail' => $mail);
249 else
250 $res['licence'][] = array('nom' => $v, 'url' => $href);
251 }
252
253 return $res;
254 }
255
256
257 /**
258 * Expanse les multi en un tableau de textes complets, un par langue
259 *
260 * @param string $texte
261 * Le texte
262 * @return array
263 * Texte expansé par code de langue : couples (code de langue => texte)
264 */
265 function normaliser_multi($texte) {
266 include_spip('inc/filtres');
267
268 if (!preg_match_all(_EXTRAIRE_MULTI, $texte, $regs, PREG_SET_ORDER))
269 return array('fr' => $texte);
270 $trads = array();
271 foreach ($regs as $reg) {
272 foreach (extraire_trads($reg[1]) as $k => $v) {
273 // Si le code de langue n'est pas precise dans le multi c'est donc fr
274 $lang = ($k) ? $k : 'fr';
275 $trads[$lang]= str_replace($reg[0], $v, isset($trads[$k]) ? $trads[$k] : $texte);
276 }
277 }
278 return $trads;
279 }
280
281 ?>