[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#985958: marked as done (unblock: spip/3.2.11-2)



Your message dated Fri, 14 May 2021 20:57:55 +0200
with message-id <268be911-c569-9348-935b-9c68356da583@debian.org>
and subject line Re: Bug#985958: unblock: spip/3.2.11-2
has caused the Debian Bug report #985958,
regarding unblock: spip/3.2.11-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
985958: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=985958
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package spip

[ Reason ]
Upstream just released a new minor version to improve PHP 7.4 compat
(latest version already improved PHP 7.3 compat). Since Bullseye ship
with PHP 7.4, including those fixes should avoid future issues (I had
to backport a PHP 7.3 compatibility issue with a buster-security upload
already to fix a serious issue with plugins handling).

[ Impact ]
On top of fixing possible problems, this update avoids filling the
web server error.log due to multiple warnings and deprecation notices.

[ Tests ]
I only tested the package manually, but I’m keeping an eye on upstream
issues that may arise about this new release.

[ Risks ]
It’s a leaf, non-key package. Even if there are various changes, they
are mostly trivial.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]
I’ve filtered the debdiff with the following command (excluding getid3
changes because the package depends on an already up to date php-getid3
rather than the version vendored in, and some documentation), but the
result is still big, sorry:

 61 files changed, 647 insertions(+), 334 deletions(-)

  git diff debian/3.2.9-1 --ignore-all-space --ignore-blank-lines | \
  filterdiff --exclude=*/plugins-dist/medias/lib/getid3/* \
  --exclude=*NEWS --exclude=*README.md > /tmp/spip_ign_filtered.diff

unblock spip/3.2.11-2
diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT
index d9db953dec..f69be25c84 100644
--- a/CHANGELOG.TXT
+++ b/CHANGELOG.TXT
@@ -1,3 +1,99 @@
+SPIP-Core v3.2.10 -> v3.2.11 (26 March 2021)
+--------------------------------------------
+
+b52a4a5b3 | cedric       | 2021-03-12 | twitterbot est aussi notre ami pour le laisser scraper l'url qu'on veut touitter (fil)
+58d5d6190 | cedric       | 2021-02-15 | Report de https://git.spip.net/spip-contrib-outils/securite/commit/e7b571681a92eb40eddabbbb24b45dc472e113c1 qui fix #4..
+6611fd50b | cedric       | 2021-02-15 | Report de https://git.spip.net/spip-contrib-outils/securite/commit/3eccaf41426d4f3c8f28b50d81e12fbe5f8af4c2
+62d33c975 | marcimat     | 2021-03-26 | Notice-- : Attribut sans ses quotes... (realet)
+
+
+
+SPIP-Core v3.2.9 -> v3.2.10 (26 mars 2021)
+-------------------------------------------
+
+0b1bd0542 | marcimat      | 2018-09-05 | Compat PHP 7.x : Scorie résiduelle du passage à mysqli. Mais ces fonctions ne semblent plus utilisées.
+7621a660a | marcimat      | 2021-03-19 | Retour partiel sur 31df72005 pour compat PHP 5.4 ...
+4de4b3c34 | marcimat      | 2021-03-19 | Correction deprecated php 7.4 : ordre de join inversé.
+0ea620c9a | marcimat      | 2018-09-05 | Tickets #4059 et #4138 : meilleure compat PHP 7.2
+f69b39c9e | marcimat      | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+a54ab9a89 | rastapopoulos | 2021-03-14 | Backport de 2e55e3a60e à la main car plus dans le même fichier en 3.3.
+bdc53dcc9 | marcimat      | 2021-03-11 | Lorsqu'on déclare un traitement à un champ de rubrique, tel que `$table_des_traitements['DEMO']['rubriques'] = ...`, c..
+510983b09 | cedric        | 2021-03-09 | Fix https://core.spip.net/issues/4442 : le vieux parseur xml a la main (qu'il faudrait virer) ne tolerait pas l'utilis..
+31df72005 | marcimat      | 2021-03-05 | Suite de e11b28be4 : plus éviter une fatale en PHP 8 si unicode2charset cherche à utiliser un charset inexistant
+00c2038da | marcimat      | 2021-03-05 | Correction d'une Fatale Suite à 27e4f1bcc. C'est sport mais le commit ajoute des accents dans le squelettes prive/sque..
+e380b0afd | cy.altern     | 2021-03-04 | report a4cdf3b633
+916b67198 | marcimat      | 2021-03-04 | Ticket #4348 : Compat PHP 7.4 (deprecated curly braces array)
+910c245ea | marcimat      | 2020-03-26 | Compat PHP 7.4 : éviter une notice lorsque la pagination ne trouve aucune entrée.
+1b5549e51 | marcimat      | 2019-08-26 | Ticket #4348 : Compat PHP 7.4 (notice).
+c5492ea3e | marcimat      | 2019-08-26 | Ticket #4348 : Compat PHP 7.4 (deprecated curly braces array)
+da6dfc068 | marcimat      | 2019-08-26 | Ticket #4348 : Compat PHP 7.4, Trying to access array offset on value of type null.
+db1814dc5 | marcimat      | 2019-08-25 | Compat PHP 7.4, Deprecated:  Array and string offset access syntax with curly braces (Francky)
+330eb930f | marcimat      | 2019-06-17 | Ticket #4348 : Correction pour PHP 7.4 (Left-associative ternary operator deprecation)
+130ada180 | marcimat      | 2018-02-09 | Compatibilité PHP 7.2 : create_function => function xxx each => key, current, next
+8075d79f2 | marcimat      | 2017-12-11 |  Ticket #4059 : Compat PHP 7.2, remplacer un create_function.
+061107f80 | marcimat      | 2017-12-11 | Ticket #4059 : Compat PHP 7.2, remplacer des create_function.
+af94fa5d9 | marcimat      | 2017-12-11 | Ticket #4059 : Compat PHP 7.2, remplacer des create_function. (encore un eval du coup).
+e7fe0d5aa | marcimat      | 2017-12-11 | Ticket #4059 : Compat PHP 7.2, remplacer des create_function.
+49f24e83b | marcimat      | 2017-12-11 | Ticket #4059 : Compat PHP 7.2. Un create_function de moins. Pour le coup, ça semble obligé ici de conserver une évalua..
+6555cb7b4 | marcimat      | 2021-03-04 | Report adapté de 5647069fb (Meilleure compat PHP 7.3)
+fcb3e1f5e | marcimat      | 2019-08-21 | Ticket #4348 : Notices/Warning en PHP 7.3+ : éviter un appel à time() avec un argument.
+31c614782 | bruno         | 2020-03-13 | report adapté de a0c24ecb6f8c1d70dce86b859eb448fb0415d869
+60d4d3d1f | cedric        | 2021-02-17 | Fix vraiment #4167 : _deja_loge peut contenir un js de redirection et doit donc etre non filtre par interdire_scripts()
+7046e391d | cedric        | 2021-02-17 | Fix #4387 : Revert "Fix #4167 : éviter d'afficher le script de redirection js quand le form de login est utilisé en aj..
+03cc99fce | cedric        | 2021-02-17 | Fix l'utilisation du niveau de log 0 (maieul) cf https://git.spip.net/spip/spip/pulls/106
+62e4284fd | bruno         | 2021-02-10 | éviter un plantage avec url_page quand on utilise une fonction perso pour generer_generer_url_XXX
+0281d90f2 | maieul        | 2021-02-10 | fix #4633, ne pas passer une date quotée au pipeline optimiser_base_disparus
+
+
+SPIP-plugins-dist v3.2.9 -> v3.2.10 (26 mars 2021)
+---------------------------------------------------
+
+aide                    | 329cfce | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+archiviste              | de3283f | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+breves                  | 668efb9 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+breves                  | 658f025 | maieul       | 2021-02-10 | Adaptation du code au fix du core https://core.spip.net/issues/4633
+compagnon               | d8aaa96 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+compresseur             | 08b96ff | marcimat     | 2021-03-24 | Mise à jour de CSSTidy en version 1.7.3
+compresseur             | 30d1b1f | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+compresseur             | 827ba88 | marcimat     | 2018-09-05 | Tickets #4059 et #4138 : meilleure compat PHP 7.2
+dump                    | d767e27 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+filtres_images          | eb9ace8 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+forum                   | cb90b1a | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+jquery_ui               | b04572e | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+mediabox                | bcadf3d | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+medias                  | d096d93 | marcimat     | 2021-03-26 | Report de d1ca0c8c : Suite de 890506eb99 : Il faut ajouteur la classe .portfolios__titre aux autres blocs documents du..
+medias                  | 4e13bea | cedric       | 2021-03-25 | Fix regression (Maieul via https://git.spip.net/spip/medias/pulls/17)
+medias                  | 1d917cd | spip.franck  | 2020-07-12 | - Mise à jour de la lib getid3 en 1.9.20, nous étions en 1.9.18 - Le changelog est dispo ici: https://github.com/James..
+medias                  | e019d3e | spip.franck  | 2019-09-20 | Mise à jour de la lib getid3 en 1.9.18, nous étions en 1.9.16. Le changelog est dispo ici: https://github.com/JamesHei..
+medias                  | 2dc03d5 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+mots                    | 6a346ba | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+organiseur              | a7177ba | marcimat     | 2021-03-19 | Correction join à l'envers.
+organiseur              | 7c665fc | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+petitions               | 2909a25 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+plan                    | e722c87 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+porte_plume             | 0003d09 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+revisions               | 1d88a68 | bruno        | 2018-09-15 | retour sur r111482 : éviter une erreur Maximum execution time
+revisions               | 2f2d47c | marcimat     | 2018-09-05 | Tickets #4059 et #4138 : meilleure compat PHP 7.2
+revisions               | 535cb2f | marcimat     | 2018-09-15 | Correction sur r111486 (compat PHP 7.2, suppression each()) qui était erronné.
+revisions               | aa56bf3 | marcimat     | 2018-09-05 | Ticket #4138 : Compatibilité PHP 7.2
+revisions               | df4b821 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+revisions               | 19c0b6c | marcimat     | 2019-08-21 | Ticket #4348 : Compat PHP 7.4+ Deprecated: The behavior of unparenthesized expressions containing both '.' and '+'/'-'
+safehtml                | b2853a1 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+safehtml                | 6e81e13 | marcimat     | 2019-08-26 | Tiket #4348 / Compat PHP 7.4 : Array and string offset access syntax with curly braces is deprecated
+sites                   | 622387c | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+squelettes_par_rubrique | 357b283 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+statistiques            | 291386b | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+svp                     | a3c6abf | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+svp                     | 9fd9349 | marcimat     | 2019-08-25 | Compat PHP 7.4, Deprecated:  Array and string offset access syntax with curly braces (Francky)
+textwheel               | 8f70594 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+textwheel               | 84d32c5 | cedric       | 2018-09-06 | create_function est deprecie en PHP 7.2, on reecrit donc l'optimisation des subwheels via une fonction anonyme de type..
+textwheel               | 1bf8732 | marcimat     | 2018-02-09 | Compat PHP 7.2 : create_function => function (les plus simples, mais il en reste !…)
+urls_etendues           | be9066b | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+vertebres               | a381bc9 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+squelettes-dist         | 6323be9 | marcimat     | 2021-03-18 | Suppression du fichier .gitattributes inutile.
+
+
+
 SPIP-Core v3.2.8 -> v3.2.9 (12 février 2021)
 ---------------------------------------------
 
diff --git a/config/ecran_securite.php b/config/ecran_securite.php
index b471156606..773ae6c139 100644
--- a/config/ecran_securite.php
+++ b/config/ecran_securite.php
@@ -5,7 +5,7 @@
  * ------------------
  */
 
-define('_ECRAN_SECURITE', '1.3.13'); // 2019-12-04
+define('_ECRAN_SECURITE', '1.4.1'); // 2021-03-12
 
 /*
  * Documentation : http://www.spip.net/fr_article4200.html
@@ -17,6 +17,10 @@ define('_ECRAN_SECURITE', '1.3.13'); // 2019-12-04
 if (isset($_GET['test_ecran_securite']))
 	$ecran_securite_raison = 'test '._ECRAN_SECURITE;
 
+if (file_exists($f = __DIR__ . DIRECTORY_SEPARATOR  . 'ecran_securite_options.php')) {
+	include ($f);
+}
+
 /*
  * Monitoring
  * var_isbot=0 peut etre utilise par un bot de monitoring pour surveiller la disponibilite d'un site vu par les users
@@ -226,12 +230,15 @@ if (!defined('_IS_BOT')){
 if (!defined('_IS_BOT_FRIEND')){
 	define('_IS_BOT_FRIEND',
 		isset($_SERVER['HTTP_USER_AGENT'])
-		and preg_match(',' . implode ('|', array(
+			and preg_match(
+				',' . implode('|', array(
 					'facebookexternalhit',
+					'twitterbot',
 					'flipboardproxy',
 					'wordpress'
 				)) . ',i',
-		(string)$_SERVER['HTTP_USER_AGENT'])
+				(string)$_SERVER['HTTP_USER_AGENT']
+			)
 	);
 }
 
@@ -544,6 +551,7 @@ if (isset($ecran_securite_raison)) {
 	header("Cache-Control: no-cache, must-revalidate");
 	header("Pragma: no-cache");
 	header("Content-Type: text/html");
+	header("Connection: close");
 	die("<html><title>Error 403: Forbidden</title><body><h1>Error 403</h1><p>You are not authorized to view this page ($ecran_securite_raison)</p></body></html>");
 }
 
@@ -598,5 +606,6 @@ if (
 	header("Cache-Control: no-cache, must-revalidate");
 	header("Pragma: no-cache");
 	header("Content-Type: text/html");
+	header("Connection: close");
 	die("<html><title>Status 429: Too Many Requests</title><body><h1>Status 429</h1><p>Too Many Requests (try again soon)</p></body></html>");
 }
diff --git a/debian/changelog b/debian/changelog
index c286bd1115..c3dc5dcbb0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,23 @@
+spip (3.2.11-2) unstable; urgency=medium
+
+  * Upload to unstable with the Release Team approval
+  * Update debian/copyright
+
+ -- David Prévot <taffit@debian.org>  Fri, 26 Mar 2021 15:37:27 -0400
+
+spip (3.2.11-1) experimental; urgency=medium
+
+  * Upload to experimental during the freeze
+
+  [ Matthieu Marcillaud ]
+  * Compat PHP 7.4
+  * Version SPIP 3.2.11
+
+  [ David Prévot ]
+  * Refresh patches header
+
+ -- David Prévot <taffit@debian.org>  Fri, 26 Mar 2021 13:45:07 -0400
+
 spip (3.2.9-1) unstable; urgency=medium
 
   * Critical security fixes, allowing identified authors to execute arbitrary
diff --git a/debian/copyright b/debian/copyright
index 2504e59c84..bbf5009997 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -22,6 +22,7 @@ Files: ecrire/inc/idna_convert.class.php
 Copyright: 2004-2016 phlyLabs Berlin <https://phlylabs.de>
            2009 Vincent Blavet
            2005-2007 Florian Schmitz <speed@webo.name>
+           2010-2019 Cedric Morin <cedric.morin@yterium.com>
            2004-2005 Dean Edwards <floele@gmail.com>
 License: LGPL-2.1+
 
diff --git a/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch b/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch
index bf0e616031..1a61ce0422 100644
--- a/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch
+++ b/debian/patches/0001-Fix-created-directories-and-files-default-rights.patch
@@ -14,7 +14,7 @@ Last-Update: 2013-05-24
  2 files changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
-index 6d45f32..2c91aed 100644
+index a4f5006..616dcf4 100644
 --- a/ecrire/inc_version.php
 +++ b/ecrire/inc_version.php
 @@ -366,7 +366,7 @@ $liste_des_authentifications = array(
diff --git a/debian/patches/0004-Fix-displayed-version-in-the-private-interface.patch b/debian/patches/0004-Fix-displayed-version-in-the-private-interface.patch
index b3c023e158..98ab0501fb 100644
--- a/debian/patches/0004-Fix-displayed-version-in-the-private-interface.patch
+++ b/debian/patches/0004-Fix-displayed-version-in-the-private-interface.patch
@@ -14,7 +14,7 @@ Last-Update: 2013-05-24
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
-index 2c91aed..e3a26d3 100644
+index 616dcf4..6b33381 100644
 --- a/ecrire/inc_version.php
 +++ b/ecrire/inc_version.php
 @@ -393,7 +393,7 @@ $spip_sql_version = 1;
diff --git a/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch b/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch
index bc58007721..41370af077 100644
--- a/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch
+++ b/debian/patches/0005-Use-HTMLSax3-class-from-the-php-xml-htmlsax3-package.patch
@@ -23,7 +23,7 @@ index 800cd95..296a87e 100644
  			$process->deleteTags[] = 'param'; // sinon bug Firefox
  		}
 diff --git a/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php b/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
-index ca88e8a..4e03ed6 100644
+index 6959b1c..66bfda1 100644
 --- a/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
 +++ b/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
 @@ -18,7 +18,7 @@
diff --git a/ecrire/auth/sha256.inc.php b/ecrire/auth/sha256.inc.php
index 3b9c49be4e..887bc49b31 100644
--- a/ecrire/auth/sha256.inc.php
+++ b/ecrire/auth/sha256.inc.php
@@ -258,7 +258,7 @@ if (!class_exists('nanoSha2')) {
 				return false;
 			}
 
-			$h = ord($c{$index});
+			$h = ord($c[$index]);
 
 			if ($h <= 0x7F) {
 				$bytes = 1;
@@ -274,20 +274,20 @@ if (!class_exists('nanoSha2')) {
 					if ($h <= 0xDF && $index < $len-1) {
 						$bytes = 2;
 
-						return ($h & 0x1F) << 6 | (ord($c{$index+1}) & 0x3F);
+						return ($h & 0x1F) << 6 | (ord($c[$index+1]) & 0x3F);
 					} else {
 						if ($h <= 0xEF && $index < $len-2) {
 							$bytes = 3;
 
-							return ($h & 0x0F) << 12 | (ord($c{$index+1}) & 0x3F) << 6
-							| (ord($c{$index+2}) & 0x3F);
+							return ($h & 0x0F) << 12 | (ord($c[$index+1]) & 0x3F) << 6
+							| (ord($c[$index+2]) & 0x3F);
 						} else {
 							if ($h <= 0xF4 && $index < $len-3) {
 								$bytes = 4;
 
-								return ($h & 0x0F) << 18 | (ord($c{$index+1}) & 0x3F) << 12
-								| (ord($c{$index+2}) & 0x3F) << 6
-								| (ord($c{$index+3}) & 0x3F);
+								return ($h & 0x0F) << 18 | (ord($c[$index+1]) & 0x3F) << 12
+								| (ord($c[$index+2]) & 0x3F) << 6
+								| (ord($c[$index+3]) & 0x3F);
 							} else {
 								// pas utf mais renvoyer quand meme ce qu'on a
 								$bytes = 1;
diff --git a/ecrire/balise/url_.php b/ecrire/balise/url_.php
index 3f16b2c41e..a3bb55c73e 100644
--- a/ecrire/balise/url_.php
+++ b/ecrire/balise/url_.php
@@ -277,7 +277,7 @@ function balise_URL_PAGE_dist($p) {
 				$code .= ", $args";
 			}
 			$code = $f('page', $code, $s);
-
+			$p->code = $code;
 			return $p;
 		}
 		$s = 'connect=' . addslashes($s);
diff --git a/ecrire/base/upgrade.php b/ecrire/base/upgrade.php
index 41ad9582d9..72f8dd4920 100644
--- a/ecrire/base/upgrade.php
+++ b/ecrire/base/upgrade.php
@@ -92,7 +92,7 @@ function base_upgrade_dist($titre = '', $reprise = '') {
  * @param string $redirect
  * @return array|bool
  */
-function maj_base($version_cible = 0, $redirect = '') {
+function maj_base($version_cible = 0, $redirect = '', $debut_page = true) {
 
 	$version_installee = @$GLOBALS['meta']['version_installee'];
 	//
@@ -152,7 +152,7 @@ function maj_base($version_cible = 0, $redirect = '') {
 
 	include_spip('maj/svn10000');
 	ksort($GLOBALS['maj']);
-	$res = maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee', 'meta', $redirect, true);
+	$res = maj_while($version_installee, $cible, $GLOBALS['maj'], 'version_installee', 'meta', $redirect, $debut_page);
 	if ($res) {
 		if (!is_array($res)) {
 			spip_log("Pb d'acces SQL a la mise a jour", 'maj.' . _LOG_INFO_ERREUR);
@@ -381,8 +381,7 @@ function maj_while($installee, $cible, $maj, $meta = '', $table = 'meta', $redir
 		define('_TIME_OUT', $time + _UPGRADE_TIME_OUT);
 	}
 
-	reset($maj);
-	while (list($v, ) = each($maj)) {
+	foreach ($maj as $v => $operations) {
 		// si une maj pour cette version
 		if ($v == 'init' or
 			(spip_version_compare($v, $installee, '>')
@@ -392,7 +391,7 @@ function maj_while($installee, $cible, $maj, $meta = '', $table = 'meta', $redir
 				maj_debut_page($v, $meta, $table);
 			}
 			echo "MAJ $v";
-			$etape = serie_alter($v, $maj[$v], $meta, $table, $redirect);
+			$etape = serie_alter($v, $operations, $meta, $table, $redirect);
 			$trouver_table(''); // vider le cache des descriptions de table
 			# echec sur une etape en cours ?
 			# on sort
diff --git a/ecrire/genie/optimiser.php b/ecrire/genie/optimiser.php
index 639aad06d4..455d969fe1 100644
--- a/ecrire/genie/optimiser.php
+++ b/ecrire/genie/optimiser.php
@@ -155,7 +155,8 @@ function optimiser_sansref($table, $id, $sel, $and = '') {
 function optimiser_base_disparus($attente = 86400) {
 
 	# format = 20060610110141, si on veut forcer une optimisation tout de suite
-	$mydate = sql_quote(date("Y-m-d H:i:s", time() - $attente));
+	$mydate = date("Y-m-d H:i:s", time() - $attente);
+	$mydate_quote = sql_quote($mydate);
 
 	$n = 0;
 
@@ -173,12 +174,12 @@ function optimiser_base_disparus($attente = 86400) {
 		          ON A.id_rubrique=R.id_rubrique",
 		"A.id_rubrique > 0
 			 AND R.id_rubrique IS NULL
-		         AND A.maj < $mydate");
+		         AND A.maj < $mydate_quote");
 
 	$n += optimiser_sansref('spip_articles', 'id_article', $res);
 
 	// les articles a la poubelle
-	sql_delete("spip_articles", "statut='poubelle' AND maj < $mydate");
+	sql_delete("spip_articles", "statut='poubelle' AND maj < $mydate_quote");
 
 	//
 	// Auteurs
@@ -195,7 +196,7 @@ function optimiser_base_disparus($attente = 86400) {
 		      	LEFT JOIN spip_auteurs_liens AS L
 		          ON L.id_auteur=A.id_auteur",
 		"L.id_auteur IS NULL
-		       	AND A.statut='5poubelle' AND A.maj < $mydate");
+		       	AND A.statut='5poubelle' AND A.maj < $mydate_quote");
 
 	$n += optimiser_sansref('spip_auteurs', 'id_auteur', $res);
 
diff --git a/ecrire/inc/charsets.php b/ecrire/inc/charsets.php
index 7dbd178e70..98036d609c 100644
--- a/ecrire/inc/charsets.php
+++ b/ecrire/inc/charsets.php
@@ -404,20 +404,26 @@ function charset2unicode($texte, $charset = 'AUTO' /* $forcer: obsolete*/) {
 		default:
 			// mbstring presente ?
 			if (init_mb_string()) {
-				if ($order = mb_detect_order() # mb_string connait-il $charset?
-					and mb_detect_order($charset)
-				) {
+				$order = mb_detect_order();
+				try {
+					# mb_string connait-il $charset?
+					if ($order and mb_detect_order($charset)) {
 						$s = mb_convert_encoding($texte, 'utf-8', $charset);
 						if ($s && $s != $texte) {
 							return utf_8_to_unicode($s);
 						}
 					}
+					
+				} catch (\Exception $e) {
+					// Le charset n'existe probablement pas
+				} 
 				mb_detect_order($order); # remettre comme precedemment
 			}
 
 			// Sinon, peut-etre connaissons-nous ce charset ?
 			if (!isset($trans[$charset])) {
-				if ($cset = load_charset($charset)
+				if (
+					$cset = load_charset($charset)
 					and is_array($GLOBALS['CHARSET'][$cset])
 				) {
 					foreach ($GLOBALS['CHARSET'][$cset] as $key => $val) {
@@ -425,7 +431,7 @@ function charset2unicode($texte, $charset = 'AUTO' /* $forcer: obsolete*/) {
 					}
 				}
 			}
-			if (count($trans[$charset])) {
+			if (isset($trans[$charset]) and count($trans[$charset])) {
 				return str_replace(array_keys($trans[$charset]), array_values($trans[$charset]), $texte);
 			}
 
@@ -831,7 +837,7 @@ function javascript_to_binary($texte) {
  * @return string
  */
 function translitteration_rapide($texte, $charset = 'AUTO', $complexe = '') {
-	static $trans;
+	static $trans = [];
 	if ($charset == 'AUTO') {
 		$charset = $GLOBALS['meta']['charset'];
 	}
@@ -842,7 +848,8 @@ function translitteration_rapide($texte, $charset = 'AUTO', $complexe = '') {
 	$table_translit = 'translit' . $complexe;
 
 	// 2. Translitterer grace a la table predefinie
-	if (!$trans[$complexe]) {
+	if (!isset($trans[$complexe])) {
+		$trans[$complexe] = [];
 		load_charset($table_translit);
 		foreach ($GLOBALS['CHARSET'][$table_translit] as $key => $val) {
 			$trans[$complexe][caractere_utf_8($key)] = $val;
@@ -897,8 +904,11 @@ function translitteration_complexe($texte, $chiffres = false) {
 	$texte = translitteration($texte, 'AUTO', 'complexe');
 
 	if ($chiffres) {
-		$texte = preg_replace("/[aeiuoyd]['`?~.^+(-]{1,2}/eS",
-			"translitteration_chiffree('\\0')", $texte);
+		$texte = preg_replace_callback(
+			"/[aeiuoyd]['`?~.^+(-]{1,2}/S",
+			function($m) { return translitteration_chiffree($m[0]); },
+			$texte
+		);
 	}
 
 	return $texte;
@@ -994,34 +1004,29 @@ function transcoder_page($texte, $headers = '') {
 		return $texte;
 	}
 
-	// Reconnaitre le BOM utf-8 (0xEFBBBF)
 	if (bom_utf8($texte)) {
+		// Reconnaitre le BOM utf-8 (0xEFBBBF)
 		$charset = 'utf-8';
 		$texte = substr($texte, 3);
-	} // charset precise par le contenu (xml)
-	else {
-		if (preg_match(
-			',<[?]xml[^>]*encoding[^>]*=[^>]*([-_a-z0-9]+?),UimsS', $texte, $regs)) {
+	} elseif (preg_match(',<[?]xml[^>]*encoding[^>]*=[^>]*([-_a-z0-9]+?),UimsS', $texte, $regs)) {
+		// charset precise par le contenu (xml)
 		$charset = trim(strtolower($regs[1]));
-		} // charset precise par le contenu (html)
-		else {
-			if (preg_match(
-					',<(meta|html|body)[^>]*charset[^>]*=[^>]*([-_a-z0-9]+?),UimsS',
-					$texte, $regs)
-				# eviter #CHARSET des squelettes
-				and (($tmp = trim(strtolower($regs[2]))) != 'charset')
+	} elseif (
+		// charset precise par le contenu (html)
+		preg_match(',<(meta|html|body)[^>]*charset[^>]*=[^>]*([#-_a-z0-9]+?),UimsS', $texte, $regs)
+		# eviter toute balise SPIP tel que #CHARSET ou #CONFIG d'un squelette
+		and false === strpos($regs[2], '#')
+		and $tmp = trim(strtolower($regs[2]))
 	) {
 		$charset = $tmp;
-			} // charset de la reponse http
-			else {
-				if (preg_match(',charset=([-_a-z0-9]+),i', $headers, $regs)) {
+	} elseif (preg_match(',charset=([-_a-z0-9]+),i', $headers, $regs)) {
+		// charset de la reponse http
 		$charset = trim(strtolower($regs[1]));
 	} else {
 		$charset = '';
 	}
-			}
-		}
-	}
+
+
 	// normaliser les noms du shif-jis japonais
 	if (preg_match(',^(x|shift)[_-]s?jis$,i', $charset)) {
 		$charset = 'shift-jis';
diff --git a/ecrire/inc/config.php b/ecrire/inc/config.php
index ede9c12fbe..d5d4113ced 100644
--- a/ecrire/inc/config.php
+++ b/ecrire/inc/config.php
@@ -544,8 +544,8 @@ function actualise_metas($liste_meta) {
 	// verifier le impt=non
 	sql_updateq('spip_meta', array('impt' => 'non'), sql_in('nom', $meta_serveur));
 
-	while (list($nom, $valeur) = each($liste_meta)) {
-		if (!isset($GLOBALS['meta'][$nom]) or !$GLOBALS['meta'][$nom]) {
+	foreach ($liste_meta as $nom => $valeur) {
+		if (empty($GLOBALS['meta'][$nom])) {
 			ecrire_meta($nom, $valeur);
 		}
 	}
diff --git a/ecrire/inc/filtres.php b/ecrire/inc/filtres.php
index 3b37483e23..064a44e7f3 100644
--- a/ecrire/inc/filtres.php
+++ b/ecrire/inc/filtres.php
@@ -1916,11 +1916,13 @@ function alterner($i) {
  **/
 function extraire_attribut($balise, $attribut, $complet = false) {
 	if (is_array($balise)) {
-		array_walk($balise,
-			create_function('&$a,$key,$t',
-				'$a = extraire_attribut($a,$t);'
-			),
-			$attribut);
+		array_walk(
+			$balise,
+			function(&$a, $key, $t){
+				$a = extraire_attribut($a, $t);
+			},
+			$attribut
+		);
 
 		return $balise;
 	}
@@ -2361,7 +2363,7 @@ function microformat2enclosure($tags) {
 function tags2dcsubject($tags) {
 	$subjects = '';
 	foreach (extraire_balises($tags, 'a') as $e) {
-		if (extraire_attribut($e, rel) == 'tag') {
+		if (extraire_attribut($e, 'rel') == 'tag') {
 			$subjects .= '<dc:subject>'
 				. texte_backend(textebrut($e))
 				. '</dc:subject>' . "\n";
@@ -2400,7 +2402,9 @@ function extraire_balise($texte, $tag = 'a') {
 	if (is_array($texte)) {
 		array_walk(
 			$texte,
-			create_function('&$a,$key,$t', '$a = extraire_balise($a,$t);'),
+			function(&$a, $key, $t){
+				$a = extraire_balise($a, $t);
+			},
 			$tag
 		);
 
@@ -2442,7 +2446,9 @@ function extraire_balises($texte, $tag = 'a') {
 	if (is_array($texte)) {
 		array_walk(
 			$texte,
-			create_function('&$a,$key,$t', '$a = extraire_balises($a,$t);'),
+			function(&$a, $key, $t){
+				$a = extraire_balises($a, $t);
+			},
 			$tag
 		);
 
@@ -2846,9 +2852,11 @@ function urls_absolues_css($contenu, $source) {
 
 	return preg_replace_callback(
 		",url\s*\(\s*['\"]?([^'\"/#\s][^:]*)['\"]?\s*\),Uims",
-		create_function('$x',
-			'return "url(\'".suivre_lien(\'' . $path . '\',$x[1])."\')";'
-		), $contenu);
+		function($x) use ($path) {
+			return "url('" . suivre_lien($path, $x[1]) . "')";
+		},
+		$contenu
+	);
 }
 
 
@@ -4273,12 +4281,16 @@ function bouton_action($libelle, $url, $class = "", $confirm = "", $title = "",
 /**
  * Proteger les champs passes dans l'url et utiliser dans {tri ...}
  * preserver l'espace pour interpreter ensuite num xxx et multi xxx
+ * on permet d'utiliser les noms de champ prefixes
+ * articles.titre
+ * et les propriete json
+ * properties.gis[0].ville
  *
  * @param string $t
  * @return string
  */
 function tri_protege_champ($t) {
-	return preg_replace(',[^\s\w.+],', '', $t);
+	return preg_replace(',[^\s\w.+\[\]],', '', $t);
 }
 
 /**
diff --git a/ecrire/inc/filtres_images_lib_mini.php b/ecrire/inc/filtres_images_lib_mini.php
index d93acc1e03..b45889b4e9 100644
--- a/ecrire/inc/filtres_images_lib_mini.php
+++ b/ecrire/inc/filtres_images_lib_mini.php
@@ -853,7 +853,7 @@ function _image_tag_changer_taille($tag, $width, $height, $style = false) {
 
 	// enlever le width et height du style
 	$style = preg_replace(",(^|;)\s*(width|height)\s*:\s*[^;]+,ims", "", $style);
-	if ($style and $style{0} == ';') {
+	if ($style and $style[0] == ';') {
 		$style = substr($style, 1);
 	}
 
diff --git a/ecrire/inc/idna_convert.class.php b/ecrire/inc/idna_convert.class.php
index 5407a998e3..5e4e4fd283 100644
--- a/ecrire/inc/idna_convert.class.php
+++ b/ecrire/inc/idna_convert.class.php
@@ -423,7 +423,7 @@ class idna_convert {
         $delim_pos = strrpos($encoded, '-');
         if ($delim_pos > self::byteLength($this->_punycode_prefix)) {
             for ($k = self::byteLength($this->_punycode_prefix); $k < $delim_pos; ++$k) {
-                $decoded[] = ord($encoded{$k});
+                $decoded[] = ord($encoded[$k]);
             }
         }
         $deco_len = count($decoded);
@@ -437,7 +437,7 @@ class idna_convert {
 
         for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) {
             for ($old_idx = $idx, $w = 1, $k = $this->_base; 1; $k += $this->_base) {
-                $digit = $this->_decode_digit($encoded{$enco_idx++});
+                $digit = $this->_decode_digit($encoded[$enco_idx++]);
                 $idx += $digit * $w;
                 $t = ($k <= $bias) ? $this->_tmin :
                         (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias));
@@ -864,7 +864,7 @@ class idna_convert {
         $mode = 'next';
         $test = 'none';
         for ($k = 0; $k < $inp_len; ++$k) {
-            $v = ord($input{$k}); // Extract byte from input string
+            $v = ord($input[$k]); // Extract byte from input string
             if ($v < 128) { // We found an ASCII char - put into stirng as is
                 $output[$out_len] = $v;
                 ++$out_len;
@@ -995,7 +995,7 @@ class idna_convert {
                 $out_len++;
                 $output[$out_len] = 0;
             }
-            $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
+            $output[$out_len] += ord($input[$i]) << (8 * (3 - ($i % 4) ) );
         }
         return $output;
     }
diff --git a/ecrire/inc/math.php b/ecrire/inc/math.php
index a134c57912..ce841dcb57 100644
--- a/ecrire/inc/math.php
+++ b/ecrire/inc/math.php
@@ -60,7 +60,7 @@ function produire_image_math($tex) {
 
 		// MathML
 		if ($GLOBALS['traiter_math'] == 'mathml') {
-			return join(file("$fichier"), "");
+			return implode("", file($fichier));
 		} // TeX
 		else {
 			list(, , , $size) = @getimagesize($fichier);
diff --git a/ecrire/inc/plonger.php b/ecrire/inc/plonger.php
index fc93da4a3e..1f55eb499e 100644
--- a/ecrire/inc/plonger.php
+++ b/ecrire/inc/plonger.php
@@ -57,8 +57,8 @@ function inc_plonger_dist($id_rubrique, $idom = "", $list = array(), $col = 1, $
 		$rec = generer_url_ecrire('plonger', "rac=$idom&exclus=$exclu&do=$do&col=" . ($col + 1));
 		$info = generer_url_ecrire('informer', "type=rubrique&rac=$idom&do=$do&id=");
 		$args = "'$idom',this,$col,'" . $GLOBALS['spip_lang_left'] . "','$info',event";
-		while (list($id, $titrebrut) = each($ordre)) {
 
+		foreach ($ordre as $id => $titrebrut) {
 			$titre = supprimer_numero($titrebrut);
 
 			$classe1 = $id_rubrique ? 'petite-rubrique' : "petit-secteur";
diff --git a/ecrire/inc/plugin.php b/ecrire/inc/plugin.php
index 417cb9f3bf..1da2f363de 100644
--- a/ecrire/inc/plugin.php
+++ b/ecrire/inc/plugin.php
@@ -209,7 +209,7 @@ function plugin_version_compatible($intervalle, $version, $avec_quoi = '') {
 		// cas du plugin qui n'est compatible qu'avec cette nouvelle version
 	}
 
-	$minimum_inc = $intervalle{0} == "[";
+	$minimum_inc = $intervalle[0] == "[";
 	$maximum_inc = substr($intervalle, -1) == "]";
 
 	if (strlen($minimum)) {
@@ -699,7 +699,7 @@ function plugin_message_incompatibilite($intervalle, $version, $nom, $balise) {
 		$minimum = $regs[1];
 		$maximum = $regs[2];
 
-		$minimum_inclus = $intervalle{0} == "[";
+		$minimum_inclus = $intervalle[0] == "[";
 		$maximum_inclus = substr($intervalle, -1) == "]";
 
 		if (strlen($minimum)) {
@@ -933,7 +933,7 @@ function plugins_precompile_chemin($plugin_valides, $ordre) {
 							$GLOBALS['spip_version_branche'], 'spip')
 					) {
 						$dir = $chemin['path'];
-						if (strlen($dir) and $dir{0} == "/") {
+						if (strlen($dir) and $dir[0] == "/") {
 							$dir = substr($dir, 1);
 						}
 						if (strlen($dir) and $dir == "./") {
diff --git a/ecrire/inc/session.php b/ecrire/inc/session.php
index a759650286..2e331bf4ab 100644
--- a/ecrire/inc/session.php
+++ b/ecrire/inc/session.php
@@ -77,16 +77,26 @@ function inc_session_dist($auteur = false) {
  */
 function supprimer_sessions($id_auteur, $toutes = true, $actives = true) {
 
+	$nb_files = 0;
+	$nb_max_files = (defined('_MAX_NB_SESSIONS_OUVERTES') ? _MAX_NB_SESSIONS_OUVERTES : 1000);
 	spip_log("supprimer sessions auteur $id_auteur", "session");
 	if ($toutes or $id_auteur !== $GLOBALS['visiteur_session']['id_auteur']) {
 		if ($dir = opendir(_DIR_SESSIONS)) {
+			$t = $_SERVER['REQUEST_TIME']  - (4*_RENOUVELLE_ALEA); // 48h par defaut
+			$t_short = $_SERVER['REQUEST_TIME']  - max(_RENOUVELLE_ALEA/4,3*3600); // 3h par defaut
 			$t = time() - (4 * _RENOUVELLE_ALEA);
 			while (($f = readdir($dir)) !== false) {
+				$nb_files++;
 				if (preg_match(",^[^\d-]*(-?\d+)_\w{32}\.php[3]?$,", $f, $regs)) {
 					$f = _DIR_SESSIONS . $f;
 					if (($actives and $regs[1] == $id_auteur) or ($t > filemtime($f))) {
 						spip_unlink($f);
 					}
+					// si il y a trop de sessions ouvertes, on purge les sessions anonymes de plus de 3H
+					// cf http://core.spip.org/issues/3276
+					elseif ($nb_files>$nb_max_files and !intval($regs[1]) and ($t_short > filemtime($f))) {
+						spip_unlink($f);
+					}
 				}
 			}
 		}
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index a89658a6a2..afc4fbc260 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -328,9 +328,12 @@ function spip_log($message = null, $name = null) {
 	if (!isset($regs[1]) or !$logname = $regs[1]) {
 		$logname = null;
 	}
-	if (!isset($regs[2]) or !$niveau = $regs[2]) {
+	if (!isset($regs[2])) {
 		$niveau = _LOG_INFO;
 	}
+	else {
+		$niveau = intval($regs[2]);
+	}
 
 	if ($niveau <= (defined('_LOG_FILTRE_GRAVITE') ? _LOG_FILTRE_GRAVITE : _LOG_INFO_IMPORTANTE)) {
 		if (!$pre) {
@@ -2741,9 +2744,11 @@ function spip_initialisation_suite() {
 	// les anciens IIS n'acceptent pas les POST sur ecrire/ (#419)
 	// meme pb sur thttpd cf. http://forum.spip.net/fr_184153.html
 	if (!defined('_SPIP_ECRIRE_SCRIPT')) {
-		define('_SPIP_ECRIRE_SCRIPT', (empty($_SERVER['SERVER_SOFTWARE']) ? '' :
-			preg_match(',IIS|thttpd,', $_SERVER['SERVER_SOFTWARE']) ?
-				'index.php' : ''));
+		if (!empty($_SERVER['SERVER_SOFTWARE']) and preg_match(',IIS|thttpd,', $_SERVER['SERVER_SOFTWARE'])) {
+			define('_SPIP_ECRIRE_SCRIPT', 'index.php');
+		} else {
+			define('_SPIP_ECRIRE_SCRIPT', '');
+		}
 	}
 
 
diff --git a/ecrire/inc/xml.php b/ecrire/inc/xml.php
index 26c8077388..a9a55eeb72 100644
--- a/ecrire/inc/xml.php
+++ b/ecrire/inc/xml.php
@@ -212,13 +212,12 @@ function spip_xml_tagname($tag) {
 function spip_xml_decompose_tag($tag) {
 	$tagname = spip_xml_tagname($tag);
 	$liste = array();
-	$p = strpos($tag, ' ');
-	$tag = substr($tag, $p);
+	$tag = ltrim(strpbrk($tag, " \n\t"));
 	$p = strpos($tag, '=');
 	while ($p !== false) {
 		$attr = trim(substr($tag, 0, $p));
 		$tag = ltrim(substr($tag, $p + 1));
-		$quote = $tag{0};
+		$quote = $tag[0];
 		$p = strpos($tag, $quote, 1);
 		$cont = substr($tag, 1, $p - 1);
 		$liste[$attr] = $cont;
diff --git a/ecrire/inc_version.php b/ecrire/inc_version.php
index 6d45f32879..a4f5006e4a 100644
--- a/ecrire/inc_version.php
+++ b/ecrire/inc_version.php
@@ -374,8 +374,8 @@ $liste_des_authentifications = array(
 // ex : 2.0.0, 2.0.0-dev, 2.0.0-beta, 2.0.0-beta2
 // le _SPIP_VERSION_ID est un nombre entier représentant le numéro de version (2 chiffres pour chaque 03 + 02 + 06 = 30206
 // le _SPIP_EXTRA_VERSION sert à repérer les version dev, beta etc. Pour une version stable il est vide.
-$spip_version_branche = "3.2.9";
-define('_SPIP_VERSION_ID', 30209);
+$spip_version_branche = "3.2.11";
+define('_SPIP_VERSION_ID', 30211);
 define('_SPIP_EXTRA_VERSION', '');
 
 // cette version dev accepte tous les plugins compatible avec la version ci-dessous
diff --git a/ecrire/install/etape_chmod.php b/ecrire/install/etape_chmod.php
index 0021f74a39..15e7d7654e 100644
--- a/ecrire/install/etape_chmod.php
+++ b/ecrire/install/etape_chmod.php
@@ -93,7 +93,7 @@ function install_etape_chmod_dist() {
 	$bad_dirs = array();
 	$absent_dirs = array();
 
-	while (list(, $my_dir) = each($GLOBALS['test_dirs'])) {
+	foreach ($GLOBALS['test_dirs'] as $i => $my_dir) {
 		$test = test_ecrire($my_dir);
 		if (!$test) {
 			$m = preg_replace(',^' . _DIR_RACINE . ',', '', $my_dir);
diff --git a/ecrire/iterateur/data.php b/ecrire/iterateur/data.php
index 5536788800..616bfc8a7a 100644
--- a/ecrire/iterateur/data.php
+++ b/ecrire/iterateur/data.php
@@ -127,7 +127,9 @@ class IterateurDATA implements Iterator {
 	 */
 	public function rewind() {
 		reset($this->tableau);
-		list($this->cle, $this->valeur) = each($this->tableau);
+		$this->cle = key($this->tableau);
+		$this->valeur = current($this->tableau);
+		next($this->tableau);
 	}
 
 	/**
@@ -433,7 +435,7 @@ class IterateurDATA implements Iterator {
 	 *
 	 **/
 	protected function select_datapath() {
-		list(, $base) = each($this->command['datapath']);
+		$base = reset($this->command['datapath']);
 		if (strlen($base = ltrim(trim($base), "/"))) {
 			$this->tableau = table_valeur($this->tableau, $base);
 			if (!is_array($this->tableau)) {
@@ -486,17 +488,17 @@ class IterateurDATA implements Iterator {
 					$a = ' . sprintf($tv, '$aa') . ';
 					$b = ' . sprintf($tv, '$bb') . ';
 					if ($a <> $b)
-						return ($a ' . ((isset($r[2]) and $r[2]) ? '>' : '<') . ' $b) ? -1 : 1;';
+						return ($a ' . (!empty($r[2]) ? '>' : '<') . ' $b) ? -1 : 1;';
 					}
 				}
 			}
 		}
 
 		if ($sortfunc) {
-			uasort($this->tableau, create_function('$aa,$bb',
-				$sortfunc . '
-				return 0;'
-			));
+			$sortfunc .= "\n return 0;";
+			uasort($this->tableau, function($aa, $bb) use ($sortfunc) {
+				return eval($sortfunc);
+			});
 		}
 	}
 
@@ -556,7 +558,9 @@ class IterateurDATA implements Iterator {
 	 */
 	public function next() {
 		if ($this->valid()) {
-			list($this->cle, $this->valeur) = each($this->tableau);
+			$this->cle = key($this->tableau);
+			$this->valeur = current($this->tableau);
+			next($this->tableau);
 		}
 	}
 
diff --git a/ecrire/paquet.xml b/ecrire/paquet.xml
index d62467ff7a..b441cd0968 100644
--- a/ecrire/paquet.xml
+++ b/ecrire/paquet.xml
@@ -1,7 +1,7 @@
 <paquet
 	prefix="spip"
 	categorie="outil"
-	version="3.2.9"
+	version="3.2.11"
 	etat="stable"
 	compatibilite="];["
 	schema="23375"
diff --git a/ecrire/public/assembler.php b/ecrire/public/assembler.php
index bbe6ba01fc..8fc3f7a1a7 100644
--- a/ecrire/public/assembler.php
+++ b/ecrire/public/assembler.php
@@ -537,11 +537,10 @@ function inclure_modele($type, $id, $params, $lien, $connect = '', $env = array(
 
 	$params = array_filter(explode('|', $params));
 	if ($params) {
-		list(, $soustype) = each($params);
+		$soustype = current($params);
 		$soustype = strtolower(trim($soustype));
-		if (in_array($soustype,
-			array('left', 'right', 'center', 'ajax'))) {
-			list(, $soustype) = each($params);
+		if (in_array($soustype, array('left', 'right', 'center', 'ajax'))) {
+			$soustype = next($params);
 			$soustype = strtolower($soustype);
 		}
 
diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php
index f1a0d7a385..9e80959493 100644
--- a/ecrire/public/balises.php
+++ b/ecrire/public/balises.php
@@ -1158,7 +1158,7 @@ function balise_PAGINATION_dist($p, $liste = 'true') {
 	// si true, les arguments simples (sans truc=chose) vont degager
 	$_contexte = argumenter_inclure($p->param, true, $p, $p->boucles, $p->id_boucle, false, false);
 	if (count($_contexte)) {
-		list($key, $val) = each($_contexte);
+		$key = key($_contexte);
 		if (is_numeric($key)) {
 			array_shift($_contexte);
 			$__modele = interprete_argument_balise(1, $p);
diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index 42ab5da7b8..47ac7eb9bc 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -1194,7 +1194,13 @@ function public_compiler_dist($squelette, $nom, $gram, $sourcefile, $connect = '
 		$i++;
 	}
 	$squelette = preg_replace_callback(',\\\\([#[()\]{}<>]),',
-		create_function('$a', "return '$inerte-'.ord(\$a[1]).'-';"), $squelette, -1, $esc);
+		function($a) use ($inerte) {
+			return "$inerte-" . ord($a[1]) . '-';
+		},
+		$squelette,
+		-1,
+		$esc
+	);
 
 	$descr = array(
 		'nom' => $nom,
@@ -1215,11 +1221,20 @@ function public_compiler_dist($squelette, $nom, $gram, $sourcefile, $connect = '
 	// restituer les echappements
 	if ($esc) {
 		foreach ($boucles as $i => $boucle) {
-			$boucles[$i]->return = preg_replace_callback(",$inerte-(\d+)-,", create_function('$a', 'return chr($a[1]);'),
-				$boucle->return);
-			$boucles[$i]->descr['squelette'] = preg_replace_callback(",$inerte-(\d+)-,",
-				create_function('$a', 'return "\\\\".chr($a[1]);'),
-				$boucle->descr['squelette']);
+			$boucles[$i]->return = preg_replace_callback(
+				",$inerte-(\d+)-,",
+				function($a) {
+					return chr($a[1]);
+				},
+				$boucle->return
+			);
+			$boucles[$i]->descr['squelette'] = preg_replace_callback(
+				",$inerte-(\d+)-,",
+				function($a) {
+					return "\\\\" . chr($a[1]);
+				},
+				$boucle->descr['squelette']
+			);
 		}
 	}
 
diff --git a/ecrire/public/composer.php b/ecrire/public/composer.php
index c3d11749b3..62b476fea2 100644
--- a/ecrire/public/composer.php
+++ b/ecrire/public/composer.php
@@ -979,7 +979,8 @@ function calculer_select(
 		// penser a regarder aussi la clause groubpy pour ne pas simplifier abusivement
 		// <BOUCLE10(EVENEMENTS){id_rubrique} />#TOTAL_BOUCLE<//B10>
 
-		list($t, $c) = each($from);
+		$t = key($from);
+		$c = current($from);
 		reset($from);
 		$e = '/\b(' . "$t\\." . join("|" . $t . '\.', $equiv) . ')\b/';
 		if (!(strpos($t, ' ') or // jointure des le depart cf boucle_doc
@@ -991,8 +992,8 @@ function calculer_select(
 				calculer_jointnul($t, $having, $e))
 			&& count($afrom[$t])
 		) {
-			reset($afrom[$t]);
-			list($nt, $nfrom) = each($afrom[$t]);
+			$nfrom = reset($afrom[$t]);
+			$nt = key($afrom[$t]);
 			unset($from[$t]);
 			$from[$nt] = $nfrom[1];
 			unset($afrom[$t][$nt]);
diff --git a/ecrire/public/iterateur.php b/ecrire/public/iterateur.php
index 1e274d59c0..b5c2e35c3c 100644
--- a/ecrire/public/iterateur.php
+++ b/ecrire/public/iterateur.php
@@ -300,7 +300,10 @@ class IterDecorator extends FilterIterator {
 
 		// Creer la fonction de filtrage sur $this
 		if ($this->filtre) {
-			$this->func_filtre = create_function('$me', $b = 'return (' . join(') AND (', $this->filtre) . ');');
+			$filtres = 'return (' . join(') AND (', $this->filtre) . ');';
+			$this->func_filtre = function () use ($filtres) {
+				return eval($filtres);
+			};
 		}
 	}
 
@@ -320,7 +323,7 @@ class IterDecorator extends FilterIterator {
 		# if (!in_array($cle, array('cle', 'valeur')))
 		#	return;
 
-		$a = '$me->get_select(\'' . $cle . '\')';
+		$a = '$this->get_select(\'' . $cle . '\')';
 
 		$filtre = '';
 
@@ -566,7 +569,7 @@ class IterDecorator extends FilterIterator {
 	 **/
 	public function accept() {
 		if ($f = $this->func_filtre) {
-			return $f($this);
+			return $f();
 		}
 
 		return true;
diff --git a/ecrire/public/quete.php b/ecrire/public/quete.php
index 09a4b1d93d..f8f406d75f 100644
--- a/ecrire/public/quete.php
+++ b/ecrire/public/quete.php
@@ -669,7 +669,7 @@ function quete_debut_pagination($primary, $valeur, $pas, $iter) {
 		$pos++;
 	}
 	// si on a pas trouve
-	if ($row[$primary] != $valeur) {
+	if (!$row or $row[$primary] != $valeur) {
 		return 0;
 	}
 
diff --git a/ecrire/public/references.php b/ecrire/public/references.php
index 218f29030c..6a6116a828 100644
--- a/ecrire/public/references.php
+++ b/ecrire/public/references.php
@@ -704,13 +704,18 @@ function champs_traitements($p) {
 		$type_requete = isset($p->boucles[$idb]->type_requete) ? $p->boucles[$idb]->type_requete : false;
 		$table_sql = isset($p->boucles[$idb]->show['table_sql']) ? $p->boucles[$idb]->show['table_sql'] : false;
 
+		// bien prendre en compte les alias de boucles (hierarchie => rubrique, syndication => syncdic, etc.)
+		if ($type_requete and isset($GLOBALS['table_des_tables'][$type_requete])) {
+			$type_requete = $GLOBALS['table_des_tables'][$type_requete];
+		}
+
 		// le traitement peut n'etre defini que pour une table en particulier "spip_articles"
 		if ($table_sql and isset($ps[$table_sql])) {
 			$ps = $ps[$table_sql];
 		} // ou pour une boucle en particulier "DATA","articles"
 		elseif ($type_requete and isset($ps[$type_requete])) {
 			$ps = $ps[$type_requete];
-		} // ou pour indiferrement quelle que soit la boucle
+		} // ou pour indifféremment quelle que soit la boucle
 		elseif (isset($ps[0])) {
 			$ps = $ps[0];
 		} else {
diff --git a/ecrire/req/mysql.php b/ecrire/req/mysql.php
index 5cd2c0d2a8..4c78e1c636 100644
--- a/ecrire/req/mysql.php
+++ b/ecrire/req/mysql.php
@@ -243,7 +243,7 @@ function spip_mysql_query($query, $serveur = '', $requeter = true) {
 	if (defined('_DEBUG_SLOW_QUERIES') and _DEBUG_SLOW_QUERIES) {
 		if (isset($GLOBALS['debug']['aucasou'])) {
 			list(, $id, , $infos) = $GLOBALS['debug']['aucasou'];
-			$debug .= "BOUCLE$id @ " . $infos[0] . " | ";
+			$debug .= "BOUCLE$id @ " . (isset($infos[0]) ? $infos[0] : '') . " | ";
 		}
 		$debug .= $_SERVER['REQUEST_URI'] . ' + ' . $GLOBALS['ip'];
 		$debug = ' /* ' . mysqli_real_escape_string($link, str_replace('*/', '@/', $debug)) . ' */';
@@ -1681,7 +1681,8 @@ function spip_get_lock($nom, $timeout = 0) {
 	$nom = "$bd:$prefixe:$nom" . _LOCK_TIME;
 
 	$connexion['last'] = $q = "SELECT GET_LOCK(" . _q($nom) . ", $timeout) AS n";
-	$q = @sql_fetch(mysql_query($q));
+
+	$q = @sql_fetch(mysqli_query(_mysql_link(), $q));
 	if (!$q) {
 		spip_log("pas de lock sql pour $nom", _LOG_ERREUR);
 	}
diff --git a/ecrire/req/sqlite_generique.php b/ecrire/req/sqlite_generique.php
index 64f5016eda..294df176de 100644
--- a/ecrire/req/sqlite_generique.php
+++ b/ecrire/req/sqlite_generique.php
@@ -2298,16 +2298,14 @@ function _sqlite_charger_version($version = '') {
 function _sqlite_modifier_table($table, $colonne, $opt = array(), $serveur = '') {
 
 	if (is_array($table)) {
-		reset($table);
-		list($table_origine, $table_destination) = each($table);
+		list($table_origine, $table_destination) = reset($table);
 	} else {
 		$table_origine = $table_destination = $table;
 	}
 	// ne prend actuellement qu'un changement
 	// mais pourra etre adapte pour changer plus qu'une colonne a la fois
 	if (is_array($colonne)) {
-		reset($colonne);
-		list($colonne_origine, $colonne_destination) = each($colonne);
+		list($colonne_origine, $colonne_destination) = reset($colonne);
 	} else {
 		$colonne_origine = $colonne_destination = $colonne;
 	}
diff --git a/plugins-dist/breves/breves_pipelines.php b/plugins-dist/breves/breves_pipelines.php
index 4a296275fa..6286fd5c7c 100644
--- a/plugins-dist/breves/breves_pipelines.php
+++ b/plugins-dist/breves/breves_pipelines.php
@@ -285,8 +285,7 @@ function breves_accueil_encours($flux) {
  */
 function breves_optimiser_base_disparus($flux) {
 	$n = &$flux['data'];
-	$mydate = $flux['args']['date'];
-
+	$mydate = sql_quote($flux['args']['date']);
 
 	# les breves qui sont dans une id_rubrique inexistante
 	$res = sql_select(
@@ -295,7 +294,7 @@ function breves_optimiser_base_disparus($flux) {
 			LEFT JOIN spip_rubriques AS R
 				ON B.id_rubrique=R.id_rubrique',
 		'R.id_rubrique IS NULL
-			AND B.maj < ' . sql_quote($mydate)
+			AND B.maj < ' . $mydate
 	);
 
 	$n += optimiser_sansref('spip_breves', 'id_breve', $res);
diff --git a/plugins-dist/compresseur/inc/compresseur_embarquer.php b/plugins-dist/compresseur/inc/compresseur_embarquer.php
index 85d940d497..891c7b8eaa 100644
--- a/plugins-dist/compresseur/inc/compresseur_embarquer.php
+++ b/plugins-dist/compresseur/inc/compresseur_embarquer.php
@@ -47,10 +47,9 @@ function compresseur_embarquer_images_css($contenu, $source, $source_file = null
 
 	return preg_replace_callback(
 		",url\s*\(\s*['\"]?([^'\"/][^:]*[.](png|gif|jpg))['\"]?\s*\),Uims",
-		create_function(
-			'$x',
-			'return "url(\"".' . $filtre_embarque_fichier . '($x[1],"' . $base . '",_CSS_EMBARQUE_FICHIER_MAX_SIZE)."\")";'
-		),
+		function($x) use ($filtre_embarque_fichier, $base) {
+			return "url(\"" . $filtre_embarque_fichier($x[1], $base, _CSS_EMBARQUE_FICHIER_MAX_SIZE) . "\");";
+		},
 		$contenu
 	);
 }
diff --git a/plugins-dist/compresseur/lib/csstidy/class.csstidy.php b/plugins-dist/compresseur/lib/csstidy/class.csstidy.php
index d29068a030..b09373d456 100644
--- a/plugins-dist/compresseur/lib/csstidy/class.csstidy.php
+++ b/plugins-dist/compresseur/lib/csstidy/class.csstidy.php
@@ -32,31 +32,6 @@
  * @author Mark Scherer (remove $GLOBALS once and for all + PHP5.4 comp) 2012
  */
 
-/**
- * Defines ctype functions if required.
- *
- * @TODO: Make these methods of CSSTidy.
- * @since 1.0.0
- */
-if (!function_exists('ctype_space')){
-	/* ctype_space Check for whitespace character(s) */
-	function ctype_space($text){
-		return (1===preg_match("/^[ \r\n\t\f]+$/", $text));
-	}
-}
-if (!function_exists('ctype_alpha')){
-	/* ctype_alpha Check for alphabetic character(s) */
-	function ctype_alpha($text){
-		return (1===preg_match('/^[a-zA-Z]+$/', $text));
-	}
-}
-if (!function_exists('ctype_xdigit')){
-	/* ctype_xdigit Check for HEX character(s) */
-	function ctype_xdigit($text){
-		return (1===preg_match('/^[a-fA-F0-9]+$/', $text));
-	}
-}
-
 /**
  * Defines constants
  * @todo //TODO: make them class constants of csstidy
@@ -95,7 +70,7 @@ require('class.csstidy_optimise.php');
  * An online version should be available here: http://cdburnerxp.se/cssparse/css_optimiser.php
  * @package csstidy
  * @author Florian Schmitz (floele at gmail dot com) 2005-2006
- * @version 1.6.5
+ * @version 1.7.3
  */
 class csstidy {
 
@@ -148,7 +123,7 @@ class csstidy {
 	 * @var string
 	 * @access private
 	 */
-	public $version = '1.6.5';
+	public $version = '1.7.3';
 	/**
 	 * Stores the settings
 	 * @var array
@@ -416,9 +391,19 @@ class csstidy {
 	 */
 	public function _add_token($type, $data, $do = false) {
 		if ($this->get_cfg('preserve_css') || $do) {
+			// nested @... : if opening a new part we just closed, remove the previous closing instead of adding opening
+			if ($type === AT_START
+				and count($this->tokens)
+				and $last = end($this->tokens)
+				and $last[0] === AT_END
+				and $last[1] === trim($data)) {
+				array_pop($this->tokens);
+			}
+			else {
 				$this->tokens[] = array($type, ($type == COMMENT or $type == IMPORTANT_COMMENT) ? $data : trim($data));
 			}
 		}
+	}
 
 	/**
 	 * Add a message to the message log
@@ -452,10 +437,10 @@ class csstidy {
 		$add = '';
 		$replaced = false;
 
-		while ($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6) {
-			$add .= $string{$i};
+		while ($i < strlen($string) && (ctype_xdigit($string[$i]) || ctype_space($string[$i])) && strlen($add) < 6) {
+			$add .= $string[$i];
 
-			if (ctype_space($string{$i})) {
+			if (ctype_space($string[$i])) {
 				break;
 			}
 			$i++;
@@ -469,12 +454,12 @@ class csstidy {
 			$add = trim('\\' . $add);
 		}
 
-		if (@ctype_xdigit($string{$i + 1}) && ctype_space($string{$i})
-						&& !$replaced || !ctype_space($string{$i})) {
+		if (@ctype_xdigit($string[$i + 1]) && ctype_space($string[$i])
+						&& !$replaced || !ctype_space($string[$i])) {
 			$i--;
 		}
 
-		if ($add !== '\\' || !$this->get_cfg('remove_bslash') || strpos($this->tokens_list, $string{$i + 1}) !== false) {
+		if ($add !== '\\' || !$this->get_cfg('remove_bslash') || strpos($this->tokens_list, $string[$i + 1]) !== false) {
 			return $add;
 		}
 
@@ -576,7 +561,7 @@ class csstidy {
 	 * @version 1.11
 	 */
 	public function is_token(&$string, $i) {
-		return (strpos($this->tokens_list, $string{$i}) !== false && !$this->escaped($string, $i));
+		return (strpos($this->tokens_list, $string[$i]) !== false && !$this->escaped($string, $i));
 	}
 
 	/**
@@ -603,9 +588,10 @@ class csstidy {
 		$this->print->input_css = $string;
 		$string = str_replace("\r\n", "\n", $string) . ' ';
 		$cur_comment = '';
+		$cur_at = '';
 
 		for ($i = 0, $size = strlen($string); $i < $size; $i++) {
-			if ($string{$i} === "\n" || $string{$i} === "\r") {
+			if ($string[$i] === "\n" || $string[$i] === "\r") {
 				++$this->line;
 			}
 
@@ -613,27 +599,27 @@ class csstidy {
 				/* Case in at-block */
 				case 'at':
 					if ($this->is_token($string, $i)) {
-						if ($string{$i} === '/' && @$string{$i + 1} === '*') {
+						if ($string[$i] === '/' && @$string[$i + 1] === '*') {
 							$this->status = 'ic';
 							++$i;
 							$this->from[] = 'at';
-						} elseif ($string{$i} === '{') {
+						} elseif ($string[$i] === '{') {
 							$this->status = 'is';
-							$this->at = $this->css_new_media_section($this->at);
+							$this->at = $this->css_new_media_section($this->at, $cur_at);
 							$this->_add_token(AT_START, $this->at);
-						} elseif ($string{$i} === ',') {
-							$this->at = trim($this->at) . ',';
-						} elseif ($string{$i} === '\\') {
-							$this->at .= $this->_unicode($string, $i);
+						} elseif ($string[$i] === ',') {
+							$cur_at = trim($cur_at) . ',';
+						} elseif ($string[$i] === '\\') {
+							$cur_at .= $this->_unicode($string, $i);
 						}
 						// fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5)
-						elseif (in_array($string{$i}, array('(', ')', ':', '.', '/'))) {
-							$this->at .= $string{$i};
+						elseif (in_array($string[$i], array('(', ')', ':', '.', '/'))) {
+							$cur_at .= $string[$i];
 						}
 					} else {
-						$lastpos = strlen($this->at) - 1;
-						if (!( (ctype_space($this->at{$lastpos}) || $this->is_token($this->at, $lastpos) && $this->at{$lastpos} === ',') && ctype_space($string{$i}))) {
-							$this->at .= $string{$i};
+						$lastpos = strlen($cur_at) - 1;
+						if (!( (ctype_space($cur_at[$lastpos]) || $this->is_token($cur_at, $lastpos) && $cur_at[$lastpos] === ',') && ctype_space($string[$i]))) {
+							$cur_at .= $string[$i];
 						}
 					}
 					break;
@@ -641,24 +627,25 @@ class csstidy {
 				/* Case in-selector */
 				case 'is':
 					if ($this->is_token($string, $i)) {
-						if ($string{$i} === '/' && @$string{$i + 1} === '*' && trim($this->selector) == '') {
+						if ($string[$i] === '/' && @$string[$i + 1] === '*' && trim($this->selector) == '') {
 							$this->status = 'ic';
 							++$i;
 							$this->from[] = 'is';
-						} elseif ($string{$i} === '@' && trim($this->selector) == '') {
+						} elseif ($string[$i] === '@' && trim($this->selector) == '') {
 							// Check for at-rule
 							$this->invalid_at = true;
 							foreach ($at_rules as $name => $type) {
 								if (!strcasecmp(substr($string, $i + 1, strlen($name)), $name)) {
-									($type === 'at') ? $this->at = '@' . $name : $this->selector = '@' . $name;
+									($type === 'at') ? $cur_at = '@' . $name : $this->selector = '@' . $name;
 									if ($type === 'atis') {
 										$this->next_selector_at = ($this->next_selector_at?$this->next_selector_at:($this->at?$this->at:DEFAULT_AT));
-										$this->at = $this->css_new_media_section(' ');
+										$this->at = $this->css_new_media_section($this->at, ' ', true);
 										$type = 'is';
 									}
 									$this->status = $type;
 									$i += strlen($name);
 									$this->invalid_at = false;
+									break;
 								}
 							}
 
@@ -666,54 +653,55 @@ class csstidy {
 								$this->selector = '@';
 								$invalid_at_name = '';
 								for ($j = $i + 1; $j < $size; ++$j) {
-									if (!ctype_alpha($string{$j})) {
+									if (!ctype_alpha($string[$j])) {
 										break;
 									}
-									$invalid_at_name .= $string{$j};
+									$invalid_at_name .= $string[$j];
 								}
 								$this->log('Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning');
 							}
-						} elseif (($string{$i} === '"' || $string{$i} === "'")) {
-							$this->cur_string[] = $string{$i};
+						} elseif (($string[$i] === '"' || $string[$i] === "'")) {
+							$this->cur_string[] = $string[$i];
 							$this->status = 'instr';
-							$this->str_char[] = $string{$i};
+							$this->str_char[] = $string[$i];
 							$this->from[] = 'is';
 							/* fixing CSS3 attribute selectors, i.e. a[href$=".mp3" */
-							$this->quoted_string[] = ($string{$i - 1} === '=' );
-						} elseif ($this->invalid_at && $string{$i} === ';') {
+							$this->quoted_string[] = ($string[$i - 1] === '=' );
+						} elseif ($this->invalid_at && $string[$i] === ';') {
 							$this->invalid_at = false;
 							$this->status = 'is';
 							if ($this->next_selector_at) {
-								$this->at = $this->css_new_media_section($this->next_selector_at);
+								$this->at = $this->css_close_media_section($this->at);
+								$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
 								$this->next_selector_at = '';
 							}
-						} elseif ($string{$i} === '{') {
+						} elseif ($string[$i] === '{') {
 							$this->status = 'ip';
 							if ($this->at == '') {
-								$this->at = $this->css_new_media_section(DEFAULT_AT);
+								$this->at = $this->css_new_media_section($this->at, DEFAULT_AT);
 							}
 							$this->selector = $this->css_new_selector($this->at,$this->selector);
 							$this->_add_token(SEL_START, $this->selector);
 							$this->added = false;
-						} elseif ($string{$i} === '}') {
+						} elseif ($string[$i] === '}') {
 							$this->_add_token(AT_END, $this->at);
-							$this->at = '';
+							$this->at = $this->css_close_media_section($this->at);
 							$this->selector = '';
 							$this->sel_separate = array();
-						} elseif ($string{$i} === ',') {
+						} elseif ($string[$i] === ',') {
 							$this->selector = trim($this->selector) . ',';
 							$this->sel_separate[] = strlen($this->selector);
-						} elseif ($string{$i} === '\\') {
+						} elseif ($string[$i] === '\\') {
 							$this->selector .= $this->_unicode($string, $i);
-						} elseif ($string{$i} === '*' && @in_array($string{$i + 1}, array('.', '#', '[', ':')) && ($i==0 OR $string{$i - 1}!=='/')) {
+						} elseif ($string[$i] === '*' && @in_array($string[$i + 1], array('.', '#', '[', ':')) && ($i==0 OR $string[$i - 1]!=='/')) {
 							// remove unnecessary universal selector, FS#147, but not comment in selector
 						} else {
-							$this->selector .= $string{$i};
+							$this->selector .= $string[$i];
 						}
 					} else {
 						$lastpos = strlen($this->selector) - 1;
-						if ($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || $this->is_token($this->selector, $lastpos) && $this->selector{$lastpos} === ',') && ctype_space($string{$i}))) {
-							$this->selector .= $string{$i};
+						if ($lastpos == -1 || !( (ctype_space($this->selector[$lastpos]) || $this->is_token($this->selector, $lastpos) && $this->selector[$lastpos] === ',') && ctype_space($string[$i]))) {
+							$this->selector .= $string[$i];
 						}
 					}
 					break;
@@ -721,17 +709,17 @@ class csstidy {
 				/* Case in-property */
 				case 'ip':
 					if ($this->is_token($string, $i)) {
-						if (($string{$i} === ':' || $string{$i} === '=') && $this->property != '') {
+						if (($string[$i] === ':' || $string[$i] === '=') && $this->property != '') {
 							$this->status = 'iv';
 							if (!$this->get_cfg('discard_invalid_properties') || $this->property_is_valid($this->property)) {
 								$this->property = $this->css_new_property($this->at,$this->selector,$this->property);
 								$this->_add_token(PROPERTY, $this->property);
 							}
-						} elseif ($string{$i} === '/' && @$string{$i + 1} === '*' && $this->property == '') {
+						} elseif ($string[$i] === '/' && @$string[$i + 1] === '*' && $this->property == '') {
 							$this->status = 'ic';
 							++$i;
 							$this->from[] = 'ip';
-						} elseif ($string{$i} === '}') {
+						} elseif ($string[$i] === '}') {
 							$this->explode_selectors();
 							$this->status = 'is';
 							$this->invalid_at = false;
@@ -739,45 +727,46 @@ class csstidy {
 							$this->selector = '';
 							$this->property = '';
 							if ($this->next_selector_at) {
-								$this->at = $this->css_new_media_section($this->next_selector_at);
+								$this->at = $this->css_close_media_section($this->at);
+								$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
 								$this->next_selector_at = '';
 							}
-						} elseif ($string{$i} === ';') {
+						} elseif ($string[$i] === ';') {
 							$this->property = '';
-						} elseif ($string{$i} === '\\') {
+						} elseif ($string[$i] === '\\') {
 							$this->property .= $this->_unicode($string, $i);
 						}
 						// else this is dumb IE a hack, keep it
 						// including //
-						elseif (($this->property === '' && !ctype_space($string{$i}))
-							|| ($this->property === '/' || $string{$i} === '/')) {
-							$this->property .= $string{$i};
+						elseif (($this->property === '' && !ctype_space($string[$i]))
+							|| ($this->property === '/' || $string[$i] === '/')) {
+							$this->property .= $string[$i];
 						}
-					} elseif (!ctype_space($string{$i})) {
-						$this->property .= $string{$i};
+					} elseif (!ctype_space($string[$i])) {
+						$this->property .= $string[$i];
 					}
 					break;
 
 				/* Case in-value */
 				case 'iv':
-					$pn = (($string{$i} === "\n" || $string{$i} === "\r") && $this->property_is_next($string, $i + 1) || $i == strlen($string) - 1);
+					$pn = (($string[$i] === "\n" || $string[$i] === "\r") && $this->property_is_next($string, $i + 1) || $i == strlen($string) - 1);
 					if ($this->is_token($string, $i) || $pn) {
-						if ($string{$i} === '/' && @$string{$i + 1} === '*') {
+						if ($string[$i] === '/' && @$string[$i + 1] === '*') {
 							$this->status = 'ic';
 							++$i;
 							$this->from[] = 'iv';
-						} elseif (($string{$i} === '"' || $string{$i} === "'" || $string{$i} === '(')) {
-							$this->cur_string[] = $string{$i};
-							$this->str_char[] = ($string{$i} === '(') ? ')' : $string{$i};
+						} elseif (($string[$i] === '"' || $string[$i] === "'" || $string[$i] === '(')) {
+							$this->cur_string[] = $string[$i];
+							$this->str_char[] = ($string[$i] === '(') ? ')' : $string[$i];
 							$this->status = 'instr';
 							$this->from[] = 'iv';
 							$this->quoted_string[] = in_array(strtolower($this->property), $quoted_string_properties);
-						} elseif ($string{$i} === ',') {
+						} elseif ($string[$i] === ',') {
 							$this->sub_value = trim($this->sub_value) . ',';
-						} elseif ($string{$i} === '\\') {
+						} elseif ($string[$i] === '\\') {
 							$this->sub_value .= $this->_unicode($string, $i);
-						} elseif ($string{$i} === ';' || $pn) {
-							if ($this->selector{0} === '@' && isset($at_rules[substr($this->selector, 1)]) && $at_rules[substr($this->selector, 1)] === 'iv') {
+						} elseif ($string[$i] === ';' || $pn) {
+							if ($this->selector[0] === '@' && isset($at_rules[substr($this->selector, 1)]) && $at_rules[substr($this->selector, 1)] === 'iv') {
 								/* Add quotes to charset, import, namespace */
 								$this->sub_value_arr[] = trim($this->sub_value);
 
@@ -799,12 +788,12 @@ class csstidy {
 							} else {
 								$this->status = 'ip';
 							}
-						} elseif ($string{$i} !== '}') {
-							$this->sub_value .= $string{$i};
+						} elseif ($string[$i] !== '}') {
+							$this->sub_value .= $string[$i];
 						}
-						if (($string{$i} === '}' || $string{$i} === ';' || $pn) && !empty($this->selector)) {
+						if (($string[$i] === '}' || $string[$i] === ';' || $pn) && !empty($this->selector)) {
 							if ($this->at == '') {
-								$this->at = $this->css_new_media_section(DEFAULT_AT);
+								$this->at = $this->css_new_media_section($this->at,DEFAULT_AT);
 							}
 
 							// case settings
@@ -850,21 +839,22 @@ class csstidy {
 							$this->sub_value_arr = array();
 							$this->value = '';
 						}
-						if ($string{$i} === '}') {
+						if ($string[$i] === '}') {
 							$this->explode_selectors();
 							$this->_add_token(SEL_END, $this->selector);
 							$this->status = 'is';
 							$this->invalid_at = false;
 							$this->selector = '';
 							if ($this->next_selector_at) {
-								$this->at = $this->css_new_media_section($this->next_selector_at);
+								$this->at = $this->css_close_media_section($this->at);
+								$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
 								$this->next_selector_at = '';
 							}
 						}
 					} elseif (!$pn) {
-						$this->sub_value .= $string{$i};
+						$this->sub_value .= $string[$i];
 
-						if (ctype_space($string{$i})) {
+						if (ctype_space($string[$i])) {
 							$this->optimise->subvalue();
 							if ($this->sub_value != '') {
 								$this->sub_value_arr[] = $this->sub_value;
@@ -879,26 +869,26 @@ class csstidy {
 					$_str_char = $this->str_char[count($this->str_char)-1];
 					$_cur_string = $this->cur_string[count($this->cur_string)-1];
 					$_quoted_string = $this->quoted_string[count($this->quoted_string)-1];
-					$temp_add = $string{$i};
+					$temp_add = $string[$i];
 
 					// Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
 					// parentheticals can be nested more than once.
-					if ($_str_char === ")" && ($string{$i} === "(" || $string{$i} === '"' || $string{$i} === '\'') && !$this->escaped($string, $i)) {
-						$this->cur_string[] = $string{$i};
-						$this->str_char[] = $string{$i} === '(' ? ')' : $string{$i};
+					if ($_str_char === ")" && ($string[$i] === "(" || $string[$i] === '"' || $string[$i] === '\'') && !$this->escaped($string, $i)) {
+						$this->cur_string[] = $string[$i];
+						$this->str_char[] = $string[$i] === '(' ? ')' : $string[$i];
 						$this->from[] = 'instr';
-						$this->quoted_string[] = ($_str_char === ')' && $string{$i} !== '(' && trim($_cur_string)==='(')?$_quoted_string:!($string{$i} === '(');
+						$this->quoted_string[] = ($_str_char === ')' && $string[$i] !== '(' && trim($_cur_string)==='(')?$_quoted_string:!($string[$i] === '(');
 						continue 2;
 					}
 
-					if ($_str_char !== ")" && ($string{$i} === "\n" || $string{$i} === "\r") && !($string{$i - 1} === '\\' && !$this->escaped($string, $i - 1))) {
+					if ($_str_char !== ")" && ($string[$i] === "\n" || $string[$i] === "\r") && !($string[$i - 1] === '\\' && !$this->escaped($string, $i - 1))) {
 						$temp_add = "\\A";
 						$this->log('Fixed incorrect newline in string', 'Warning');
 					}
 
 					$_cur_string .= $temp_add;
 
-					if ($string{$i} === $_str_char && !$this->escaped($string, $i)) {
+					if ($string[$i] === $_str_char && !$this->escaped($string, $i)) {
 						$this->status = array_pop($this->from);
 
 						if (!preg_match('|[' . implode('', $this->data['csstidy']['whitespace']) . ']|uis', $_cur_string) && $this->property !== 'content') {
@@ -949,7 +939,7 @@ class csstidy {
 
 				/* Case in-comment */
 				case 'ic':
-					if ($string{$i} === '*' && $string{$i + 1} === '/') {
+					if ($string[$i] === '*' && $string[$i + 1] === '/') {
 						$this->status = array_pop($this->from);
 						$i++;
 						if (strlen($cur_comment) > 1 and strncmp($cur_comment, '!', 1) === 0) {
@@ -961,7 +951,7 @@ class csstidy {
 						}
 						$cur_comment = '';
 					} else {
-						$cur_comment .= $string{$i};
+						$cur_comment .= $string[$i];
 					}
 					break;
 			}
@@ -1044,7 +1034,7 @@ class csstidy {
 	 * @version 1.02
 	 */
 	static function escaped(&$string, $pos) {
-		return!(@($string{$pos - 1} !== '\\') || csstidy::escaped($string, $pos - 1));
+		return!(@($string[$pos - 1] !== '\\') || csstidy::escaped($string, $pos - 1));
 	}
 
 
@@ -1091,29 +1081,27 @@ class csstidy {
 	}
 
 	/**
-	 * Start a new media section.
-	 * Check if the media is not already known,
-	 * else rename it with extra spaces
-	 * to avoid merging
+	 * Check if a current media section is the continuation of the last one
+	 * if not inc the name of the media section to avoid a merging
 	 *
-	 * @param string $media
-	 * @return string
+	 * @param int|string $media
+	 * @return int|string
 	 */
-	public function css_new_media_section($media) {
-		if ($this->get_cfg('preserve_css')) {
+	public function css_check_last_media_section_or_inc($media) {
+		// are we starting?
+		if (!$this->css || !is_array($this->css) || empty($this->css)) {
 			return $media;
 		}
 
 		// if the last @media is the same as this
 		// keep it
-		if (!$this->css || !is_array($this->css) || empty($this->css)) {
-			return $media;
-		}
 		end($this->css);
 		$at = key($this->css);
 		if ($at == $media) {
 			return $media;
 		}
+
+		// else inc the section in the array
 		while (isset($this->css[$media]))
 			if (is_numeric($media))
 				$media++;
@@ -1122,6 +1110,56 @@ class csstidy {
 		return $media;
 	}
 
+	/**
+	 * Start a new media section.
+	 * Check if the media is not already known,
+	 * else rename it with extra spaces
+	 * to avoid merging
+	 *
+	 * @param string $current_media
+	 * @param string $media
+	 * @param bool $at_root
+	 * @return string
+	 */
+	public function css_new_media_section($current_media, $new_media, $at_root = false) {
+		if ($this->get_cfg('preserve_css')) {
+			return $new_media;
+		}
+
+		// if we already are in a media and CSS level is 3, manage nested medias
+		if ($current_media
+			&& !$at_root
+			// numeric $current_media means DEFAULT_AT or inc
+			&& !is_numeric($current_media)
+			&& strncmp($this->get_cfg('css_level'), 'CSS3', 4) == 0) {
+
+			$new_media = rtrim($current_media) . "{" . rtrim($new_media);
+		}
+
+		return $this->css_check_last_media_section_or_inc($new_media);
+	}
+
+	/**
+	 * Close a media section
+	 * Find the parent media we were in before or the root
+	 * @param $current_media
+	 * @return string
+	 */
+	public function css_close_media_section($current_media) {
+		if ($this->get_cfg('preserve_css')) {
+			return '';
+		}
+
+		if (strpos($current_media, '{') !== false) {
+			$current_media = explode('{', $current_media);
+			array_pop($current_media);
+			$current_media = implode('{', $current_media);
+			return $current_media;
+		}
+
+		return '';
+	}
+
 	/**
 	 * Start a new selector.
 	 * If already referenced in this media section,
@@ -1255,7 +1293,7 @@ class csstidy {
 	/**
 	 * Checks if a property is valid
 	 * @param string $property
-	 * @return bool;
+	 * @return bool
 	 * @access public
 	 * @version 1.0
 	 */
@@ -1292,26 +1329,26 @@ class csstidy {
 		$current_string = '';
 
 		for ($i = 0, $_len = strlen($value); $i < $_len; $i++) {
-			if (($value{$i} === ',' || $value{$i} === ' ') && $in_str === true) {
+			if (($value[$i] === ',' || $value[$i] === ' ') && $in_str === true) {
 				$in_str = false;
 				$strings[] = $current_string;
 				$current_string = '';
-			} elseif ($value{$i} === '"' || $value{$i} === "'") {
-				if ($in_str === $value{$i}) {
+			} elseif ($value[$i] === '"' || $value[$i] === "'") {
+				if ($in_str === $value[$i]) {
 					$strings[] = $current_string;
 					$in_str = false;
 					$current_string = '';
 					continue;
 				} elseif (!$in_str) {
-					$in_str = $value{$i};
+					$in_str = $value[$i];
 				}
 			} else {
 				if ($in_str) {
-					$current_string .= $value{$i};
+					$current_string .= $value[$i];
 				} else {
-					if (!preg_match("/[\s,]/", $value{$i})) {
+					if (!preg_match("/[\s,]/", $value[$i])) {
 						$in_str = true;
-						$current_string = $value{$i};
+						$current_string = $value[$i];
 					}
 				}
 			}
diff --git a/plugins-dist/compresseur/lib/csstidy/class.csstidy_optimise.php b/plugins-dist/compresseur/lib/csstidy/class.csstidy_optimise.php
index 49724369c8..e4971f6eea 100644
--- a/plugins-dist/compresseur/lib/csstidy/class.csstidy_optimise.php
+++ b/plugins-dist/compresseur/lib/csstidy/class.csstidy_optimise.php
@@ -358,8 +358,8 @@ class csstidy_optimise {
 		// #aabbcc -> #abc
 		if (strlen($color) == 7) {
 			$color_temp = strtolower($color);
-			if ($color_temp{0} === '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6}) {
-				$color = '#' . $color{1} . $color{3} . $color{5};
+			if ($color_temp[0] === '#' && $color_temp[1] == $color_temp[2] && $color_temp[3] == $color_temp[4] && $color_temp[5] == $color_temp[6]) {
+				$color = '#' . $color[1] . $color[3] . $color[5];
 			}
 		}
 
@@ -438,7 +438,7 @@ class csstidy_optimise {
 	 */
 	public function AnalyseCssNumber($string) {
 		// most simple checks first
-		if (strlen($string) == 0 || ctype_alpha($string{0})) {
+		if (strlen($string) == 0 || ctype_alpha($string[0])) {
 			return false;
 		}
 
@@ -647,22 +647,22 @@ class csstidy_optimise {
 		for ($i = 0, $len = strlen($string); $i < $len; $i++) {
 			switch ($status) {
 				case 'st':
-					if ($string{$i} == $sep && !$this->parser->escaped($string, $i)) {
+					if ($string[$i] == $sep && !$this->parser->escaped($string, $i)) {
 						++$num;
-					} elseif ($string{$i} === '"' || $string{$i} === '\'' || (!$explode_in_parenthesis && $string{$i} === '(') && !$this->parser->escaped($string, $i)) {
+					} elseif ($string[$i] === '"' || $string[$i] === '\'' || (!$explode_in_parenthesis && $string[$i] === '(') && !$this->parser->escaped($string, $i)) {
 						$status = 'str';
-						$to = ($string{$i} === '(') ? ')' : $string{$i};
-						(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
+						$to = ($string[$i] === '(') ? ')' : $string[$i];
+						(isset($output[$num])) ? $output[$num] .= $string[$i] : $output[$num] = $string[$i];
 					} else {
-						(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
+						(isset($output[$num])) ? $output[$num] .= $string[$i] : $output[$num] = $string[$i];
 					}
 					break;
 
 				case 'str':
-					if ($string{$i} == $to && !$this->parser->escaped($string, $i)) {
+					if ($string[$i] == $to && !$this->parser->escaped($string, $i)) {
 						$status = 'st';
 					}
-					(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
+					(isset($output[$num])) ? $output[$num] .= $string[$i] : $output[$num] = $string[$i];
 					break;
 			}
 		}
@@ -797,9 +797,9 @@ class csstidy_optimise {
 					$have['clip'] = true;
 				} elseif (in_array($str_value[$i][$j], $origin, true)) {
 					$return['background-origin'] .= $str_value[$i][$j] . ',';
-				} elseif ($str_value[$i][$j]{0} === '(') {
+				} elseif ($str_value[$i][$j][0] === '(') {
 					$return['background-size'] .= substr($str_value[$i][$j], 1, -1) . ',';
-				} elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === null || $str_value[$i][$j]{0} === '-' || $str_value[$i][$j]{0} === '.') {
+				} elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j][0]) || $str_value[$i][$j][0] === null || $str_value[$i][$j][0] === '-' || $str_value[$i][$j][0] === '.') {
 					$return['background-position'] .= $str_value[$i][$j];
 					if (!$have['pos'])
 						$return['background-position'] .= ' '; else
@@ -945,7 +945,7 @@ class csstidy_optimise {
 			} elseif ($have['style'] === false && in_array($str_value[0][$j], $font_style)) {
 				$return['font-style'] = $str_value[0][$j];
 				$have['style'] = true;
-			} elseif ($have['size'] === false && (is_numeric($str_value[0][$j]{0}) || $str_value[0][$j]{0} === null || $str_value[0][$j]{0} === '.')) {
+			} elseif ($have['size'] === false && (is_numeric($str_value[0][$j][0]) || $str_value[0][$j][0] === null || $str_value[0][$j][0] === '.')) {
 				$size = $this->explode_ws('/', trim($str_value[0][$j]));
 				$return['font-size'] = $size[0];
 				if (isset($size[1])) {
@@ -975,7 +975,7 @@ class csstidy_optimise {
 
 		// Fix for 100 and more font-size
 		if ($have['size'] === false && isset($return['font-weight']) &&
-						is_numeric($return['font-weight']{0})) {
+						is_numeric($return['font-weight'][0])) {
 			$return['font-size'] = $return['font-weight'];
 			unset($return['font-weight']);
 		}
@@ -1011,8 +1011,8 @@ class csstidy_optimise {
 					$family = trim($family);
 					$len = strlen($family);
 					if (strpos($family, ' ') &&
-									!(($family{0} === '"' && $family{$len - 1} === '"') ||
-									($family{0} === "'" && $family{$len - 1} === "'"))) {
+									!(($family[0] === '"' && $family[$len - 1] === '"') ||
+									($family[0] === "'" && $family[$len - 1] === "'"))) {
 						$family = '"' . $family . '"';
 					}
 					$result_families[] = $family;
@@ -1278,16 +1278,25 @@ class csstidy_optimise {
 		if (stripos($value, 'left') === false and stripos($value, 'right') === false) {
 			$values = $this->explode_ws(' ', trim($value));
 			$values = array_map('trim', $values);
-			$values = array_filter($values);
+			$values = array_filter($values, function ($v) { return strlen($v);});
 			$values = array_values($values);
 			if (count($values) == 1) {
+				if (in_array($value, array('center', 'top', 'bottom', 'inherit', 'initial', 'unset'))) {
+					return $value;
+				}
 				return "left $value";
 			}
 			if ($values[1] == 'top' or $values[1] == 'bottom') {
+				if ($values[0] === 'center') {
+					return $value;
+				}
 				return 'left ' . implode(' ', $values);
 			}
 			else {
 				$last = array_pop($values);
+				if ($last === 'center') {
+					return $value;
+				}
 				return implode(' ', $values) . ' left ' . $last;
 			}
 		}
diff --git a/plugins-dist/compresseur/lib/csstidy/class.csstidy_print.php b/plugins-dist/compresseur/lib/csstidy/class.csstidy_print.php
index f4ea07c71d..e5011074e3 100644
--- a/plugins-dist/compresseur/lib/csstidy/class.csstidy_print.php
+++ b/plugins-dist/compresseur/lib/csstidy/class.csstidy_print.php
@@ -219,20 +219,25 @@ class csstidy_print {
 			$output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6] . $template[13];
 		}
 
-		$in_at_out = '';
+		$in_at_out = [];
 		$out = & $output;
+		$indent_level = 0;
 
 		foreach ($this->tokens as $key => $token) {
 			switch ($token[0]) {
 				case AT_START:
 					$out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
-					$out = & $in_at_out;
+					$indent_level++;
+					if (!isset($in_at_out[$indent_level])) {
+						$in_at_out[$indent_level] = '';
+					}
+					$out = & $in_at_out[$indent_level];
 					break;
 
 				case SEL_START:
 					if ($this->parser->get_cfg('lowercase_s'))
 						$token[1] = strtolower($token[1]);
-					$out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
+					$out .= ( $token[1][0] !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
 					$out .= $template[3];
 					break;
 
@@ -261,12 +266,28 @@ class csstidy_print {
 					break;
 
 				case AT_END:
+					if (strlen($template[10])) {
+						// indent the bloc we are closing
+						$out = str_replace("\n\n", "\r\n", $out); // don't fill empty lines
+						$out = str_replace("\n", "\n" . $template[10], $out);
+						$out = str_replace("\r\n", "\n\n", $out);
+					}
+					if ($indent_level > 1) {
+						$out = & $in_at_out[$indent_level-1];
+					}
+					else {
 						$out = & $output;
-					$in_at_out = str_replace("\n\n", "\r\n", $in_at_out); // don't fill empty lines
-					$in_at_out = str_replace("\n", "\n" . $template[10], $in_at_out);
-					$in_at_out = str_replace("\r\n", "\n\n", $in_at_out);
-					$out .= $template[10] . $in_at_out . $template[9];
-					$in_at_out = '';
+					}
+					$out .= $template[10] . $in_at_out[$indent_level];
+					if ($this->_seeknocomment($key, 1) != AT_END) {
+						$out .= $template[9];
+					}
+					else {
+						$out .= rtrim($template[9]);
+					}
+
+					unset($in_at_out[$indent_level]);
+					$indent_level--;
 					break;
 
 				case IMPORTANT_COMMENT:
@@ -332,7 +353,10 @@ class csstidy_print {
 			if (intval($medium) < DEFAULT_AT) {
 				// un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
 				if (strlen(trim($medium))) {
-					$this->parser->_add_token(AT_START, $medium, true);
+					$parts_to_open = explode('{', $medium);
+					foreach ($parts_to_open as $part) {
+						$this->parser->_add_token(AT_START, $part, true);
+					}
 				}
 			} elseif ($default_media) {
 				$this->parser->_add_token(AT_START, $default_media, true);
@@ -372,7 +396,10 @@ class csstidy_print {
 			if (intval($medium) < DEFAULT_AT) {
 				// un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
 				if (strlen(trim($medium))) {
-					$this->parser->_add_token(AT_END, $medium, true);
+					$parts_to_close = explode('{', $medium);
+					foreach (array_reverse($parts_to_close) as $part) {
+						$this->parser->_add_token(AT_END, $part, true);
+					}
 				}
 			} elseif ($default_media) {
 				$this->parser->_add_token(AT_END, $default_media, true);
diff --git a/plugins-dist/compresseur/lib/csstidy/data.inc.php b/plugins-dist/compresseur/lib/csstidy/data.inc.php
index 5bbc2ae5b9..63eeae8c5b 100644
--- a/plugins-dist/compresseur/lib/csstidy/data.inc.php
+++ b/plugins-dist/compresseur/lib/csstidy/data.inc.php
@@ -55,7 +55,7 @@ $data['csstidy']['units'] = array('in','cm','mm','pt','pc','px','rem','em','%','
  * @global array $data['csstidy']['at_rules']
  * @version 1.1
  */
-$data['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'atis','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at','keyframes' => 'at','-moz-keyframes' => 'at','-o-keyframes' => 'at','-webkit-keyframes' => 'at','-ms-keyframes' => 'at');
+$data['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'atis','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at', 'supports' => 'at', 'keyframes' => 'at','-moz-keyframes' => 'at','-o-keyframes' => 'at','-webkit-keyframes' => 'at','-ms-keyframes' => 'at');
 
  /**
  * Properties that need a value with unit
@@ -588,20 +588,20 @@ $data['csstidy']['multiple_properties'] = array('background', 'background-image'
  * @version 1.0
  * @see csstidy::load_template()
  */
-$data['csstidy']['predefined_templates']['default'][] = '<span class="at">'; //string before @rule
-$data['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
-$data['csstidy']['predefined_templates']['default'][] = '<span class="selector">'; //string before selector
-$data['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after selector
-$data['csstidy']['predefined_templates']['default'][] = '<span class="property">'; //string before property
-$data['csstidy']['predefined_templates']['default'][] = '</span><span class="value">'; //string after property+before value
-$data['csstidy']['predefined_templates']['default'][] = '</span><span class="format">;</span>'."\n"; //string after value
-$data['csstidy']['predefined_templates']['default'][] = '<span class="format">}</span>'; //closing bracket - selector
-$data['csstidy']['predefined_templates']['default'][] = "\n\n"; //space between blocks {...}
-$data['csstidy']['predefined_templates']['default'][] = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
-$data['csstidy']['predefined_templates']['default'][] = ''; //indent in @-rule
-$data['csstidy']['predefined_templates']['default'][] = '<span class="comment">'; // before comment
-$data['csstidy']['predefined_templates']['default'][] = '</span>'."\n"; // after comment
-$data['csstidy']['predefined_templates']['default'][] = "\n"; // after each line @-rule
+$data['csstidy']['predefined_templates']['default'][0]  = '<span class="at">'; //string before @rule
+$data['csstidy']['predefined_templates']['default'][1]  = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
+$data['csstidy']['predefined_templates']['default'][2]  = '<span class="selector">'; //string before selector
+$data['csstidy']['predefined_templates']['default'][3]  = '</span> <span class="format">{</span>'."\n"; //bracket after selector
+$data['csstidy']['predefined_templates']['default'][4]  = '<span class="property">'; //string before property
+$data['csstidy']['predefined_templates']['default'][5]  = '</span><span class="value">'; //string after property+before value
+$data['csstidy']['predefined_templates']['default'][6]  = '</span><span class="format">;</span>'."\n"; //string after value
+$data['csstidy']['predefined_templates']['default'][7]  = '<span class="format">}</span>'; //closing bracket - selector
+$data['csstidy']['predefined_templates']['default'][8]  = "\n\n"; //space between blocks {...}
+$data['csstidy']['predefined_templates']['default'][9]  = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
+$data['csstidy']['predefined_templates']['default'][10] = ''; //indent in @-rule
+$data['csstidy']['predefined_templates']['default'][11] = '<span class="comment">'; // before comment
+$data['csstidy']['predefined_templates']['default'][12] = '</span>'."\n"; // after comment
+$data['csstidy']['predefined_templates']['default'][13] = "\n"; // after each line @-rule
 
 $data['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
 $data['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>'."\n";
diff --git a/plugins-dist/compresseur/paquet.xml b/plugins-dist/compresseur/paquet.xml
index 151e8e9b74..36eea2e1e5 100644
--- a/plugins-dist/compresseur/paquet.xml
+++ b/plugins-dist/compresseur/paquet.xml
@@ -12,6 +12,8 @@
 
 	<auteur>Collectif SPIP</auteur>
 
+	<credit lien="https://github.com/Cerdic/CSSTidy";>Cerdic/CSSTidy</credit>
+
 	<licence lien="http://www.gnu.org/licenses/gpl-3.0.html";>GPL</licence>
 
 	<traduire module="compresseur" reference="fr" gestionnaire="salvatore" />
@@ -24,4 +26,6 @@
 	<pipeline nom="ieconfig_metas" inclure="compresseur_ieconfig.php" />
 
 	<utilise nom="porte_plume" compatibilite="[1.18.1;]" />
+
+	<procure nom="csstidy" version="1.7.3" />
 </paquet>
diff --git a/plugins-dist/medias/action/editer_document.php b/plugins-dist/medias/action/editer_document.php
index e39986c2c7..fd1f758954 100644
--- a/plugins-dist/medias/action/editer_document.php
+++ b/plugins-dist/medias/action/editer_document.php
@@ -233,7 +233,7 @@ function document_instituer($id_document, $champs = array()) {
 	}
 
 	sql_updateq('spip_documents', $champs, 'id_document=' . intval($id_document));
-	if ($statut !== $statut_ancien) {
+	if (!empty($champs['statut'])) {
 		$publier_rubriques = sql_allfetsel(
 			'id_objet',
 			'spip_documents_liens',
@@ -242,7 +242,7 @@ function document_instituer($id_document, $champs = array()) {
 		if (count($publier_rubriques)) {
 			include_spip('inc/rubriques');
 			foreach ($publier_rubriques as $r) {
-				calculer_rubriques_if($r['id_objet'], array('statut' => $statut), $statut_ancien, false);
+				calculer_rubriques_if($r['id_objet'], array('statut' => $champs['statut']), $statut_ancien, false);
 			}
 		}
 	}
diff --git a/plugins-dist/medias/lib/getid3/module.archive.hpk.php b/plugins-dist/medias/lib/getid3/module.archive.hpk.php
new file mode 100644
index 0000000000..328dbd5962
diff --git a/plugins-dist/medias/lib/getid3/module.archive.xz.php b/plugins-dist/medias/lib/getid3/module.archive.xz.php
new file mode 100644
index 0000000000..1557bfb57e
diff --git a/plugins-dist/medias/lib/getid3/module.audio-video.ivf.php b/plugins-dist/medias/lib/getid3/module.audio-video.ivf.php
new file mode 100644
index 0000000000..791b88bc9f
diff --git a/plugins-dist/medias/lib/getid3/module.audio-video.wtv.php b/plugins-dist/medias/lib/getid3/module.audio-video.wtv.php
new file mode 100644
index 0000000000..ed37abe326
diff --git a/plugins-dist/medias/lib/getid3/module.audio.dsdiff.php b/plugins-dist/medias/lib/getid3/module.audio.dsdiff.php
new file mode 100644
index 0000000000..bed2afca59
diff --git a/plugins-dist/medias/lib/getid3/module.audio.tak.php b/plugins-dist/medias/lib/getid3/module.audio.tak.php
new file mode 100644
index 0000000000..5d4ada5676
diff --git a/plugins-dist/medias/lib/mejs/package.js b/plugins-dist/medias/lib/mejs/package.js
old mode 100644
new mode 100755
diff --git a/plugins-dist/medias/lib/mejs/package.json b/plugins-dist/medias/lib/mejs/package.json
diff --git a/plugins-dist/medias/lib/mejs/package.json b/plugins-dist/medias/lib/mejs/package.json
old mode 100644
new mode 100755
diff --git a/plugins-dist/medias/paquet.xml b/plugins-dist/medias/paquet.xml
diff --git a/plugins-dist/medias/paquet.xml b/plugins-dist/medias/paquet.xml
index 6b09414f29..5a184a02f5 100644
--- a/plugins-dist/medias/paquet.xml
+++ b/plugins-dist/medias/paquet.xml
@@ -1,7 +1,7 @@
 <paquet
 	prefix="medias"
 	categorie="multimedia"
-	version="2.20.34"
+	version="2.20.35"
 	etat="stable"
 	compatibilite="[3.2.0;3.2.*]"
 	logo="prive/themes/spip/images/portfolio-32.png"
diff --git a/plugins-dist/medias/prive/squelettes/inclure/portfolio-documents.html b/plugins-dist/medias/prive/squelettes/inclure/portfolio-documents.html
index 4a80ae9241..2a877ec3c2 100644
--- a/plugins-dist/medias/prive/squelettes/inclure/portfolio-documents.html
+++ b/plugins-dist/medias/prive/squelettes/inclure/portfolio-documents.html
@@ -32,7 +32,7 @@
 
 [(#REM) puis les images du portfolio]
 <B_portfolio>
-<h3><:medias:info_portfolio:></h3>
+<h3 class="portfolios__titre"><:medias:info_portfolio:></h3>
 <div class="liste_items documents ordonner_rang_lien" id="portfolio#ENV{id_unique}" data-cookie-affichage="portfolio" data-lien="[(#OBJET|concat{'/',#ID_OBJET}|attribut_html)]">
 [<p class="pagination">(#PAGINATION{prive})</p>]
 <div class="sortable">
@@ -53,7 +53,7 @@
 
 [(#REM) puis les documents]
 <B_documents>
-<h3><:medias:info_documents:></h3>
+<h3 class="portfolios__titre"><:medias:info_documents:></h3>
 <div class="liste_items documents ordonner_rang_lien" id="documents#ENV{id_unique}" data-cookie-affichage="documents" data-lien="[(#OBJET|concat{'/',#ID_OBJET}|attribut_html)]">
 [<p class="pagination">(#PAGINATION{prive})</p>]
 <div class="sortable">
diff --git a/plugins-dist/organiseur/inc/quete_calendrier.php b/plugins-dist/organiseur/inc/quete_calendrier.php
index c2b8cf718f..1278f3e786 100644
--- a/plugins-dist/organiseur/inc/quete_calendrier.php
+++ b/plugins-dist/organiseur/inc/quete_calendrier.php
@@ -345,7 +345,7 @@ function quete_calendrier_interval_rv($avant, $apres) {
 						'DESCRIPTION' => $row['texte'],
 						'SUMMARY' => $row['titre'],
 						'CATEGORIES' => $cat,
-						'ATTENDEE' => (count($auteurs) == 0) ? '' : join($auteurs, ', ')
+						'ATTENDEE' => (count($auteurs) == 0) ? '' : implode(', ', $auteurs)
 					);
 			}
 
diff --git a/plugins-dist/revisions/inc/diff.php b/plugins-dist/revisions/inc/diff.php
index 4fbec349da..a159525b37 100644
--- a/plugins-dist/revisions/inc/diff.php
+++ b/plugins-dist/revisions/inc/diff.php
@@ -194,7 +194,9 @@ class Diff {
 			if (!$fin_old) {
 				// Paragraphes supprimes jusqu'au paragraphe courant
 				if (!isset($i_old)) {
-					list($i_old, $p_old) = each($paras_old);
+					$i_old = key($paras_old);
+					$p_old = current($paras_old);
+					next($paras_old);
 					if (!$p_old) {
 						$fin_old = true;
 					}
@@ -204,7 +206,9 @@ class Diff {
 						$this->diff->supprimer($p_old);
 					}
 					unset($i_old);
-					list($i_old, $p_old) = each($paras_old);
+					$i_old = key($paras_old);
+					$p_old = current($paras_old);
+					next($paras_old);
 					if (!$p_old) {
 						$fin_old = true;
 					}
@@ -216,7 +220,9 @@ class Diff {
 		// Paragraphes supprimes a la fin du texte
 		if (!$fin_old) {
 			if (!isset($i_old)) {
-				list($i_old, $p_old) = each($paras_old);
+				$i_old = key($paras_old);
+				$p_old = current($paras_old);
+				next($paras_old);
 				if (!strlen($p_old)) {
 					$fin_old = true;
 				}
@@ -225,7 +231,9 @@ class Diff {
 				if (!isset($trans_rev[$i_old])) {
 					$this->diff->supprimer($p_old);
 				}
-				list($i_old, $p_old) = each($paras_old);
+				$i_old = key($paras_old);
+				$p_old = current($paras_old);
+				next($paras_old);
 				if (!$p_old) {
 					$fin_old = true;
 				}
diff --git a/plugins-dist/revisions/inc/revisions.php b/plugins-dist/revisions/inc/revisions.php
index cb60ec8148..cfe2a64aec 100644
--- a/plugins-dist/revisions/inc/revisions.php
+++ b/plugins-dist/revisions/inc/revisions.php
@@ -561,8 +561,8 @@ function ajouter_version($id_objet, $objet, $champs, $titre_version = "", $id_au
 	// distinctif (pour eviter la violation d'unicite)
 	// et un titre contenant en fait le moment de l'insertion
 	list($ms, $sec) = explode(' ', microtime());
-	$date = $sec . substr($ms, 1,
-			4) - 20; // SQL ne ramene que 4 chiffres significatifs apres la virgule pour 0.0+titre_version
+	// SQL ne ramene que 4 chiffres significatifs apres la virgule pour 0.0+titre_version
+	$date = ($sec . substr($ms, 1, 4)) - 20;
 	$datediff = ($sec - mktime(0, 0, 0, 9, 1, 2007)) * 1000000 + substr($ms, 2, strlen($ms) - 4);
 
 	$valeurs = array(
@@ -653,7 +653,8 @@ function ajouter_version($id_objet, $objet, $champs, $titre_version = "", $id_au
 
 		for ($i = 0; $i < $n; $i++) {
 			while ($i >= $paras_champ[$nom]) {
-				list($nom, ) = each($champs);
+				$nom = key($champs);
+				next($champs);
 			}
 			// Lier au fragment existant si possible, sinon creer un nouveau fragment
 			$id_fragment = isset($trans[$i]) ? $trans[$i] : $next++;
diff --git a/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php b/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
index ca88e8a8d4..6959b1cdd6 100644
--- a/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
+++ b/plugins-dist/safehtml/lib/safehtml/classes/safehtml.php
@@ -285,7 +285,7 @@ class SafeHTML
         foreach ($this->blackProtocols as $proto) {
             $preg = "/[\s\x01-\x1F]*";
             for ($i=0; $i<strlen($proto); $i++) {
-                $preg .= $proto{$i} . "[\s\x01-\x1F]*";
+                $preg .= $proto[$i] . "[\s\x01-\x1F]*";
             }
             $preg .= ":/i";
             $this->protoRegexps[] = $preg;
diff --git a/plugins-dist/svp/inc/svp_outiller.php b/plugins-dist/svp/inc/svp_outiller.php
index 9f74f5f740..e3185d938f 100644
--- a/plugins-dist/svp/inc/svp_outiller.php
+++ b/plugins-dist/svp/inc/svp_outiller.php
@@ -196,7 +196,7 @@ function extraire_bornes($intervalle, $initialiser = false) {
 	) {
 		if ($matches[1]) {
 			$bornes['min']['valeur'] = trim($matches[1]);
-			$bornes['min']['incluse'] = ($intervalle{0} == "[");
+			$bornes['min']['incluse'] = ($intervalle[0] == "[");
 		}
 		if ($matches[2]) {
 			$bornes['max']['valeur'] = trim($matches[2]);
diff --git a/plugins-dist/svp/svp_fonctions.php b/plugins-dist/svp/svp_fonctions.php
index 9ab89f2b03..a0d9c02e82 100644
--- a/plugins-dist/svp/svp_fonctions.php
+++ b/plugins-dist/svp/svp_fonctions.php
@@ -40,8 +40,9 @@ function svp_afficher_intervalle($intervalle, $logiciel) {
 	}
 
 	$mineure = $regs[1];
+
 	$majeure = preg_replace(',\.99$,', '.*', $regs[2]);
-	$mineure_inc = $intervalle{0} == "[";
+	$mineure_inc = $intervalle[0] == "[";
 	$majeure_inc = substr($intervalle, -1) == "]";
 	if (strlen($mineure)) {
 		if (!strlen($majeure)) {
diff --git a/plugins-dist/textwheel/engine/textwheel.php b/plugins-dist/textwheel/engine/textwheel.php
index 3768e4899c..9cb9b64b9c 100644
--- a/plugins-dist/textwheel/engine/textwheel.php
+++ b/plugins-dist/textwheel/engine/textwheel.php
@@ -28,6 +28,8 @@ class TextWheel {
 	protected $ruleset;
 	protected static $subwheel = array();
 
+	// Experimental : projet de compilation PHP d'une wheel
+	// pour generation d'un fichier php execute a la place de ->text()
 	protected $compiled = array();
 
 	/**
@@ -83,13 +85,14 @@ class TextWheel {
 		foreach ($rules as $name => $rule) {
 			$rule->name = $name;
 			$this->initRule($rule);
-			if (is_string($rule->replace)
-				and isset($this->compiled[$rule->replace])
-				and $fun = $this->compiled[$rule->replace]
+			if ($rule->replace
+				and $compiledEntry = $this->ruleCompiledEntryName($rule->replace)
+				and isset($this->compiled[$compiledEntry])
+				and $fun = $this->compiled[$compiledEntry]
 			) {
 				$pre[] = "\n###\n## $name\n###\n" . $fun;
 				preg_match(',function (\w+), ', $fun, $r);
-				$rule->compilereplace = $r[1]; # ne pas modifier ->replace sinon on casse l'execution...
+				$rule->compilereplace = "'".$r[1]."'"; # ne pas modifier ->replace sinon on casse l'execution...
 			}
 
 			$r = "\t/* $name */\n";
@@ -109,9 +112,18 @@ class TextWheel {
 
 			if ($rule->func_replace !== 'replace_identity') {
 				$fun = 'TextWheel::' . $rule->func_replace;
+				$call = '';
 				switch ($fun) {
 					case 'TextWheel::replace_all_cb':
-						$fun = $rule->replace; # trim()...
+						if (is_string($rule->replace)) {
+							$fun = $rule->replace;
+						}
+						elseif ($rule->compilereplace) {
+							$fun = trim($rule->compilereplace, "'");
+						};
+						if ($fun) {
+							$call = "\$t = $fun(\$t);";
+						}
 						break;
 					case 'TextWheel::replace_preg':
 						$fun = 'preg_replace';
@@ -125,7 +137,13 @@ class TextWheel {
 					default:
 						break;
 				}
-				$r .= "\t" . '$t = ' . $fun . '(' . TextWheel::export($rule->match) . ', ' . TextWheel::export($rule->replace) . ', $t);' . "\n";
+				if (!$call) {
+					if (empty($rule->compilereplace)) {
+						$rule->compilereplace = TextWheel::export($rule->replace);
+					}
+					$call = '$t = ' . $fun . '(' . TextWheel::export($rule->match) . ', ' . $rule->compilereplace . ', $t);';
+				}
+				$r .= "\t$call\n";
 			}
 
 			$comp[] = $r;
@@ -161,6 +179,20 @@ class TextWheel {
 		return $tw;
 	}
 
+	/**
+	 * @param $replace
+	 * @return string
+	 */
+	protected function ruleCompiledEntryName($replace) {
+		if (is_array($replace)) {
+			return serialize($replace);
+		}
+		elseif (is_object($replace)) {
+			return get_class($replace) . ':' . spl_object_hash($replace);
+		}
+		return $replace;
+	}
+
 	/**
 	 * Initializing a rule a first call
 	 * including file, creating function or wheel
@@ -183,25 +215,35 @@ class TextWheel {
 		}
 
 		if ($rule->create_replace) {
+			// DEPRECATED : rule->create_replace, on ne peut rien faire de mieux ici
+			// mais c'est voue a disparaitre
 			$compile = $rule->replace . '($t)';
 			$rule->replace = create_function('$m', $rule->replace);
-			$this->compiled[$rule->replace] = $compile;
+			$this->compiled[$this->ruleCompiledEntryName($rule->replace)] = $compile;
 			$rule->create_replace = false;
 			$rule->is_callback = true;
-		} elseif ($rule->is_wheel) {
-			$n = count(TextWheel::$subwheel);
+		}
+		elseif ($rule->is_wheel) {
+			$rule_number = count(TextWheel::$subwheel);
 			TextWheel::$subwheel[] = $this->createSubWheel($rule->replace);
-			$var = '$m[' . intval($rule->pick_match) . ']';
+			$cname = 'compiled_' . str_replace('-', '_', $rule->name) . '_' . substr(md5(spl_object_hash($rule)),0,7);
 			if ($rule->type == 'all' or $rule->type == 'str' or $rule->type == 'split' or !isset($rule->match)) {
-				$var = '$m';
+				$rule->replace = function ($m) use ($rule_number) {
+					return TextWheel::getSubWheel($rule_number)->text($m);
+				};
+				$rule->compilereplace = "'$cname'";
+			}
+			else {
+				$pick_match = intval($rule->pick_match);
+				$rule->replace = function ($m) use ($rule_number, $pick_match) {
+					return TextWheel::getSubWheel($rule_number)->text($m[$pick_match]);
+				};
+				$rule->compilereplace = 'function ($m) { return '.$cname.'($m['.$pick_match.']) }';
 			}
-			$code = 'return TextWheel::getSubWheel(' . $n . ')->text(' . $var . ');';
-			$rule->replace = create_function('$m', $code);
-			$cname = 'compiled_' . str_replace('-', '_', $rule->name);
-			$compile = TextWheel::getSubWheel($n)->compile($cname);
-			$this->compiled[$rule->replace] = $compile;
 			$rule->is_wheel = false;
 			$rule->is_callback = true;
+			$compile = TextWheel::getSubWheel($rule_number)->compile($cname);
+			$this->compiled[$this->ruleCompiledEntryName($rule->replace)] = $compile;
 		}
 
 		# optimization
diff --git a/plugins-dist/textwheel/engine/textwheelrule.php b/plugins-dist/textwheel/engine/textwheelrule.php
index a3cd6fdf6e..2f0efc2456 100644
--- a/plugins-dist/textwheel/engine/textwheelrule.php
+++ b/plugins-dist/textwheel/engine/textwheelrule.php
@@ -65,10 +65,12 @@ class TextWheelRule {
 	# optional
 	# language specific
 	public $require; # file to require_once
+	# DEPRECATED : create_function deprecated a partir de PHP 7.2, ne plus utiliser
 	public $create_replace; # do create_function('$m', %) on $this->replace, $m is the matched array
 
 	# optimizations
 	public $func_replace;
+	public $compilereplace;
 
 	/**
 	 * Rule constructor
diff --git a/plugins-dist/textwheel/inc/texte.php b/plugins-dist/textwheel/inc/texte.php
index 71aa559411..325bedb7e5 100644
--- a/plugins-dist/textwheel/inc/texte.php
+++ b/plugins-dist/textwheel/inc/texte.php
@@ -377,7 +377,6 @@ function traiter_tableau($bloc) {
 	$lignes = array();
 	$debut_table = $summary = '';
 	$l = 0;
-	$numeric = true;
 
 	// Traiter chaque ligne
 	$reg_line1 = ',^(\|(' . _RACCOURCI_TH_SPAN . '))+$,sS';
diff --git a/plugins-dist/textwheel/lib/yaml/sfYamlInline.php b/plugins-dist/textwheel/lib/yaml/sfYamlInline.php
index 6645dd793a..b72d6ee031 100644
--- a/plugins-dist/textwheel/lib/yaml/sfYamlInline.php
+++ b/plugins-dist/textwheel/lib/yaml/sfYamlInline.php
@@ -110,7 +110,7 @@ class sfYamlInline
     if (
       (1 == count($keys) && '0' == $keys[0])
       ||
-      (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2))
+      (count($keys) > 1 && array_reduce($keys, function($v,$w) { return (integer) $v + $w; }, 0) == count($keys) * (count($keys) - 1) / 2))
     {
       $output = array();
       foreach ($value as $val)
@@ -222,7 +222,7 @@ class sfYamlInline
       // evaluate the string
       $buffer = str_replace(array('\\n', '\\r'), array("\n", "\r"), $buffer);
 			if (strpos($buffer,'\\x')!==false){
-				$buffer = preg_replace_callback(',\\\\x([0-9a-f]+),', create_function('$m', 'return chr(hexdec($m[1]));'), $buffer);
+				$buffer = preg_replace_callback(',\\\\x([0-9a-f]+),', function($m) { return chr(hexdec($m[1])); }, $buffer);
 			}
     }
 
diff --git a/plugins-dist/textwheel/paquet.xml b/plugins-dist/textwheel/paquet.xml
index 5a427bf287..40d79d92d9 100644
--- a/plugins-dist/textwheel/paquet.xml
+++ b/plugins-dist/textwheel/paquet.xml
@@ -1,7 +1,7 @@
 <paquet
 	prefix="tw"
 	categorie="edition"
-	version="1.5.5"
+	version="1.5.6"
 	etat="stable"
 	compatibilite="[3.2.0;3.2.*]"
 	logo="textwheel-32.png"
diff --git a/prive/formulaires/login.html b/prive/formulaires/login.html
index 705e95260b..c7148af05e 100644
--- a/prive/formulaires/login.html
+++ b/prive/formulaires/login.html
@@ -2,7 +2,7 @@
 #HTTP_HEADER{"Pragma: no-cache"}
 
 <div class='formulaire_spip formulaire_login'>
-	[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{_deja_loge})</p>]
+	[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV**{_deja_loge})</p>]
 	[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
 	[<p class='reponse_formulaire reponse_formulaire_erreur'>(#ENV*{message_erreur})</p>]
 
diff --git a/prive/formulaires/login.php b/prive/formulaires/login.php
index 9ec45aca8e..393bb309bc 100644
--- a/prive/formulaires/login.php
+++ b/prive/formulaires/login.php
@@ -121,7 +121,7 @@ function formulaires_login_charger_dist($cible = '', $login = '', $prive = null)
 		if (isset($res['redirect']) and $res['redirect']) {
 			include_spip('inc/headers');
 			# preparer un lien pour quand redirige_formulaire ne fonctionne pas
-			$m = redirige_formulaire($res['redirect'], '', 'ajaxform');
+			$m = redirige_formulaire($res['redirect']);
 			$valeurs['_deja_loge'] = inserer_attribut(
 				'<a>' . _T('login_par_ici') . "</a>$m",
 				'href',
diff --git a/prive/javascript/js.cookie.js b/prive/javascript/js.cookie.js
old mode 100644
new mode 100755
diff --git a/prive/objets/infos/auteur.html b/prive/objets/infos/auteur.html
diff --git a/prive/objets/infos/auteur.html b/prive/objets/infos/auteur.html
index 6c0a0af7a3..93f0714d2f 100644
--- a/prive/objets/infos/auteur.html
+++ b/prive/objets/infos/auteur.html
@@ -14,7 +14,7 @@
 		<:info_webmestre_forces{file_options=#GET{options}}:>
 	]
 	[(#VAL{_ID_WEBMESTRES}|defined|non)
-		[(#BOUTON_ACTION{<:info_admin_etre_webmestre:>,[(#URL_ACTION_AUTEUR{etre_webmestre,[(#REM|time)],#SELF})]})]
+		[(#BOUTON_ACTION{<:info_admin_etre_webmestre:>,[(#URL_ACTION_AUTEUR{etre_webmestre,[(#EVAL{'time()'})],#SELF})]})]
 	]
 ]
 <INCLURE{fond=prive/objets/infos/inc-auteur-rubriques,id_auteur,statut} />
diff --git a/prive/objets/liste/auteurs_fonctions.php b/prive/objets/liste/auteurs_fonctions.php
index 3e4f837862..99bb10a4ae 100644
--- a/prive/objets/liste/auteurs_fonctions.php
+++ b/prive/objets/liste/auteurs_fonctions.php
@@ -117,7 +117,8 @@ function afficher_initiale($url, $initiale, $compteur, $debut, $pas) {
 		if (count($res) > 1) {
 			$out = implode(' ', $res);
 		}
-		$memo = $res = null;
+		$memo = null;
+		$res = array();
 	}
 
 	return $out;
diff --git a/prive/squelettes/inclure/admin_vider_cache.html b/prive/squelettes/inclure/admin_vider_cache.html
index 14877b7d43..08c09b1e42 100644
--- a/prive/squelettes/inclure/admin_vider_cache.html
+++ b/prive/squelettes/inclure/admin_vider_cache.html
@@ -11,7 +11,7 @@
 		<iframe src="#URL_ACTION_AUTEUR{calculer_taille_cache,skel}" style="width: 100%;height: 3em;overflow: hidden;"></iframe>
 	</noscript>
 
-	#SET{cache_inhib,#CONFIG{cache_inhib}|sinon{0}|>{#REM|time}|oui}
+	#SET{cache_inhib,#CONFIG{cache_inhib}|sinon{0}|>{#EVAL{'time()'}}|oui}
 
 	[(#GET{cache_inhib}|oui)
 	<div><strong><:info_cache_desactive:></strong>

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Hi David,

On 04-05-2021 15:16, David Prévot wrote:
> I’m not aware of any issue with 3.2.11 upstream (and nobody complained
> so far in Debian). On the contrary, I’ve seen people having issues with
> PHP 7.4 and the answer from the community was “upgrade SPIP to 3.2.11
> (or downgrade to PHP 7.2)” that actually seem to fix their issues.

unblocked.

Paul

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


--- End Message ---

Reply to: