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