|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/***************************************************************************\ |
|
4
|
|
|
* SPIP, Système de publication pour l'internet * |
|
5
|
|
|
* * |
|
6
|
|
|
* Copyright © avec tendresse depuis 2001 * |
|
7
|
|
|
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * |
|
8
|
|
|
* * |
|
9
|
|
|
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. * |
|
10
|
|
|
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. * |
|
11
|
|
|
\***************************************************************************/ |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Fonctions pour l'affichage des informations de plugins |
|
15
|
|
|
* |
|
16
|
|
|
* @package SPIP\Core\Plugins |
|
17
|
|
|
**/ |
|
18
|
|
|
|
|
19
|
|
|
if (!defined('_ECRIRE_INC_VERSION')) { |
|
20
|
|
|
return; |
|
21
|
|
|
} |
|
22
|
|
|
include_spip('inc/charsets'); |
|
23
|
|
|
include_spip('inc/texte'); |
|
24
|
|
|
include_spip('inc/plugin'); // pour plugin_est_installe |
|
25
|
|
|
|
|
26
|
|
|
// https://code.spip.net/@ligne_plug |
|
27
|
|
|
function plugins_afficher_plugin_dist( |
|
28
|
|
|
$url_page, |
|
29
|
|
|
$plug_file, |
|
30
|
|
|
$checked, |
|
31
|
|
|
$actif, |
|
32
|
|
|
$expose = false, |
|
33
|
|
|
$class_li = "item", |
|
34
|
|
|
$dir_plugins = _DIR_PLUGINS |
|
35
|
|
|
) { |
|
36
|
|
|
|
|
37
|
|
|
static $id_input = 0; |
|
38
|
|
|
static $versions = array(); |
|
39
|
|
|
|
|
40
|
|
|
$force_reload = (_request('var_mode') == 'recalcul'); |
|
41
|
|
|
$get_infos = charger_fonction('get_infos', 'plugins'); |
|
42
|
|
|
$info = $get_infos($plug_file, $force_reload, $dir_plugins); |
|
43
|
|
|
$prefix = $info['prefix']; |
|
44
|
|
|
$cfg = ""; |
|
45
|
|
|
$checkable = ($dir_plugins !== _DIR_PLUGINS_DIST); |
|
46
|
|
|
$nom = plugin_nom($info, $dir_plugins, $plug_file); |
|
47
|
|
|
$erreur = ""; |
|
48
|
|
|
|
|
49
|
|
|
if (!plugin_version_compatible($info['compatibilite'], $GLOBALS['spip_version_branche'], 'spip')) { |
|
50
|
|
|
$info['slogan'] = _T('plugin_info_non_compatible_spip'); |
|
51
|
|
|
$erreur = http_img_pack("plugin-dis-32.png", _T('plugin_info_non_compatible_spip'), " class='picto_err'", |
|
52
|
|
|
_T('plugin_info_non_compatible_spip')); |
|
53
|
|
|
$class_li .= " disabled"; |
|
54
|
|
|
$checkable = false; |
|
55
|
|
|
} elseif (isset($info['erreur'])) { |
|
56
|
|
|
$class_li .= " error"; |
|
57
|
|
|
$erreur = http_img_pack("plugin-err-32.png", _T('plugin_info_erreur_xml'), " class='picto_err'", |
|
58
|
|
|
_T('plugin_info_erreur_xml')) |
|
59
|
|
|
. "<div class='erreur'>" . join('<br >', $info['erreur']) . "</div>"; |
|
60
|
|
|
$checkable = false; |
|
61
|
|
|
} elseif (isset($GLOBALS['erreurs_activation_raw'][$dir_plugins . $plug_file])) { |
|
62
|
|
|
$class_li .= " error"; |
|
63
|
|
|
$erreur = http_img_pack("plugin-err-32.png", _T('plugin_impossible_activer', array('plugin' => $nom)), |
|
64
|
|
|
" class='picto_err'", _T('plugin_impossible_activer', array('plugin' => $nom))) |
|
65
|
|
|
. "<div class='erreur'>" . implode("<br />", |
|
66
|
|
|
$GLOBALS['erreurs_activation_raw'][$dir_plugins . $plug_file]) . "</div>"; |
|
67
|
|
|
} else { |
|
68
|
|
|
$cfg = $actif ? plugin_bouton_config($plug_file, $info, $dir_plugins) : ""; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
// numerotons les occurrences d'un meme prefix |
|
72
|
|
|
$versions[$prefix] = $id = isset($versions[$prefix]) ? intval($versions[$prefix]) + 1 : ''; |
|
73
|
|
|
|
|
74
|
|
|
$class_li .= ($actif ? " actif" : "") . ($expose ? " on" : ""); |
|
75
|
|
|
|
|
76
|
|
|
return "<li id='$prefix$id' class='$class_li'>" |
|
77
|
|
|
. ((!$checkable and !$checked) |
|
78
|
|
|
? '' : plugin_checkbox(++$id_input, $dir_plugins . $plug_file, $checked)) |
|
79
|
|
|
. plugin_resume($info, $dir_plugins, $plug_file, $url_page) |
|
80
|
|
|
. $cfg |
|
81
|
|
|
. $erreur |
|
82
|
|
|
. (($dir_plugins !== _DIR_PLUGINS_DIST and plugin_est_installe($plug_file)) |
|
83
|
|
|
? plugin_desintalle($plug_file, $nom, $dir_plugins) : '') |
|
84
|
|
|
. "<div class='details'>" // pour l'ajax de exec/info_plugin |
|
85
|
|
|
. (!$expose ? '' : affiche_bloc_plugin($plug_file, $info, $dir_plugins)) |
|
86
|
|
|
. "</div>" |
|
87
|
|
|
. "</li>"; |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
function plugin_bouton_config($nom, $infos, $dir) { |
|
91
|
|
|
// la verification se base sur le filesystem |
|
92
|
|
|
// il faut donc n'utiliser que des minuscules, par convention |
|
93
|
|
|
$prefix = strtolower($infos['prefix']); |
|
94
|
|
|
// si paquet.xml fournit un squelette, le prendre |
|
95
|
|
|
if (isset($infos['config']) and $infos['config']) { |
|
96
|
|
|
return recuperer_fond("$dir$nom/" . $infos['config'], |
|
97
|
|
|
array( |
|
98
|
|
|
'script' => 'configurer_' . $prefix, |
|
99
|
|
|
'nom' => $nom |
|
100
|
|
|
)); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
// si le plugin CFG est la, l'essayer |
|
104
|
|
|
if (defined('_DIR_PLUGIN_CFG')) { |
|
105
|
|
|
if (include_spip('inc/cfg')) // test CFG version >= 1.0.5 |
|
106
|
|
|
{ |
|
107
|
|
|
if ($cfg = icone_lien_cfg("$dir$nom", "cfg")) { |
|
108
|
|
|
return "<div class='cfg_link'>$cfg</div>"; |
|
109
|
|
|
} |
|
110
|
|
|
} |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
// sinon prendre le squelette std sur le nom std |
|
114
|
|
|
return recuperer_fond("prive/squelettes/inclure/cfg", |
|
115
|
|
|
array( |
|
116
|
|
|
'script' => 'configurer_' . $prefix, |
|
117
|
|
|
'nom' => $nom |
|
118
|
|
|
)); |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
// checkbox pour activer ou desactiver |
|
122
|
|
|
// si ce n'est pas une extension |
|
123
|
|
|
|
|
124
|
|
|
function plugin_checkbox($id_input, $file, $actif) { |
|
125
|
|
|
$name = substr(md5($file), 0, 16); |
|
126
|
|
|
|
|
127
|
|
|
return "<div class='check'>\n" |
|
128
|
|
|
. "<input type='checkbox' name='s$name' id='label_$id_input'" |
|
129
|
|
|
. ($actif ? " checked='checked'" : "") |
|
130
|
|
|
. " class='checkbox' value='O' />" |
|
131
|
|
|
. "\n<label for='label_$id_input'>" . _T('activer_plugin') . "</label>" |
|
132
|
|
|
. "</div>"; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
function plugin_nom($info, $dir_plugins, $plug_file) { |
|
136
|
|
|
$prefix = $info['prefix']; |
|
137
|
|
|
$dir = "$dir_plugins$plug_file"; |
|
138
|
|
|
// Si dtd paquet, on traite le nom soit par son item de langue soit par sa valeur immediate a l'index "nom" |
|
139
|
|
|
if ($info['dtd'] == "paquet") { |
|
140
|
|
|
$nom = plugin_typo("{$prefix}_nom", "$dir/lang/paquet-$prefix"); |
|
141
|
|
|
if (!$nom) { |
|
142
|
|
|
$nom = typo($info['nom']); |
|
143
|
|
|
} |
|
144
|
|
|
} else { |
|
145
|
|
|
$nom = typo(attribut_html($info['nom'])); |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
return trim($nom); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
// Cartouche Resume |
|
152
|
|
|
function plugin_resume($info, $dir_plugins, $plug_file, $url_page) { |
|
153
|
|
|
$prefix = $info['prefix']; |
|
154
|
|
|
$dir = "$dir_plugins$plug_file"; |
|
155
|
|
|
$slogan = PtoBR(plugin_propre($info['slogan'], "$dir/lang/paquet-$prefix")); |
|
156
|
|
|
// une seule ligne dans le slogan : couper si besoin |
|
157
|
|
View Code Duplication |
if (($p = strpos($slogan, "<br />")) !== false) { |
|
|
|
|
|
|
158
|
|
|
$slogan = substr($slogan, 0, $p); |
|
159
|
|
|
} |
|
160
|
|
|
// couper par securite |
|
161
|
|
|
$slogan = couper($slogan, 80); |
|
162
|
|
|
|
|
163
|
|
|
$nom = plugin_nom($info, $dir_plugins, $plug_file); |
|
164
|
|
|
|
|
165
|
|
|
$url = parametre_url($url_page, "plugin", substr($dir, strlen(_DIR_RACINE))); |
|
166
|
|
|
|
|
167
|
|
|
$icon_class = 'icon'; |
|
168
|
|
|
$img = ''; |
|
169
|
|
|
if (isset($info['logo']) and $i = trim($info['logo'])) { |
|
170
|
|
|
if ($img = chemin_image("$dir/$i")) { |
|
171
|
|
|
$img = http_img_pack($img, '', " width='32' height='32'", '', ['variante_svg_si_possible' => true, 'chemin_image' => false]); |
|
172
|
|
|
} |
|
173
|
|
|
} |
|
174
|
|
|
if (!$img) { |
|
175
|
|
|
$img = http_img_pack("plugin-xx.svg", '', " width='32' height='32'"); |
|
176
|
|
|
$icon_class .= ' no-logo'; |
|
177
|
|
|
} |
|
178
|
|
|
else { |
|
179
|
|
|
# $img = "<img src='$img' width='32' height='32' alt='' />"; |
|
180
|
|
|
} |
|
181
|
|
|
$i = "<div class='$icon_class'><a href='$url' rel='info'>$img</a></div>"; |
|
182
|
|
|
|
|
183
|
|
|
return "<div class='resume'>" |
|
184
|
|
|
. "<h3><a href='$url' rel='info'>" |
|
185
|
|
|
. $nom |
|
186
|
|
|
. "</a></h3>" |
|
187
|
|
|
. " <span class='version'>" . $info['version'] . "</span>" |
|
188
|
|
|
. " <span class='etat'> - " |
|
189
|
|
|
. plugin_etat_en_clair($info['etat']) |
|
190
|
|
|
. "</span>" |
|
191
|
|
|
. "<div class='short'>" . $slogan . "</div>" |
|
192
|
|
|
. $i |
|
193
|
|
|
. "</div>"; |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
function plugin_desintalle($plug_file, $nom, $dir_plugins = null) { |
|
197
|
|
|
if (!$dir_plugins) { |
|
198
|
|
|
$dir_plugins = _DIR_PLUGINS; |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
$action = redirige_action_auteur('desinstaller_plugin', "$dir_plugins::$plug_file", 'admin_plugin'); |
|
202
|
|
|
$text = _T('bouton_desinstaller'); |
|
203
|
|
|
$text2 = _T('info_desinstaller_plugin'); |
|
204
|
|
|
$file = basename($plug_file); |
|
|
|
|
|
|
205
|
|
|
|
|
206
|
|
|
return "<div class='actions'>[" . |
|
207
|
|
|
"<a href='$action' |
|
208
|
|
|
onclick='return confirm(\"$text $nom ?\\n$text2\")'>" |
|
209
|
|
|
. $text |
|
210
|
|
|
. "</a>]</div>"; |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** |
|
214
|
|
|
* Traduit un type d'état de plugin |
|
215
|
|
|
* |
|
216
|
|
|
* Si l'état n'existe pas, prendra par défaut 'developpement' |
|
217
|
|
|
* |
|
218
|
|
|
* @param string $etat |
|
219
|
|
|
* Le type d'état (stable, test, ...) |
|
220
|
|
|
* @return string |
|
221
|
|
|
* Traduction de l'état dans la langue en cours |
|
222
|
|
|
**/ |
|
223
|
|
|
function plugin_etat_en_clair($etat) { |
|
224
|
|
|
if (!in_array($etat, array('stable', 'test', 'experimental'))) { |
|
225
|
|
|
$etat = 'developpement'; |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
return _T('plugin_etat_' . $etat); |
|
229
|
|
|
} |
|
230
|
|
|
|
|
231
|
|
|
// https://code.spip.net/@plugin_propre |
|
232
|
|
|
function plugin_propre($texte, $module = '',$propre='propre') { |
|
233
|
|
|
// retirer le retour a la racine du module, car le find_in_path se fait depuis la racine |
|
234
|
|
View Code Duplication |
if (_DIR_RACINE and strncmp($module, _DIR_RACINE, strlen(_DIR_RACINE)) == 0) { |
|
|
|
|
|
|
235
|
|
|
$module = substr($module, strlen(_DIR_RACINE)); |
|
236
|
|
|
} |
|
237
|
|
|
if (preg_match("|^\w+_[\w_]+$|", $texte)) { |
|
238
|
|
|
$texte = _T(($module ? "$module:" : '') . $texte, array(), array('force' => false)); |
|
239
|
|
|
} |
|
240
|
|
|
|
|
241
|
|
|
return $propre($texte); |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
function plugin_typo($texte, $module = '') { |
|
245
|
|
|
return plugin_propre($texte, $module, 'typo'); |
|
246
|
|
|
} |
|
247
|
|
|
|
|
248
|
|
|
|
|
249
|
|
|
// https://code.spip.net/@affiche_bloc_plugin |
|
250
|
|
|
function affiche_bloc_plugin($plug_file, $info, $dir_plugins = null) { |
|
251
|
|
|
if (!$dir_plugins) { |
|
252
|
|
|
$dir_plugins = _DIR_PLUGINS; |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
$prefix = $info['prefix']; |
|
256
|
|
|
$dir = "$dir_plugins$plug_file/lang/paquet-$prefix"; |
|
257
|
|
|
|
|
258
|
|
|
$s = ""; |
|
259
|
|
|
// TODO: le traiter_multi ici n'est pas beau |
|
260
|
|
|
// cf. description du plugin/_stable_/ortho/plugin.xml |
|
261
|
|
|
// concerne les anciens plugin.xml donc on devrait plus en avoir besoin |
|
262
|
|
|
$description = ""; |
|
263
|
|
|
if (isset($info['description'])) { |
|
264
|
|
|
$description = plugin_propre($info['description'], $dir); |
|
265
|
|
|
} |
|
266
|
|
|
|
|
267
|
|
|
if (isset($info['documentation']) |
|
268
|
|
|
and $lien = $info['documentation'] |
|
269
|
|
|
) { |
|
270
|
|
|
$description .= "<p><em class='site'><a href='$lien' class='spip_out'>" . _T('en_savoir_plus') . '</a></em></p>'; |
|
271
|
|
|
} |
|
272
|
|
|
$s .= "<dd class='desc'>" . $description . "</dd>\n"; |
|
273
|
|
|
|
|
274
|
|
View Code Duplication |
if (isset($info['auteur'])) { |
|
|
|
|
|
|
275
|
|
|
if (is_array($info['auteur'])) { |
|
276
|
|
|
$a = formater_credits($info['auteur'], ', '); |
|
277
|
|
|
} // pour compat mais ne doit plus arriver |
|
278
|
|
|
else { |
|
279
|
|
|
$a = trim($info['auteur']); |
|
280
|
|
|
} |
|
281
|
|
|
if ($a) { |
|
282
|
|
|
$s .= "<dt class='auteurs'>" . _T('public:par_auteur') . "</dt><dd class='auteurs'>" . PtoBR(propre($a, |
|
283
|
|
|
$dir)) . "</dd>\n"; |
|
284
|
|
|
} |
|
285
|
|
|
} |
|
286
|
|
|
|
|
287
|
|
|
if (isset($info['credit'])) { |
|
288
|
|
|
if ($a = formater_credits($info['credit'], ', ')) { |
|
289
|
|
|
$s .= "<dt class='credits'>" . _T('plugin_info_credit') . "</dt><dd class='credits'>" . PtoBR(propre($a, |
|
290
|
|
|
$dir)) . "</dd>\n"; |
|
291
|
|
|
} |
|
292
|
|
|
} |
|
293
|
|
|
|
|
294
|
|
View Code Duplication |
if (isset($info['licence'])) { |
|
|
|
|
|
|
295
|
|
|
if (is_array($info['licence'])) { |
|
296
|
|
|
$a = formater_credits($info['licence'], ', '); |
|
297
|
|
|
} // pour compat mais ne doit plus arriver |
|
298
|
|
|
else { |
|
299
|
|
|
$a = trim($info['licence']); |
|
300
|
|
|
} |
|
301
|
|
|
if ($a) { |
|
302
|
|
|
$s .= "<dt class='licence'>" . _T('intitule_licence') . "</dt><dd class='licence'>" . PtoBR(propre($a, |
|
303
|
|
|
$dir)) . "</dd>\n"; |
|
304
|
|
|
} |
|
305
|
|
|
} |
|
306
|
|
|
|
|
307
|
|
|
$s = "<dl class='description'>$s</dl>"; |
|
308
|
|
|
|
|
309
|
|
|
// |
|
310
|
|
|
// Ajouter les infos techniques |
|
311
|
|
|
// |
|
312
|
|
|
$infotech = array(); |
|
313
|
|
|
|
|
314
|
|
|
$version = "<dt>" . _T('version') . "</dt><dd>" . $info['version']; |
|
315
|
|
|
// Version VCS |
|
316
|
|
|
if ($vcs = version_vcs_courante($dir_plugins . $plug_file)) { |
|
317
|
|
|
$version .= ' ' . $vcs; |
|
318
|
|
|
} |
|
319
|
|
|
$version .= "</dd>"; |
|
320
|
|
|
$infotech[] = $version; |
|
321
|
|
|
$infotech[] = "<dt>" . _T('repertoire_plugins') . "</dt><dd>" . joli_repertoire("$dir_plugins$plug_file") . "</dd>"; |
|
322
|
|
|
// source zip le cas echeant |
|
323
|
|
|
$infotech[] = (lire_fichier($dir_plugins . $plug_file . '/install.log', $log) |
|
324
|
|
|
and preg_match(',^source:(.*)$,m', $log, $r)) |
|
325
|
|
|
? '<dt>' . _T('plugin_source') . '</dt><dd>' . trim($r[1]) . "</dd>" |
|
|
|
|
|
|
326
|
|
|
: ''; |
|
327
|
|
|
|
|
328
|
|
|
$infotech[] = !$info['necessite'] ? '' : |
|
329
|
|
|
('<dt>' . _T('plugin_info_necessite') . '</dt><dd>' . join(' ', |
|
330
|
|
|
array_map('array_shift', $info['necessite'])) . '</dd>'); |
|
331
|
|
|
|
|
332
|
|
|
$s .= "<dl class='tech'>" |
|
333
|
|
|
. join('', $infotech) |
|
334
|
|
|
. "</dl>"; |
|
335
|
|
|
|
|
336
|
|
|
|
|
337
|
|
|
return $s; |
|
338
|
|
|
} |
|
339
|
|
|
|
|
340
|
|
|
function formater_credits($infos, $sep = ', ') { |
|
341
|
|
|
$texte = ''; |
|
342
|
|
|
|
|
343
|
|
|
foreach ($infos as $_credit) { |
|
344
|
|
|
if ($texte) { |
|
345
|
|
|
$texte .= $sep; |
|
346
|
|
|
} |
|
347
|
|
|
// Si le credit en cours n'est pas un array c'est donc un copyright |
|
348
|
|
|
$texte .= |
|
349
|
|
|
(!is_array($_credit)) |
|
350
|
|
|
? PtoBR(propre($_credit)) |
|
351
|
|
|
: ($_credit['url'] ? '<a href="' . $_credit['url'] . '">' : '') . |
|
352
|
|
|
$_credit['nom'] . |
|
353
|
|
|
($_credit['url'] ? '</a>' : ''); |
|
354
|
|
|
} |
|
355
|
|
|
|
|
356
|
|
|
return $texte; |
|
357
|
|
|
} |
|
358
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.