Index: .hgsubstate
===================================================================
--- .hgsubstate	(revision 3595)
+++ .hgsubstate	(revision 3549)
@@ -1,1 +1,1 @@
-3144b4803f5b25a77adedbd025928366667107ac inc/libs/clearbricks
+31cc764e47c0edb22866311ff1ad4484173b17f9 inc/libs/clearbricks
Index: admin/category.php
===================================================================
--- admin/category.php	(revision 3572)
+++ admin/category.php	(revision 3330)
@@ -216,5 +216,5 @@
 '<div class="lockable">'.
 '<p><label for="cat_url">'.__('URL:').'</label> '
-.form::field('cat_url',40,191,html::escapeHTML($cat_url)).
+.form::field('cat_url',40,255,html::escapeHTML($cat_url)).
 '</p>'.
 '<p class="form-note warn" id="note-cat-url">'.
Index: admin/install/check.php
===================================================================
--- admin/install/check.php	(revision 3565)
+++ admin/install/check.php	(revision 3137)
@@ -49,5 +49,5 @@
 	}
 
-	if ($con->driver() == 'mysql' || $con->driver() == 'mysqli' || $con->driver() == 'mysqlimb4')
+	if ($con->driver() == 'mysql' || $con->driver() == 'mysqli')
 	{
 		if (version_compare($con->version(),'4.1','<'))
Index: admin/install/index.php
===================================================================
--- admin/install/index.php	(revision 3557)
+++ admin/install/index.php	(revision 3599)
@@ -186,5 +186,5 @@
 			$csp_prefix."'self' 'unsafe-inline'".$csp_suffix,'string','CSP style-src directive',true,true);
 		$blog_settings->system->put('csp_admin_img',
-			$csp_prefix."'self' data: media.dotaddict.org blob:",'string','CSP img-src directive',true,true);
+			$csp_prefix."'self' data: http://media.dotaddict.org blob:",'string','CSP img-src directive',true,true);
 
 		# Add Dotclear version
Index: admin/install/wizard.php
===================================================================
--- admin/install/wizard.php	(revision 3565)
+++ admin/install/wizard.php	(revision 3404)
@@ -201,5 +201,5 @@
 '<form action="wizard.php" method="post">'.
 '<p><label class="required" for="DBDRIVER"><abbr title="'.__('Required field').'">*</abbr> '.__('Database type:').'</label> '.
-    form::combo('DBDRIVER',array(__('MySQL (deprecated)')=>'mysql',__('MySQLi')=>'mysqli',__('MySQLi (full UTF-8)')=>'mysqlimb4',__('PostgreSQL')=>'pgsql',__('SQLite')=>'sqlite'),$DBDRIVER).'</p>'.
+    form::combo('DBDRIVER',array(__('MySQL (deprecated)')=>'mysql',__('MySQLi')=>'mysqli',__('PostgreSQL')=>'pgsql',__('SQLite')=>'sqlite'),$DBDRIVER).'</p>'.
 '<p><label for="DBHOST">'.__('Database Host Name:').'</label> '.
 form::field('DBHOST',30,255,html::escapeHTML($DBHOST)).'</p>'.
Index: admin/post.php
===================================================================
--- admin/post.php	(revision 3572)
+++ admin/post.php	(revision 3550)
@@ -638,5 +638,5 @@
 					'<div class="lockable">'.
 					'<p><label for="post_url">'.__('Edit basename').'</label>'.
-					form::field('post_url',10,191,html::escapeHTML($post_url),'maximal').
+					form::field('post_url',10,255,html::escapeHTML($post_url),'maximal').
 					'</p>'.
 					'<p class="form-note warn">'.
Index: admin/preferences.php
===================================================================
--- admin/preferences.php	(revision 3566)
+++ admin/preferences.php	(revision 3560)
@@ -46,5 +46,4 @@
 $user_ui_enhanceduploader = $core->auth->user_prefs->interface->enhanceduploader;
 $user_ui_hidemoreinfo = $core->auth->user_prefs->interface->hidemoreinfo;
-$user_ui_hidehelpbutton = $core->auth->user_prefs->interface->hidehelpbutton;
 $user_ui_htmlfontsize = $core->auth->user_prefs->interface->htmlfontsize;
 $user_ui_dynfontsize = $core->auth->user_prefs->interface->dynfontsize;
@@ -246,5 +245,4 @@
 		$core->auth->user_prefs->interface->put('enhanceduploader',!empty($_POST['user_ui_enhanceduploader']),'boolean');
 		$core->auth->user_prefs->interface->put('hidemoreinfo',!empty($_POST['user_ui_hidemoreinfo']),'boolean');
-		$core->auth->user_prefs->interface->put('hidehelpbutton',!empty($_POST['user_ui_hidehelpbutton']),'boolean');
 		$core->auth->user_prefs->interface->put('htmlfontsize',$_POST['user_ui_htmlfontsize'],'string');
 		$core->auth->user_prefs->interface->put('dynfontsize',!empty($_POST['user_ui_dynfontsize']),'boolean');
@@ -526,8 +524,4 @@
 __('Hide all secondary information and notes').'</label></p>'.
 
-'<p><label for="user_ui_hidehelpbutton" class="classic">'.
-form::checkbox('user_ui_hidehelpbutton',1,$user_ui_hidehelpbutton).' '.
-__('Hide help button').'</label></p>'.
-
 '<p><label for="user_ui_htmlfontsize" class="classic">'.__('Font size:').'</label>'.' '.
 form::combo('user_ui_htmlfontsize',$htmlfontsize_combo,$user_ui_htmlfontsize).'</p>'.
Index: admin/style/default.css
===================================================================
--- admin/style/default.css	(revision 3576)
+++ admin/style/default.css	(revision 3544)
@@ -1491,6 +1491,4 @@
   display: flex;
   justify-content: space-between; }
-  .close-notice-parent ul {
-    flex: 1; }
 
 .close-notice {
Index: admin/style/scss/partials/_messages.scss
===================================================================
--- admin/style/scss/partials/_messages.scss	(revision 3576)
+++ admin/style/scss/partials/_messages.scss	(revision 3544)
@@ -100,7 +100,4 @@
 	display: flex;
 	justify-content: space-between;
-	ul {
-		flex: 1;
-	}
 }
 .close-notice {
Index: inc/admin/lib.dc.page.php
===================================================================
--- inc/admin/lib.dc.page.php	(revision 3566)
+++ inc/admin/lib.dc.page.php	(revision 3599)
@@ -119,5 +119,5 @@
 				$csp_prefix."'self' 'unsafe-inline'".$csp_suffix;
 			$csp['img-src'] = $core->blog->settings->system->csp_admin_img ?:
-				$csp_prefix."'self' data: media.dotaddict.org blob:";
+				$csp_prefix."'self' data: http://media.dotaddict.org blob:";
 
 			# Cope with blog post preview (via public URL in iframe)
@@ -352,9 +352,7 @@
 
 		if (!$GLOBALS['__resources']['ctxhelp']) {
-			if (!$core->auth->user_prefs->interface->hidehelpbutton) {
-				echo
-				'<p id="help-button"><a href="'.$core->adminurl->get("admin.help").'" class="outgoing" title="'.
-				__('Global help').'">'.__('Global help').'</a></p>';
-			}
+			echo
+			'<p id="help-button"><a href="'.$core->adminurl->get("admin.help").'" class="outgoing" title="'.
+			__('Global help').'">'.__('Global help').'</a></p>';
 		}
 
@@ -598,10 +596,6 @@
 	{
 		global $core;
-
-		if ($core->auth->user_prefs->interface->hidehelpbutton) {
-			return;
-		}
-
 		$args = func_get_args();
+
 		$args = new ArrayObject($args);
 
Index: inc/config.php.in
===================================================================
--- inc/config.php.in	(revision 3565)
+++ inc/config.php.in	(revision 3533)
@@ -12,5 +12,5 @@
 if (!defined('DC_RC_PATH')) { return; }
 
-// Database driver (mysql (deprecated, disabled in PHP7), mysqli, mysqlimb4 (full UTF-8), pgsql, sqlite)
+// Database driver (mysql (deprecated, disabled in PHP7), mysqli, pgsql, sqlite)
 define('DC_DBDRIVER','');
 
Index: inc/core/class.dc.blog.php
===================================================================
--- inc/core/class.dc.blog.php	(revision 3565)
+++ inc/core/class.dc.blog.php	(revision 3592)
@@ -694,5 +694,5 @@
 		if (!$rs->isEmpty())
 		{
-			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli' || $this->con->driver() == 'mysqlimb4') {
+			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli') {
 				$clause = "REGEXP '^".$this->con->escape($url)."[0-9]+$'";
 			} elseif ($this->con->driver() == 'pgsql') {
@@ -1939,10 +1939,12 @@
 		if (!$rs->isEmpty())
 		{
-			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli' || $this->con->driver() == 'mysqlimb4') {
-				$clause = "REGEXP '^".$this->con->escape($url)."[0-9]+$'";
+			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli') {
+				$clause = "REGEXP '^".$this->con->escape(preg_quote($url))."[0-9]+$'";
 			} elseif ($this->con->driver() == 'pgsql') {
-				$clause = "~ '^".$this->con->escape($url)."[0-9]+$'";
+				$clause = "~ '^".$this->con->escape(preg_quote($url))."[0-9]+$'";
 			} else {
-				$clause = "LIKE '".$this->con->escape($url)."%'";
+				$clause = "LIKE '".
+						$this->con->escape(preg_replace(array('%','_','!'),array('!%','!_','!!'),$url)).
+						"%' ESCAPE '!'";
 			}
 			$strReq = 'SELECT post_url FROM '.$this->prefix.'post '.
Index: inc/core/class.dc.core.php
===================================================================
--- inc/core/class.dc.core.php	(revision 3565)
+++ inc/core/class.dc.core.php	(revision 3402)
@@ -72,6 +72,4 @@
 		} elseif ($this->con instanceof mysqliConnection) {
 			mysqliConnection::$weak_locks = true;
-		} elseif ($this->con instanceof mysqlimb4Connection) {
-			mysqlimb4Connection::$weak_locks = true;
 		}
 
Index: inc/dbschema/db-schema.php
===================================================================
--- inc/dbschema/db-schema.php	(revision 3572)
+++ inc/dbschema/db-schema.php	(revision 3423)
@@ -35,5 +35,5 @@
 	->blog_id				('varchar',		32,		false)
 	->cat_title				('varchar',		255,	false)
-	->cat_url				('varchar',		191,	false)
+	->cat_url				('varchar',		255,	false)
 	->cat_desc				('text',		0,		true)
 	->cat_position			('integer',		0,		true,	0)
@@ -56,5 +56,5 @@
 
 $_s->setting
-	->setting_id			('varchar',		191,	false)
+	->setting_id			('varchar',		255,	false)
 	->blog_id				('varchar',		32,		true)
 	->setting_ns			('varchar',		32,		false,	"'system'")
@@ -110,5 +110,5 @@
 	->post_type				('varchar',		32,		false,	"'post'")
 	->post_format			('varchar',		32,		false,	"'xhtml'")
-	->post_url				('varchar',		191,	false)
+	->post_url				('varchar',		255,	false)
 	->post_lang				('varchar',		5,		true,	null)
 	->post_title			('varchar',		255,	true,	null)
@@ -179,5 +179,5 @@
 $_s->ping
 	->post_id				('bigint',		0,		false)
-	->ping_url				('varchar',		191,	false)
+	->ping_url				('varchar',		255,	false)
 	->ping_dt				('timestamp',	0,		false,	'now()')
 
@@ -206,5 +206,5 @@
 
 $_s->meta
-	->meta_id				('varchar',		191,	false)
+	->meta_id				('varchar',		255,	false)
 	->meta_type				('varchar',		64,		false)
 	->post_id				('bigint',		0,		false)
@@ -214,5 +214,5 @@
 
 $_s->pref
-	->pref_id				('varchar',		191,	false)
+	->pref_id				('varchar',		255,	false)
 	->user_id				('varchar',		32,		true)
 	->pref_ws				('varchar',		32,		false,	"'system'")
Index: inc/dbschema/upgrade.php
===================================================================
--- inc/dbschema/upgrade.php	(revision 3528)
+++ inc/dbschema/upgrade.php	(revision 3599)
@@ -697,4 +697,19 @@
 		}
 
+		if (version_compare($version,'2.12.2','<'))
+		{
+			// SQlite Clearbricks driver does not allow using single quote at beginning or end of a field value
+			// so we have to use neutral values (localhost and 127.0.0.1) for some CSP directives
+			$csp_prefix = $core->con->driver() == 'sqlite' ? 'localhost ' : '';	// Hack for SQlite Clearbricks driver
+
+			# Update CSP img-src default directive
+			$strReq = 'UPDATE '.$core->prefix.'setting '.
+					" SET setting_value = '".$csp_prefix."''self'' data: http://media.dotaddict.org blob:' ".
+					" WHERE setting_id = 'csp_admin_img' ".
+					" AND setting_ns = 'system' ".
+					" AND setting_value = '".$csp_prefix."''self'' data: media.dotaddict.org blob:' ";
+			$core->con->execute($strReq);
+		}
+
 		$core->setVersion('core',DC_VERSION);
 		$core->blogDefaults();
Index: inc/prepend.php
===================================================================
--- inc/prepend.php	(revision 3575)
+++ inc/prepend.php	(revision 3573)
@@ -144,5 +144,5 @@
 # Constants
 define('DC_ROOT',path::real(dirname(__FILE__).'/..'));
-define('DC_VERSION','2.13-dev');
+define('DC_VERSION','2.12.1');
 define('DC_DIGESTS',dirname(__FILE__).'/digests');
 define('DC_L10N_ROOT',dirname(__FILE__).'/../locales');
Index: inc/public/class.dc.template.php
===================================================================
--- inc/public/class.dc.template.php	(revision 3479)
+++ inc/public/class.dc.template.php	(revision 3593)
@@ -2930,5 +2930,9 @@
 
 		if (isset($attr['blog_lang'])) {
-			$sign = (boolean) $attr['blog_lang'] ? '!' : '=';
+			$sign = '=';
+			if (substr($attr['blog_lang'],0,1) == '!') {
+				$sign = '!';
+				$attr['blog_lang'] = substr($attr['blog_lang'],1);
+			}
 			$if[] = "\$core->blog->settings->system->lang ".$sign."= '".addslashes($attr['blog_lang'])."'";
 		}
Index: inc/public/default-templates/currywurst/_entry-content.html
===================================================================
--- inc/public/default-templates/currywurst/_entry-content.html	(revision 3167)
+++ inc/public/default-templates/currywurst/_entry-content.html	(revision 3601)
@@ -1,3 +1,3 @@
-<div class="post simple" id="p{{tpl:EntryID}}" role="article">
+<div class="post simple" id="p{{tpl:EntryID}}" role="article" lang="{{tpl:EntryLang}}">
 	<h2 class="post-title">{{tpl:EntryTitle encode_html="1"}}</h2>
 
Index: inc/public/default-templates/dotty/_entry-content.html
===================================================================
--- inc/public/default-templates/dotty/_entry-content.html	(revision 3331)
+++ inc/public/default-templates/dotty/_entry-content.html	(revision 3601)
@@ -1,3 +1,3 @@
-<article class="post simple" id="p{{tpl:EntryID}}" role="article">
+<article class="post simple" id="p{{tpl:EntryID}}" role="article" lang="{{tpl:EntryLang}}">
 	<header>
 		<h2 class="post-title">{{tpl:EntryTitle encode_html="1"}}</h2>
Index: locales/fr/main.po
===================================================================
--- locales/fr/main.po	(revision 3566)
+++ locales/fr/main.po	(revision 3557)
@@ -2195,7 +2195,4 @@
 msgstr "Cacher les informations secondaires et les notes"
 
-msgid "Hide help button"
-msgstr "Cacher le bouton d'aide"
-
 msgid "Font size:"
 msgstr "Taille de police de caractère :"
Index: locales/fr/plugins.po
===================================================================
--- locales/fr/plugins.po	(revision 3585)
+++ locales/fr/plugins.po	(revision 3594)
@@ -1414,4 +1414,88 @@
 msgstr "Au fur at à mesure des suppressions ou modifications dans vos billets, les tables de la base de données se fragmentent. L'opération d'optimisation permet de compacter celles-ci. Cette opération n'a aucun impact sur l'intégrité de vos données. Il est fortement conseillé d'optimiser la base de données avant tout export de blog."
 
+msgid "UTF8-mb4 check"
+msgstr "Contrôle UTF8-mb4"
+
+msgid "UTF8-mb4 compatibility check"
+msgstr "Contrôle de compatibilité UTF8-mb4"
+
+msgid "Next: %s"
+msgstr "Suivant : %s"
+
+msgid "Next"
+msgstr "Suivant"
+
+msgid "Check end"
+msgstr "Fin du contrôle"
+
+msgid "Some data will not be fully importable in a UTF8-mb4 database. You need to reduce them before."
+msgstr "Certaines données ne seront pas complètement importables dans une base de données au format UTF8-mb4. Vous devrez d'abord les réduire."
+
+msgid "Check various data for compatibility with UTF8-mb4 (full UTF8 encoding storage) before exporting and importing them in a new UTF8-mb4 MySQL database."
+msgstr "Contrôle la compatibilité de certaines données avec le format UTF8-mb4 (encodage complet de l'UTF8) avant un export et un import dans une nouvelle base de données au format UTF8-mb4."
+
+msgid "All post URLs are importable in UTF8-mb4 database"
+msgstr "Toutes les URLs des entrées sont importables dans une base données UTF8-mb4"
+
+msgid "%s post URLs are longer than %d characters:"
+msgstr "%s URLs d'entrée sont plus longues que les %d caractères max :"
+
+msgid "URL Length"
+msgstr "Longueur d'URL"
+
+msgid "All ping URLs are importable in UTF8-mb4 database"
+msgstr "Toutes les URLs de ping sont importables dans une base de données UTF8-mb4"
+
+msgid "%s ping URLs are longer than %d characters:"
+msgstr "%s URLs de ping sont plus longues que les %d caractères max :"
+
+msgid "Ping URL"
+msgstr "URL de ping"
+
+msgid "All meta IDs are importable in UTF8-mb4 database"
+msgstr "Tous les identifiants de métadonnée sont importables dans une base de données UTF8-mb4"
+
+msgid "%s meta IDs are longer than %d characters:"
+msgstr "%s identifiants de métadonnée sont plus longs que les %d caractères max :"
+
+msgid "Meta ID"
+msgstr "Identifiant de métadonnée"
+
+msgid "Type"
+msgstr "Type"
+
+msgid "Length"
+msgstr "Longueur"
+
+msgid "All Category URLs are importable in UTF8-mb4 database"
+msgstr "Toutes les URLs de catégorie sont importables dans une base de données UTF8-mb4"
+
+msgid "%s category URLs are longer than %d characters:"
+msgstr "%s URLs de catégorie sont plus longues que les %d caractères max :"
+
+msgid "All User preferences are importable in UTF8-mb4 database"
+msgstr "Toutes les préférences utilisateur sont importables dans une base de données UTF8-mb4"
+
+msgid "%s User preference IDs are longer than %d characters:"
+msgstr "%s identifiants de préférence utilisateur sont plus longs que les %d caractères max :"
+
+msgid "Preference ID"
+msgstr "Identifiant de préférence utilisateur"
+
+msgid "Workspace"
+msgstr "Espace de travail"
+
+msgid "All Blog settings are importable in UTF8-mb4 database"
+msgstr "Tous les identifiants de réglage de blog sont importables dans une base de données UTF8-mb4"
+
+msgid "%s Blog setting IDs are longer than %d characters:"
+msgstr "%s identifiants de réglage de blog sont plus longs que les %d caractères max :"
+
+msgid "Setting ID"
+msgstr "Identifiant de réglage de blog"
+
+msgid "Namespace"
+msgstr "Espace de noms"
+
 msgid "Download media folder of current blog"
 msgstr "Télécharger la médiathèque du blog courant"
@@ -2001,10 +2085,4 @@
 msgstr "Liens de navigation"
 
-msgid "Open URL on a new tab"
-msgstr "S'ouvre dans un nouvel onglet"
-
-msgid "the link will open a new window"
-msgstr "Ce lien s'ouvrira dans une nouvelle fenêtre"
-
 msgid "Selected entries"
 msgstr "Billets sélectionnés"
Index: plugins/importExport/inc/class.dc.import.dc1.php
===================================================================
--- plugins/importExport/inc/class.dc.import.dc1.php	(revision 3572)
+++ plugins/importExport/inc/class.dc.import.dc1.php	(revision 3551)
@@ -489,5 +489,5 @@
 
 		$cur->post_url = date('Y/m/d/',strtotime($cur->post_dt)).$rs->post_id.'-'.$rs->post_titre_url;
-		$cur->post_url = substr($cur->post_url,0,191);
+		$cur->post_url = substr($cur->post_url,0,255);
 
 		$cur->post_format        = $rs->post_content_wiki == '' ? 'xhtml' : 'wiki';
Index: plugins/importExport/inc/class.dc.import.wp.php
===================================================================
--- plugins/importExport/inc/class.dc.import.wp.php	(revision 3572)
+++ plugins/importExport/inc/class.dc.import.wp.php	(revision 3340)
@@ -624,5 +624,5 @@
 			$rs->post_type== 'post' ? $this->vars['permalink_template'] : '%postname%'
 		);
-		$cur->post_url = substr($cur->post_url,0,191);
+		$cur->post_url = substr($cur->post_url,0,255);
 
 		if (!$cur->post_url) {
Index: plugins/importExport/inc/flat/class.flat.import.php
===================================================================
--- plugins/importExport/inc/flat/class.flat.import.php	(revision 3572)
+++ plugins/importExport/inc/flat/class.flat.import.php	(revision 3323)
@@ -164,5 +164,5 @@
 					if (in_array($last_line_name,$constrained)) {
 						# UNDEFER
-						if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli' || $this->con->driver() == 'mysqlimb4') $this->con->execute('SET foreign_key_checks = 1');
+						if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli') $this->con->execute('SET foreign_key_checks = 1');
 						if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL DEFERRED');
 					}
@@ -170,5 +170,5 @@
 					if (in_array($line->__name,$constrained)) {
 						# DEFER
-						if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli' || $this->con->driver() == 'mysqlimb4') $this->con->execute('SET foreign_key_checks = 0');
+						if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli') $this->con->execute('SET foreign_key_checks = 0');
 						if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL IMMEDIATE');
 					}
@@ -209,5 +209,5 @@
 			}
 
-			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli' || $this->con->driver() == 'mysqlimb4') $this->con->execute('SET foreign_key_checks = 1');
+			if ($this->con->driver() == 'mysql' || $this->con->driver() == 'mysqli') $this->con->execute('SET foreign_key_checks = 1');
 			if ($this->con->driver() == 'pgsql') $this->con->execute('SET CONSTRAINTS ALL DEFERRED');
 		}
@@ -834,5 +834,5 @@
 				$line->post_title = html::decodeEntities($line->post_title);
 				$line->post_url = date('Y/m/d/',strtotime($line->post_dt)).$line->post_id.'-'.$line->post_titre_url;
-				$line->post_url = substr($line->post_url,0,191);
+				$line->post_url = substr($line->post_url,0,255);
 				$line->post_format = $line->post_content_wiki == '' ? 'xhtml' : 'wiki';
 				$line->post_content_xhtml = $line->post_content;
Index: plugins/maintenance/_admin.php
===================================================================
--- plugins/maintenance/_admin.php	(revision 3340)
+++ plugins/maintenance/_admin.php	(revision 3594)
@@ -67,4 +67,5 @@
 		->addTask('dcMaintenanceSynchpostsmeta')
 		->addTask('dcMaintenanceLogs')
+		->addTask('dcMaintenanceUtf8mb4')
 		->addTask('dcMaintenanceVacuum')
 		->addTask('dcMaintenanceZipmedia')
Index: plugins/maintenance/_prepend.php
===================================================================
--- plugins/maintenance/_prepend.php	(revision 3324)
+++ plugins/maintenance/_prepend.php	(revision 3594)
@@ -25,4 +25,5 @@
 $__autoload['dcMaintenanceSynchpostsmeta'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.synchpostsmeta.php';
 $__autoload['dcMaintenanceLogs'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.logs.php';
+$__autoload['dcMaintenanceUtf8mb4'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.utf8mb4.php';
 $__autoload['dcMaintenanceVacuum'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.vacuum.php';
 $__autoload['dcMaintenanceZipmedia'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.zipmedia.php';
Index: plugins/maintenance/inc/tasks/class.dc.maintenance.utf8mb4.php
===================================================================
--- plugins/maintenance/inc/tasks/class.dc.maintenance.utf8mb4.php	(revision 3594)
+++ plugins/maintenance/inc/tasks/class.dc.maintenance.utf8mb4.php	(revision 3594)
@@ -0,0 +1,256 @@
+<?php
+# -- BEGIN LICENSE BLOCK ---------------------------------------
+#
+# This file is part of Dotclear 2.
+#
+# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
+# Licensed under the GPL version 2.0 license.
+# See LICENSE file or
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+#
+# -- END LICENSE BLOCK -----------------------------------------
+if (!defined('DC_RC_PATH')) { return; }
+
+define('UTF8MB4_MAXLEN',191);
+
+class dcMaintenanceUtf8mb4 extends dcMaintenanceTask
+{
+	protected $perm = null;		// super admin only
+	protected $step_task;
+	protected $list;
+
+	protected function init()
+	{
+		$this->name 		= __('UTF8-mb4 check');
+		$this->task 		= __('UTF8-mb4 compatibility check');
+		$this->step			= __('Next: %s');
+		$this->step_task	= __('Next');
+		$this->success 		= __('Check end');
+		$this->error 		= __('Some data will not be fully importable in a UTF8-mb4 database. You need to reduce them before.');
+
+		$this->description = __('Check various data for compatibility with UTF8-mb4 (full UTF8 encoding storage) before exporting and importing them in a new UTF8-mb4 MySQL database.');
+	}
+
+	public function execute()
+	{
+		$this->code = $this->checkUtf8mb4($this->code);
+		return $this->code ?: true;
+	}
+
+	public function task()
+	{
+		return $this->code ? $this->step_task : $this->task;
+	}
+
+	public function step()
+	{
+		return $this->code ? '<p>'.$this->list.'</p>' : null;
+	}
+
+	public function success()
+	{
+		return $this->code ? sprintf($this->step, $this->step_task) : $this->success;
+	}
+
+	public function header()
+	{
+		return sprintf($this->step, $this->step_task);
+	}
+
+	protected function checkUtf8mb4($code=null)
+	{
+		switch ($code) {
+			case null:
+			case 0:
+				# check posts
+				$this->list = __('All post URLs are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT post_id, post_type, post_title, post_url, LENGTH(post_url) AS xlen FROM '.$this->core->prefix.'post '.
+					'WHERE LENGTH(post_url) > '.UTF8MB4_MAXLEN.' ORDER BY post_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s post URLs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Title').'</th>'.
+						'<th>'.__('URL Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="p'.$rs->post_id.'">'.
+							'<td class="maximal" scope="row"><a href="'.
+								$this->core->getPostAdminURL($rs->post_type,$rs->post_id).'">'.
+								html::escapeHTML($rs->post_title).'</a></td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			case 1:
+				# check pings
+				$this->list = __('All ping URLs are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT post_id, ping_url, LENGTH(ping_url) AS xlen FROM '.$this->core->prefix.'ping '.
+					'WHERE LENGTH(ping_url) > '.UTF8MB4_MAXLEN.' ORDER BY post_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s ping URLs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Ping URL').'</th>'.
+						'<th>'.__('URL Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="p'.$rs->post_id.'">'.
+							'<td class="maximal" scope="row"><a href="'.
+								$this->core->getPostAdminURL('post',$rs->post_id).'#trackbacks">'.
+								html::escapeHTML($rs->ping_url).'</a></td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			case 2:
+				# check meta
+				$this->list = __('All meta IDs are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT meta_id, meta_type, LENGTH(meta_id) AS xlen FROM '.$this->core->prefix.'meta '.
+					'WHERE LENGTH(meta_id) > '.UTF8MB4_MAXLEN.' ORDER BY meta_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s meta IDs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Meta ID').'</th>'.
+						'<th>'.__('Type').'</th>'.
+						'<th>'.__('Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="m-'.$rs->meta_id.'">'.
+							'<td class="maximal" scope="row">'.
+								($rs->meta_type == 'tag' ?
+									'<a href="'.$this->core->adminurl->get('admin.plugin.tags',
+										array('m' => 'tag_posts','tag' => $rs->meta_id)).'">' : '').
+								html::escapeHTML($rs->meta_id).($rs->meta_type == 'tag' ? '</a>' : '').'</td>'.
+							'<td>'.$rs->meta_type.'</td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			case 3:
+				# check categories
+				$this->list = __('All Category URLs are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT cat_id, cat_title, cat_url, LENGTH(cat_url) AS xlen FROM '.$this->core->prefix.'category '.
+					'WHERE LENGTH(cat_url) > '.UTF8MB4_MAXLEN.' ORDER BY cat_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s category URLs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Title').'</th>'.
+						'<th>'.__('URL Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="c-'.$rs->cat_id.'">'.
+							'<td class="maximal" scope="row">'.
+								'<a href="'.$this->core->adminurl->get('admin.category',array('id' => $rs->cat_id)).'">'.
+								html::escapeHTML($rs->cat_title).'</a></td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			case 4:
+				# check prefs
+				$this->list = __('All User preferences are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT pref_id, pref_ws, LENGTH(pref_id) AS xlen FROM '.$this->core->prefix.'pref '.
+					'WHERE LENGTH(pref_id) > '.UTF8MB4_MAXLEN.' ORDER BY pref_ws,pref_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s User preference IDs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Preference ID').'</th>'.
+						'<th>'.__('Workspace').'</th>'.
+						'<th>'.__('Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="p-'.$rs->pref_id.'">'.
+							'<td class="maximal" scope="row">'.html::escapeHTML($rs->pref_id).'</td>'.
+							'<td>'.html::escapeHTML($rs->pref_ws).'</td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			case 5:
+				# check settings
+				$this->list = __('All Blog settings are importable in UTF8-mb4 database');
+
+				$rs = $this->core->con->select(
+					'SELECT setting_id, setting_ns, LENGTH(setting_id) AS xlen FROM '.$this->core->prefix.'setting '.
+					'WHERE LENGTH(setting_id) > '.UTF8MB4_MAXLEN.' ORDER BY setting_ns,setting_id', true);
+				if (!$rs->isEmpty()) {
+					$this->list =
+						'<p class="step-msg">'.
+						sprintf(__('%s Blog setting IDs are longer than %d characters:'),$rs->count(),UTF8MB4_MAXLEN).'</p>'.
+						'<div class="table-outer">'.
+						'<table>'.
+						'<th class="first">'.__('Setting ID').'</th>'.
+						'<th>'.__('Namespace').'</th>'.
+						'<th>'.__('Length').'</th>';
+					while ($rs->fetch()) {
+						$this->list .=
+							'<tr class="line" id="s-'.$rs->setting_id.'">'.
+							'<td class="maximal" scope="row">'.html::escapeHTML($rs->setting_id).'</td>'.
+							'<td>'.html::escapeHTML($rs->setting_ns).'</td>'.
+							'<td class="nowrap count">'.$rs->xlen.'</td>'.
+							'</tr>';
+					}
+					$this->list .=
+						'</table>'.
+						'</div>';
+				}
+				$code++;
+				break;
+			default:
+				# Ending check
+				$code = null;
+				break;
+		}
+		return $code;
+	}
+
+}
Index: plugins/pages/page.php
===================================================================
--- plugins/pages/page.php	(revision 3572)
+++ plugins/pages/page.php	(revision 3466)
@@ -477,5 +477,5 @@
 					'<div class="lockable">'.
 					'<p><label for="post_url">'.__('Edit basename').'</label>'.
-					form::field('post_url',10,191,html::escapeHTML($post_url),'maximal').
+					form::field('post_url',10,255,html::escapeHTML($post_url),'maximal').
 					'</p>'.
 					'<p class="form-note warn">'.
Index: plugins/pings/index.php
===================================================================
--- plugins/pings/index.php	(revision 3572)
+++ plugins/pings/index.php	(revision 3428)
@@ -75,5 +75,5 @@
 	form::field(array('pings_srv_name[]','pings_srv_name-'.$i),20,128,html::escapeHTML($n)).' '.
 	'<label for="pings_srv_uri-'.$i.'" class="classic">'.__('Service URI:').'</label> '.
-	form::field(array('pings_srv_uri[]','pings_srv_uri-'.$i),40,191,html::escapeHTML($u));
+	form::field(array('pings_srv_uri[]','pings_srv_uri-'.$i),40,255,html::escapeHTML($u));
 
 	if (!empty($_GET['test']))
@@ -95,5 +95,5 @@
 form::field(array('pings_srv_name[]','pings_srv_name2'),20,128).' '.
 '<label for="pings_srv_uri2" class="classic">'.__('Service URI:').'</label> '.
-form::field(array('pings_srv_uri[]','pings_srv_uri2'),40,191).
+form::field(array('pings_srv_uri[]','pings_srv_uri2'),40,255).
 '</p>'.
 
Index: plugins/simpleMenu/_define.php
===================================================================
--- plugins/simpleMenu/_define.php	(revision 3578)
+++ plugins/simpleMenu/_define.php	(revision 3333)
@@ -16,5 +16,5 @@
 	/* Description*/		"Simple menu for Dotclear",
 	/* Author */			"Franck Paul",
-	/* Version */			'1.4',
+	/* Version */			'1.3',
 	array(
 		'permissions' =>	'admin',
Index: plugins/simpleMenu/_install.php
===================================================================
--- plugins/simpleMenu/_install.php	(revision 3578)
+++ plugins/simpleMenu/_install.php	(revision 3159)
@@ -20,6 +20,6 @@
 $blog_url = html::stripHostURL($core->blog->url);
 $menu_default = array(
-	array('label' => 'Home', 'descr' => 'Recent posts', 'url' => $blog_url, 'targetBlank'  => false),
-	array('label' => 'Archives', 'descr' => '', 'url' => $blog_url.$core->url->getURLFor('archive'), 'targetBlank'  => false)
+	array('label' => 'Home', 'descr' => 'Recent posts', 'url' => $blog_url),
+	array('label' => 'Archives', 'descr' => '', 'url' => $blog_url.$core->url->getURLFor('archive'))
 );
 $core->blog->settings->system->put('simpleMenu',$menu_default,'array','simpleMenu default menu',false,true);
Index: plugins/simpleMenu/_public.php
===================================================================
--- plugins/simpleMenu/_public.php	(revision 3600)
+++ plugins/simpleMenu/_public.php	(revision 3427)
@@ -101,6 +101,4 @@
 				$href = html::escapeHTML($href);
 
-				$targetBlank = ((isset($m['targetBlank'])) && ($m['targetBlank']))? true:false;
-
 				# Active item test
 				$active = false;
@@ -112,10 +110,6 @@
 				}
 				$title = $span = '';
-
 				if ($m['descr']) {
-					if (($description == 'title' || $description == 'both') && $targetBlank) {
-						$title = ' title="'.html::escapeHTML(__($m['descr'])).' ('.
-						__("the link will open a new window").')"';
-					}elseif($description == 'title' || $description == 'both'){
+					if ($description == 'title' || $description == 'both') {
 						$title = ' title="'.html::escapeHTML(__($m['descr'])).'"';
 					}
@@ -124,9 +118,4 @@
 					}
 				}
-
-				if( empty($title) && $targetBlank){
-					$title = ' title="'.__("the link will open a new window").'"';
-				}
-
 				$label = html::escapeHTML(__($m['label']));
 
@@ -149,10 +138,10 @@
 							($item['class'] ? $item['class'] : '').
 						'">'.
-						'<a href="'.$href.'"'.$item['title'].
-						(($targetBlank) ? 'target="_blank" rel="noopener noreferrer"': '').'>'.
+						'<a href="'.$href.'"'.$item['title'].'>'.
 						'<span class="simple-menu-label">'.$item['label'].'</span>'.
 						$item['span'].'</a>'.
 						'</li>';
 			}
+
 			// Final rendering
 			if ($ret) {
Index: plugins/simpleMenu/index.php
===================================================================
--- plugins/simpleMenu/index.php	(revision 3582)
+++ plugins/simpleMenu/index.php	(revision 3182)
@@ -136,5 +136,5 @@
 	$item_descr = isset($_POST['item_descr']) ? $_POST['item_descr'] : '';
 	$item_url = isset($_POST['item_url']) ? $_POST['item_url'] : '';
-	$item_targetBlank  = isset($_POST['item_targetBlank']) ?  (empty($_POST['item_targetBlank'])) ? false : true : false;
+
 	# Traitement
 	$step = (!empty($_GET['add']) ? (integer) $_GET['add'] : 0);
@@ -229,8 +229,6 @@
 							'label' => $item_label,
 							'descr' => $item_descr,
-							'url' => $item_url,
-							'targetBlank'	=> $item_targetBlank 
+							'url' => $item_url
 						);
-						
 						// Save menu in blog settings
 						$core->blog->settings->system->put('simpleMenu',$menu);
@@ -267,7 +265,5 @@
 								'label' => $v['label'],
 								'descr' => $v['descr'],
-								'url' => $v['url'],
-								'targetBlank'	=> $v['targetBlank']
-								);
+								'url' => $v['url']);
 						}
 					}
@@ -305,7 +301,5 @@
 						'label' => $_POST['items_label'][$i],
 						'descr' => $_POST['items_descr'][$i],
-						'url' => $_POST['items_url'][$i],
-						'targetBlank'	=> (empty($_POST['items_targetBlank'.$i])) ? false : true
-						);
+						'url' => $_POST['items_url'][$i]);
 				}
 				$menu = $newmenu;
@@ -486,6 +480,4 @@
 				__('URL of item menu:').'</label>'.form::field('item_url',40,255,$item_url).'</p>';
 			echo form::hidden('item_type',$item_type).form::hidden('item_select',$item_select);
-			echo '<p class="field"><label for="item_descr" class="classic">'.
-				__('Open URL on a new tab').':</label>'.form::checkbox('item_targetBlank','blank').'</p>';
 			echo '<p>'.$core->formNonce().'<input type="submit" name="appendaction" value="'.__('Add this item').'" /></p>';
 			echo '</fieldset>';
@@ -530,5 +522,4 @@
 		'<th scope="col">'.__('Description').'</th>'.
 		'<th scope="col">'.__('URL').'</th>'.
-		'<th scope="col">'.__('Open URL on a new tab').'</th>'.
 		'</tr>'.
 		'</thead>'.
@@ -537,14 +528,4 @@
 	foreach ($menu as $i => $m) {
 		echo '<tr class="line" id="l_'.$i.'">';
-		
-		//because targetBlank can not exists. This value has been added after this plugin creation.
-		if((isset($m['targetBlank'])) && ($m['targetBlank'])) {
-			$targetBlank = true;
-			$targetBlankStr ='X';
-		}else{
-			$targetBlank = false;
-			$targetBlankStr ='';
-		}
-		
 		if (!$step) {
 			$count++;
@@ -556,11 +537,8 @@
 			echo '<td class="nowrap">'.form::field(array('items_descr[]','imd-'.$i),'30',255,html::escapeHTML(__($m['descr']))).'</td>';
 			echo '<td class="nowrap">'.form::field(array('items_url[]','imu-'.$i),'30',255,html::escapeHTML($m['url'])).'</td>';
-			echo '<td class="nowrap">'.form::checkbox('items_targetBlank'.$i,'blank',$targetBlank).'</td>';
 		} else {
 			echo '<td class="nowrap" scope="row">'.html::escapeHTML(__($m['label'])).'</td>';
 			echo '<td class="nowrap">'.html::escapeHTML(__($m['descr'])).'</td>';
 			echo '<td class="nowrap">'.html::escapeHTML($m['url']).'</td>';
-			echo '<td class="nowrap">'.$targetBlankStr.'</td>';
- 
 		}
 		echo '</tr>';
Index: plugins/simpleMenu/locales/en/help/help.html
===================================================================
--- plugins/simpleMenu/locales/en/help/help.html	(revision 3589)
+++ plugins/simpleMenu/locales/en/help/help.html	(revision 2534)
@@ -34,5 +34,4 @@
       <li><strong>URL:</strong> The item URL. This field is 
       mandatory.</li>
-      <li><strong>Open URL on a new tab:</strong> Check if this link should be opened in a new tab or a new window.</li>
   </ul>
   </dd>
Index: plugins/simpleMenu/locales/fr/help/help.html
===================================================================
--- plugins/simpleMenu/locales/fr/help/help.html	(revision 3589)
+++ plugins/simpleMenu/locales/fr/help/help.html	(revision 2425)
@@ -37,5 +37,4 @@
       <li><strong>URL&nbsp;:</strong> indiquez ici la destination. Ce champ est
       obligatoire.</li>
-      <li><strong>S'ouvre dans un nouvel onglet&nbsp;:</strong> Cochez si le lien doit s'ouvrir dans un nouvel onglet ou une nouvelle fenêtre.</li>
     </ul>
   </dd>
Index: plugins/simpleMenu/simplemenu.js
===================================================================
--- plugins/simpleMenu/simplemenu.js	(revision 3591)
+++ plugins/simpleMenu/simplemenu.js	(revision 3182)
@@ -16,4 +16,4 @@
 	$("#menuitemslist tr td input.position").hide();
 	$("#menuitemslist tr td.handle").addClass('handler');
-	dotclear.condSubmit('#menuitems tr td input[name^=items_selected]','#menuitems #remove-action');
+	dotclear.condSubmit('#menuitems tr td input[type="checkbox"]','#menuitems #remove-action');
 });
Index: plugins/tags/tag_posts.php
===================================================================
--- plugins/tags/tag_posts.php	(revision 3572)
+++ plugins/tags/tag_posts.php	(revision 3421)
@@ -109,5 +109,5 @@
 		'<form action="'.$this_url.'" method="post" id="tag_rename">'.
 		'<p><label for="new_tag_id" class="classic">'.__('Rename').'</label> '.
-		form::field('new_tag_id',20,191,html::escapeHTML($tag)).
+		form::field('new_tag_id',20,255,html::escapeHTML($tag)).
 		'<input type="submit" value="'.__('OK').'" />'.
 		$core->formNonce().
