Index: locales/en/plugins.po
===================================================================
--- locales/en/plugins.po	(revision 1940)
+++ locales/en/plugins.po	(revision 1955)
@@ -861,4 +861,8 @@
 msgstr ""
 
+#, php-format
+msgid "maximum size %s"
+msgstr ""
+
 msgid "or pick up a local file in your public directory"
 msgstr ""
@@ -870,4 +874,7 @@
 msgstr ""
 
+msgid "File is empty or not a compressed file."
+msgstr ""
+
 msgid "WordPress import"
 msgstr ""
@@ -931,4 +938,16 @@
 msgstr ""
 
+msgid "Database export"
+msgstr ""
+
+msgid "Download database of current blog"
+msgstr ""
+
+msgid "Zip file ready to download."
+msgstr ""
+
+msgid "Download database of all blogs"
+msgstr ""
+
 msgid "Please wait..."
 msgstr ""
@@ -937,4 +956,10 @@
 msgstr ""
 
+msgid "Servicing"
+msgstr ""
+
+msgid "Backup"
+msgstr ""
+
 msgid "Optimize"
 msgstr ""
@@ -949,4 +974,10 @@
 msgstr ""
 
+msgid "Compressed file for current blog"
+msgstr ""
+
+msgid "Compressed file for all blogs"
+msgstr ""
+
 msgid "Execute task"
 msgstr ""
@@ -1056,4 +1087,10 @@
 
 msgid "Empty directory"
+msgstr ""
+
+msgid "Download media folder of current blog"
+msgstr ""
+
+msgid "Download active theme of current blog"
 msgstr ""
 
Index: locales/fr/plugins.po
===================================================================
--- locales/fr/plugins.po	(revision 1947)
+++ locales/fr/plugins.po	(revision 1955)
@@ -994,4 +994,8 @@
 #, php-format
 msgid "maximum size %s"
+msgstr "taille maximum de %s"
+
+#, php-format
+msgid "maximum size %s"
 msgstr ""
 
@@ -1002,4 +1006,7 @@
 msgstr "Attention : Cela supprimera au préalable tout le contenu de votre base de données à l'exception des utilisateurs."
 
+msgid "File is empty or not a compressed file."
+msgstr "Le fichier est vide ou n'est pas un fichier compressé."
+
 msgid "Another file with same name exists."
 msgstr "Un autre fichier portant ce nom existe déjà."
@@ -1073,4 +1080,16 @@
 msgstr "L'ID de \"%3$s\" ne correspond pas dans l'enregistrement \"%1$s\" à la ligne %2$s du fichier de sauvegarde."
 
+msgid "Database export"
+msgstr "Export de base de données"
+
+msgid "Download database of current blog"
+msgstr "Télécharger la base de données du blog courant"
+
+msgid "Zip file ready to be downloaded."
+msgstr "Fichier Zip prêt à être télécharger."
+
+msgid "Download database of all blogs"
+msgstr "Télécharger la base de données de tous les blogs"
+
 msgid "Please wait..."
 msgstr "Veuillez patientez…"
@@ -1079,4 +1098,10 @@
 msgstr "Maintenance"
 
+msgid "Servicing"
+msgstr "Entretien"
+
+msgid "Backup"
+msgstr "Sauvegarde"
+
 msgid "Optimize"
 msgstr "Optimiser"
@@ -1090,4 +1115,10 @@
 msgid "Other"
 msgstr "Autre"
+
+msgid "Compressed file for current blog"
+msgstr "Fichier compressé pour le blog courant"
+
+msgid "Compressed file for all blogs"
+msgstr "Fichier compressé pour tous les blogs"
 
 #, php-format
@@ -1174,4 +1205,10 @@
 msgstr "Impossible de vider les tables."
 
+msgid "Download media folder of current blog"
+msgstr "Télécharger le dossier media du blog courant"
+
+msgid "Download active theme of current blog"
+msgstr "Télécharger le theme actif du blog courant"
+
 msgid "Back"
 msgstr "Retour"
Index: plugins/importExport/_prepend.php
===================================================================
--- plugins/importExport/_prepend.php	(revision 891)
+++ plugins/importExport/_prepend.php	(revision 1955)
@@ -12,5 +12,5 @@
 if (!defined('DC_RC_PATH')) { return; }
 
-global $__autoload,$core;
+global $__autoload;
 
 $__autoload['dcIeModule'] = 	dirname(__FILE__).'/inc/class.dc.ieModule.php';
@@ -28,5 +28,5 @@
 $__autoload['flatExport'] = 	dirname(__FILE__).'/inc/flat/class.flat.export.php';
 
-$core->addBehavior('importExportModules','registerIeModules');
+$this->core->addBehavior('importExportModules','registerIeModules');
 
 function registerIeModules($modules)
@@ -42,3 +42,14 @@
 	}
 }
+
+$__autoload['ieMaintenanceExportblog'] = dirname(__FILE__).'/inc/lib.ie.maintenance.php';
+$__autoload['ieMaintenanceExportfull'] = dirname(__FILE__).'/inc/lib.ie.maintenance.php';
+
+$this->core->addBehavior('dcMaintenanceRegister', 'ieMaintenanceRegister');
+
+function ieMaintenanceRegister($core, $tasks, $groups, $tabs)
+{
+	$tasks[] = 'ieMaintenanceExportblog';
+	$tasks[] = 'ieMaintenanceExportfull';
+}
 ?>
Index: plugins/importExport/inc/lib.ie.maintenance.php
===================================================================
--- plugins/importExport/inc/lib.ie.maintenance.php	(revision 1955)
+++ plugins/importExport/inc/lib.ie.maintenance.php	(revision 1955)
@@ -0,0 +1,131 @@
+<?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; }
+
+class ieMaintenanceExportblog extends dcMaintenanceTask
+{
+	protected $tab = 'backup';
+	protected $group = 'zipblog';
+
+	protected $export_name;
+	protected $export_type;
+
+	protected function init()
+	{
+		$this->name = __('Database export');
+		$this->task = __('Download database of current blog');
+		$this->step = __('Zip file ready to be downloaded.');
+
+		$this->export_name = html::escapeHTML($this->core->blog->id.'-backup.txt');
+		$this->export_type = 'export_blog';
+	}
+
+	public function execute()
+	{
+		// 1) Create zip file
+		if (!isset($_SESSION['export_file']) || !file_exists($_SESSION['export_file'])) {
+			// Bad hack to skip one step
+			$_POST['file_name'] = date('Y-m-d-H-i-').$this->export_name;
+			$_POST['file_zip'] = 1;
+
+			// This process make an http redirect
+			$ie = new maintenanceDcExportFlat($this->core);
+			$ie->setURL($this->id);
+			$ie->process($this->export_type);
+		}
+		// 2) Download zip file
+		else {
+			// Log task execution here as we sent file and stop script
+			$this->log();
+
+			// This process send file by http and stop script
+			$ie = new maintenanceDcExportFlat($this->core);
+			$ie->setURL($this->id);
+			$ie->process('ok');
+		}
+
+		return null;
+	}
+
+	public function step()
+	{
+		return isset($_SESSION['export_file']) && file_exists($_SESSION['export_file']) ?
+			$this->step : null;
+	}
+}
+
+class ieMaintenanceExportfull extends dcMaintenanceTask
+{
+	protected $tab = 'backup';
+	protected $group = 'zipfull';
+
+	protected $export_name;
+	protected $export_type;
+
+	protected function init()
+	{
+		$this->name = __('Database export');
+		$this->task = __('Download database of all blogs');
+		$this->step = __('Zip file ready to be downloaded.');
+
+		$this->export_name = 'dotclear-backup.txt';
+		$this->export_type = 'export_all';
+	}
+
+	public function execute()
+	{
+		// 1) Create zip file
+		if (!isset($_SESSION['export_file']) || !file_exists($_SESSION['export_file'])) {
+			// Bad hack to skip one step
+			$_POST['file_name'] = date('Y-m-d-H-i-').$this->export_name;
+			$_POST['file_zip'] = 1;
+
+			// This process make an http redirect
+			$ie = new maintenanceDcExportFlat($this->core);
+			$ie->setURL($this->id);
+			$ie->process($this->export_type);
+		}
+		// 2) Download zip file
+		else {
+			// Log task execution here as we sent file and stop script
+			$this->log();
+
+			// This process send file by http and stop script
+			$ie = new maintenanceDcExportFlat($this->core);
+			$ie->setURL($this->id);
+			$ie->process('ok');
+		}
+
+		return null;
+	}
+
+	public function step()
+	{
+		return isset($_SESSION['export_file']) && file_exists($_SESSION['export_file']) ?
+			$this->step : null;
+	}
+}
+
+class maintenanceDcExportFlat extends dcExportFlat
+{
+	/**
+	 * Set redirection URL of bakcup process.
+	 *
+	 * Bad hack to change redirection of dcExportFlat::process()
+	 *
+	 * @param	id	<b>string</b>	Task id
+	 */
+	public function setURL($id)
+	{
+		$this->url = sprintf('plugin.php?p=maintenance&task=%s', $id);
+	}
+}
Index: lugins/importExport/locales/fr/main.po
===================================================================
--- plugins/importExport/locales/fr/main.po	(revision 1499)
+++ 	(revision )
@@ -1,333 +1,0 @@
-# Language: Français
-# Module: importExport - 3.1
-# Date: 2012-07-09 14:37:32
-# Translated with translater 1.5
-
-msgid ""
-msgstr ""
-"Content-Type: text/plain; charset=UTF-8\n"
-"Project-Id-Version: importExport 3.1\n"
-"POT-Creation-Date: \n"
-"PO-Revision-Date: 2012-07-09T14:37:32+00:00\n"
-"Last-Translator: Jean-Christian Denis\n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: _admin.php:15
-#: _admin.php:28
-#: index.php:59
-msgid "Import/Export"
-msgstr "Import/Export"
-
-#: inc/class.dc.export.flat.php:19
-msgid "Flat file export"
-msgstr "Exporter un fichier texte"
-
-#: inc/class.dc.export.flat.php:20
-msgid "Exports a blog or a full Dotclear installation to flat file."
-msgstr "Exporte un blog ou toutes les données de Dotclear dans un fichier texte."
-
-#: inc/class.dc.export.flat.php:140
-msgid "Export file not found."
-msgstr "Fichier d'export non trouvé."
-
-#: inc/class.dc.export.flat.php:184
-msgid "Failed to compress export file."
-msgstr "Impossible de compresser le fichier d'export."
-
-#: inc/class.dc.export.flat.php:194
-#: inc/class.dc.import.feed.php:84
-#: inc/class.dc.import.flat.php:183
-msgid "Single blog"
-msgstr "Un seul blog"
-
-#: inc/class.dc.export.flat.php:195
-msgid "This will create an export of your current blog: %s"
-msgstr "Ceci va exporter le contenu du blog en cours : %s."
-
-#: inc/class.dc.export.flat.php:197
-#: inc/class.dc.export.flat.php:223
-msgid "File name:"
-msgstr "Nom du fichier :"
-
-#: inc/class.dc.export.flat.php:203
-#: inc/class.dc.export.flat.php:229
-msgid "Compress file"
-msgstr "Compresser le fichier"
-
-#: inc/class.dc.export.flat.php:207
-msgid "You may also want to download your media directory as a zip file"
-msgstr "Vous pouvez également télécharger votre répertoire de médias au format zip."
-
-#: inc/class.dc.export.flat.php:209
-#: inc/class.dc.export.flat.php:232
-#: index.php:89
-msgid "Export"
-msgstr "Exporter"
-
-#: inc/class.dc.export.flat.php:220
-#: inc/class.dc.import.flat.php:211
-msgid "Multiple blogs"
-msgstr "Tous les blogs"
-
-#: inc/class.dc.export.flat.php:221
-msgid "This will create an export of all the content of your database."
-msgstr "Ceci va exporter le contenu complet de votre base de données."
-
-#: inc/class.dc.ieModule.php:74
-msgid "Congratulation!"
-msgstr "Félicitations !"
-
-#: inc/class.dc.ieModule.php:75
-msgid "Your blog has been successfully imported. Welcome on Dotclear 2!"
-msgstr "Votre blog a été importé avec succès. Bienvenue sur Dotclear 2 !"
-
-#: inc/class.dc.ieModule.php:76
-msgid "Why don't you blog this now?"
-msgstr "Pourquoi ne pas le bloguer maintenant ?"
-
-#: inc/class.dc.ieModule.php:77
-msgid "or"
-msgstr "ou"
-
-#: inc/class.dc.ieModule.php:77
-msgid "visit your dashboard"
-msgstr "vous rendre sur votre tableau de bord"
-
-#: inc/class.dc.import.dc1.php:43
-msgid "Dotclear 1.2 import"
-msgstr "Importer depuis Dotclear 1.2"
-
-#: inc/class.dc.import.dc1.php:44
-msgid "Import a Dotclear 1.2 installation into your current blog."
-msgstr "Importe un blog Dotclear 1.2 dans votre blog en cours."
-
-#: inc/class.dc.import.dc1.php:145
-msgid "This will import your Dotclear 1.2 content as new content in the current blog: %s."
-msgstr "Ceci va importer votre blog Dotclear 1.2 comme un nouveau contenu dans le blog en cours : %s."
-
-#: inc/class.dc.import.dc1.php:149
-#: inc/class.dc.import.wp.php:180
-msgid "Depending on the size of your blog, it could take a few minutes."
-msgstr "Selon la taille de votre blog, ceci peut prendre quelques minutes."
-
-#: inc/class.dc.import.dc1.php:151
-#: inc/class.dc.import.wp.php:182
-msgid "General information"
-msgstr "Informations générales"
-
-#: inc/class.dc.import.dc1.php:151
-#: inc/class.dc.import.wp.php:182
-msgid "Import my blog now"
-msgstr "Importer mon blog"
-
-#: inc/class.dc.import.dc1.php:152
-msgid "We first need some information about your old Dotclear 1.2 installation."
-msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation Dotclear 1.2."
-
-#: inc/class.dc.import.dc1.php:163
-#: inc/class.dc.import.wp.php:194
-msgid "Entries import options"
-msgstr "Options d'importation des billets"
-
-#: inc/class.dc.import.dc1.php:164
-#: inc/class.dc.import.wp.php:212
-msgid "Number of entries to import at once:"
-msgstr "Nombre de billets à importer à chaque étape :"
-
-#: inc/class.dc.import.dc1.php:169
-#: inc/class.dc.import.wp.php:222
-msgid "Importing users"
-msgstr "Importe les utilisateurs"
-
-#: inc/class.dc.import.dc1.php:174
-#: inc/class.dc.import.wp.php:227
-msgid "Importing categories"
-msgstr "Importe les catégories"
-
-#: inc/class.dc.import.dc1.php:179
-#: inc/class.dc.import.wp.php:232
-msgid "Importing blogroll"
-msgstr "Importe les liens"
-
-#: inc/class.dc.import.dc1.php:184
-#: inc/class.dc.import.wp.php:237
-msgid "Importing entries from %d to %d / %d"
-msgstr "Importation des billets %d à %d"
-
-#: inc/class.dc.import.dc1.php:193
-msgid "Please read carefully"
-msgstr "Merci de lire attentivement"
-
-#: inc/class.dc.import.dc1.php:214
-#: inc/class.dc.import.wp.php:258
-msgid "next step"
-msgstr "étape suivante"
-
-#: inc/class.dc.import.dc1.php:242
-msgid "Dotclear tables not found"
-msgstr "Tables Dotclear non trouvées"
-
-#: inc/class.dc.import.feed.php:22
-msgid "Feed import"
-msgstr "Importer depuis un flux"
-
-#: inc/class.dc.import.feed.php:23
-msgid "Imports a feed as new entries."
-msgstr "Importe un flux comme nouveaux billets."
-
-#: inc/class.dc.import.feed.php:41
-msgid "Cannot retrieve feed URL."
-msgstr "Impossible d'atteindre l'URL du fil."
-
-#: inc/class.dc.import.feed.php:44
-msgid "No items in feed."
-msgstr "Aucun élément dans le fil."
-
-#: inc/class.dc.import.feed.php:79
-#: inc/class.dc.import.flat.php:149
-msgid "Content successfully imported."
-msgstr "Contenu importé avec succès."
-
-#: inc/class.dc.import.feed.php:85
-msgid "This will import a feed (RSS or Atom) a as new content in the current blog: %s."
-msgstr "Ceci va importer un fil (RSS ou Atom) comme un nouveau contenu dans le blog en cours : %s."
-
-#: inc/class.dc.import.feed.php:87
-msgid "Feed URL:"
-msgstr "URL du fil :"
-
-#: inc/class.dc.import.feed.php:93
-#: inc/class.dc.import.flat.php:202
-#: inc/class.dc.import.flat.php:233
-#: index.php:88
-msgid "Import"
-msgstr "Importer"
-
-#: inc/class.dc.import.flat.php:21
-msgid "Flat file import"
-msgstr "Importer depuis un fichier texte"
-
-#: inc/class.dc.import.flat.php:22
-msgid "Imports a blog or a full Dotclear installation from flat file."
-msgstr "Importe un blog ou toutes les données depuis un fichier texte."
-
-#: inc/class.dc.import.flat.php:144
-msgid "Single blog successfully imported."
-msgstr "Blog importé avec succès."
-
-#: inc/class.dc.import.flat.php:160
-msgid "Are you sure you want to import a full backup file?"
-msgstr "Êtes-vous certain de vouloir charger un fichier de sauvegarde complet ?"
-
-#: inc/class.dc.import.flat.php:184
-msgid "This will import a single blog backup as new content in the current blog: <strong>%s</strong>."
-msgstr "Ceci va charger une sauvegarde de blog comme un nouveau contenu dans le blog en cours : %s."
-
-#: inc/class.dc.import.flat.php:186
-#: inc/class.dc.import.flat.php:214
-msgid "Upload a backup file"
-msgstr "Charger un fichier de sauvegarde"
-
-#: inc/class.dc.import.flat.php:192
-#: inc/class.dc.import.flat.php:220
-msgid "or pick up a local file in your public directory"
-msgstr "ou choisissez un fichier local dans votre répertoire public"
-
-#: inc/class.dc.import.flat.php:212
-msgid "This will reset all the content of your database, except users."
-msgstr "Ceci va remettre à zéro tout le contenu, sauf les utilisateurs."
-
-#: inc/class.dc.import.flat.php:281
-msgid "File is empty or not a compressed file."
-msgstr "Le Fichier est vide ou n'est pas un fichier compressé."
-
-#: inc/class.dc.import.flat.php:304
-msgid "Another file with same name exists."
-msgstr "Un autre fichier du même nom existe déjà."
-
-#: inc/class.dc.import.flat.php:311
-msgid "Failed to extract backup file."
-msgstr "Impossible d'extraire le fichier de sauvegarde."
-
-#: inc/class.dc.import.flat.php:322
-msgid "No backup in compressed file."
-msgstr "Pas de sauvegarde dans le fichier compressé."
-
-#: inc/class.dc.import.wp.php:64
-msgid "WordPress import"
-msgstr "Importer depuis WordPress"
-
-#: inc/class.dc.import.wp.php:65
-msgid "Import a WordPress installation into your current blog."
-msgstr "Importe un blog WordPress dans votre blog en cours."
-
-#: inc/class.dc.import.wp.php:176
-msgid "This will import your WordPress content as new content in the current blog: %s."
-msgstr "Ceci va importer votre blog WordPress comme un nouveau contenu dans le blog en cours : %s."
-
-#: inc/class.dc.import.wp.php:183
-msgid "We first need some information about your old WordPress installation."
-msgstr "Nous avons d'abord besoin de renseignements à propos de votre ancienne installation WordPress."
-
-#: inc/class.dc.import.wp.php:205
-msgid "Ignore the first category:"
-msgstr "Ignorer la première catégorie :"
-
-#: inc/class.dc.import.wp.php:207
-msgid "Import lowest numbered category on posts:"
-msgstr "Importer la catégorie la plus ancienne sur les articles :"
-
-#: inc/class.dc.import.wp.php:209
-msgid "Import all categories as tags:"
-msgstr "Importer les catégories comme des mots-clés :"
-
-#: inc/class.dc.import.wp.php:210
-msgid "Prefix such tags with:"
-msgstr "Préfixer ces mots-clés avec :"
-
-#: inc/class.dc.import.wp.php:215
-msgid "Content filters"
-msgstr "Filtres de contenu"
-
-#: inc/class.dc.import.wp.php:216
-msgid "You may want to process your post and/or comment content with the following filters."
-msgstr "Vous pouvez utiliser les filtres suivants sur vos articles et/ou commentaires."
-
-#: inc/class.dc.import.wp.php:217
-msgid "Post content formatter:"
-msgstr "Formatage des articles :"
-
-#: inc/class.dc.import.wp.php:218
-msgid "Comment content formatter:"
-msgstr "Formatage des commentaires :"
-
-#: inc/class.dc.import.wp.php:286
-msgid "WordPress tables not found"
-msgstr "Tables WordPress non trouvées"
-
-#: inc/flat/class.flat.backup.php:34
-msgid "No file to read."
-msgstr "Aucun fichier lisible."
-
-#: inc/flat/class.flat.import.php:54
-msgid "File is not a DotClear backup."
-msgstr "Le fichier n'est pas une sauvegarde DotClear."
-
-#: inc/flat/class.flat.import.php:105
-msgid "File is not a single blog export."
-msgstr "Le fichier n'est pas un fichier d'export simple."
-
-#: inc/flat/class.flat.import.php:222
-msgid "File is not a full export."
-msgstr "Le fichier n'est pas un fichier d'export complet."
-
-#: inc/flat/class.flat.import.php:704
-msgid "ID of \"%3$s\" does not match on record \"%1$s\" at line %2$s of backup file."
-msgstr "L'ID de \"%3$s\" ne correspond pas dans l'enregistrement de \"%1$s\" à la ligne %2$s du fichier de sauvegarde."
-
-#: index.php:69
-msgid "Please wait..."
-msgstr "Veuillez patienter..."
-
Index: plugins/maintenance/_admin.php
===================================================================
--- plugins/maintenance/_admin.php	(revision 1940)
+++ plugins/maintenance/_admin.php	(revision 1955)
@@ -43,11 +43,17 @@
 	 * @param	$tasks	<b>arrayObject</b>	Array of tasks to register
 	 * @param	$groups	<b>arrayObject</b>	Array of groups to register
+	 * @param	$tabs	<b>arrayObject</b>	Array of tabs to register
 	 */
-	 public static function register($core, $tasks, $groups)
+	 public static function register($core, $tasks, $groups, $tabs)
 	{
+		$tabs['maintenance'] = __('Servicing');
+		$tabs['backup'] = __('Backup');
+
 		$groups['optimize'] = __('Optimize');
 		$groups['index'] = __('Count and index');
 		$groups['purge'] = __('Purge');
 		$groups['other'] = __('Other');
+		$groups['zipblog'] = __('Compressed file for current blog');
+		$groups['zipfull'] = __('Compressed file for all blogs');
 
 		$tasks[] = 'dcMaintenanceCache';
@@ -57,4 +63,6 @@
 		$tasks[] = 'dcMaintenanceLogs';
 		$tasks[] = 'dcMaintenanceVacuum';
+		$tasks[] = 'dcMaintenanceZipmedia';
+		$tasks[] = 'dcMaintenanceZiptheme';
 	}
 
Index: plugins/maintenance/_prepend.php
===================================================================
--- plugins/maintenance/_prepend.php	(revision 1925)
+++ plugins/maintenance/_prepend.php	(revision 1955)
@@ -24,4 +24,6 @@
 $__autoload['dcMaintenanceLogs'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.logs.php';
 $__autoload['dcMaintenanceVacuum'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.vacuum.php';
+$__autoload['dcMaintenanceZipmedia'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.zipmedia.php';
+$__autoload['dcMaintenanceZiptheme'] = dirname(__FILE__).'/inc/tasks/class.dc.maintenance.ziptheme.php';
 
 $this->core->rest->addFunction('dcMaintenanceStep', array('dcMaintenanceRest', 'step'));
Index: plugins/maintenance/inc/class.dc.maintenance.php
===================================================================
--- plugins/maintenance/inc/class.dc.maintenance.php	(revision 1940)
+++ plugins/maintenance/inc/class.dc.maintenance.php	(revision 1955)
@@ -27,4 +27,5 @@
 	private $core;
 	private $tasks = array();
+	private $tabs = array();
 	private $groups = array();
 
@@ -41,10 +42,11 @@
 
 		$tasks = new ArrayObject();
+		$tabs = new ArrayObject();
 		$groups = new ArrayObject();
 
 		# --BEHAVIOR-- dcMaintenanceRegister
-		$core->callBehavior('dcMaintenanceRegister', $core, $tasks, $groups);
-
-		$this->init($tasks, $groups);
+		$core->callBehavior('dcMaintenanceRegister', $core, $tasks, $groups, $tabs);
+
+		$this->init($tasks, $groups, $tabs);
 	}
 
@@ -54,6 +56,7 @@
 	 * @param	tasks	<b>arrayObject</b>	Array of task to register
 	 * @param	groups	<b>arrayObject</b>	Array of groups to add
-	 */
-	public function init($tasks, $groups)
+	 * @param	tabs	<b>arrayObject</b>	Array of tabs to add
+	 */
+	public function init($tasks, $groups, $tabs)
 	{
 		$this->tasks = $this->groups = array();
@@ -79,4 +82,30 @@
 			$this->groups[(string) $id] = (string) $name;
 		}
+
+		foreach($tabs as $id => $name)
+		{
+			$this->tabs[(string) $id] = (string) $name;
+		}
+	}
+
+	/**
+	 * Get a tab name.
+	 *
+	 * @param	id	<b>string</b> Tab ID
+	 * @return	<b>mixed</b> tab name or null if not exists
+	 */
+	public function getTab($id)
+	{
+		return array_key_exists($id, $this->tabs) ? $this->tabs[$id] : null;
+	}
+
+	/**
+	 * Get tabs.
+	 *
+	 * @return	<b>array</b> Array of tabs ID and name
+	 */
+	public function getTabs()
+	{
+		return $this->tabs;
 	}
 
Index: plugins/maintenance/inc/class.dc.maintenance.task.php
===================================================================
--- plugins/maintenance/inc/class.dc.maintenance.task.php	(revision 1940)
+++ plugins/maintenance/inc/class.dc.maintenance.task.php	(revision 1955)
@@ -28,4 +28,5 @@
 	protected $id;
 	protected $name;
+	protected $tab = 'maintenance';
 	protected $group = 'other';
 
@@ -115,4 +116,14 @@
 
 	/**
+	 * Get task tab.
+	 *
+	 * @return	<b>mixed</b>	Task tab ID or null
+	 */
+	public function tab()
+	{
+		return $this->tab;
+	}
+
+	/**
 	 * Get task group.
 	 *
@@ -211,3 +222,16 @@
 		return null;
 	}
+
+	/**
+	 * Log task execution.
+	 *
+	 * Sometimes we need to log task execution 
+	 * direct from task itself.
+	 *
+	 */
+	protected function log()
+	{
+		$maintenance = new dcMaintenance($this->core);
+		$maintenance->setLog($this->id);
+	}
 }
Index: plugins/maintenance/inc/tasks/class.dc.maintenance.zipmedia.php
===================================================================
--- plugins/maintenance/inc/tasks/class.dc.maintenance.zipmedia.php	(revision 1955)
+++ plugins/maintenance/inc/tasks/class.dc.maintenance.zipmedia.php	(revision 1955)
@@ -0,0 +1,48 @@
+<?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; }
+
+class dcMaintenanceZipmedia extends dcMaintenanceTask
+{
+	protected $tab = 'backup';
+	protected $group = 'zipblog';
+
+	protected function init()
+	{
+		$this->task = __('Download media folder of current blog');
+	}
+
+	public function execute()
+	{
+		// Instance media
+		$this->core->media = new dcMedia($this->core);
+		$this->core->media->chdir(null);
+		$this->core->media->getDir();
+
+		// Create zip
+		@set_time_limit(300);
+		$fp = fopen('php://output', 'wb');
+		$zip = new fileZip($fp);
+		$zip->addExclusion('#(^|/).(.*?)_(m|s|sq|t).jpg$#');
+		$zip->addDirectory($this->core->media->root.'/', '', true);
+
+		// Log task execution here as we sent file and stop script
+		$this->log();
+
+		// Send zip
+		header('Content-Disposition: attachment;filename=media.zip');
+		header('Content-Type: application/x-zip');
+		$zip->write();
+		unset($zip);
+		exit(1);
+	}
+}
Index: plugins/maintenance/inc/tasks/class.dc.maintenance.ziptheme.php
===================================================================
--- plugins/maintenance/inc/tasks/class.dc.maintenance.ziptheme.php	(revision 1955)
+++ plugins/maintenance/inc/tasks/class.dc.maintenance.ziptheme.php	(revision 1955)
@@ -0,0 +1,51 @@
+<?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; }
+
+class dcMaintenanceZiptheme extends dcMaintenanceTask
+{
+	protected $tab = 'backup';
+	protected $group = 'zipblog';
+
+	protected function init()
+	{
+		$this->task = __('Download active theme of current blog');
+	}
+
+	public function execute()
+	{
+		// Get theme path
+		$path = $this->core->blog->themes_path;
+		$theme =$this->core->blog->settings->system->theme;
+		$dir = path::real($path.'/'.$theme);
+		if (empty($path) || empty($theme) || !is_dir($dir)) {
+			return false;
+		}
+
+		// Create zip
+		@set_time_limit(300);
+		$fp = fopen('php://output', 'wb');
+		$zip = new fileZip($fp);
+		$zip->addExclusion('#(^|/).(.*?)_(m|s|sq|t).jpg$#');
+		$zip->addDirectory($dir.'/', '', true);
+
+		// Log task execution here as we sent file and stop script
+		$this->log();
+
+		// Send zip
+		header('Content-Disposition: attachment;filename=theme-'.$theme.'.zip');
+		header('Content-Type: application/x-zip');
+		$zip->write();
+		unset($zip);
+		exit(1);
+	}
+}
Index: plugins/maintenance/index.php
===================================================================
--- plugins/maintenance/index.php	(revision 1940)
+++ plugins/maintenance/index.php	(revision 1955)
@@ -70,5 +70,5 @@
 dcPage::jsPageTabs($tab);
 
-if ($task) {
+if (0){//$task) {
 	echo 
 	'<script type="text/javascript">'."\n".
@@ -137,46 +137,55 @@
 	// Simple task (with only a button to start it)
 
-	echo 
-	'<div id="maintenance" class="multi-part" title="'.__('Maintenance').'">'.
-	'<h3>'.__('Maintenance').'</h3>'.
-	'<form action="'.$p_url.'" method="post">';
-
-	foreach($maintenance->getGroups($core) as $g_id => $g_name)
+	foreach($maintenance->getTabs() as $tab_id => $tab_name)
 	{
-		$res = '';
-		foreach($maintenance->getTasks($core) as $t)
+		$res_group = '';
+		foreach($maintenance->getGroups($core) as $group_id => $group_name)
 		{
-			if ($t->group() != $g_id) {
-				continue;
+			$res_task = '';
+			foreach($maintenance->getTasks($core) as $t)
+			{
+				if ($t->group() != $group_id || $t->tab() != $tab_id) {
+					continue;
+				}
+
+				$res_task .=  
+				'<p>'.form::radio(array('task', $t->id()), $t->id()).' '.
+				'<label class="classic" for="'.$t->id().'">'.
+				html::escapeHTML($t->task()).'</label>';
+
+				if (array_key_exists($t->id(), $expired)) {
+					$res_task .= 
+					' <span class="clear form-note warn">'.sprintf(
+						__('Last execution of this task was on %s. You should execute it again.'),
+						dt::dt2str(__('%Y-%m-%d %H:%M'), $expired[$t->id()])
+					).'</span>';
+				}
+
+				$res_task .= '</p>';
 			}
 
-			$res .=  
-			'<p>'.form::radio(array('task', $t->id()), $t->id()).' '.
-			'<label class="classic" for="'.$t->id().'">'.
-			html::escapeHTML($t->task()).'</label>';
-
-			if (array_key_exists($t->id(), $expired)) {
-				$res .= 
-				' <span class="clear form-note warn">'.sprintf(
-					__('Last execution of this task was on %s. You should execute it again.'),
-					dt::dt2str(__('%Y-%m-%d %H:%M'), $expired[$t->id()])
-				).'</span>';
+			if (!empty($res_task)) {
+				$res_group .= 
+				'<div class="fieldset">'.
+				'<h4 id="'.$group_id.'">'.$group_name.'</h4>'.
+				$res_task.
+				'</div>';
 			}
-
-			$res .= '</p>';
-		}
-
-		if (!empty($res)) {
-			echo '<div class="fieldset"><h4 id="'.$g_id.'">'.$g_name.'</h4>'.$res.'</div>';
-		}
-	}
-
-	echo 
-	'<p><input type="submit" value="'.__('Execute task').'" /> '.
-	form::hidden(array('tab'), 'maintenance').
-	$core->formNonce().'</p>'.
-	'<p class="form-note info">'.__('This may take a very long time').'.</p>'.
-	'</form>'.
-	'</div>';
+		}
+
+		if (!empty($res_group)) {
+			echo 
+			'<div id="'.$tab_id.'" class="multi-part" title="'.$tab_name.'">'.
+			'<h3>'.$tab_name.'</h3>'.
+			'<form action="'.$p_url.'" method="post">'.
+			$res_group.
+			'<p><input type="submit" value="'.__('Execute task').'" /> '.
+			form::hidden(array('tab'), $tab_id).
+			$core->formNonce().'</p>'.
+			'<p class="form-note info">'.__('This may take a very long time').'.</p>'.
+			'</form>'.
+			'</div>';
+		}
+	}
 
 	// Advanced tasks (that required a tab)
