<?php class ActionScheduler_FatalErrorMonitor { private $claim = NULL; private $store = NULL; private $action_id = 0; public function __construct(ActionScheduler_Store $store) { $this->store = $store; } public function attach(ActionScheduler_ActionClaim $claim) { $this->claim = $claim; add_action('shutdown', array($this, 'handle_unexpected_shutdown')); add_action('action_scheduler_before_execute', array($this, 'track_current_action'), 0, 1); add_action('action_scheduler_after_execute', array($this, 'untrack_action'), 0, 0); add_action('action_scheduler_execution_ignored', array($this, 'untrack_action'), 0, 0); add_action('action_scheduler_failed_execution', array($this, 'untrack_action'), 0, 0); } public function detach() { $this->claim = NULL; $this->untrack_action(); remove_action('shutdown', array($this, 'handle_unexpected_shutdown')); remove_action('action_scheduler_before_execute', array($this, 'track_current_action'), 0); remove_action('action_scheduler_after_execute', array($this, 'untrack_action'), 0); remove_action('action_scheduler_execution_ignored', array($this, 'untrack_action'), 0); remove_action('action_scheduler_failed_execution', array($this, 'untrack_action'), 0); } public function track_current_action($action_id) { $this->action_id = $action_id; } public function untrack_action() { $this->action_id = 0; } public function handle_unexpected_shutdown() { if ($error = error_get_last()) { if (in_array($error['type'], array(E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR))) { if (!empty($this->action_id)) { $this->store->mark_failure($this->action_id); do_action('action_scheduler_unexpected_shutdown', $this->action_id, $error); } } $this->store->release_claim($this->claim); } } }