170 lines
4.9 KiB
PHP
170 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace Vrts\Services;
|
|
|
|
use Vrts\Features\Service;
|
|
use Vrts\Features\Subscription;
|
|
use Vrts\Models\Test;
|
|
use Vrts\Models\Test_Run;
|
|
use Vrts\Services\Email_Service;
|
|
|
|
class Test_Run_Service {
|
|
|
|
/**
|
|
* Create test from API data.
|
|
*
|
|
* @param array $data Data.
|
|
* @param bool $with_cleanup With cleanup.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function update_run_from_api_data( $data, $with_cleanup = true ) {
|
|
$run_id = $data['run_id'];
|
|
|
|
if ( empty( $run_id ) ) {
|
|
return false;
|
|
}
|
|
|
|
$test_run = Test_Run::get_by_service_test_run_id( $run_id );
|
|
|
|
$test_run_just_finished = false;
|
|
|
|
if ( $test_run && empty( $test_run->finished_at ) && ! empty( $data['finished_at'] ) ) {
|
|
$test_run_just_finished = true;
|
|
$alert_ids = $this->update_tests_and_create_alerts( $data['comparisons'], $test_run );
|
|
}
|
|
|
|
$test_ids = empty( $data['comparison_schedule_ids'] ) ? [] : array_map(function ( $test ) {
|
|
return [
|
|
'id' => $test->id,
|
|
'post_id' => $test->post_id,
|
|
'post_title' => get_the_title( $test->post_id ),
|
|
'permalink' => get_permalink( $test->post_id ),
|
|
];
|
|
}, Test::get_by_service_test_ids( $data['comparison_schedule_ids'] ));
|
|
|
|
$test_run_id = $this->create_test_run( $data['run_id'], [
|
|
'tests' => maybe_serialize( $test_ids ),
|
|
'started_at' => $data['started_at'],
|
|
'finished_at' => $data['finished_at'],
|
|
'scheduled_at' => $data['scheduled_at'],
|
|
'trigger' => $data['trigger'],
|
|
'trigger_notes' => $data['trigger_notes'],
|
|
'trigger_meta' => maybe_serialize( $data['trigger_meta'] ),
|
|
], true, $with_cleanup );
|
|
|
|
if ( $test_run_just_finished && ! empty( $alert_ids ) ) {
|
|
$email_service = new Email_Service();
|
|
$email_service->send_test_run_email( $test_run_id );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update tests and create alerts.
|
|
*
|
|
* @param array $comparisons Comparisons.
|
|
* @param object $test_run Test run.
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function update_tests_and_create_alerts( $comparisons, $test_run ) {
|
|
$alert_ids = [];
|
|
|
|
foreach ( $comparisons as $comparison ) {
|
|
$test_id = $comparison['comparison_schedule_id'];
|
|
$alert_id = null;
|
|
|
|
if ( $comparison['pixels_diff'] > 1 && ! $comparison['matches_false_positive'] ) {
|
|
$post_id = Test::get_post_id_by_service_test_id( $test_id );
|
|
$alert_service = new Alert_Service();
|
|
$alert_id = $alert_service->create_alert_from_comparison( $post_id, $test_id, $comparison, $test_run );
|
|
$alert_ids[] = $alert_id;
|
|
}//end if
|
|
|
|
$test_service = new Test_Service();
|
|
$test_service->update_test_from_comparison( $alert_id, $test_id, [
|
|
'comparison' => $comparison,
|
|
] );
|
|
}
|
|
return $alert_ids;
|
|
}
|
|
|
|
/**
|
|
* Create test run.
|
|
*
|
|
* @param string $service_test_run_id Service test run id.
|
|
* @param array $data Data.
|
|
* @param bool $update Update.
|
|
* @param bool $with_cleanup With cleanup.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function create_test_run( $service_test_run_id, $data, $update = false, $with_cleanup = true ) {
|
|
$test_run = Test_Run::get_by_service_test_run_id( $service_test_run_id );
|
|
|
|
if ( $test_run && ! $update ) {
|
|
return false;
|
|
}
|
|
$test_run_id = Test_Run::save(array_merge( $data, [
|
|
'service_test_run_id' => $service_test_run_id,
|
|
]), $test_run->id ?? null);
|
|
if ( $with_cleanup ) {
|
|
Test_Run::delete_duplicates();
|
|
Test_Run::delete_empty();
|
|
$this->check_stalled_test_runs();
|
|
}
|
|
return $test_run_id;
|
|
}
|
|
|
|
/**
|
|
* Check stalled test runs.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function check_stalled_test_runs() {
|
|
$test_run_ids = array_column( Test_Run::get_stalled_test_run_ids(), 'service_test_run_id' );
|
|
if ( empty( $test_run_ids ) ) {
|
|
return;
|
|
}
|
|
$response = Service::fetch_test_runs( $test_run_ids );
|
|
if ( 200 === $response['status_code'] ) {
|
|
$test_runs = $response['response']['data'] ?? [];
|
|
foreach ( $test_runs as $test_run ) {
|
|
$this->update_run_from_api_data( $test_run, false );
|
|
}
|
|
$missing_test_run_ids = array_diff( $test_run_ids, array_column( $test_runs, 'run_id' ) );
|
|
foreach ( $missing_test_run_ids as $missing_test_run_id ) {
|
|
Test_Run::delete_by_service_test_run_id( $missing_test_run_id );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch and update tests.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function fetch_and_update_test_runs() {
|
|
$service_request = Service::fetch_updates();
|
|
if ( 200 === $service_request['status_code'] ) {
|
|
$response = $service_request['response'];
|
|
if ( array_key_exists( 'run_updates', $response ) ) {
|
|
$updates = $response['run_updates'];
|
|
foreach ( $updates as $update ) {
|
|
$this->update_run_from_api_data( $update, false );
|
|
}
|
|
}
|
|
if (
|
|
array_key_exists( 'remaining_credits', $response )
|
|
&& array_key_exists( 'total_credits', $response )
|
|
&& array_key_exists( 'has_subscription', $response )
|
|
&& array_key_exists( 'tier_id', $response )
|
|
) {
|
|
Subscription::update_available_tests( $response['remaining_credits'], $response['total_credits'], $response['has_subscription'], $response['tier_id'] );
|
|
}
|
|
}
|
|
}
|
|
}
|