WP_CLI
1 year ago
abstracts
1 year ago
actions
1 year ago
data-stores
1 year ago
migration
1 year ago
schedules
1 year ago
schema
1 year ago
ActionScheduler_ActionClaim.php
1 year ago
ActionScheduler_ActionFactory.php
1 year ago
ActionScheduler_AdminView.php
1 year ago
ActionScheduler_AsyncRequest_QueueRunner.php
1 year ago
ActionScheduler_Compatibility.php
1 year ago
ActionScheduler_DataController.php
1 year ago
ActionScheduler_DateTime.php
1 year ago
ActionScheduler_Exception.php
4 years ago
ActionScheduler_FatalErrorMonitor.php
1 year ago
ActionScheduler_InvalidActionException.php
1 year ago
ActionScheduler_ListTable.php
1 year ago
ActionScheduler_LogEntry.php
1 year ago
ActionScheduler_NullLogEntry.php
1 year ago
ActionScheduler_OptionLock.php
2 years ago
ActionScheduler_QueueCleaner.php
1 year ago
ActionScheduler_QueueRunner.php
1 year ago
ActionScheduler_SystemInformation.php
1 year ago
ActionScheduler_Versions.php
1 year ago
ActionScheduler_WPCommentCleaner.php
1 year ago
ActionScheduler_wcSystemStatus.php
4 years ago
index.php
3 years ago
ActionScheduler_AdminView.php
199 lines
| 1 | <?php |
| 2 | if (!defined('ABSPATH')) exit; |
| 3 | class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated { |
| 4 | private static $admin_view = null; |
| 5 | private static $screen_id = 'tools_page_action-scheduler'; |
| 6 | protected $list_table; |
| 7 | public static function instance() { |
| 8 | if ( empty( self::$admin_view ) ) { |
| 9 | $class = apply_filters( 'action_scheduler_admin_view_class', 'ActionScheduler_AdminView' ); |
| 10 | self::$admin_view = new $class(); |
| 11 | } |
| 12 | return self::$admin_view; |
| 13 | } |
| 14 | public function init() { |
| 15 | if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) { |
| 16 | if ( class_exists( 'WooCommerce' ) ) { |
| 17 | add_action( 'woocommerce_admin_status_content_action-scheduler', array( $this, 'render_admin_ui' ) ); |
| 18 | add_action( 'woocommerce_system_status_report', array( $this, 'system_status_report' ) ); |
| 19 | add_filter( 'woocommerce_admin_status_tabs', array( $this, 'register_system_status_tab' ) ); |
| 20 | } |
| 21 | add_action( 'admin_menu', array( $this, 'register_menu' ) ); |
| 22 | add_action( 'admin_notices', array( $this, 'maybe_check_pastdue_actions' ) ); |
| 23 | add_action( 'current_screen', array( $this, 'add_help_tabs' ) ); |
| 24 | } |
| 25 | } |
| 26 | public function system_status_report() { |
| 27 | $table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() ); |
| 28 | $table->render(); |
| 29 | } |
| 30 | public function register_system_status_tab( array $tabs ) { |
| 31 | $tabs['action-scheduler'] = __( 'Scheduled Actions', 'action-scheduler' ); |
| 32 | return $tabs; |
| 33 | } |
| 34 | public function register_menu() { |
| 35 | $hook_suffix = add_submenu_page( |
| 36 | 'tools.php', |
| 37 | __( 'Scheduled Actions', 'action-scheduler' ), |
| 38 | __( 'Scheduled Actions', 'action-scheduler' ), |
| 39 | 'manage_options', |
| 40 | 'action-scheduler', |
| 41 | array( $this, 'render_admin_ui' ) |
| 42 | ); |
| 43 | add_action( 'load-' . $hook_suffix, array( $this, 'process_admin_ui' ) ); |
| 44 | } |
| 45 | public function process_admin_ui() { |
| 46 | $this->get_list_table(); |
| 47 | } |
| 48 | public function render_admin_ui() { |
| 49 | $table = $this->get_list_table(); |
| 50 | $table->display_page(); |
| 51 | } |
| 52 | protected function get_list_table() { |
| 53 | if ( null === $this->list_table ) { |
| 54 | $this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() ); |
| 55 | $this->list_table->process_actions(); |
| 56 | } |
| 57 | return $this->list_table; |
| 58 | } |
| 59 | public function maybe_check_pastdue_actions() { |
| 60 | // Filter to prevent checking actions (ex: inappropriate user). |
| 61 | if ( ! apply_filters( 'action_scheduler_check_pastdue_actions', current_user_can( 'manage_options' ) ) ) { |
| 62 | return; |
| 63 | } |
| 64 | // Get last check transient. |
| 65 | $last_check = get_transient( 'action_scheduler_last_pastdue_actions_check' ); |
| 66 | // If transient exists, we're within interval, so bail. |
| 67 | if ( ! empty( $last_check ) ) { |
| 68 | return; |
| 69 | } |
| 70 | // Perform the check. |
| 71 | $this->check_pastdue_actions(); |
| 72 | } |
| 73 | protected function check_pastdue_actions() { |
| 74 | // Set thresholds. |
| 75 | $threshold_seconds = (int) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS ); |
| 76 | $threshold_min = (int) apply_filters( 'action_scheduler_pastdue_actions_min', 1 ); |
| 77 | // Set fallback value for past-due actions count. |
| 78 | $num_pastdue_actions = 0; |
| 79 | // Allow third-parties to preempt the default check logic. |
| 80 | $check = apply_filters( 'action_scheduler_pastdue_actions_check_pre', null ); |
| 81 | // If no third-party preempted and there are no past-due actions, return early. |
| 82 | if ( ! is_null( $check ) ) { |
| 83 | return; |
| 84 | } |
| 85 | // Scheduled actions query arguments. |
| 86 | $query_args = array( |
| 87 | 'date' => as_get_datetime_object( time() - $threshold_seconds ), |
| 88 | 'status' => ActionScheduler_Store::STATUS_PENDING, |
| 89 | 'per_page' => $threshold_min, |
| 90 | ); |
| 91 | // If no third-party preempted, run default check. |
| 92 | if ( is_null( $check ) ) { |
| 93 | $store = ActionScheduler_Store::instance(); |
| 94 | $num_pastdue_actions = (int) $store->query_actions( $query_args, 'count' ); |
| 95 | // Check if past-due actions count is greater than or equal to threshold. |
| 96 | $check = ( $num_pastdue_actions >= $threshold_min ); |
| 97 | $check = (bool) apply_filters( 'action_scheduler_pastdue_actions_check', $check, $num_pastdue_actions, $threshold_seconds, $threshold_min ); |
| 98 | } |
| 99 | // If check failed, set transient and abort. |
| 100 | if ( ! boolval( $check ) ) { |
| 101 | $interval = apply_filters( 'action_scheduler_pastdue_actions_check_interval', round( $threshold_seconds / 4 ), $threshold_seconds ); |
| 102 | set_transient( 'action_scheduler_last_pastdue_actions_check', time(), $interval ); |
| 103 | return; |
| 104 | } |
| 105 | $actions_url = add_query_arg( |
| 106 | array( |
| 107 | 'page' => 'action-scheduler', |
| 108 | 'status' => 'past-due', |
| 109 | 'order' => 'asc', |
| 110 | ), |
| 111 | admin_url( 'tools.php' ) |
| 112 | ); |
| 113 | // Print notice. |
| 114 | echo '<div class="notice notice-warning"><p>'; |
| 115 | printf( |
| 116 | wp_kses( |
| 117 | // translators: 1) is the number of affected actions, 2) is a link to an admin screen. |
| 118 | _n( |
| 119 | '<strong>Action Scheduler:</strong> %1$d <a href="%2$s">past-due action</a> found; something may be wrong. <a href="https://actionscheduler.org/faq/#my-site-has-past-due-actions-what-can-i-do" target="_blank">Read documentation »</a>', |
| 120 | '<strong>Action Scheduler:</strong> %1$d <a href="%2$s">past-due actions</a> found; something may be wrong. <a href="https://actionscheduler.org/faq/#my-site-has-past-due-actions-what-can-i-do" target="_blank">Read documentation »</a>', |
| 121 | $num_pastdue_actions, |
| 122 | 'action-scheduler' |
| 123 | ), |
| 124 | array( |
| 125 | 'strong' => array(), |
| 126 | 'a' => array( |
| 127 | 'href' => true, |
| 128 | 'target' => true, |
| 129 | ), |
| 130 | ) |
| 131 | ), |
| 132 | absint( $num_pastdue_actions ), |
| 133 | esc_attr( esc_url( $actions_url ) ) |
| 134 | ); |
| 135 | echo '</p></div>'; |
| 136 | // Facilitate third-parties to evaluate and print notices. |
| 137 | do_action( 'action_scheduler_pastdue_actions_extra_notices', $query_args ); |
| 138 | } |
| 139 | public function add_help_tabs() { |
| 140 | $screen = get_current_screen(); |
| 141 | if ( ! $screen || self::$screen_id !== $screen->id ) { |
| 142 | return; |
| 143 | } |
| 144 | $as_version = ActionScheduler_Versions::instance()->latest_version(); |
| 145 | $as_source = ActionScheduler_SystemInformation::active_source(); |
| 146 | $as_source_path = ActionScheduler_SystemInformation::active_source_path(); |
| 147 | $as_source_markup = sprintf( '<code>%s</code>', esc_html( $as_source_path ) ); |
| 148 | if ( ! empty( $as_source ) ) { |
| 149 | $as_source_markup = sprintf( |
| 150 | '%s: <abbr title="%s">%s</abbr>', |
| 151 | ucfirst( $as_source['type'] ), |
| 152 | esc_attr( $as_source_path ), |
| 153 | esc_html( $as_source['name'] ) |
| 154 | ); |
| 155 | } |
| 156 | $screen->add_help_tab( |
| 157 | array( |
| 158 | 'id' => 'action_scheduler_about', |
| 159 | 'title' => __( 'About', 'action-scheduler' ), |
| 160 | 'content' => |
| 161 | // translators: %s is the Action Scheduler version. |
| 162 | '<h2>' . sprintf( __( 'About Action Scheduler %s', 'action-scheduler' ), $as_version ) . '</h2>' . |
| 163 | '<p>' . |
| 164 | __( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) . |
| 165 | '</p>' . |
| 166 | '<h3>' . esc_html__( 'Source', 'action-scheduler' ) . '</h3>' . |
| 167 | '<p>' . |
| 168 | esc_html__( 'Action Scheduler is currently being loaded from the following location. This can be useful when debugging, or if requested by the support team.', 'action-scheduler' ) . |
| 169 | '</p>' . |
| 170 | '<p>' . $as_source_markup . '</p>' . |
| 171 | '<h3>' . esc_html__( 'WP CLI', 'action-scheduler' ) . '</h3>' . |
| 172 | '<p>' . |
| 173 | sprintf( |
| 174 | esc_html__( 'WP CLI commands are available: execute %1$s for a list of available commands.', 'action-scheduler' ), |
| 175 | '<code>wp help action-scheduler</code>' |
| 176 | ) . |
| 177 | '</p>', |
| 178 | ) |
| 179 | ); |
| 180 | $screen->add_help_tab( |
| 181 | array( |
| 182 | 'id' => 'action_scheduler_columns', |
| 183 | 'title' => __( 'Columns', 'action-scheduler' ), |
| 184 | 'content' => |
| 185 | '<h2>' . __( 'Scheduled Action Columns', 'action-scheduler' ) . '</h2>' . |
| 186 | '<ul>' . |
| 187 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Hook', 'action-scheduler' ), __( 'Name of the action hook that will be triggered.', 'action-scheduler' ) ) . |
| 188 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Status', 'action-scheduler' ), __( 'Action statuses are Pending, Complete, Canceled, Failed', 'action-scheduler' ) ) . |
| 189 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Arguments', 'action-scheduler' ), __( 'Optional data array passed to the action hook.', 'action-scheduler' ) ) . |
| 190 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Group', 'action-scheduler' ), __( 'Optional action group.', 'action-scheduler' ) ) . |
| 191 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Recurrence', 'action-scheduler' ), __( 'The action\'s schedule frequency.', 'action-scheduler' ) ) . |
| 192 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Scheduled', 'action-scheduler' ), __( 'The date/time the action is/was scheduled to run.', 'action-scheduler' ) ) . |
| 193 | sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Log', 'action-scheduler' ), __( 'Activity log for the action.', 'action-scheduler' ) ) . |
| 194 | '</ul>', |
| 195 | ) |
| 196 | ); |
| 197 | } |
| 198 | } |
| 199 |