Commit 6bc3cf07 authored by Nigel McNie's avatar Nigel McNie
Browse files

Add progress support to the export API and both export plugins.

This allows them to inform code on the outside about what's going on. This is used by the export UI.
parent 721a1732
......@@ -46,8 +46,8 @@ class PluginExportHtml extends PluginExport {
* constructor. overrides the parent class
* to set up smarty and the attachment directory
*/
public function __construct(User $user, $views, $artefacts) {
parent::__construct($user, $views, $artefacts);
public function __construct(User $user, $views, $artefacts, $progresscallback=null) {
parent::__construct($user, $views, $artefacts, $progresscallback);
$this->rootdir = 'portfolio-for-' . self::text_to_path($user->get('username'));
// Create basic required directories
......@@ -59,6 +59,7 @@ class PluginExportHtml extends PluginExport {
}
$this->zipfile = 'mahara-export-html-user'
. $this->get('user')->get('id') . '-' . $this->exporttime . '.zip';
$this->notify_progress_callback(15, 'Setup complete');
}
public static function get_title() {
......@@ -76,8 +77,15 @@ class PluginExportHtml extends PluginExport {
// For each artefact plugin, if it implements leap export, ask it to
// dump out its structure
$summaries = array();
foreach (plugins_installed('artefact', true) as $plugin) {
$plugins = plugins_installed('artefact', true);
$progressstart = 15;
$progressend = 60;
$plugincount = count($plugins);
$i = 0;
foreach ($plugins as $plugin) {
$plugin = $plugin->name;
$this->notify_progress_callback(intval($progressstart + ($i++ / $plugincount) * ($progressend - $progressstart)), 'Exporting data for ' . $plugin);
if (safe_require('export', 'html/' . $plugin, 'lib.php', 'require_once', true)) {
$classname = 'HtmlExport' . ucfirst($plugin);
if (!is_subclass_of($classname, 'HtmlExportArtefactPlugin')) {
......@@ -93,10 +101,12 @@ class PluginExportHtml extends PluginExport {
}
// Get the view data
$this->notify_progress_callback(60, 'Exporting Views');
$this->dump_view_export_data();
$summaries['view'] = array(100, $this->get_view_summary());
// Sort by weight (then drop the weight information)
$this->notify_progress_callback(65, 'Building index page');
uasort($summaries, create_function('$a, $b', 'return $a[0] > $b[0];'));
foreach ($summaries as &$summary) {
$summary = $summary[1];
......@@ -106,10 +116,12 @@ class PluginExportHtml extends PluginExport {
$this->build_index_page($summaries);
// Copy all static files into the export
$this->notify_progress_callback(75, 'Copying static files');
$this->copy_static_files();
// zip everything up
$this->notify_progress_callback(80, 'Creating zipfile');
$cwd = getcwd();
$command = sprintf('%s %s %s %s',
get_config('pathtozip'),
......@@ -124,6 +136,7 @@ class PluginExportHtml extends PluginExport {
if ($returnvar != 0) {
throw new SystemException('Failed to zip the export file');
}
$this->notify_progress_callback(100, 'Done');
return $this->zipfile;
}
......
......@@ -83,8 +83,8 @@ class PluginExportLeap extends PluginExport {
* constructor. overrides the parent class
* to set up smarty and the attachment directory
*/
public function __construct(User $user, $views, $artefacts) {
parent::__construct($user, $views, $artefacts);
public function __construct(User $user, $views, $artefacts, $progresshandler=null) {
parent::__construct($user, $views, $artefacts, $progresshandler);
$this->smarty = smarty_core();
if (!check_dir_exists($this->exportdir . '/' . $this->filedir)) {
......@@ -102,6 +102,7 @@ class PluginExportLeap extends PluginExport {
}
}
}
$this->notify_progress_callback(15, 'Setup complete');
}
public static function get_title() {
......@@ -118,9 +119,12 @@ class PluginExportLeap extends PluginExport {
public function export() {
// the xml stuff
$this->export_header();
$this->notify_progress_callback(20, 'Exporting Views');
$this->export_views();
$this->notify_progress_callback(30, 'Exporting artefacts');
$this->export_artefacts();
$this->notify_progress_callback(70, 'Exporting artefact plugin data');
$internal = null;
foreach ($this->specialcases as $plugin => $artefacts) {
if ($plugin == 'internal') {
......@@ -136,8 +140,10 @@ class PluginExportLeap extends PluginExport {
$pluginexport = new LeapExportInternal($this, $internal);
$this->xml .= $pluginexport->get_export_xml();
}
$this->notify_progress_callback(75, 'Exporting footer');
$this->export_footer();
$this->notify_progress_callback(80, 'Writing files');
// write out xml to a file
if (!file_put_contents($this->exportdir . $this->leapfile, $this->xml)) {
......@@ -150,6 +156,7 @@ class PluginExportLeap extends PluginExport {
$desiredname = $fileinfo->name;
copy($existingfile, $this->exportdir . $this->filedir . $id . '-' . $desiredname);
}
$this->notify_progress_callback(85, 'Creating zipfile');
// zip everything up
$cwd = getcwd();
......@@ -167,6 +174,7 @@ class PluginExportLeap extends PluginExport {
if ($returnvar != 0) {
throw new SystemException('Failed to zip the export file: return code ' . $returnvar);
}
$this->notify_progress_callback(100, 'Done');
return $this->zipfile;
}
......@@ -211,7 +219,16 @@ class PluginExportLeap extends PluginExport {
* export all the artefacts
*/
private function export_artefacts() {
foreach ($this->get('artefacts') as $artefact) {
$progressstart = 30;
$progressend = 70;
$artefacts = $this->get('artefacts');
$artefactcount = count($artefacts);
$i = 0;
foreach ($artefacts as $artefact) {
if ($i++ % 10 == 1) {
$percent = intval($progressstart + ($i / $artefactcount) * ($progressend - $progressstart));
$this->notify_progress_callback($percent, "Exporting artefacts: $i/$artefactcount");
};
$element = null;
// go see if we have to do anything special for this artefact type.
try {
......
......@@ -120,6 +120,11 @@ abstract class PluginExport extends Plugin {
*/
protected $exporttime;
/**
* Callbacks to notify when progress is made
*/
private $progresscallback = null;
/**
* Establishes exactly what views and artefacts are to be exported, and
* sets up temporary export directories
......@@ -142,7 +147,17 @@ abstract class PluginExport extends Plugin {
* - stdclass objects - db rows
* - ArtefactType subclasses
*/
public function __construct(User $user, $views, $artefacts) {
public function __construct(User $user, $views, $artefacts, $progresscallback) {
if (!is_null($progresscallback)) {
if (is_callable($progresscallback)) {
$this->progresscallback = $progresscallback;
}
else {
throw new SystemException("The specified progress callback isn't callable");
}
}
$this->notify_progress_callback(0, 'Starting');
$this->exporttime = time();
$this->user = $user;
......@@ -222,6 +237,8 @@ abstract class PluginExport extends Plugin {
if (!check_dir_exists($this->exportdir)) {
throw new SystemException("Couldn't create the temporary export directory $this->exportdir");
}
$this->notify_progress_callback(10, 'Setup');
}
/**
......@@ -237,6 +254,14 @@ abstract class PluginExport extends Plugin {
return $this->{$field};
}
protected function notify_progress_callback($percent, $status) {
if ($this->progresscallback) {
call_user_func_array($this->progresscallback, array(
$percent, $status
));
}
}
}
?>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment