diff --git a/src/Tribe/Aggregator/Cron.php b/src/Tribe/Aggregator/Cron.php index c0f4eef3e2..37cfecc6d4 100644 --- a/src/Tribe/Aggregator/Cron.php +++ b/src/Tribe/Aggregator/Cron.php @@ -293,14 +293,13 @@ public function verify_child_record_creation() { if ( ! tribe( 'events-aggregator.main' )->is_service_active() ) { return; } - $records = Tribe__Events__Aggregator__Records::instance(); $service = tribe( 'events-aggregator.service' ); - $query = $records->query( array( - 'post_status' => Tribe__Events__Aggregator__Records::$status->schedule, + $query = $records->query( [ + 'post_status' => Tribe__Events__Aggregator__Records::$status->schedule, 'posts_per_page' => -1, - ) ); + ] ); if ( ! $query->have_posts() ) { tribe( 'logger' )->log_debug( 'No Records Scheduled, skipped creating children', 'EA Cron' ); @@ -344,7 +343,6 @@ public function verify_child_record_creation() { // Creating the child records based on this Parent $child = $record->create_child_record(); - tribe( 'logger' )->log_debug( sprintf( 'Creating child record %d for %d', $child->id, $record->id ), 'EA Cron' ); if ( ! is_wp_error( $child ) ) { @@ -401,31 +399,34 @@ public function verify_fetching_from_service() { $records = Tribe__Events__Aggregator__Records::instance(); - $query = $records->query( array( + $query = $records->query( [ 'post_status' => Tribe__Events__Aggregator__Records::$status->pending, - 'posts_per_page' => - 1, + 'posts_per_page' => -1, 'order' => 'ASC', - 'meta_query' => array( - 'origin-not-csv' => array( - 'key' => '_tribe_aggregator_origin', - 'value' => 'csv', + 'meta_query' => [ + 'origin-not-csv' => [ + 'key' => '_tribe_aggregator_origin', + 'value' => 'csv', 'compare' => '!=', - ), - // if not specified then assume batch push is not supported - 'no-batch-push-support-specified' => array( - 'key' => '_tribe_aggregator_allow_batch_push', - 'value' => 'bug #23268', - 'compare' => 'NOT EXISTS', - ), - // if specified and not `1` then batch push is not supported - 'explicit-no-batch-push-support' => array( - 'key' => '_tribe_aggregator_allow_batch_push', - 'value' => '1', - 'compare' => '!=', - ), - ), + ], + [ + 'relation' => 'OR', + // If not specified then assume batch push is not supported. + 'no-batch-push-support-specified' => [ + 'key' => '_tribe_aggregator_allow_batch_push', + 'value' => 'bug #23268', + 'compare' => 'NOT EXISTS', + ], + // If specified, and not `1`, then batch push is not supported. + 'explicit-no-batch-push-support' => [ + 'key' => '_tribe_aggregator_allow_batch_push', + 'value' => '1', + 'compare' => '!=', + ], + ], + ], 'after' => '-4 hours', - ) ); + ] ); if ( ! $query->have_posts() ) { tribe( 'logger' )->log_debug( 'No Records Pending, skipped Fetching from service', 'EA Cron' ); @@ -516,22 +517,22 @@ public function purge_expired_records() { ) ); - $args = array( - 'post_status' => array( + $args = [ + 'post_status' => [ $statuses->pending, $statuses->success, $statuses->failed, $statuses->draft, - ), - 'date_query' => array( - array( + ], + 'date_query' => [ + [ 'before' => date( 'Y-m-d H:i:s', time() - $records->get_retention() ), 'column' => 'post_date_gmt', - ), - ), - 'order' => 'ASC', + ], + ], + 'order' => 'ASC', 'posts_per_page' => 100, - ); + ]; if ( $records_to_retain ) { $args['post__not_in'] = $records_to_retain; @@ -590,6 +591,10 @@ protected function maybe_process_immediately( Tribe__Events__Aggregator__Record_ $import_data = $record->prep_import_data(); if ( empty( $import_data ) || $import_data instanceof WP_Error || ! is_array( $import_data ) ) { + + $record->update_meta( 'last_import_status', 'error:import-failed' ); + $record->set_status_as_failed( $import_data ); + return; } diff --git a/src/Tribe/Aggregator/Record/Abstract.php b/src/Tribe/Aggregator/Record/Abstract.php index 8186860515..f42fda14c7 100644 --- a/src/Tribe/Aggregator/Record/Abstract.php +++ b/src/Tribe/Aggregator/Record/Abstract.php @@ -655,7 +655,7 @@ public function maybe_add_meta_via_pre_wp_44_method( $id, $meta ) { * post ID if the record had to be re-scheduled due to HTTP request * limit. */ - public function queue_import( $args = array() ) { + public function queue_import( $args = [] ) { $aggregator = tribe( 'events-aggregator.main' ); $is_previewing = ( @@ -761,11 +761,11 @@ public function queue_import( $args = array() ) { if ( 'core:aggregator:http_request-limit' === $response->get_error_code() ) { $this->should_queue_import( true ); return $this->set_status_as_pending(); - } else { - $error = $response; - - return $this->set_status_as_failed( $error ); } + + $error = $response; + + return $this->set_status_as_failed( $error ); } // if the Aggregator response has an unexpected format, set this record as failed @@ -1207,7 +1207,6 @@ public function get_last_import_status( $type = 'error', $lookup_children = fals if ( 'error:usage-limit-exceeded' === $status ) { return __( 'When this import was last scheduled to run, the daily limit for your Event Aggregator license had already been reached.', 'the-events-calendar' ); } - return tribe( 'events-aggregator.service' )->get_service_message( $status ); } @@ -1264,6 +1263,7 @@ public function process_posts( $data = array(), $start_immediately = false ) { $items = $this->prep_import_data( $data ); if ( is_wp_error( $items ) ) { + $this->set_status_as_failed( $items ); return $items; } diff --git a/src/Tribe/Aggregator/Record/List_Table.php b/src/Tribe/Aggregator/Record/List_Table.php index 8f184e5f9e..587a00b0d1 100644 --- a/src/Tribe/Aggregator/Record/List_Table.php +++ b/src/Tribe/Aggregator/Record/List_Table.php @@ -529,12 +529,14 @@ public function column_imported( $post ) { if ( 'scheduled' === $this->tab->get_slug() ) { $last_import_error = $record->get_last_import_status( 'error' ); + $status = 'success'; if ( $last_import_error ) { $html[] = ''; + $status = 'failed'; } - $has_child_record = $record->get_child_record_by_status( 'success', 1 ); + $has_child_record = $record->get_child_record_by_status( $status, 1 ); if ( ! $has_child_record ) { $html[] = '' . esc_html__( 'Unknown', 'the-events-calendar' ) . ''; diff --git a/src/Tribe/Aggregator/Record/Queue.php b/src/Tribe/Aggregator/Record/Queue.php index 4189d19227..ffc3898f25 100644 --- a/src/Tribe/Aggregator/Record/Queue.php +++ b/src/Tribe/Aggregator/Record/Queue.php @@ -72,7 +72,7 @@ public function __construct( $record, $items = array(), Tribe__Events__Aggregato $record = Tribe__Events__Aggregator__Records::instance()->get_by_post_id( $record ); } - if ( ! is_object( $record ) || ! in_array( 'Tribe__Events__Aggregator__Record__Abstract', class_parents( $record ) ) ) { + if ( ! is_object( $record ) || ! $record instanceof \Tribe__Events__Aggregator__Record__Abstract ) { $this->null_process = true; return; @@ -80,7 +80,6 @@ public function __construct( $record, $items = array(), Tribe__Events__Aggregato if ( is_wp_error( $items ) ) { $this->null_process = true; - return; } @@ -184,12 +183,16 @@ public function count() { } /** - * Shortcut to check if this queue is empty. + * Shortcut to check if this queue is empty or it has a null process. * * @return boolean `true` if this queue instance has acquired the lock and * the count is 0, `false` otherwise. */ public function is_empty() { + if ( $this->null_process ) { + return true; + } + return $this->has_lock && 0 === $this->count(); } @@ -292,6 +295,7 @@ public function process( $batch_size = null ) { || is_wp_error( $data ) ) { $this->release_lock(); + $this->is_fetching = false; return $this->activity(); } diff --git a/src/Tribe/Aggregator/Record/Queue_Cleaner.php b/src/Tribe/Aggregator/Record/Queue_Cleaner.php index 7a6b319e39..8fe09ccab9 100644 --- a/src/Tribe/Aggregator/Record/Queue_Cleaner.php +++ b/src/Tribe/Aggregator/Record/Queue_Cleaner.php @@ -6,10 +6,10 @@ class Tribe__Events__Aggregator__Record__Queue_Cleaner { /** * Default is 12hrs. * - * @var int The time a record is allowed to stall before havint its status set to to failed since its creation in + * @var int The time a record is allowed to stall before have the status set to to failed since its creation in * seconds. */ - protected $time_to_live = 43200; // For pre-PHP 5.6 compat, we do not define as 12 * HOUR_IN_SECONDS + protected $time_to_live = HOUR_IN_SECONDS * 12; /** * @var int The time a record is allowed to stall before having @@ -94,7 +94,7 @@ public function maybe_fail_stalled_record( Tribe__Events__Aggregator__Record__Ab $post_status = $record->post->post_status; - if ( ! in_array( $post_status, array( $pending, $failed ) ) ) { + if ( ! in_array( $post_status, [ $pending, $failed ], true ) ) { return false; } diff --git a/src/Tribe/Aggregator/Record/Queue_Processor.php b/src/Tribe/Aggregator/Record/Queue_Processor.php index cd17086caa..1b012356ad 100644 --- a/src/Tribe/Aggregator/Record/Queue_Processor.php +++ b/src/Tribe/Aggregator/Record/Queue_Processor.php @@ -192,10 +192,10 @@ public function next_waiting_record( $interactive_only = false ) { if ( empty( $waiting_records ) ) { return $this->current_record_id = 0; - } else { - $next_record = array_shift( $waiting_records ); - return $this->current_record_id = $next_record->ID; } + + $next_record = array_shift( $waiting_records ); + return $this->current_record_id = $next_record->ID; } /** diff --git a/src/Tribe/Aggregator/Record/Queue_Realtime.php b/src/Tribe/Aggregator/Record/Queue_Realtime.php index 0a1ff8421a..16d535639f 100644 --- a/src/Tribe/Aggregator/Record/Queue_Realtime.php +++ b/src/Tribe/Aggregator/Record/Queue_Realtime.php @@ -63,7 +63,7 @@ public function update_loop_vars() { public function render_update_message() { if ( ! Tribe__Events__Aggregator__Page::instance()->is_screen() ) { - return; + return false; } /** @var Tribe__Events__Aggregator__Record__Queue_Processor $processor */ @@ -121,7 +121,6 @@ public function ajax() { // Load the queue /** @var \Tribe__Events__Aggregator__Record__Queue_Interface $queue */ $queue = $this->queue ? $this->queue : Tribe__Events__Aggregator__Record__Queue_Processor::build_queue( $this->record_id ); - // We always need to setup the Current Queue $this->queue_processor->set_current_queue( $queue ); @@ -138,7 +137,6 @@ public function ajax() { $current_queue = $this->queue_processor->current_queue; $done = $current_queue->is_empty() && empty( $current_queue->is_fetching ); $percentage = $current_queue->progress_percentage(); - $this->ajax_operations->exit_data( $this->get_progress_message_data( $current_queue, $percentage, $done ) ); } diff --git a/src/Tribe/Aggregator/Record/Void_Queue.php b/src/Tribe/Aggregator/Record/Void_Queue.php index bcf1f75940..d7cf722079 100644 --- a/src/Tribe/Aggregator/Record/Void_Queue.php +++ b/src/Tribe/Aggregator/Record/Void_Queue.php @@ -36,7 +36,6 @@ public function __construct( $error ) { return; } - $this->error = $error; } diff --git a/src/Tribe/Aggregator/Tabs/Scheduled.php b/src/Tribe/Aggregator/Tabs/Scheduled.php index fe21f224dd..c9ecb303e5 100644 --- a/src/Tribe/Aggregator/Tabs/Scheduled.php +++ b/src/Tribe/Aggregator/Tabs/Scheduled.php @@ -261,8 +261,8 @@ private function action_notice( $action, $ids = array(), $error = null ) { private function action_delete_record( $records = array() ) { $record_obj = Tribe__Events__Aggregator__Records::instance()->get_post_type(); $records = array_filter( (array) $records, 'is_numeric' ); - $success = array(); - $errors = array(); + $success = []; + $errors = []; foreach ( $records as $record_id ) { $record = Tribe__Events__Aggregator__Records::instance()->get_by_post_id( $record_id ); @@ -287,7 +287,7 @@ private function action_delete_record( $records = array() ) { $success[ $record->id ] = true; } - return array( $success, $errors ); + return [ $success, $errors ]; } /** @@ -299,12 +299,11 @@ private function action_delete_record( $records = array() ) { * * @return array */ - public function action_run_import( $records = array() ) { + public function action_run_import( $records = [] ) { $service = tribe( 'events-aggregator.service' ); - $record_obj = Tribe__Events__Aggregator__Records::instance()->get_post_type(); $records = array_filter( (array) $records, 'is_numeric' ); - $success = array(); - $errors = array(); + $success = []; + $errors = []; foreach ( $records as $record_id ) { $record = Tribe__Events__Aggregator__Records::instance()->get_by_post_id( $record_id ); @@ -337,16 +336,21 @@ public function action_run_import( $records = array() ) { continue; } - $record->update_meta( 'last_import_status', 'success:queued' ); - $child->update_meta( 'import_id', $status->data->import_id ); - $child->finalize(); - $child->process_posts( array(), true ); + $post = $child->process_posts( [], true ); - $success[ $record->id ] = $record; + if ( is_wp_error( $post ) ) { + $errors[ $record->id ] = $post; + $record->update_meta( 'last_import_status', 'error:import-failed' ); + } else { + $record->update_meta( 'last_import_status', 'success:queued' ); + $child->update_meta( 'import_id', $status->data->import_id ); + + $success[ $record->id ] = $record; + } } - return array( $success, $errors ); + return [ $success, $errors ]; } /** @@ -356,7 +360,7 @@ public function action_run_import( $records = array() ) { */ public function maybe_display_aggregator_missing_license_key_message() { if ( tribe( 'events-aggregator.main' )->is_service_active() ) { - return; + return ''; } ob_start(); diff --git a/tests/wpunit/Tribe/Events/Aggregator/CronTest.php b/tests/wpunit/Tribe/Events/Aggregator/CronTest.php index bf6212a597..83b01e8951 100644 --- a/tests/wpunit/Tribe/Events/Aggregator/CronTest.php +++ b/tests/wpunit/Tribe/Events/Aggregator/CronTest.php @@ -16,6 +16,15 @@ public function it_should_be_instantiatable() { $this->assertInstanceOf( Cron::class, $sut ); } + public function _before() { + // By pass the is_active() EA call. + add_filter( 'tribe_aggregator_api', function ( $api ) { + $api->key = 'foo-bar'; + + return $api; + } ); + } + /** * @return Cron */ @@ -43,13 +52,69 @@ public function should_trash_record_posts_not_belonging_to_a_supported_origin() $this->assertEquals( Records::$status->schedule, get_post_status( $record_post ) ); $cron = $this->make_instance(); - add_filter( 'tribe_aggregator_api', function ( $api ) { - $api->key = 'foo-bar'; - - return $api; - } ); $cron->verify_child_record_creation(); $this->assertEmpty( get_post( $record_post ) ); } + + /** + * It should process all pending records + * + * @test + */ + public function should_process_all_pending_records() { + $first = $this->factory()->post->create( [ + 'post_type' => Records::$post_type, + 'post_status' => Records::$status->pending, + 'post_mime_type' => 'ea/foo-bar' + ] ); + + add_post_meta( $first, '_tribe_aggregator_origin', 'eventbrite' ); + + $second = $this->factory()->post->create( [ + 'post_type' => Records::$post_type, + 'post_status' => Records::$status->pending, + 'post_mime_type' => 'ea/foo-bar' + ] ); + + add_post_meta( $second, '_tribe_aggregator_origin', 'meetup' ); + add_post_meta( $second, '_tribe_aggregator_allow_batch_push', '0' ); + + $batch = $this->factory()->post->create( [ + 'post_type' => Records::$post_type, + 'post_status' => Records::$status->pending, + 'post_mime_type' => 'ea/foo-bar' + ] ); + + add_post_meta( $batch, '_tribe_aggregator_origin', 'meetup' ); + add_post_meta( $batch, '_tribe_aggregator_allow_batch_push', '1' ); + + $cron = $this->make_instance(); + $cron->verify_fetching_from_service(); + + $this->assertEquals( Records::$status->failed, get_post_status( $first ) ); + $this->assertEquals( Records::$status->failed, get_post_status( $second ) ); + $this->assertEquals( Records::$status->pending, get_post_status( $batch ) ); + } + + /** + * Test batch records are not processed by cron task. + * + * @test + */ + public function it_should_bypass_batch_push_records() { + $batch = $this->factory()->post->create( [ + 'post_type' => Records::$post_type, + 'post_status' => Records::$status->pending, + 'post_mime_type' => 'ea/foo-bar' + ] ); + + add_post_meta( $batch, '_tribe_aggregator_origin', 'meetup' ); + add_post_meta( $batch, '_tribe_aggregator_allow_batch_push', '1' ); + + $cron = $this->make_instance(); + $cron->verify_fetching_from_service(); + + $this->assertEquals( Records::$status->pending, get_post_status( $batch ) ); + } } \ No newline at end of file diff --git a/tests/wpunit/Tribe/Events/Importer/File_Importer_Events_BooleanFieldsTest.php b/tests/wpunit/Tribe/Events/Importer/File_Importer_Events_BooleanFieldsTest.php index f12abfbde9..f8ab524a3a 100644 --- a/tests/wpunit/Tribe/Events/Importer/File_Importer_Events_BooleanFieldsTest.php +++ b/tests/wpunit/Tribe/Events/Importer/File_Importer_Events_BooleanFieldsTest.php @@ -20,7 +20,7 @@ public function boolean_fields() { } - /** + /**z * @test * it should not mark record as invalid if boolean field is missing * @dataProvider boolean_fields diff --git a/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_EventTest.php b/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_EventTest.php index e86d948479..aaba0d746c 100644 --- a/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_EventTest.php +++ b/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_EventTest.php @@ -190,7 +190,7 @@ public function it_should_return_venue_error_if_trying_to_insert_event_with_inva 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'venue' => 23, + 'venue' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -221,7 +221,7 @@ public function it_should_return_organizer_error_if_trying_to_insert_organizer_w 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'organizer' => 23, + 'organizer' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -415,7 +415,7 @@ public function it_should_return_venue_error_if_trying_to_insert_event_with_inva 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'venue' => 23, + 'venue' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -449,7 +449,7 @@ public function it_should_return_organizer_error_if_trying_to_insert_organizer_w 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'organizer' => 23, + 'organizer' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { diff --git a/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_Event_SlugTest.php b/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_Event_SlugTest.php index e50afc93f3..65a7f74fc9 100644 --- a/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_Event_SlugTest.php +++ b/tests/wpunit/Tribe/Events/REST/V1/Endpoints/Single_Event_SlugTest.php @@ -199,7 +199,7 @@ public function it_should_return_venue_error_if_trying_to_insert_event_with_inva 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'venue' => 23, + 'venue' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -230,7 +230,7 @@ public function it_should_return_organizer_error_if_trying_to_insert_organizer_w 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'organizer' => 23, + 'organizer' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -437,7 +437,7 @@ public function it_should_return_venue_error_if_trying_to_insert_event_with_inva 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'venue' => 23, + 'venue' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { @@ -473,7 +473,7 @@ public function it_should_return_organizer_error_if_trying_to_insert_organizer_w 'description' => 'An event content', 'start_date' => 'tomorrow 9am', 'end_date' => 'tomorrow 11am', - 'organizer' => 23, + 'organizer' => PHP_INT_MAX, ]; foreach ( $params as $key => $value ) { diff --git a/tests/wpunit/Tribe/Events/REST/V1/Validator/BaseTest.php b/tests/wpunit/Tribe/Events/REST/V1/Validator/BaseTest.php index af4a526376..79f3da010f 100644 --- a/tests/wpunit/Tribe/Events/REST/V1/Validator/BaseTest.php +++ b/tests/wpunit/Tribe/Events/REST/V1/Validator/BaseTest.php @@ -9,9 +9,9 @@ class BaseTest extends Events_Testcase { public function linked_post_bad_inputs() { return [ - [ 23 ], + [ PHP_INT_MAX ], [ 'foo' ], - [ '23' ], + [ "{PHP_INT_MAX}" ], [ [ 'website' => 'http://example.com' ] ], ]; } diff --git a/tests/wpunit/Tribe/Events/Validator/BaseTest.php b/tests/wpunit/Tribe/Events/Validator/BaseTest.php index 3d37defc27..215faebe2f 100644 --- a/tests/wpunit/Tribe/Events/Validator/BaseTest.php +++ b/tests/wpunit/Tribe/Events/Validator/BaseTest.php @@ -133,7 +133,7 @@ public function it_should_not_validate_an_empty_organizer_id_as_organizer() { public function it_should_not_validate_a_non_existing_post_id_as_organizer() { $sut = $this->make_instance(); - $this->assertFalse( $sut->is_organizer_id( 23 ) ); + $this->assertFalse( $sut->is_organizer_id( PHP_INT_MAX ) ); } /** @@ -260,7 +260,7 @@ public function test_is_organizer_id_list() { $this->assertTrue( $sut->is_organizer_id_list( implode( ', ', $organizers ) ) ); $this->assertTrue( $sut->is_organizer_id_list( implode( ' , ', $organizers ) ) ); $this->assertTrue( $sut->is_organizer_id_list( implode( ' ,', $organizers ) ) ); - $this->assertFalse( $sut->is_organizer_id_list( implode( ' ,', array_merge( $organizers, [ 23 ] ) ) ) ); + $this->assertFalse( $sut->is_organizer_id_list( implode( ' ,', array_merge( $organizers, [ PHP_INT_MAX ] ) ) ) ); } public function post_id_bad_inputs() { @@ -269,8 +269,8 @@ public function post_id_bad_inputs() { [ null ], [ false ], [ 'foo' ], - [ '23' ], - [ 23 ], + [ "{PHP_INT_MAX}" ], + [ PHP_INT_MAX ], [ 0 ], [ '0' ], ];