'eventlist-event', 'plural' => 'eventlist-events', 'ajax' => false, 'screen' => 'eventlist-events', ] ); $this->pt = $pt; } public function get_schedules() { $schedules = wp_get_schedules(); uasort( $schedules, function (array $a, array $b) { return $a['interval'] - $b['interval']; } ); array_walk( $schedules, function (array &$schedule, $name) { $schedule['name'] = $name; } ); return $schedules; } public function get_crons() { $is_switch = $this->pt->switch_cron_site(); $crons = $this->pt->get_crons(true); $events = []; if (empty($crons)) { if ($is_switch) { restore_current_blog(); } return []; } foreach ($crons as $time => $cron) { foreach ($cron as $hook => $dings) { if (!has_action($hook)) { // wp_clear_scheduled_hook($hook); continue; } foreach ($dings as $sig => $data) { $events[$hook.'-'.$sig.'-'.$time] = (object) [ 'hook' => $hook, 'time' => $time, 'sig' => $sig, 'args' => $data['args'], 'schedule' => $data['schedule'], 'interval' => isset($data['interval']) ? $data['interval'] : null, ]; } } } uasort( $events, function ($a, $b) { if ($a->time === $b->time) { return 0; } return ($a->time > $b->time) ? 1 : -1; } ); if ($is_switch) { restore_current_blog(); } return $events; } public function shorten_path($callback) { return preg_replace_callback( '@\\\\[a-zA-Z0-9_\\\\]{4,}\\\\@', function ($mm) { preg_match_all('@\\\\([a-zA-Z0-9_])@', $mm[0], $m); return '\\'.implode('\\', $m[1]).'\\'; }, $callback ); } public function populate_callback($callback) { $callback = (array) $callback; if (method_exists('\QM_Util', 'populate_callback')) { return \QM_Util::populate_callback($callback); } if (\is_string($callback['function']) && (false !== strpos($callback['function'], '::'))) { $callback['function'] = explode('::', $callback['function']); } if (\is_array($callback['function'])) { if (\is_object($callback['function'][0])) { $class = \get_class($callback['function'][0]); $access = '->'; } else { $class = $callback['function'][0]; $access = '::'; } $callback['name'] = $this->shorten_path($class.$access.$callback['function'][1].'()'); } elseif (\is_object($callback['function'])) { if (is_a($callback['function'], 'Closure')) { $callback['name'] = 'Closure'; } else { $class = \get_class($callback['function']); $callback['name'] = $this->shorten_path($class).'->__invoke()'; } } else { $callback['name'] = $this->shorten_path($callback['function']).'()'; } return $callback; } public function pretty_args($input) { $json_options = 0; if (\defined('JSON_UNESCAPED_SLASHES')) { $json_options |= \JSON_UNESCAPED_SLASHES; } if (\defined('JSON_PRETTY_PRINT')) { $json_options |= \JSON_PRETTY_PRINT; } return wp_json_encode($input, $json_options); } public function get_hook_callbacks($name) { global $wp_filter; $actions = []; if (isset($wp_filter[$name])) { $action = $wp_filter[$name]; foreach ($action as $priority => $callbacks) { foreach ($callbacks as $callback) { $callback = $this->populate_callback($callback); $actions[] = [ 'priority' => $priority, 'callback' => $callback, ]; } } } return $actions; } public function get_schedule_name(\stdClass $event) { $schedules = $this->get_schedules(); if (isset($event->schedule) && isset($schedules[$event->schedule])) { return $schedules[$event->schedule]['display']; } /* translators: %s: Schedule name */ $error_text = sprintf(__('Unknown (%s)', 'docket-cache'), $event->schedule); return new \WP_Error('unknown_schedule', $error_text); } public function interval($since) { // Array of time period chunks. $chunks = [ /* translators: %s: The number of years in an interval of time. */ [60 * 60 * 24 * 365, _n_noop('%s year', '%s years', 'docket-cache')], /* translators: %s: The number of months in an interval of time. */ [60 * 60 * 24 * 30, _n_noop('%s month', '%s months', 'docket-cache')], /* translators: %s: The number of weeks in an interval of time. */ [60 * 60 * 24 * 7, _n_noop('%s week', '%s weeks', 'docket-cache')], /* translators: %s: The number of days in an interval of time. */ [60 * 60 * 24, _n_noop('%s day', '%s days', 'docket-cache')], /* translators: %s: The number of hours in an interval of time. */ [60 * 60, _n_noop('%s hour', '%s hours', 'docket-cache')], /* translators: %s: The number of minutes in an interval of time. */ [60, _n_noop('%s minute', '%s minutes', 'docket-cache')], /* translators: %s: The number of seconds in an interval of time. */ [1, _n_noop('%s second', '%s seconds', 'docket-cache')], ]; if ($since <= 0) { return __('now', 'docket-cache'); } $j = \count($chunks); for ($i = 0; $i < $j; ++$i) { $seconds = $chunks[$i][0]; $name = $chunks[$i][1]; $count = floor($since / $seconds); if ($count) { break; } } $output = sprintf(translate_nooped_plural($name, $count, 'docket-cache'), $count); if ($i + 1 < $j) { $seconds2 = $chunks[$i + 1][0]; $name2 = $chunks[$i + 1][1]; $count2 = floor(($since - ($seconds * $count)) / $seconds2); if ($count2) { $output .= ' '.sprintf(translate_nooped_plural($name2, $count2, 'docket-cache'), $count2); } } return $output; } public function is_late($event) { $event = (object) $event; $until = $event->time - time(); return $until < (0 - (10 * MINUTE_IN_SECONDS)); } public function prepare_items() { $events = $this->get_crons(); if (!empty($_GET['s'])) { $s = sanitize_text_field(wp_unslash($_GET['s'])); $events = array_filter( $events, function ($event) use ($s) { return false !== strpos($event->hook, $s); } ); } $count = \count($events); $per_page = 50; $offset = ($this->get_pagenum() - 1) * $per_page; $this->items = \array_slice($events, $offset, $per_page); $this->set_pagination_args( [ 'total_items' => $count, 'per_page' => $per_page, 'total_pages' => ceil($count / $per_page), ] ); } public function get_columns() { /* translators: %s: UTC offset */ $next_run_text = sprintf(esc_html__('Next Schedule (%s)', 'docket-cache'), $this->pt->get_utc_offset()); return [ 'eventlist_hook' => esc_html__('Hook', 'docket-cache'), 'eventlist_args' => esc_html__('Arguments', 'docket-cache'), 'eventlist_next' => $next_run_text, 'eventlist_actions' => esc_html__('Action', 'docket-cache'), 'eventlist_recurrence' => esc_html__('Recurrence', 'docket-cache'), ]; } public function get_table_classes() { return ['widefat', 'striped', $this->_args['plural']]; } protected function handle_row_actions($event, $column_name, $primary) { if ($primary !== $column_name) { return ''; } $action = $this->pt->action_query( 'runeventuno-cronbot', [ 'idx' => 'cronbot', 'ehk' => rawurlencode($event->hook), 'eky' => rawurlencode($event->sig), ] ); $links[] = "".esc_html__('Run Now', 'docket-cache').''; return $this->row_actions($links); } public function column_eventlist_hook($event) { return esc_html($event->hook); } public function column_eventlist_args($event) { if (!empty($event->args)) { if (\count($event->args) > 1) { return sprintf( '
%s', esc_html($this->pretty_args($event->args)) ); } return $event->args[0]; } return sprintf( '%s', esc_html__('None', 'docket-cache') ); } public function column_eventlist_actions($event) { $hook_callbacks = $this->get_hook_callbacks($event->hook); if (!empty($hook_callbacks)) { $callbacks = []; foreach ($hook_callbacks as $callback) { $callbacks[] = '
'.$callback['callback']['name'].'';
}
return implode('