Changeset 3356826
- Timestamp:
- 09/05/2025 05:06:51 PM (3 months ago)
- Location:
- advanced-cron-manager
- Files:
-
- 44 edited
- 1 copied
- tags/2.6.4 (copied) (copied from advanced-cron-manager/trunk)
- tags/2.6.4/advanced-cron-manager.php (modified) (6 diffs)
- tags/2.6.4/inc/AdminScreen.php (modified) (12 diffs)
- tags/2.6.4/inc/Assets.php (modified) (2 diffs)
- tags/2.6.4/inc/Cron/Element/Event.php (modified) (4 diffs)
- tags/2.6.4/inc/Cron/Element/Schedule.php (modified) (5 diffs)
- tags/2.6.4/inc/Cron/Events.php (modified) (3 diffs)
- tags/2.6.4/inc/Cron/EventsActions.php (modified) (12 diffs)
- tags/2.6.4/inc/Cron/EventsLibrary.php (modified) (9 diffs)
- tags/2.6.4/inc/Cron/Schedules.php (modified) (4 diffs)
- tags/2.6.4/inc/Cron/SchedulesActions.php (modified) (6 diffs)
- tags/2.6.4/inc/Cron/SchedulesLibrary.php (modified) (6 diffs)
- tags/2.6.4/inc/FormProvider.php (modified) (5 diffs)
- tags/2.6.4/inc/Misc.php (modified) (1 diff)
- tags/2.6.4/inc/Server/Processor.php (modified) (1 diff)
- tags/2.6.4/inc/Server/Settings.php (modified) (3 diffs)
- tags/2.6.4/readme.txt (modified) (2 diffs)
- tags/2.6.4/uninstall.php (modified) (3 diffs)
- tags/2.6.4/vendor/autoload.php (modified) (1 diff)
- tags/2.6.4/vendor/composer/autoload_real.php (modified) (2 diffs)
- tags/2.6.4/vendor/composer/autoload_static.php (modified) (2 diffs)
- tags/2.6.4/vendor/composer/installed.php (modified) (2 diffs)
- tags/2.6.4/views/parts/events/row.php (modified) (1 diff)
- trunk/advanced-cron-manager.php (modified) (6 diffs)
- trunk/inc/AdminScreen.php (modified) (12 diffs)
- trunk/inc/Assets.php (modified) (2 diffs)
- trunk/inc/Cron/Element/Event.php (modified) (4 diffs)
- trunk/inc/Cron/Element/Schedule.php (modified) (5 diffs)
- trunk/inc/Cron/Events.php (modified) (3 diffs)
- trunk/inc/Cron/EventsActions.php (modified) (12 diffs)
- trunk/inc/Cron/EventsLibrary.php (modified) (9 diffs)
- trunk/inc/Cron/Schedules.php (modified) (4 diffs)
- trunk/inc/Cron/SchedulesActions.php (modified) (6 diffs)
- trunk/inc/Cron/SchedulesLibrary.php (modified) (6 diffs)
- trunk/inc/FormProvider.php (modified) (5 diffs)
- trunk/inc/Misc.php (modified) (1 diff)
- trunk/inc/Server/Processor.php (modified) (1 diff)
- trunk/inc/Server/Settings.php (modified) (3 diffs)
- trunk/readme.txt (modified) (2 diffs)
- trunk/uninstall.php (modified) (3 diffs)
- trunk/vendor/autoload.php (modified) (1 diff)
- trunk/vendor/composer/autoload_real.php (modified) (2 diffs)
- trunk/vendor/composer/autoload_static.php (modified) (2 diffs)
- trunk/vendor/composer/installed.php (modified) (2 diffs)
- trunk/views/parts/events/row.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
advanced-cron-manager/tags/2.6.4/advanced-cron-manager.php
r3353664 r3356826 3 3 * Plugin Name: Advanced Cron Manager 4 4 * Description: View, pause, remove, edit and add WP Cron events. 5 * Version: 2.6. 35 * Version: 2.6.4 6 6 * Author: BracketSpace 7 7 * Author URI: https://bracketspace.com … … 12 12 */ 13 13 14 $plugin_version = '2.6. 3';14 $plugin_version = '2.6.4'; 15 15 $plugin_file = __FILE__; 16 16 … … 60 60 } 61 61 } 62 63 62 } 64 63 … … 80 79 $files = new underDEV\Utils\Files( $plugin_file ); 81 80 82 $view = function () use ( $files ) {81 $view = function () use ( $files ) { 83 82 return new underDEV\Utils\View( $files ); 84 83 }; 85 84 86 $ajax = function () {85 $ajax = function () { 87 86 return new underDEV\Utils\Ajax(); 88 87 }; 89 88 90 $server_settings = function () use ( $view, $ajax ) {89 $server_settings = function () use ( $view, $ajax ) { 91 90 return new underDEV\AdvancedCronManager\Server\Settings( $view(), $ajax() ); 92 91 }; 93 92 94 $misc = function () use ( $view ) {93 $misc = function () use ( $view ) { 95 94 return new underDEV\AdvancedCronManager\Misc( $view() ); 96 95 }; 97 96 98 $server_processor = function () use ( $server_settings ) {97 $server_processor = function () use ( $server_settings ) { 99 98 return new underDEV\AdvancedCronManager\Server\Processor( $server_settings() ); 100 99 }; … … 102 101 $schedules_library = new underDEV\AdvancedCronManager\Cron\SchedulesLibrary( $ajax() ); 103 102 104 $schedules = function () use ( $schedules_library ) {103 $schedules = function () use ( $schedules_library ) { 105 104 return new underDEV\AdvancedCronManager\Cron\Schedules( $schedules_library ); 106 105 }; 107 106 108 $schedules_actions = function () use ( $ajax, $schedules_library ) {107 $schedules_actions = function () use ( $ajax, $schedules_library ) { 109 108 return new underDEV\AdvancedCronManager\Cron\SchedulesActions( $ajax(), $schedules_library ); 110 109 }; 111 110 112 $events = function () use ( $schedules ) {111 $events = function () use ( $schedules ) { 113 112 return new underDEV\AdvancedCronManager\Cron\Events( $schedules() ); 114 113 }; 115 114 116 $events_library = function () use ( $schedules, $events ) {115 $events_library = function () use ( $schedules, $events ) { 117 116 return new underDEV\AdvancedCronManager\Cron\EventsLibrary( $schedules(), $events() ); 118 117 }; 119 118 120 $events_actions = function () use ( $ajax, $events, $events_library, $schedules ) {119 $events_actions = function () use ( $ajax, $events, $events_library, $schedules ) { 121 120 return new underDEV\AdvancedCronManager\Cron\EventsActions( $ajax(), $events(), $events_library(), $schedules() ); 122 121 }; … … 184 183 185 184 // Notification promo. 186 add_action( 'plugins_loaded', function () use ( $misc ) {185 add_action( 'plugins_loaded', function () use ( $misc ) { 187 186 if ( ! function_exists( 'register_trigger' ) ) { 188 187 add_action( 'advanced-cron-manager/screen/sidebar', array( $misc(), 'load_notification_promo_part' ), 1000, 1 ); -
advanced-cron-manager/tags/2.6.4/inc/AdminScreen.php
r3353664 r3356826 74 74 $this->schedules = $schedules; 75 75 $this->events = $events; 76 77 76 } 78 77 … … 126 125 127 126 } 128 129 127 } 130 128 … … 143 141 * because we want to separate scopes 144 142 * 145 * @param object $view instance of parent view. 146 * @return void 147 */ 148 public function load_searchbox_part( $view ) { 143 * @return void 144 */ 145 public function load_searchbox_part() { 149 146 $this->view->get_view( 'parts/searchbox' ); 150 147 } … … 155 152 * because we want to separate scopes 156 153 * 157 * @param object $view instance of parent view. 158 * @return void 159 */ 160 public function load_events_table_part( $view ) { 154 * @return void 155 */ 156 public function load_events_table_part() { 157 158 if ( ! current_user_can( 'manage_options' ) ) { 159 return; 160 } 161 161 162 162 $this->view->set_var( 'events', $this->events->get_events() ); … … 170 170 171 171 $this->view->get_view( 'parts/events/section' ); 172 173 172 } 174 173 … … 178 177 * because we want to separate scopes 179 178 * 180 * @param object $view instance of parent view. 181 * @return void 182 */ 183 public function load_schedules_table_part( $view ) { 179 * @return void 180 */ 181 public function load_schedules_table_part() { 182 183 if ( ! current_user_can( 'manage_options' ) ) { 184 return; 185 } 184 186 185 187 $this->view->set_var( 'schedules', $this->schedules->get_schedules(), true ); 186 188 187 189 $this->view->get_view( 'parts/schedules/section' ); 188 189 190 } 190 191 … … 194 195 * because we want to separate scopes 195 196 * 196 * @param object $view instance of parent view. 197 * @return void 198 */ 199 public function load_slidebar_part( $view ) { 197 * @return void 198 */ 199 public function load_slidebar_part() { 200 200 $this->view->get_view( 'elements/slidebar' ); 201 201 } … … 206 206 * because we want to separate scopes 207 207 * 208 * @param object $view instance of parent view. 209 * @return void 210 */ 211 public function load_preview_modal_part( $view ) { 208 * @return void 209 */ 210 public function load_preview_modal_part() { 212 211 $this->view->get_view( 'elements/preview-modal' ); 213 212 } … … 227 226 228 227 return $tabs; 229 230 228 } 231 229 … … 309 307 array( $this, 'load_page_wrapper' ) 310 308 ); 311 312 309 } 313 310 … … 355 352 } 356 353 357 $args_length = array_sum( array_map( function ( $ar ) {354 $args_length = array_sum( array_map( function ( $ar ) { 358 355 return strlen( $ar['msg'] ); 359 356 }, $parsed_args ) ); … … 365 362 ); 366 363 } 367 368 364 } -
advanced-cron-manager/tags/2.6.4/inc/Assets.php
r3353664 r3356826 49 49 $this->files = $files; 50 50 $this->screen = $screen; 51 52 51 } 53 52 … … 87 86 88 87 do_action( 'advanced-cron-manager/screen/enqueue', $current_page_hook ); 89 90 88 } 91 92 89 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/Element/Event.php
r3096140 r3356826 79 79 * @param array $args Arguments. 80 80 * @param integer $next_call Next call timestamp. 81 * @param boolean $ protected If protected.81 * @param boolean $is_protected If protected. 82 82 * @param boolean $paused If paused. 83 * @throws \InvalidArgumentException When hook is empty. 83 84 */ 84 public function __construct( $hook = null, $schedule = '', $interval = 0, $args = array(), $next_call = 0, $ protected = false, $paused = false ) {85 public function __construct( $hook = null, $schedule = '', $interval = 0, $args = array(), $next_call = 0, $is_protected = false, $paused = false ) { 85 86 86 87 if ( empty( $hook ) ) { 87 t rigger_error( 'Hook cannot be empty', E_USER_ERROR);88 throw new \InvalidArgumentException( 'Hook cannot be empty' ); 88 89 } 89 90 … … 93 94 $this->args = $args; 94 95 $this->next_call = $next_call; 95 $this->protected = $ protected;96 $this->protected = $is_protected; 96 97 $this->paused = $paused; 97 98 98 99 // phpcs:ignore 99 100 $this->hash = substr( md5( $this->hook . $this->schedule . $this->next_call . serialize( $this->args ) ), 0, 8 ); 100 101 101 } 102 102 … … 128 128 $imp = ''; 129 129 130 $imp .= 'function ' . $function_name . '(' . $arguments . ') {<br>'; 131 $imp .= ' // do stuff<br>'; 132 $imp .= '}<br>'; 133 $imp .= '<br>'; 134 $imp .= "add_action( '" . $this->hook . "', '" . $function_name . "', 10, " . count( $this->args ) . ' );'; 130 $imp .= 'function ' . $function_name . '(' . $arguments . ') {<br>'; 131 $imp .= ' // do stuff<br>'; 132 $imp .= '}<br>'; 133 $imp .= '<br>'; 134 $args_count = is_array( $this->args ) ? count( $this->args ) : 0; 135 $imp .= "add_action( '" . $this->hook . "', '" . $function_name . "', 10, " . $args_count . ' );'; 135 136 136 137 return $imp; 137 138 138 } 139 139 … … 147 147 return esc_attr( wp_create_nonce( 'acm/event/' . $action . '/' . $this->hash ) ); 148 148 } 149 150 149 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/Element/Schedule.php
r3096140 r3356826 49 49 * @param integer $interval Interval. 50 50 * @param string $label Label. 51 * @param boolean $ protected If protected.51 * @param boolean $is_protected If protected. 52 52 */ 53 public function __construct( $slug = null, $interval = 0, $label = null, $ protected = false ) {53 public function __construct( $slug = null, $interval = 0, $label = null, $is_protected = false ) { 54 54 55 55 if ( empty( $label ) ) { … … 60 60 $this->interval = $interval; 61 61 $this->label = $label; 62 $this->protected = $protected; 63 62 $this->protected = $is_protected; 64 63 } 65 64 … … 103 102 104 103 return $interval; 105 106 104 } 107 105 … … 138 136 139 137 return trim( $human_time ); 140 141 138 } 142 139 … … 150 147 return esc_attr( wp_create_nonce( 'acm/schedule/' . $action . '/' . $this->slug ) ); 151 148 } 152 153 149 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/Events.php
r3096140 r3356826 106 106 107 107 return $this->events; 108 109 108 } 110 109 … … 119 118 $events = $this->get_events(); 120 119 return isset( $events[ $hash ] ) ? $events[ $hash ] : false; 121 122 120 } 123 121 … … 157 155 158 156 return ( $e1->next_call < $e2->next_call ) ? -1 : 1; 159 160 157 } 161 162 158 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/EventsActions.php
r3096145 r3356826 58 58 $this->library = $library; 59 59 $this->schedules = $schedules; 60 61 60 } 62 61 … … 95 94 } 96 95 97 $hook = trim( wp_strip_all_tags( $data['hook'] ) ); 96 $hook = sanitize_text_field( trim( $data['hook'] ) ); 97 98 if ( empty( $hook ) ) { 99 $this->ajax->response( false, array( 100 __( 'Hook name is required.', 'advanced-cron-manager' ), 101 ) ); 102 } 98 103 99 104 $result = $this->library->insert( $hook, $execution, $data['schedule'], $args ); … … 116 121 117 122 $this->ajax->response( $success, $errors ); 118 119 123 } 120 124 … … 128 132 global $acm_current_event; 129 133 130 // phpcs:ignore 131 $event = $this->events->get_event_by_hash( $_REQUEST['event']);134 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 135 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 132 136 133 137 if ( ! $event ) { … … 157 161 158 162 $this->ajax->response( $success, array() ); 159 160 163 } 161 164 … … 167 170 public function remove() { 168 171 169 // phpcs:ignore 170 $event = $this->events->get_event_by_hash( $_REQUEST['event']);172 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 173 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 171 174 172 175 if ( false === $event ) { … … 175 178 ) ); 176 179 } 177 178 $errors = array();179 180 180 181 $this->ajax->verify_nonce( 'acm/event/remove/' . $event->hash ); … … 198 199 199 200 $this->ajax->response( $success, $errors ); 200 201 201 } 202 202 … … 208 208 public function pause() { 209 209 210 // phpcs:ignore 211 $event = $this->events->get_event_by_hash( $_REQUEST['event'] ); 210 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 211 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 212 213 if ( ! $event ) { 214 $this->ajax->response( false, array( 215 __( 'This event doesn\'t seem to exist anymore', 'advanced-cron-manager' ), 216 ) ); 217 } 212 218 213 219 $this->ajax->verify_nonce( 'acm/event/pause/' . $event->hash ); … … 231 237 232 238 $this->ajax->response( $success, $errors ); 233 234 239 } 235 240 … … 241 246 public function unpause() { 242 247 243 // phpcs:ignore 244 $event = $this->events->get_event_by_hash( $_REQUEST['event'] ); 248 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 249 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 250 251 if ( ! $event ) { 252 $this->ajax->response( false, array( 253 __( 'This event doesn\'t seem to exist anymore', 'advanced-cron-manager' ), 254 ) ); 255 } 245 256 246 257 $this->ajax->verify_nonce( 'acm/event/unpause/' . $event->hash ); … … 264 275 265 276 $this->ajax->response( $success, $errors ); 266 267 } 268 277 } 269 278 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/EventsLibrary.php
r3096140 r3356826 49 49 50 50 $this->paused_option_name = 'acm_paused_events'; 51 52 51 } 53 52 … … 67 66 68 67 return $events; 69 70 68 } 71 69 … … 77 75 * @param string $schedule_slug Schedule slug. 78 76 * @param array $args arguments. 79 * @param boolean $new if event is new.77 * @param boolean $new_event if event is new. 80 78 * @return mixed array with errors on error or true 81 79 */ 82 public function insert( $hook, $execution_timestamp, $schedule_slug, $args, $new = true ) {80 public function insert( $hook, $execution_timestamp, $schedule_slug, $args, $new_event = true ) { 83 81 84 82 $errors = array(); … … 105 103 } 106 104 107 if ( $new ) {105 if ( $new_event ) { 108 106 do_action( 'advanced-cron-manager/event/scheduled', $hook, $execution_timestamp, $schedule, $args ); 109 107 } 110 108 111 109 return true; 112 113 110 } 114 111 … … 142 139 143 140 return true; 144 145 141 } 146 142 … … 180 176 181 177 return true; 182 183 178 } 184 179 … … 214 209 215 210 return $result; 216 217 211 } 218 212 … … 235 229 236 230 update_option( $this->paused_option_name, $paused_events ); 237 238 231 } 239 232 … … 253 246 254 247 } 255 256 } 257 248 } 258 249 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/Schedules.php
r3096140 r3356826 43 43 44 44 $this->library = $library; 45 46 45 } 47 46 … … 77 76 78 77 return apply_filters( 'advanced-cron-manager/schedules', $this->schedules ); 79 80 78 } 81 79 … … 100 98 101 99 return isset( $schedules[ $slug ] ) ? $schedules[ $slug ] : $this->get_single_event_schedule(); 102 103 100 } 104 101 … … 115 112 116 113 return $this->single_event_schedule; 117 118 114 } 119 120 115 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/SchedulesActions.php
r3096140 r3356826 63 63 $slug = str_replace( '-', '_', $slug ); 64 64 65 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $data['interval'] ); 65 // Validate interval - must be between 60 seconds and 1 year. 66 $interval = absint( $data['interval'] ); 67 if ( $interval < 60 || $interval > YEAR_IN_SECONDS ) { 68 $this->ajax->response( false, array( 69 __( 'Interval must be between 60 seconds and 1 year.', 'advanced-cron-manager' ), 70 ) ); 71 } 72 73 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $interval ); 66 74 67 75 if ( is_array( $result ) ) { … … 75 83 76 84 $this->ajax->response( $success, $errors ); 77 78 85 } 79 86 … … 99 106 $slug = str_replace( '-', '_', $slug ); 100 107 101 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $data['interval'], true ); 108 // Validate interval - must be between 60 seconds and 1 year. 109 $interval = absint( $data['interval'] ); 110 if ( $interval < 60 || $interval > YEAR_IN_SECONDS ) { 111 $this->ajax->response( false, array( 112 __( 'Interval must be between 60 seconds and 1 year.', 'advanced-cron-manager' ), 113 ) ); 114 } 115 116 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $interval, true ); 102 117 103 118 if ( is_array( $result ) ) { … … 111 126 112 127 $this->ajax->response( $success, $errors ); 113 114 128 } 115 129 … … 121 135 public function remove() { 122 136 123 // phpcs:ignore 124 $schedule_slug = $_REQUEST['schedule']; 137 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need schedule slug for nonce string. 138 $schedule_slug = sanitize_key( isset( $_REQUEST['schedule'] ) ? $_REQUEST['schedule'] : '' ); 139 140 if ( empty( $schedule_slug ) ) { 141 $this->ajax->response( false, array( 142 __( 'Invalid schedule slug.', 'advanced-cron-manager' ), 143 ) ); 144 } 125 145 126 146 $this->ajax->verify_nonce( 'acm/schedule/remove/' . $schedule_slug ); … … 144 164 145 165 $this->ajax->response( $success, $errors ); 146 147 166 } 148 149 167 } -
advanced-cron-manager/tags/2.6.4/inc/Cron/SchedulesLibrary.php
r3096140 r3356826 47 47 $this->ajax = $ajax; 48 48 $this->option_name = 'acm_schedules'; 49 50 49 } 51 50 … … 71 70 72 71 return $this->schedules; 73 74 72 } 75 73 … … 89 87 90 88 return isset( $schedules[ $slug ] ) ? $schedules[ $slug ] : false; 91 92 89 } 93 90 … … 123 120 124 121 return $schedules; 125 126 122 } 127 123 … … 186 182 187 183 return true; 188 189 184 } 190 185 … … 216 211 217 212 return true; 218 219 } 220 213 } 221 214 } -
advanced-cron-manager/tags/2.6.4/inc/FormProvider.php
r3096140 r3356826 85 85 86 86 $this->ajax->response( $form_html ); 87 88 87 } 89 88 … … 96 95 97 96 $this->get_form( 'schedule/add', __( 'New schedule', 'advanced-cron-manager' ), __( 'Add schedule', 'advanced-cron-manager' ) ); 98 99 97 } 100 98 … … 104 102 public function edit_schedule() { 105 103 106 // phpcs:ignore 107 $schedule_slug = $_REQUEST['schedule']; 104 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need schedule slug for nonce string. 105 $schedule_slug = sanitize_key( isset( $_REQUEST['schedule'] ) ? $_REQUEST['schedule'] : '' ); 106 107 if ( empty( $schedule_slug ) ) { 108 $this->ajax->response( false, array( 109 __( 'Invalid schedule slug.', 'advanced-cron-manager' ), 110 ) ); 111 } 108 112 109 113 $this->ajax->verify_nonce( 'acm/schedule/edit/' . $schedule_slug ); … … 115 119 // Translators: schedule slug. 116 120 $this->get_form( 'schedule/edit', sprintf( __( 'Edit "%s" schedule', 'advanced-cron-manager' ), $schedule->slug ), __( 'Edit schedule', 'advanced-cron-manager' ) ); 117 118 121 } 119 122 … … 129 132 130 133 $this->get_form( 'event/add', __( 'New event', 'advanced-cron-manager' ), __( 'Schedule event', 'advanced-cron-manager' ) ); 131 132 134 } 133 134 135 } -
advanced-cron-manager/tags/2.6.4/inc/Misc.php
r3096140 r3356826 50 50 return $links; 51 51 } 52 53 52 } -
advanced-cron-manager/tags/2.6.4/inc/Server/Processor.php
r3096140 r3356826 49 49 50 50 } 51 52 51 } 53 54 52 } -
advanced-cron-manager/tags/2.6.4/inc/Server/Settings.php
r3353338 r3356826 93 93 94 94 return $this->settings; 95 96 95 } 97 96 … … 115 114 $this->ajax->verify_nonce( 'acm/server/settings/save' ); 116 115 116 if ( ! current_user_can( 'manage_options' ) ) { 117 $this->ajax->response( false, array( 118 __( "You're not allowed to do that.", 'advanced-cron-manager' ), 119 ) ); 120 } 121 117 122 $errors = array(); 118 123 119 $form_options = array_map( function ( $val) {124 $form_options = array_map( function () { 120 125 return 0; 121 126 }, $this->default ); … … 124 129 $form_data = wp_parse_args( $_REQUEST['data'], $form_options ); 125 130 126 update_option( $this->option_name, $form_data ); 131 // Validate and sanitize settings. 132 $sanitized_data = array(); 133 foreach ( $form_data as $key => $value ) { 134 if ( ! array_key_exists( $key, $this->default ) ) { 135 continue; // Skip unknown settings. 136 } 137 138 // All current settings are boolean (0 or 1). 139 $sanitized_data[ $key ] = absint( $value ) === 1 ? 1 : 0; 140 } 141 142 update_option( $this->option_name, $sanitized_data ); 127 143 128 144 $this->ajax->response( __( 'Settings has been saved', 'advanced-cron-manager' ), $errors ); 129 130 145 } 131 132 146 } -
advanced-cron-manager/tags/2.6.4/readme.txt
r3353664 r3356826 5 5 Requires PHP: 5.3 6 6 Tested up to: 6.8 7 Stable tag: 2.6. 37 Stable tag: 2.6.4 8 8 License: GPLv2 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 102 102 == Changelog == 103 103 104 = 2.6.4 = 105 * [Security] Improved event hook sanitization using sanitize_text_field() to prevent XSS while allowing valid hook characters 106 * [Security] Added validation for schedule intervals to prevent invalid values 107 * [Security] Strengthened authorization checks in admin screen methods 108 * [Security] Enhanced output escaping in event row view template 109 * [Security] Standardized nonce verification in AJAX handlers with better input validation 110 * [Security] Added proper validation and sanitization for server settings 111 * [Security] Fixed unsanitized input in FormProvider.php schedule slug handling 112 * [Fixed] Fixed PHP 8.4 deprecation warning with trigger_error() by replacing with exception 113 * [Fixed] Fixed TypeError on PHP 8.3+ where count() was called on non-countable value in Event implementation 114 * [Changed] Updated WordPress Coding Standards to version 3.2 and resolved all coding standard warnings 115 * [Changed] Renamed reserved keyword parameters for better PHP compatibility ($protected to $is_protected, $new to $new_event) 116 104 117 = 2.6.3 = 105 118 * [Fixed] Fixed translation loading issue that was triggered too early in AdminScreen constructor. -
advanced-cron-manager/tags/2.6.4/uninstall.php
r3096140 r3356826 16 16 17 17 $plugin_version = 'x'; 18 $plugin_file = dirname( __FILE__ ). '/advanced-cron-manager.php';18 $plugin_file = __DIR__ . '/advanced-cron-manager.php'; 19 19 20 20 /** … … 27 27 */ 28 28 29 $ajax = function () {29 $ajax = function () { 30 30 return new underDEV\Utils\Ajax(); 31 31 }; … … 33 33 $schedules_library = new underDEV\AdvancedCronManager\Cron\SchedulesLibrary( $ajax() ); 34 34 35 $schedules = function () use ( $schedules_library ) {35 $schedules = function () use ( $schedules_library ) { 36 36 return new underDEV\AdvancedCronManager\Cron\Schedules( $schedules_library ); 37 37 }; 38 38 39 $events = function () use ( $schedules ) {39 $events = function () use ( $schedules ) { 40 40 return new underDEV\AdvancedCronManager\Cron\Events( $schedules() ); 41 41 }; -
advanced-cron-manager/tags/2.6.4/vendor/autoload.php
r3353359 r3356826 20 20 require_once __DIR__ . '/composer/autoload_real.php'; 21 21 22 return ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24::getLoader();22 return ComposerAutoloaderInit7dbce783dc983385ac7421112661002f::getLoader(); -
advanced-cron-manager/tags/2.6.4/vendor/composer/autoload_real.php
r3353359 r3356826 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f245 class ComposerAutoloaderInit7dbce783dc983385ac7421112661002f 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInit7dbce783dc983385ac7421112661002f', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); 29 spl_autoload_unregister(array('ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInit7dbce783dc983385ac7421112661002f', 'loadClassLoader')); 30 30 31 31 require __DIR__ . '/autoload_static.php'; 32 call_user_func(\Composer\Autoload\ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::getInitializer($loader));32 call_user_func(\Composer\Autoload\ComposerStaticInit7dbce783dc983385ac7421112661002f::getInitializer($loader)); 33 33 34 34 $loader->register(true); -
advanced-cron-manager/tags/2.6.4/vendor/composer/autoload_static.php
r3353664 r3356826 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInit 8163cfec9d18b389656cb27b7a241f247 class ComposerStaticInit7dbce783dc983385ac7421112661002f 8 8 { 9 9 public static $prefixLengthsPsr4 = array ( … … 58 58 { 59 59 return \Closure::bind(function () use ($loader) { 60 $loader->prefixLengthsPsr4 = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$prefixLengthsPsr4;61 $loader->prefixDirsPsr4 = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$prefixDirsPsr4;62 $loader->classMap = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$classMap;60 $loader->prefixLengthsPsr4 = ComposerStaticInit7dbce783dc983385ac7421112661002f::$prefixLengthsPsr4; 61 $loader->prefixDirsPsr4 = ComposerStaticInit7dbce783dc983385ac7421112661002f::$prefixDirsPsr4; 62 $loader->classMap = ComposerStaticInit7dbce783dc983385ac7421112661002f::$classMap; 63 63 64 64 }, null, ClassLoader::class); -
advanced-cron-manager/tags/2.6.4/vendor/composer/installed.php
r3353664 r3356826 2 2 'root' => array( 3 3 'name' => 'bracketspace/advanced-cron-manager', 4 'pretty_version' => '2.6. 3',5 'version' => '2.6. 3.0',6 'reference' => ' 44774c0dbb40cee8548e9b848a4958e4e23c7feb',4 'pretty_version' => '2.6.4', 5 'version' => '2.6.4.0', 6 'reference' => '5c0943b645e4ed15acc71496bc9ace1d363250c2', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'bracketspace/advanced-cron-manager' => array( 14 'pretty_version' => '2.6. 3',15 'version' => '2.6. 3.0',16 'reference' => ' 44774c0dbb40cee8548e9b848a4958e4e23c7feb',14 'pretty_version' => '2.6.4', 15 'version' => '2.6.4.0', 16 'reference' => '5c0943b645e4ed15acc71496bc9ace1d363250c2', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', -
advanced-cron-manager/tags/2.6.4/views/parts/events/row.php
r3096140 r3356826 97 97 <br> 98 98 <span title="<?php echo esc_attr( 'UTC: ' . date_i18n( $date_format . ' ' . $time_format, $event->next_call ) ); ?>"> 99 <?php echo date_i18n( $date_format . ' ' . $time_format, $event->next_call + $time_offset ); // phpcs:ignore?>99 <?php echo esc_html( date_i18n( $date_format . ' ' . $time_format, $event->next_call + $time_offset ) ); ?> 100 100 </span> 101 101 <?php endif ?> -
advanced-cron-manager/trunk/advanced-cron-manager.php
r3353664 r3356826 3 3 * Plugin Name: Advanced Cron Manager 4 4 * Description: View, pause, remove, edit and add WP Cron events. 5 * Version: 2.6. 35 * Version: 2.6.4 6 6 * Author: BracketSpace 7 7 * Author URI: https://bracketspace.com … … 12 12 */ 13 13 14 $plugin_version = '2.6. 3';14 $plugin_version = '2.6.4'; 15 15 $plugin_file = __FILE__; 16 16 … … 60 60 } 61 61 } 62 63 62 } 64 63 … … 80 79 $files = new underDEV\Utils\Files( $plugin_file ); 81 80 82 $view = function () use ( $files ) {81 $view = function () use ( $files ) { 83 82 return new underDEV\Utils\View( $files ); 84 83 }; 85 84 86 $ajax = function () {85 $ajax = function () { 87 86 return new underDEV\Utils\Ajax(); 88 87 }; 89 88 90 $server_settings = function () use ( $view, $ajax ) {89 $server_settings = function () use ( $view, $ajax ) { 91 90 return new underDEV\AdvancedCronManager\Server\Settings( $view(), $ajax() ); 92 91 }; 93 92 94 $misc = function () use ( $view ) {93 $misc = function () use ( $view ) { 95 94 return new underDEV\AdvancedCronManager\Misc( $view() ); 96 95 }; 97 96 98 $server_processor = function () use ( $server_settings ) {97 $server_processor = function () use ( $server_settings ) { 99 98 return new underDEV\AdvancedCronManager\Server\Processor( $server_settings() ); 100 99 }; … … 102 101 $schedules_library = new underDEV\AdvancedCronManager\Cron\SchedulesLibrary( $ajax() ); 103 102 104 $schedules = function () use ( $schedules_library ) {103 $schedules = function () use ( $schedules_library ) { 105 104 return new underDEV\AdvancedCronManager\Cron\Schedules( $schedules_library ); 106 105 }; 107 106 108 $schedules_actions = function () use ( $ajax, $schedules_library ) {107 $schedules_actions = function () use ( $ajax, $schedules_library ) { 109 108 return new underDEV\AdvancedCronManager\Cron\SchedulesActions( $ajax(), $schedules_library ); 110 109 }; 111 110 112 $events = function () use ( $schedules ) {111 $events = function () use ( $schedules ) { 113 112 return new underDEV\AdvancedCronManager\Cron\Events( $schedules() ); 114 113 }; 115 114 116 $events_library = function () use ( $schedules, $events ) {115 $events_library = function () use ( $schedules, $events ) { 117 116 return new underDEV\AdvancedCronManager\Cron\EventsLibrary( $schedules(), $events() ); 118 117 }; 119 118 120 $events_actions = function () use ( $ajax, $events, $events_library, $schedules ) {119 $events_actions = function () use ( $ajax, $events, $events_library, $schedules ) { 121 120 return new underDEV\AdvancedCronManager\Cron\EventsActions( $ajax(), $events(), $events_library(), $schedules() ); 122 121 }; … … 184 183 185 184 // Notification promo. 186 add_action( 'plugins_loaded', function () use ( $misc ) {185 add_action( 'plugins_loaded', function () use ( $misc ) { 187 186 if ( ! function_exists( 'register_trigger' ) ) { 188 187 add_action( 'advanced-cron-manager/screen/sidebar', array( $misc(), 'load_notification_promo_part' ), 1000, 1 ); -
advanced-cron-manager/trunk/inc/AdminScreen.php
r3353664 r3356826 74 74 $this->schedules = $schedules; 75 75 $this->events = $events; 76 77 76 } 78 77 … … 126 125 127 126 } 128 129 127 } 130 128 … … 143 141 * because we want to separate scopes 144 142 * 145 * @param object $view instance of parent view. 146 * @return void 147 */ 148 public function load_searchbox_part( $view ) { 143 * @return void 144 */ 145 public function load_searchbox_part() { 149 146 $this->view->get_view( 'parts/searchbox' ); 150 147 } … … 155 152 * because we want to separate scopes 156 153 * 157 * @param object $view instance of parent view. 158 * @return void 159 */ 160 public function load_events_table_part( $view ) { 154 * @return void 155 */ 156 public function load_events_table_part() { 157 158 if ( ! current_user_can( 'manage_options' ) ) { 159 return; 160 } 161 161 162 162 $this->view->set_var( 'events', $this->events->get_events() ); … … 170 170 171 171 $this->view->get_view( 'parts/events/section' ); 172 173 172 } 174 173 … … 178 177 * because we want to separate scopes 179 178 * 180 * @param object $view instance of parent view. 181 * @return void 182 */ 183 public function load_schedules_table_part( $view ) { 179 * @return void 180 */ 181 public function load_schedules_table_part() { 182 183 if ( ! current_user_can( 'manage_options' ) ) { 184 return; 185 } 184 186 185 187 $this->view->set_var( 'schedules', $this->schedules->get_schedules(), true ); 186 188 187 189 $this->view->get_view( 'parts/schedules/section' ); 188 189 190 } 190 191 … … 194 195 * because we want to separate scopes 195 196 * 196 * @param object $view instance of parent view. 197 * @return void 198 */ 199 public function load_slidebar_part( $view ) { 197 * @return void 198 */ 199 public function load_slidebar_part() { 200 200 $this->view->get_view( 'elements/slidebar' ); 201 201 } … … 206 206 * because we want to separate scopes 207 207 * 208 * @param object $view instance of parent view. 209 * @return void 210 */ 211 public function load_preview_modal_part( $view ) { 208 * @return void 209 */ 210 public function load_preview_modal_part() { 212 211 $this->view->get_view( 'elements/preview-modal' ); 213 212 } … … 227 226 228 227 return $tabs; 229 230 228 } 231 229 … … 309 307 array( $this, 'load_page_wrapper' ) 310 308 ); 311 312 309 } 313 310 … … 355 352 } 356 353 357 $args_length = array_sum( array_map( function ( $ar ) {354 $args_length = array_sum( array_map( function ( $ar ) { 358 355 return strlen( $ar['msg'] ); 359 356 }, $parsed_args ) ); … … 365 362 ); 366 363 } 367 368 364 } -
advanced-cron-manager/trunk/inc/Assets.php
r3353664 r3356826 49 49 $this->files = $files; 50 50 $this->screen = $screen; 51 52 51 } 53 52 … … 87 86 88 87 do_action( 'advanced-cron-manager/screen/enqueue', $current_page_hook ); 89 90 88 } 91 92 89 } -
advanced-cron-manager/trunk/inc/Cron/Element/Event.php
r3096140 r3356826 79 79 * @param array $args Arguments. 80 80 * @param integer $next_call Next call timestamp. 81 * @param boolean $ protected If protected.81 * @param boolean $is_protected If protected. 82 82 * @param boolean $paused If paused. 83 * @throws \InvalidArgumentException When hook is empty. 83 84 */ 84 public function __construct( $hook = null, $schedule = '', $interval = 0, $args = array(), $next_call = 0, $ protected = false, $paused = false ) {85 public function __construct( $hook = null, $schedule = '', $interval = 0, $args = array(), $next_call = 0, $is_protected = false, $paused = false ) { 85 86 86 87 if ( empty( $hook ) ) { 87 t rigger_error( 'Hook cannot be empty', E_USER_ERROR);88 throw new \InvalidArgumentException( 'Hook cannot be empty' ); 88 89 } 89 90 … … 93 94 $this->args = $args; 94 95 $this->next_call = $next_call; 95 $this->protected = $ protected;96 $this->protected = $is_protected; 96 97 $this->paused = $paused; 97 98 98 99 // phpcs:ignore 99 100 $this->hash = substr( md5( $this->hook . $this->schedule . $this->next_call . serialize( $this->args ) ), 0, 8 ); 100 101 101 } 102 102 … … 128 128 $imp = ''; 129 129 130 $imp .= 'function ' . $function_name . '(' . $arguments . ') {<br>'; 131 $imp .= ' // do stuff<br>'; 132 $imp .= '}<br>'; 133 $imp .= '<br>'; 134 $imp .= "add_action( '" . $this->hook . "', '" . $function_name . "', 10, " . count( $this->args ) . ' );'; 130 $imp .= 'function ' . $function_name . '(' . $arguments . ') {<br>'; 131 $imp .= ' // do stuff<br>'; 132 $imp .= '}<br>'; 133 $imp .= '<br>'; 134 $args_count = is_array( $this->args ) ? count( $this->args ) : 0; 135 $imp .= "add_action( '" . $this->hook . "', '" . $function_name . "', 10, " . $args_count . ' );'; 135 136 136 137 return $imp; 137 138 138 } 139 139 … … 147 147 return esc_attr( wp_create_nonce( 'acm/event/' . $action . '/' . $this->hash ) ); 148 148 } 149 150 149 } -
advanced-cron-manager/trunk/inc/Cron/Element/Schedule.php
r3096140 r3356826 49 49 * @param integer $interval Interval. 50 50 * @param string $label Label. 51 * @param boolean $ protected If protected.51 * @param boolean $is_protected If protected. 52 52 */ 53 public function __construct( $slug = null, $interval = 0, $label = null, $ protected = false ) {53 public function __construct( $slug = null, $interval = 0, $label = null, $is_protected = false ) { 54 54 55 55 if ( empty( $label ) ) { … … 60 60 $this->interval = $interval; 61 61 $this->label = $label; 62 $this->protected = $protected; 63 62 $this->protected = $is_protected; 64 63 } 65 64 … … 103 102 104 103 return $interval; 105 106 104 } 107 105 … … 138 136 139 137 return trim( $human_time ); 140 141 138 } 142 139 … … 150 147 return esc_attr( wp_create_nonce( 'acm/schedule/' . $action . '/' . $this->slug ) ); 151 148 } 152 153 149 } -
advanced-cron-manager/trunk/inc/Cron/Events.php
r3096140 r3356826 106 106 107 107 return $this->events; 108 109 108 } 110 109 … … 119 118 $events = $this->get_events(); 120 119 return isset( $events[ $hash ] ) ? $events[ $hash ] : false; 121 122 120 } 123 121 … … 157 155 158 156 return ( $e1->next_call < $e2->next_call ) ? -1 : 1; 159 160 157 } 161 162 158 } -
advanced-cron-manager/trunk/inc/Cron/EventsActions.php
r3096145 r3356826 58 58 $this->library = $library; 59 59 $this->schedules = $schedules; 60 61 60 } 62 61 … … 95 94 } 96 95 97 $hook = trim( wp_strip_all_tags( $data['hook'] ) ); 96 $hook = sanitize_text_field( trim( $data['hook'] ) ); 97 98 if ( empty( $hook ) ) { 99 $this->ajax->response( false, array( 100 __( 'Hook name is required.', 'advanced-cron-manager' ), 101 ) ); 102 } 98 103 99 104 $result = $this->library->insert( $hook, $execution, $data['schedule'], $args ); … … 116 121 117 122 $this->ajax->response( $success, $errors ); 118 119 123 } 120 124 … … 128 132 global $acm_current_event; 129 133 130 // phpcs:ignore 131 $event = $this->events->get_event_by_hash( $_REQUEST['event']);134 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 135 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 132 136 133 137 if ( ! $event ) { … … 157 161 158 162 $this->ajax->response( $success, array() ); 159 160 163 } 161 164 … … 167 170 public function remove() { 168 171 169 // phpcs:ignore 170 $event = $this->events->get_event_by_hash( $_REQUEST['event']);172 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 173 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 171 174 172 175 if ( false === $event ) { … … 175 178 ) ); 176 179 } 177 178 $errors = array();179 180 180 181 $this->ajax->verify_nonce( 'acm/event/remove/' . $event->hash ); … … 198 199 199 200 $this->ajax->response( $success, $errors ); 200 201 201 } 202 202 … … 208 208 public function pause() { 209 209 210 // phpcs:ignore 211 $event = $this->events->get_event_by_hash( $_REQUEST['event'] ); 210 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 211 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 212 213 if ( ! $event ) { 214 $this->ajax->response( false, array( 215 __( 'This event doesn\'t seem to exist anymore', 'advanced-cron-manager' ), 216 ) ); 217 } 212 218 213 219 $this->ajax->verify_nonce( 'acm/event/pause/' . $event->hash ); … … 231 237 232 238 $this->ajax->response( $success, $errors ); 233 234 239 } 235 240 … … 241 246 public function unpause() { 242 247 243 // phpcs:ignore 244 $event = $this->events->get_event_by_hash( $_REQUEST['event'] ); 248 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need event hash for nonce string. 249 $event = $this->events->get_event_by_hash( sanitize_text_field( wp_unslash( isset( $_REQUEST['event'] ) ? $_REQUEST['event'] : '' ) ) ); 250 251 if ( ! $event ) { 252 $this->ajax->response( false, array( 253 __( 'This event doesn\'t seem to exist anymore', 'advanced-cron-manager' ), 254 ) ); 255 } 245 256 246 257 $this->ajax->verify_nonce( 'acm/event/unpause/' . $event->hash ); … … 264 275 265 276 $this->ajax->response( $success, $errors ); 266 267 } 268 277 } 269 278 } -
advanced-cron-manager/trunk/inc/Cron/EventsLibrary.php
r3096140 r3356826 49 49 50 50 $this->paused_option_name = 'acm_paused_events'; 51 52 51 } 53 52 … … 67 66 68 67 return $events; 69 70 68 } 71 69 … … 77 75 * @param string $schedule_slug Schedule slug. 78 76 * @param array $args arguments. 79 * @param boolean $new if event is new.77 * @param boolean $new_event if event is new. 80 78 * @return mixed array with errors on error or true 81 79 */ 82 public function insert( $hook, $execution_timestamp, $schedule_slug, $args, $new = true ) {80 public function insert( $hook, $execution_timestamp, $schedule_slug, $args, $new_event = true ) { 83 81 84 82 $errors = array(); … … 105 103 } 106 104 107 if ( $new ) {105 if ( $new_event ) { 108 106 do_action( 'advanced-cron-manager/event/scheduled', $hook, $execution_timestamp, $schedule, $args ); 109 107 } 110 108 111 109 return true; 112 113 110 } 114 111 … … 142 139 143 140 return true; 144 145 141 } 146 142 … … 180 176 181 177 return true; 182 183 178 } 184 179 … … 214 209 215 210 return $result; 216 217 211 } 218 212 … … 235 229 236 230 update_option( $this->paused_option_name, $paused_events ); 237 238 231 } 239 232 … … 253 246 254 247 } 255 256 } 257 248 } 258 249 } -
advanced-cron-manager/trunk/inc/Cron/Schedules.php
r3096140 r3356826 43 43 44 44 $this->library = $library; 45 46 45 } 47 46 … … 77 76 78 77 return apply_filters( 'advanced-cron-manager/schedules', $this->schedules ); 79 80 78 } 81 79 … … 100 98 101 99 return isset( $schedules[ $slug ] ) ? $schedules[ $slug ] : $this->get_single_event_schedule(); 102 103 100 } 104 101 … … 115 112 116 113 return $this->single_event_schedule; 117 118 114 } 119 120 115 } -
advanced-cron-manager/trunk/inc/Cron/SchedulesActions.php
r3096140 r3356826 63 63 $slug = str_replace( '-', '_', $slug ); 64 64 65 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $data['interval'] ); 65 // Validate interval - must be between 60 seconds and 1 year. 66 $interval = absint( $data['interval'] ); 67 if ( $interval < 60 || $interval > YEAR_IN_SECONDS ) { 68 $this->ajax->response( false, array( 69 __( 'Interval must be between 60 seconds and 1 year.', 'advanced-cron-manager' ), 70 ) ); 71 } 72 73 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $interval ); 66 74 67 75 if ( is_array( $result ) ) { … … 75 83 76 84 $this->ajax->response( $success, $errors ); 77 78 85 } 79 86 … … 99 106 $slug = str_replace( '-', '_', $slug ); 100 107 101 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $data['interval'], true ); 108 // Validate interval - must be between 60 seconds and 1 year. 109 $interval = absint( $data['interval'] ); 110 if ( $interval < 60 || $interval > YEAR_IN_SECONDS ) { 111 $this->ajax->response( false, array( 112 __( 'Interval must be between 60 seconds and 1 year.', 'advanced-cron-manager' ), 113 ) ); 114 } 115 116 $result = $this->library->insert( $slug, sanitize_text_field( $data['name'] ), $interval, true ); 102 117 103 118 if ( is_array( $result ) ) { … … 111 126 112 127 $this->ajax->response( $success, $errors ); 113 114 128 } 115 129 … … 121 135 public function remove() { 122 136 123 // phpcs:ignore 124 $schedule_slug = $_REQUEST['schedule']; 137 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need schedule slug for nonce string. 138 $schedule_slug = sanitize_key( isset( $_REQUEST['schedule'] ) ? $_REQUEST['schedule'] : '' ); 139 140 if ( empty( $schedule_slug ) ) { 141 $this->ajax->response( false, array( 142 __( 'Invalid schedule slug.', 'advanced-cron-manager' ), 143 ) ); 144 } 125 145 126 146 $this->ajax->verify_nonce( 'acm/schedule/remove/' . $schedule_slug ); … … 144 164 145 165 $this->ajax->response( $success, $errors ); 146 147 166 } 148 149 167 } -
advanced-cron-manager/trunk/inc/Cron/SchedulesLibrary.php
r3096140 r3356826 47 47 $this->ajax = $ajax; 48 48 $this->option_name = 'acm_schedules'; 49 50 49 } 51 50 … … 71 70 72 71 return $this->schedules; 73 74 72 } 75 73 … … 89 87 90 88 return isset( $schedules[ $slug ] ) ? $schedules[ $slug ] : false; 91 92 89 } 93 90 … … 123 120 124 121 return $schedules; 125 126 122 } 127 123 … … 186 182 187 183 return true; 188 189 184 } 190 185 … … 216 211 217 212 return true; 218 219 } 220 213 } 221 214 } -
advanced-cron-manager/trunk/inc/FormProvider.php
r3096140 r3356826 85 85 86 86 $this->ajax->response( $form_html ); 87 88 87 } 89 88 … … 96 95 97 96 $this->get_form( 'schedule/add', __( 'New schedule', 'advanced-cron-manager' ), __( 'Add schedule', 'advanced-cron-manager' ) ); 98 99 97 } 100 98 … … 104 102 public function edit_schedule() { 105 103 106 // phpcs:ignore 107 $schedule_slug = $_REQUEST['schedule']; 104 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Need schedule slug for nonce string. 105 $schedule_slug = sanitize_key( isset( $_REQUEST['schedule'] ) ? $_REQUEST['schedule'] : '' ); 106 107 if ( empty( $schedule_slug ) ) { 108 $this->ajax->response( false, array( 109 __( 'Invalid schedule slug.', 'advanced-cron-manager' ), 110 ) ); 111 } 108 112 109 113 $this->ajax->verify_nonce( 'acm/schedule/edit/' . $schedule_slug ); … … 115 119 // Translators: schedule slug. 116 120 $this->get_form( 'schedule/edit', sprintf( __( 'Edit "%s" schedule', 'advanced-cron-manager' ), $schedule->slug ), __( 'Edit schedule', 'advanced-cron-manager' ) ); 117 118 121 } 119 122 … … 129 132 130 133 $this->get_form( 'event/add', __( 'New event', 'advanced-cron-manager' ), __( 'Schedule event', 'advanced-cron-manager' ) ); 131 132 134 } 133 134 135 } -
advanced-cron-manager/trunk/inc/Misc.php
r3096140 r3356826 50 50 return $links; 51 51 } 52 53 52 } -
advanced-cron-manager/trunk/inc/Server/Processor.php
r3096140 r3356826 49 49 50 50 } 51 52 51 } 53 54 52 } -
advanced-cron-manager/trunk/inc/Server/Settings.php
r3353338 r3356826 93 93 94 94 return $this->settings; 95 96 95 } 97 96 … … 115 114 $this->ajax->verify_nonce( 'acm/server/settings/save' ); 116 115 116 if ( ! current_user_can( 'manage_options' ) ) { 117 $this->ajax->response( false, array( 118 __( "You're not allowed to do that.", 'advanced-cron-manager' ), 119 ) ); 120 } 121 117 122 $errors = array(); 118 123 119 $form_options = array_map( function ( $val) {124 $form_options = array_map( function () { 120 125 return 0; 121 126 }, $this->default ); … … 124 129 $form_data = wp_parse_args( $_REQUEST['data'], $form_options ); 125 130 126 update_option( $this->option_name, $form_data ); 131 // Validate and sanitize settings. 132 $sanitized_data = array(); 133 foreach ( $form_data as $key => $value ) { 134 if ( ! array_key_exists( $key, $this->default ) ) { 135 continue; // Skip unknown settings. 136 } 137 138 // All current settings are boolean (0 or 1). 139 $sanitized_data[ $key ] = absint( $value ) === 1 ? 1 : 0; 140 } 141 142 update_option( $this->option_name, $sanitized_data ); 127 143 128 144 $this->ajax->response( __( 'Settings has been saved', 'advanced-cron-manager' ), $errors ); 129 130 145 } 131 132 146 } -
advanced-cron-manager/trunk/readme.txt
r3353664 r3356826 5 5 Requires PHP: 5.3 6 6 Tested up to: 6.8 7 Stable tag: 2.6. 37 Stable tag: 2.6.4 8 8 License: GPLv2 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 102 102 == Changelog == 103 103 104 = 2.6.4 = 105 * [Security] Improved event hook sanitization using sanitize_text_field() to prevent XSS while allowing valid hook characters 106 * [Security] Added validation for schedule intervals to prevent invalid values 107 * [Security] Strengthened authorization checks in admin screen methods 108 * [Security] Enhanced output escaping in event row view template 109 * [Security] Standardized nonce verification in AJAX handlers with better input validation 110 * [Security] Added proper validation and sanitization for server settings 111 * [Security] Fixed unsanitized input in FormProvider.php schedule slug handling 112 * [Fixed] Fixed PHP 8.4 deprecation warning with trigger_error() by replacing with exception 113 * [Fixed] Fixed TypeError on PHP 8.3+ where count() was called on non-countable value in Event implementation 114 * [Changed] Updated WordPress Coding Standards to version 3.2 and resolved all coding standard warnings 115 * [Changed] Renamed reserved keyword parameters for better PHP compatibility ($protected to $is_protected, $new to $new_event) 116 104 117 = 2.6.3 = 105 118 * [Fixed] Fixed translation loading issue that was triggered too early in AdminScreen constructor. -
advanced-cron-manager/trunk/uninstall.php
r3096140 r3356826 16 16 17 17 $plugin_version = 'x'; 18 $plugin_file = dirname( __FILE__ ). '/advanced-cron-manager.php';18 $plugin_file = __DIR__ . '/advanced-cron-manager.php'; 19 19 20 20 /** … … 27 27 */ 28 28 29 $ajax = function () {29 $ajax = function () { 30 30 return new underDEV\Utils\Ajax(); 31 31 }; … … 33 33 $schedules_library = new underDEV\AdvancedCronManager\Cron\SchedulesLibrary( $ajax() ); 34 34 35 $schedules = function () use ( $schedules_library ) {35 $schedules = function () use ( $schedules_library ) { 36 36 return new underDEV\AdvancedCronManager\Cron\Schedules( $schedules_library ); 37 37 }; 38 38 39 $events = function () use ( $schedules ) {39 $events = function () use ( $schedules ) { 40 40 return new underDEV\AdvancedCronManager\Cron\Events( $schedules() ); 41 41 }; -
advanced-cron-manager/trunk/vendor/autoload.php
r3353359 r3356826 20 20 require_once __DIR__ . '/composer/autoload_real.php'; 21 21 22 return ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24::getLoader();22 return ComposerAutoloaderInit7dbce783dc983385ac7421112661002f::getLoader(); -
advanced-cron-manager/trunk/vendor/composer/autoload_real.php
r3353359 r3356826 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f245 class ComposerAutoloaderInit7dbce783dc983385ac7421112661002f 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInit7dbce783dc983385ac7421112661002f', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); 29 spl_autoload_unregister(array('ComposerAutoloaderInit 8163cfec9d18b389656cb27b7a241f24', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInit7dbce783dc983385ac7421112661002f', 'loadClassLoader')); 30 30 31 31 require __DIR__ . '/autoload_static.php'; 32 call_user_func(\Composer\Autoload\ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::getInitializer($loader));32 call_user_func(\Composer\Autoload\ComposerStaticInit7dbce783dc983385ac7421112661002f::getInitializer($loader)); 33 33 34 34 $loader->register(true); -
advanced-cron-manager/trunk/vendor/composer/autoload_static.php
r3353664 r3356826 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInit 8163cfec9d18b389656cb27b7a241f247 class ComposerStaticInit7dbce783dc983385ac7421112661002f 8 8 { 9 9 public static $prefixLengthsPsr4 = array ( … … 58 58 { 59 59 return \Closure::bind(function () use ($loader) { 60 $loader->prefixLengthsPsr4 = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$prefixLengthsPsr4;61 $loader->prefixDirsPsr4 = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$prefixDirsPsr4;62 $loader->classMap = ComposerStaticInit 8163cfec9d18b389656cb27b7a241f24::$classMap;60 $loader->prefixLengthsPsr4 = ComposerStaticInit7dbce783dc983385ac7421112661002f::$prefixLengthsPsr4; 61 $loader->prefixDirsPsr4 = ComposerStaticInit7dbce783dc983385ac7421112661002f::$prefixDirsPsr4; 62 $loader->classMap = ComposerStaticInit7dbce783dc983385ac7421112661002f::$classMap; 63 63 64 64 }, null, ClassLoader::class); -
advanced-cron-manager/trunk/vendor/composer/installed.php
r3353664 r3356826 2 2 'root' => array( 3 3 'name' => 'bracketspace/advanced-cron-manager', 4 'pretty_version' => '2.6. 3',5 'version' => '2.6. 3.0',6 'reference' => ' 44774c0dbb40cee8548e9b848a4958e4e23c7feb',4 'pretty_version' => '2.6.4', 5 'version' => '2.6.4.0', 6 'reference' => '5c0943b645e4ed15acc71496bc9ace1d363250c2', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 12 12 'versions' => array( 13 13 'bracketspace/advanced-cron-manager' => array( 14 'pretty_version' => '2.6. 3',15 'version' => '2.6. 3.0',16 'reference' => ' 44774c0dbb40cee8548e9b848a4958e4e23c7feb',14 'pretty_version' => '2.6.4', 15 'version' => '2.6.4.0', 16 'reference' => '5c0943b645e4ed15acc71496bc9ace1d363250c2', 17 17 'type' => 'wordpress-plugin', 18 18 'install_path' => __DIR__ . '/../../', -
advanced-cron-manager/trunk/views/parts/events/row.php
r3096140 r3356826 97 97 <br> 98 98 <span title="<?php echo esc_attr( 'UTC: ' . date_i18n( $date_format . ' ' . $time_format, $event->next_call ) ); ?>"> 99 <?php echo date_i18n( $date_format . ' ' . $time_format, $event->next_call + $time_offset ); // phpcs:ignore?>99 <?php echo esc_html( date_i18n( $date_format . ' ' . $time_format, $event->next_call + $time_offset ) ); ?> 100 100 </span> 101 101 <?php endif ?>
Note: See TracChangeset for help on using the changeset viewer.