summaryrefslogtreecommitdiff
path: root/core/controllers/admin_maintenance.php
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2008-12-28 23:48:15 +0000
committerBharat Mediratta <bharat@menalto.com>2008-12-28 23:48:15 +0000
commited8689f768f81d2c3ed8bee70c43d4f7c71c108e (patch)
tree35fccdad514cd834cc0b7cea86966604e617d3f0 /core/controllers/admin_maintenance.php
parent1d76689e4b3ea68cada5154d1c0e17b00dec6bd7 (diff)
Expand on the maintenance code to make it more robust and give the
admin more control. You can now track running tasks, resume stalled tasks, cancel running tasks, and remove finished tasks. Added graphics::compose() as a placeholder for future watermark operations. Added CSRF protection to maintenance urls.
Diffstat (limited to 'core/controllers/admin_maintenance.php')
-rw-r--r--core/controllers/admin_maintenance.php159
1 files changed, 141 insertions, 18 deletions
diff --git a/core/controllers/admin_maintenance.php b/core/controllers/admin_maintenance.php
index b695cfcb..fba78a40 100644
--- a/core/controllers/admin_maintenance.php
+++ b/core/controllers/admin_maintenance.php
@@ -18,49 +18,172 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Admin_Maintenance_Controller extends Admin_Controller {
- public function index() {
- $view = new Admin_View("admin.html");
-
- $available_tasks = array(
- new ArrayObject(
- array("name" => "rebuild_images",
- "description" => _("Rebuild out of date thumbnails and resizes")),
+ /**
+ * Get all available tasks
+ * @todo move task definition out into the modules
+ */
+ private function _get_task_definitions() {
+ $dirty_count = graphics::find_dirty_images_query()->count();
+ return array(
+ "graphics::rebuild_dirty_images" => new ArrayObject(
+ array("name" => _("Rebuild Images"),
+ "callback" => "graphics::rebuild_dirty_images",
+ "description" => (
+ $dirty_count ?
+ sprintf(
+ _("You have %d out-of-date images"), $dirty_count)
+ : _("All your images are up to date")),
+ "severity" => $dirty_count ? log::WARNING : log::SUCCESS),
ArrayObject::ARRAY_AS_PROPS));
+ }
+ /**
+ * Show a list of all available, running and finished tasks.
+ */
+ public function index() {
+ $query = Database::instance()->query(
+ "UPDATE `tasks` SET `state` = 'stalled' " .
+ "WHERE done = 0 " .
+ "AND state <> 'stalled' " .
+ "AND unix_timestamp(now()) - updated > 120");
+ $stalled_count = $query->count();
+ if ($stalled_count) {
+ log::warning("tasks",
+ sprintf(_("%d tasks are stalled"), $stalled_count),
+ sprintf(_("%sview%s"),
+ "<a href=\"" . url::site("admin/maintenance") . "\">",
+ "</a>"));
+ }
+
+ $view = new Admin_View("admin.html");
$view->content = new View("admin_maintenance.html");
- $view->content->available_tasks = $available_tasks;
- $view->content->running_tasks = ORM::factory("task")->find_all();
+ $view->content->task_definitions = $this->_get_task_definitions();
+ $view->content->running_tasks = ORM::factory("task")->where("done", 0)->find_all();
+ $view->content->finished_tasks = ORM::factory("task")->where("done", 1)->find_all();
+ $view->content->csrf = access::csrf_token();
print $view;
}
- public function start($task_name) {
+ /**
+ * Start a new task
+ * @param string $task_callback
+ */
+ public function start($task_callback) {
+ access::verify_csrf();
+
+ $task_definitions = $this->_get_task_definitions();
+
$task = ORM::factory("task");
- $task->name = $task_name;
+ $task->callback = $task_callback;
+ $task->name = $task_definitions[$task_callback]->name;
$task->percent_complete = 0;
$task->status = "";
+ $task->state = "started";
$task->context = serialize(array());
$task->save();
$view = new View("admin_maintenance_task.html");
+ $view->csrf = access::csrf_token();
$view->task = $task;
+
+ log::info("tasks", sprintf(_("Task %s started (task id %d)"), $task->name, $task->id),
+ html::anchor(url::site("admin/maintenance"), _("maintenance")));
print $view;
}
- public function run($task_id) {
+ /**
+ * Resume a stalled task
+ * @param string $task_id
+ */
+ public function resume($task_id) {
+ access::verify_csrf();
+
$task = ORM::factory("task", $task_id);
if (!$task->loaded) {
throw new Exception("@todo MISSING_TASK");
}
+ $view = new View("admin_maintenance_task.html");
+ $view->csrf = access::csrf_token();
+ $view->task = $task;
+
+ log::info("tasks", sprintf(_("Task %s resumed (task id %d)"), $task->name, $task->id),
+ html::anchor(url::site("admin/maintenance"), _("maintenance")));
+ print $view;
+ }
+
+ /**
+ * Cancel a task.
+ * @param string $task_id
+ */
+ public function cancel($task_id) {
+ access::verify_csrf();
- switch($task->name) {
- case "rebuild_images":
- graphics::rebuild_dirty_images($task);
+ $task = ORM::factory("task", $task_id);
+ if (!$task->loaded) {
+ throw new Exception("@todo MISSING_TASK");
+ }
+ $task->done = 1;
+ $task->state = "cancelled";
+ $task->save();
+
+ message::success(_("Task cancelled"));
+ url::redirect("admin/maintenance");
+ }
+
+ /**
+ * Remove a task.
+ * @param string $task_id
+ */
+ public function remove($task_id) {
+ access::verify_csrf();
+
+ $task = ORM::factory("task", $task_id);
+ if (!$task->loaded) {
+ throw new Exception("@todo MISSING_TASK");
+ }
+ $task->delete();
+ message::success(_("Task removed"));
+ url::redirect("admin/maintenance");
+ }
+
+ /**
+ * Run a task. This will trigger the task to do a small amount of work, then it will report
+ * back with status on the task.
+ * @param string $task_id
+ */
+ public function run($task_id) {
+ access::verify_csrf();
+
+ $task = ORM::factory("task", $task_id);
+ if (!$task->loaded) {
+ throw new Exception("@todo MISSING_TASK");
}
+ $task->state = "running";
+ call_user_func_array($task->callback, array(&$task));
$task->save();
- print json_encode(
- array("status" => "success",
- "task" => $task->as_array()));
+ if ($task->done) {
+ switch ($task->state) {
+ case "success":
+ log::success("tasks", sprintf(_("Task %s completed (task id %d)"), $task->name, $task->id),
+ html::anchor(url::site("admin/maintenance"), _("maintenance")));
+ message::success(_("Task completed successfully"));
+ break;
+
+ case "error":
+ log::error("tasks", sprintf(_("Task %s failed (task id %d)"), $task->name, $task->id),
+ html::anchor(url::site("admin/maintenance"), _("maintenance")));
+ message::success(_("Task failed"));
+ break;
+ }
+ print json_encode(
+ array("result" => "success",
+ "location" => url::site("admin/maintenance")));
+ } else {
+ print json_encode(
+ array("result" => "in_progress",
+ "task" => $task->as_array()));
+ }
}
}