55 * @package WP-Background-Processing
66 */
77
8- // phpcs:disable Generic.Commenting.DocComment.MissingShort
9- /** @noinspection PhpIllegalPsrClassPathInspection */
10- /** @noinspection AutoloadingIssuesInspection */
11- // phpcs:disable Generic.Commenting.DocComment.MissingShort
12-
138/**
149 * Abstract WPT_WP_Background_Process class.
1510 *
@@ -54,6 +49,13 @@ abstract class WPT_WP_Background_Process extends WPT_WP_Async_Request {
5449 */
5550 protected $ cron_interval_identifier ;
5651
52+ /**
53+ * Restrict object instantiation when using unserialize.
54+ *
55+ * @var bool|array
56+ */
57+ protected $ allowed_batch_data_classes = true ;
58+
5759 /**
5860 * The status set when process is cancelling.
5961 *
@@ -70,15 +72,30 @@ abstract class WPT_WP_Background_Process extends WPT_WP_Async_Request {
7072
7173 /**
7274 * Initiate new background process.
75+ *
76+ * @param bool|array $allowed_batch_data_classes Optional. Array of class WPT_names that can be unserialized. Default true (any class).
7377 */
74- public function __construct () {
78+ public function __construct ( $ allowed_batch_data_classes = true ) {
7579 parent ::__construct ();
7680
81+ if ( empty ( $ allowed_batch_data_classes ) && false !== $ allowed_batch_data_classes ) {
82+ $ allowed_batch_data_classes = true ;
83+ }
84+
85+ if ( ! is_bool ( $ allowed_batch_data_classes ) && ! is_array ( $ allowed_batch_data_classes ) ) {
86+ $ allowed_batch_data_classes = true ;
87+ }
88+
89+ // If allowed_batch_data_classes property set in subclass,
90+ // only apply override if not allowing any class.
91+ if ( true === $ this ->allowed_batch_data_classes || true !== $ allowed_batch_data_classes ) {
92+ $ this ->allowed_batch_data_classes = $ allowed_batch_data_classes ;
93+ }
94+
7795 $ this ->cron_hook_identifier = $ this ->identifier . '_cron ' ;
7896 $ this ->cron_interval_identifier = $ this ->identifier . '_cron_interval ' ;
7997
8098 add_action ( $ this ->cron_hook_identifier , array ( $ this , 'handle_cron_healthcheck ' ) );
81- // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected
8299 add_filter ( 'cron_schedules ' , array ( $ this , 'schedule_cron_healthcheck ' ) );
83100 }
84101
@@ -339,7 +356,6 @@ public function maybe_handle() {
339356 * Is queue empty?
340357 *
341358 * @return bool
342- * @noinspection IsEmptyFunctionUsageInspection
343359 */
344360 protected function is_queue_empty () {
345361 return empty ( $ this ->get_batch () );
@@ -355,7 +371,6 @@ protected function is_queue_empty() {
355371 *
356372 * @deprecated 1.1.0 Superseded.
357373 * @see is_processing()
358- * @noinspection PhpUnused
359374 */
360375 protected function is_process_running () {
361376 return $ this ->is_processing ();
@@ -451,7 +466,7 @@ public function get_batches( $limit = 0 ) {
451466 SELECT *
452467 FROM ' . $ table . '
453468 WHERE ' . $ column . ' LIKE %s
454- ORDER BY ' . $ key_column . '
469+ ORDER BY ' . $ key_column . ' ASC
455470 ' ;
456471
457472 $ args = array ( $ key );
@@ -467,11 +482,13 @@ public function get_batches( $limit = 0 ) {
467482 $ batches = array ();
468483
469484 if ( ! empty ( $ items ) ) {
485+ $ allowed_classes = $ this ->allowed_batch_data_classes ;
486+
470487 $ batches = array_map (
471- static function ( $ item ) use ( $ column , $ value_column ) {
488+ static function ( $ item ) use ( $ column , $ value_column, $ allowed_classes ) {
472489 $ batch = new stdClass ();
473490 $ batch ->key = $ item ->{$ column };
474- $ batch ->data = maybe_unserialize ( $ item ->{$ value_column } );
491+ $ batch ->data = static :: maybe_unserialize ( $ item ->{$ value_column }, $ allowed_classes );
475492
476493 return $ batch ;
477494 },
@@ -487,8 +504,6 @@ static function ( $item ) use ( $column, $value_column ) {
487504 *
488505 * Pass each queue item to the task handler, while remaining
489506 * within server memory and time limit constraints.
490- *
491- * @noinspection DisconnectedForeachInstructionInspection
492507 */
493508 protected function handle () {
494509 $ this ->lock_process ();
@@ -586,7 +601,7 @@ protected function get_memory_limit() {
586601 $ memory_limit = '128M ' ;
587602 }
588603
589- if ( ! $ memory_limit || -1 === ( int ) $ memory_limit ) {
604+ if ( ! $ memory_limit || -1 === intval ( $ memory_limit ) ) {
590605 // Unlimited, set to 32GB.
591606 $ memory_limit = '32000M ' ;
592607 }
@@ -606,10 +621,7 @@ protected function time_exceeded() {
606621 $ finish = $ this ->start_time + apply_filters ( $ this ->identifier . '_default_time_limit ' , 20 ); // 20 seconds
607622 $ return = false ;
608623
609- if (
610- ! ( defined ( 'WP_CLI ' ) && WP_CLI ) &&
611- time () >= $ finish
612- ) {
624+ if ( time () >= $ finish ) {
613625 $ return = true ;
614626 }
615627
@@ -638,6 +650,25 @@ protected function completed() {
638650 do_action ( $ this ->identifier . '_completed ' );
639651 }
640652
653+ /**
654+ * Get the cron healthcheck interval in minutes.
655+ *
656+ * Default is 5 minutes, minimum is 1 minute.
657+ *
658+ * @return int
659+ */
660+ public function get_cron_interval () {
661+ $ interval = 5 ;
662+
663+ if ( property_exists ( $ this , 'cron_interval ' ) ) {
664+ $ interval = $ this ->cron_interval ;
665+ }
666+
667+ $ interval = apply_filters ( $ this ->cron_interval_identifier , $ interval );
668+
669+ return is_int ( $ interval ) && 0 < $ interval ? $ interval : 5 ;
670+ }
671+
641672 /**
642673 * Schedule the cron healthcheck job.
643674 *
@@ -648,11 +679,7 @@ protected function completed() {
648679 * @return mixed
649680 */
650681 public function schedule_cron_healthcheck ( $ schedules ) {
651- $ interval = apply_filters ( $ this ->cron_interval_identifier , 5 );
652-
653- if ( property_exists ( $ this , 'cron_interval ' ) ) {
654- $ interval = apply_filters ( $ this ->cron_interval_identifier , $ this ->cron_interval );
655- }
682+ $ interval = $ this ->get_cron_interval ();
656683
657684 if ( 1 === $ interval ) {
658685 $ display = __ ( 'Every Minute ' );
@@ -695,7 +722,7 @@ public function handle_cron_healthcheck() {
695722 */
696723 protected function schedule_event () {
697724 if ( ! wp_next_scheduled ( $ this ->cron_hook_identifier ) ) {
698- wp_schedule_event ( time (), $ this ->cron_interval_identifier , $ this ->cron_hook_identifier );
725+ wp_schedule_event ( time () + ( $ this -> get_cron_interval () * MINUTE_IN_SECONDS ) , $ this ->cron_interval_identifier , $ this ->cron_hook_identifier );
699726 }
700727 }
701728
@@ -717,7 +744,6 @@ protected function clear_scheduled_event() {
717744 *
718745 * @deprecated 1.1.0 Superseded.
719746 * @see cancel()
720- * @noinspection PhpUnused
721747 */
722748 public function cancel_process () {
723749 $ this ->cancel ();
@@ -736,4 +762,25 @@ public function cancel_process() {
736762 * @return mixed
737763 */
738764 abstract protected function task ( $ item );
765+
766+ /**
767+ * Maybe unserialize data, but not if an object.
768+ *
769+ * @param mixed $data Data to be unserialized.
770+ * @param bool|array $allowed_classes Array of class WPT_names that can be unserialized.
771+ *
772+ * @return mixed
773+ */
774+ protected static function maybe_unserialize ( $ data , $ allowed_classes ) {
775+ if ( is_serialized ( $ data ) ) {
776+ $ options = array ();
777+ if ( is_bool ( $ allowed_classes ) || is_array ( $ allowed_classes ) ) {
778+ $ options ['allowed_classes ' ] = $ allowed_classes ;
779+ }
780+
781+ return @unserialize ( $ data , $ options ); // @phpcs:ignore
782+ }
783+
784+ return $ data ;
785+ }
739786}
0 commit comments