From f9b2879e10435af4b58f26fc0b6036a0c6c12aac Mon Sep 17 00:00:00 2001
From: Matthieu Marcillaud <marcimat@rezo.net>
Date: Tue, 7 Feb 2017 19:18:50 +0000
Subject: [PATCH] =?UTF-8?q?Ticket=20#3819=20:=20Permettre=20d'indiquer=20c?=
 =?UTF-8?q?omme=20d=C3=A9pendance=20d'un=20plugin=20une=20extension=20PHP?=
 =?UTF-8?q?=20particuli=C3=A8re.=20Pour=20cela,=20comme=20on=20le=20fait?=
 =?UTF-8?q?=20d=C3=A9j=C3=A0=20pour=20la=20version=20de=20PHP,=20on=20ajou?=
 =?UTF-8?q?te=20chaqque=20extension=20PHP=20charg=C3=A9e=20dans=20les=20?=
 =?UTF-8?q?=C3=A9l=C3=A9ments=20procur=C3=A9s=20par=20le=20simili=20plugin?=
 =?UTF-8?q?=20'SPIP',=20sous=20la=20cl=C3=A9=20"php:{nom=20de=20l'extensio?=
 =?UTF-8?q?n}".?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Ainsi il est possible d'écrire dans un paquet.xml :

```
<necessite nom="php:curl" />
<necessite nom="php:xdebug" compatibilite="[2.0.0;]" />
```

Attention certaines extensions n'ont pas de numéro de version. Vérifier avec `php_version('nom extension')`.

Il faut adapter les messages de langue cependant pour éviter de dire qu'un plugin PHP:CURL est absent,
et du coup il y a quelques chaînes de langues en plus.

Il va falloir également adapter les chaînes de langue du plugin SVP.
---
 ecrire/inc/plugin.php        | 34 +++++++++++++++++++++++++++++-----
 ecrire/lang/ecrire_fr.php    |  5 +++++
 ecrire/plugins/get_infos.php |  4 ++++
 ecrire/xml/valider.php       |  4 ++--
 4 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/ecrire/inc/plugin.php b/ecrire/inc/plugin.php
index d72491d9b3..6c363c35ea 100644
--- a/ecrire/inc/plugin.php
+++ b/ecrire/inc/plugin.php
@@ -646,9 +646,30 @@ function plugin_controler_necessite($liste, $nom, $intervalle, $balise) {
 	);
 }
 
-
+/**
+ * @param string $intervalle
+ *     L'éventuelle intervalle de compatibilité de la dépendance. ex: [1.1.0;]
+ * @param string $version
+ *     La version en cours active pour le plugin demandé (ou php ou extension php demandée)
+ * @param string $nom
+ *     Le plugin (ou php ou extension php) qui est absent
+ * @param string $balise
+ *     Le type de balise utilisé (necessite ou utilise)
+ * @return string
+ *     Le message d'erreur.
+ */
 function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
 
+	// prendre en compte les erreurs de dépendances à PHP
+	// ou à une extension PHP avec des messages d'erreurs dédiés.
+	$type = 'plugin';
+	if ($nom === 'PHP') {
+		$type = 'php';
+	} elseif (strncmp($nom, 'PHP:', 4) === 0) {
+		$type = 'extension_php';
+		list(,$nom) = explode(':', $nom, 2);
+	}
+
 	if (preg_match(_EXTRAIRE_INTERVALLE, $intervalle, $regs)) {
 		$minimum = $regs[1];
 		$maximum = $regs[2];
@@ -658,13 +679,13 @@ function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
 
 		if (strlen($minimum)) {
 			if ($minimum_inclus and spip_version_compare($version, $minimum, '<')) {
-				return _T("plugin_${balise}_plugin", array(
+				return _T("plugin_${balise}_${type}", array(
 					'plugin' => $nom,
 					'version' => ' &ge; ' . $minimum
 				));
 			}
 			if (!$minimum_inclus and spip_version_compare($version, $minimum, '<=')) {
-				return _T("plugin_${balise}_plugin", array(
+				return _T("plugin_${balise}_${type}", array(
 					'plugin' => $nom,
 					'version' => ' &gt; ' . $minimum
 				));
@@ -673,7 +694,7 @@ function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
 
 		if (strlen($maximum)) {
 			if ($maximum_inclus and spip_version_compare($version, $maximum, '>')) {
-				return _T("plugin_${balise}_plugin", array(
+				return _T("plugin_${balise}_${type}", array(
 					'plugin' => $nom,
 					'version' => ' &le; ' . $maximum
 				));
@@ -687,7 +708,10 @@ function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
 		}
 	}
 
-	return _T("plugin_necessite_plugin_sans_version", array('plugin' => $nom));
+	// note : il ne peut pas y avoir d'erreur sur
+	// - un 'utilise' sans version.
+	// - un 'php' sans version.
+	return _T("plugin_necessite_${type}_sans_version", array('plugin' => $nom));
 }
 
 
diff --git a/ecrire/lang/ecrire_fr.php b/ecrire/lang/ecrire_fr.php
index 9dae357022..316d9871e5 100644
--- a/ecrire/lang/ecrire_fr.php
+++ b/ecrire/lang/ecrire_fr.php
@@ -677,8 +677,11 @@ dans une couleur qui indique leur état :',
 	'plugin_info_telecharger' => 'à télécharger depuis @url@ et à installer dans @rep@',
 	'plugin_info_upgrade_ok' => 'Mise à jour réussie',
 	'plugin_librairies_installees' => 'Librairies installées',
+	'plugin_necessite_extension_php' => 'Nécessite l’extension PHP @plugin@ en version @version@.',
 	'plugin_necessite_lib' => 'Ce plugin nécessite la librairie @lib@',
+	'plugin_necessite_php' => 'Nécessite @plugin@ en version @version@.',
 	'plugin_necessite_plugin' => 'Nécessite le plugin @plugin@ en version @version@.',
+	'plugin_necessite_extension_php_sans_version' => 'Nécessite l’extension PHP @plugin@',
 	'plugin_necessite_plugin_sans_version' => 'Nécessite le plugin @plugin@',
 	'plugin_necessite_spip' => 'Nécessite SPIP en version @version@ minimum.',
 	'plugin_source' => 'source : ',
@@ -686,6 +689,8 @@ dans une couleur qui indique leur état :',
 	'plugin_titre_automatique_ajouter' => 'Ajouter des plugins',
 	'plugin_titre_installation' => 'Installation du plugin @plugin@',
 	'plugin_titre_modifier' => 'Mes plugins',
+	'plugin_utilise_extension_php' => 'Utilise l’extension PHP @plugin@ en version @version@.',
+	'plugin_utilise_php' => 'Utilise @plugin@ en version @version@.',
 	'plugin_utilise_plugin' => 'Utilise le plugin @plugin@ en version @version@.',
 	'plugin_zip_active' => 'Continuez pour l’activer',
 	'plugin_zip_adresse' => 'indiquez ci-dessous l’adresse d’un fichier zip de plugin à télécharger, ou encore l’adresse d’une liste de plugins.',
diff --git a/ecrire/plugins/get_infos.php b/ecrire/plugins/get_infos.php
index de87cbab4e..27156df227 100644
--- a/ecrire/plugins/get_infos.php
+++ b/ecrire/plugins/get_infos.php
@@ -124,8 +124,12 @@ function plugins_get_infos_un($plug, $reload, $dir, &$cache) {
 	$ret['md5_file'] = $md5;
 	// Si on lit le paquet.xml de SPIP, on rajoute un procure php afin que les plugins puissent
 	// utiliser un necessite php. SPIP procure donc la version php courante du serveur.
+	// chaque librairie php est aussi procurée, par exemple 'php:curl'.
 	if (isset($ret['prefix']) and $ret['prefix'] == 'spip') {
 		$ret['procure']['php'] = array('nom' => 'php', 'version' => phpversion());
+		foreach (get_loaded_extensions() as $ext) {
+			$ret['procure']['php:' . $ext] = array('nom' => 'php:' . $ext, 'version' => phpversion($ext));
+		}
 	}
 	$diff = ($ret != $pcache);
 
diff --git a/ecrire/xml/valider.php b/ecrire/xml/valider.php
index 79e6073d5c..b0e3b46e05 100644
--- a/ecrire/xml/valider.php
+++ b/ecrire/xml/valider.php
@@ -238,8 +238,8 @@ class ValidateurXML {
 						. _T('zxml_vide_balise'));
 				}
 			} else {
-				$f = $this->fratrie[substr($depth, 2)];
-				if (!preg_match($regle, $f)) {
+				$f = isset($this->fratrie[substr($depth, 2)]) ? $this->fratrie[substr($depth, 2)] : null;
+				if (is_null($f) or !preg_match($regle, $f)) {
 					coordonnees_erreur($this,
 						" <p>\n<b>$name</b> "
 						. _T('zxml_succession_fils_incorrecte')
-- 
GitLab