452 lines
15 KiB
PHP
452 lines
15 KiB
PHP
<?php
|
|
|
|
namespace Vrts\Features;
|
|
|
|
use Vrts\Core\Utilities\Sanitization;
|
|
use Vrts\Core\Utilities\Url_Helpers;
|
|
use Vrts\Features\Subscription;
|
|
use Vrts\Services\Test_Service;
|
|
|
|
class Settings_Page {
|
|
/**
|
|
* Page slug.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $page_slug = 'vrts-settings';
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'init', [ $this, 'add_settings' ] );
|
|
add_action( 'admin_menu', [ $this, 'add_submenu_page' ] );
|
|
add_action( 'admin_init', [ $this, 'settings_migration' ] );
|
|
add_action( 'add_option_vrts_click_selectors', [ $this, 'do_after_update_click_selectors' ], 10, 2 );
|
|
add_action( 'update_option_vrts_click_selectors', [ $this, 'do_after_update_click_selectors' ], 10, 2 );
|
|
add_action( 'pre_update_option_vrts_license_key', [ $this, 'do_before_add_license_key' ], 10, 2 );
|
|
add_action( 'pre_update_option_vrts_email_update_notification_address', [ $this, 'do_before_updating_email_address' ], 10 );
|
|
add_action( 'pre_update_option_vrts_email_api_notification_address', [ $this, 'do_before_updating_email_address' ], 10 );
|
|
add_action( 'update_option_vrts_automatic_comparison', [ $this, 'do_after_update_vrts_automatic_comparison' ], 10, 2 );
|
|
}
|
|
|
|
/**
|
|
* Add submenu.
|
|
*/
|
|
public function add_submenu_page() {
|
|
$submenu_page = add_submenu_page(
|
|
'vrts',
|
|
esc_html__( 'Settings', 'visual-regression-tests' ),
|
|
esc_html__( 'Settings', 'visual-regression-tests' ),
|
|
'manage_options',
|
|
$this->page_slug,
|
|
[ $this, 'render_page' ]
|
|
);
|
|
|
|
add_action( 'load-' . $submenu_page, [ $this, 'init_notifications' ] );
|
|
}
|
|
|
|
/**
|
|
* Render settings page.
|
|
*/
|
|
public function render_page() {
|
|
vrts()->component( 'settings-page', [
|
|
'title' => esc_html__( 'Settings', 'visual-regression-tests' ),
|
|
'settings_fields' => $this->page_slug,
|
|
'settings_sections' => $this->page_slug,
|
|
] );
|
|
}
|
|
|
|
/**
|
|
* Register settings.
|
|
*/
|
|
public function add_settings() {
|
|
$has_subscription = (bool) Subscription::get_subscription_status();
|
|
|
|
vrts()->settings()->add_section([
|
|
'id' => 'vrts-settings-section-general',
|
|
'page' => $this->page_slug,
|
|
'title' => '',
|
|
]);
|
|
|
|
// Notice:
|
|
// value_type can be one of these 'string', 'boolean', 'integer', 'number', 'array', and 'object'.
|
|
// sanitize_callback can be a default wp sanitize function or a custom function from the Sanitization class.
|
|
// 'sanitize_callback' => '[ Sanitization::class, 'sanitize_checkbox' ]'.
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'text',
|
|
'id' => 'vrts_click_selectors',
|
|
'section' => 'vrts-settings-section-general',
|
|
'title' => esc_html__( 'Click Element', 'visual-regression-tests' ),
|
|
'description' => sprintf(
|
|
'%s<br>%s',
|
|
sprintf(
|
|
/* translators: %s: link wrapper. */
|
|
esc_html__( 'Add a %1$sCSS selector%2$s to click on the first element found before creating a new snapshot.', 'visual-regression-tests' ),
|
|
'<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors" target="_blank">',
|
|
'</a>'
|
|
),
|
|
esc_html__( 'Useful to accept cookie banners or anything else that should be clicked after page load.', 'visual-regression-tests' )
|
|
),
|
|
'placeholder' => esc_html__( 'e.g.: #accept-cookies', 'visual-regression-tests' ),
|
|
'sanitize_callback' => 'sanitize_text_field',
|
|
'show_in_rest' => true,
|
|
'value_type' => 'string',
|
|
'default' => '',
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'text',
|
|
'id' => 'vrts_license_key',
|
|
'section' => 'vrts-settings-section-general',
|
|
'title' => esc_html__( 'License Key', 'visual-regression-tests' ),
|
|
'description' => sprintf(
|
|
'%1$s <a href="%2$s" title="%3$s">%3$s</a>',
|
|
esc_html__( 'No license key yet?', 'visual-regression-tests' ),
|
|
esc_url( Url_Helpers::get_page_url( 'upgrade' ) ),
|
|
esc_html__( 'Upgrade here.', 'visual-regression-tests' )
|
|
),
|
|
'placeholder' => esc_html_x( 'XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX', 'license key placeholder', 'visual-regression-tests' ),
|
|
'sanitize_callback' => 'sanitize_text_field',
|
|
'show_in_rest' => true,
|
|
'value_type' => 'string',
|
|
'value' => ! empty( vrts()->settings()->get_option( 'vrts_license_key', false ) ) ? 'XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX' : '',
|
|
'default' => '',
|
|
]);
|
|
|
|
vrts()->settings()->add_section([
|
|
'id' => 'vrts-settings-section-triggers',
|
|
'page' => $this->page_slug,
|
|
'title' => esc_html__( 'Triggers', 'visual-regression-tests' ) . '<span>' . esc_html__( 'When your Tests are run.', 'visual-regression-tests' ) . '</span>',
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'checkbox',
|
|
'id' => 'vrts_automatic_comparison',
|
|
'section' => 'vrts-settings-section-triggers',
|
|
'title' => esc_html__( 'Schedule', 'visual-regression-tests' ),
|
|
'label' => esc_html__( 'Run Tests every 24 hours.', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_checkbox' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'boolean',
|
|
'value' => 1,
|
|
'default' => 1,
|
|
'disabled' => 1,
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'checkbox',
|
|
'id' => 'vrts_updates_comparison',
|
|
'section' => 'vrts-settings-section-triggers',
|
|
'title' => esc_html__( 'Update', 'visual-regression-tests' ),
|
|
'label' => esc_html__( 'Run Tests after WordPress and plugin updates.', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_checkbox' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'boolean',
|
|
'value' => $has_subscription,
|
|
'default' => $has_subscription,
|
|
'disabled' => $has_subscription,
|
|
'readonly' => ! $has_subscription,
|
|
'is_pro' => $has_subscription,
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'checkbox',
|
|
'id' => 'vrts_api_comparison',
|
|
'section' => 'vrts-settings-section-triggers',
|
|
'title' => esc_html__( 'API', 'visual-regression-tests' ),
|
|
'label' => sprintf(
|
|
/* translators: %1$s, %2$s: link wrapper. */
|
|
wp_kses_post( __( 'Run Tests with your favorite apps. %1$sRead the docs%2$s.', 'visual-regression-tests' ) ),
|
|
'<a href="' . esc_url( 'https://vrts.app/docs/' ) . '" target="_blank">',
|
|
'</a>'
|
|
),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_checkbox' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'boolean',
|
|
'value' => $has_subscription,
|
|
'default' => $has_subscription,
|
|
'disabled' => $has_subscription,
|
|
'readonly' => ! $has_subscription,
|
|
'is_pro' => $has_subscription,
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'checkbox',
|
|
'id' => 'vrts_manual_comparison',
|
|
'section' => 'vrts-settings-section-triggers',
|
|
'title' => esc_html__( 'Manual', 'visual-regression-tests' ),
|
|
'label' => esc_html__( 'Run Tests on demand.', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_checkbox' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'boolean',
|
|
'value' => $has_subscription,
|
|
'default' => $has_subscription,
|
|
'disabled' => $has_subscription,
|
|
'readonly' => ! $has_subscription,
|
|
'is_pro' => $has_subscription,
|
|
]);
|
|
|
|
vrts()->settings()->add_section([
|
|
'id' => 'vrts-settings-section-notifications',
|
|
'page' => $this->page_slug,
|
|
'title' => esc_html__( 'Notifications', 'visual-regression-tests' ) . '<span>' . esc_html__( 'Notify team members based on specific Trigger events.', 'visual-regression-tests' ) . '</span>',
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'text',
|
|
'id' => 'vrts_email_notification_address',
|
|
'section' => 'vrts-settings-section-notifications',
|
|
'title' => esc_html__( 'Schedule', 'visual-regression-tests' ),
|
|
'description' => esc_html__( 'Separate multiple email addresses with commas. Or leave blank to disable notifications.', 'visual-regression-tests' ),
|
|
'placeholder' => esc_html__( 'Email address(es)', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_multiple_emails' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'string',
|
|
'default' => get_bloginfo( 'admin_email' ),
|
|
'return_value_callback' => [ $this, 'get_sanitized_emails' ],
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'text',
|
|
'id' => 'vrts_email_update_notification_address',
|
|
'section' => 'vrts-settings-section-notifications',
|
|
'title' => esc_html__( 'Update', 'visual-regression-tests' ),
|
|
'placeholder' => esc_html__( 'Email address(es)', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_multiple_emails' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'string',
|
|
'default' => '',
|
|
'readonly' => ! $has_subscription,
|
|
'is_pro' => $has_subscription,
|
|
'return_value_callback' => [ $this, 'get_sanitized_emails' ],
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'text',
|
|
'id' => 'vrts_email_api_notification_address',
|
|
'section' => 'vrts-settings-section-notifications',
|
|
'title' => esc_html__( 'API', 'visual-regression-tests' ),
|
|
'placeholder' => esc_html__( 'Email address(es)', 'visual-regression-tests' ),
|
|
'sanitize_callback' => [ Sanitization::class, 'sanitize_multiple_emails' ],
|
|
'show_in_rest' => true,
|
|
'value_type' => 'string',
|
|
'default' => '',
|
|
'readonly' => ! $has_subscription,
|
|
'is_pro' => $has_subscription,
|
|
'return_value_callback' => [ $this, 'get_sanitized_emails' ],
|
|
]);
|
|
|
|
vrts()->settings()->add_setting([
|
|
'type' => 'info',
|
|
'id' => 'vrts_email_manual_notification_address',
|
|
'section' => 'vrts-settings-section-notifications',
|
|
'title' => esc_html__( 'Manual', 'visual-regression-tests' ),
|
|
'description' => esc_html__( 'Alerts are automatically sent to the user who triggers the Manual Test.', 'visual-regression-tests' ),
|
|
'is_pro' => $has_subscription,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Settings migration.
|
|
*/
|
|
public function settings_migration() {
|
|
$has_subscription = (bool) Subscription::get_subscription_status();
|
|
$old_cc_email = get_option( 'vrts_email_notification_cc_address' );
|
|
$update_email = get_option( 'vrts_email_update_notification_address' );
|
|
$api_email = get_option( 'vrts_email_api_notification_address' );
|
|
|
|
if ( $old_cc_email ) {
|
|
$old_cc_email = $this->get_sanitized_emails( $old_cc_email );
|
|
$schedule_email = vrts()->settings()->get_option( 'vrts_email_notification_address' );
|
|
$schedule_email = array_unique( array_merge( $schedule_email, $old_cc_email ) );
|
|
$schedule_email = implode( ', ', $schedule_email );
|
|
update_option( 'vrts_email_notification_address', $schedule_email );
|
|
delete_option( 'vrts_email_notification_cc_address' );
|
|
}
|
|
|
|
if ( $has_subscription ) {
|
|
$schedule_email = vrts()->settings()->get_option( 'vrts_email_notification_address', false );
|
|
|
|
if ( false === $update_email ) {
|
|
update_option( 'vrts_email_update_notification_address', $schedule_email );
|
|
}
|
|
|
|
if ( false === $api_email ) {
|
|
update_option( 'vrts_email_api_notification_address', $schedule_email );
|
|
}
|
|
|
|
if ( get_option( 'vrts_license_success' ) ) {
|
|
update_option( 'vrts_email_update_notification_address', $schedule_email );
|
|
update_option( 'vrts_email_api_notification_address', $schedule_email );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update global click selector settings for project in service
|
|
*
|
|
* @param string $old Old value.
|
|
* @param string $new_value New value.
|
|
*/
|
|
public function do_after_update_click_selectors( $old, $new_value ) {
|
|
if ( $old !== $new_value ) {
|
|
$service_project_id = get_option( 'vrts_project_id' );
|
|
$service_api_route = 'sites/' . $service_project_id;
|
|
|
|
$parameters = [
|
|
'screenshot_options' => [
|
|
'clickSelectors' => $new_value,
|
|
],
|
|
];
|
|
|
|
$response = Service::rest_service_request( $service_api_route, $parameters, 'put' );
|
|
|
|
$service = new Test_Service();
|
|
$service->resume_tests();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register the Gumroad API key with the service.
|
|
*
|
|
* @param mixed $new_value new value.
|
|
* @param mixed $old old value.
|
|
*/
|
|
public function do_before_add_license_key( $new_value, $old ) {
|
|
// If license key is empty but was previously added.
|
|
if ( ! $new_value && $old ) {
|
|
self::remove_license_key();
|
|
update_option( 'vrts_license_failed', true );
|
|
return '';
|
|
}
|
|
|
|
if ( 'XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX' === $new_value ) {
|
|
return $old;
|
|
}
|
|
|
|
if ( $old !== $new_value ) {
|
|
|
|
$service_project_id = get_option( 'vrts_project_id' );
|
|
$service_api_route = 'sites/' . $service_project_id . '/register';
|
|
|
|
$parameters = [
|
|
'license_key' => $new_value,
|
|
];
|
|
|
|
$response = Service::rest_service_request( $service_api_route, $parameters, 'post' );
|
|
$status_code = $response['status_code'];
|
|
Subscription::get_latest_status();
|
|
|
|
if ( 200 !== $status_code ) {
|
|
// If new key is not valid, remove the old one.
|
|
self::remove_license_key();
|
|
update_option( 'vrts_license_failed', true );
|
|
return '';
|
|
}
|
|
|
|
update_option( 'vrts_license_success', true );
|
|
return $new_value;
|
|
}//end if
|
|
|
|
return $old;
|
|
}
|
|
|
|
/**
|
|
* Prevent updating email address if there is no subscription
|
|
*
|
|
* @param string $value New value.
|
|
*/
|
|
public function do_before_updating_email_address( $value ) {
|
|
$has_subscription = (bool) Subscription::get_subscription_status();
|
|
return $has_subscription ? $value : '';
|
|
}
|
|
|
|
/**
|
|
* Update automatic comparison settings for project in service
|
|
*
|
|
* @param string $old Old value.
|
|
* @param string $new_value New value.
|
|
*/
|
|
public function do_after_update_vrts_automatic_comparison( $old, $new_value ) {
|
|
if ( $old !== $new_value ) {
|
|
$service_project_id = get_option( 'vrts_project_id' );
|
|
$service_api_route = 'sites/' . $service_project_id;
|
|
|
|
$parameters = [
|
|
'automatic_comparison' => empty( $new_value ) ? false : true,
|
|
];
|
|
|
|
$response = Service::rest_service_request( $service_api_route, $parameters, 'put' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove license key from the service
|
|
*/
|
|
public static function remove_license_key() {
|
|
$service_project_id = get_option( 'vrts_project_id' );
|
|
$service_api_route = 'sites/' . $service_project_id . '/unregister';
|
|
|
|
$response = Service::rest_service_request( $service_api_route, [], 'post' );
|
|
|
|
Subscription::get_latest_status();
|
|
}
|
|
|
|
/**
|
|
* Init notifications.
|
|
*/
|
|
public function init_notifications() {
|
|
if ( true === (bool) get_option( 'vrts_license_success' ) ) {
|
|
add_action( 'admin_notices', [ $this, 'render_notification_license_added' ] );
|
|
delete_option( 'vrts_license_success' );
|
|
} elseif ( true === (bool) get_option( 'vrts_license_failed' ) ) {
|
|
add_action( 'admin_notices', [ $this, 'render_notification_license_not_added' ] );
|
|
delete_option( 'vrts_license_failed' );
|
|
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It's OK.
|
|
} elseif ( isset( $_GET['settings-updated'] ) && true === (bool) $_GET['settings-updated'] ) {
|
|
add_action( 'admin_notices', [ $this, 'render_notification_settings_saved' ] );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render Settings saved notification.
|
|
*/
|
|
public function render_notification_settings_saved() {
|
|
Admin_Notices::render_notification( 'settings_saved', false );
|
|
}
|
|
|
|
/**
|
|
* Render License added notification.
|
|
*/
|
|
public function render_notification_license_added() {
|
|
Admin_Notices::render_notification( 'license_added', false );
|
|
}
|
|
|
|
/**
|
|
* Render License adding failed notification.
|
|
*/
|
|
public function render_notification_license_not_added() {
|
|
Admin_Notices::render_notification( 'license_not_added', false );
|
|
}
|
|
|
|
/**
|
|
* Render License adding removed notification.
|
|
*/
|
|
public function render_notification_license_removed() {
|
|
Admin_Notices::render_notification( 'license_removed', false );
|
|
}
|
|
|
|
/**
|
|
* Sanitize multiple emails.
|
|
*
|
|
* @param string $emails The emails.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_sanitized_emails( $emails ) {
|
|
return array_filter( array_map( 'sanitize_email', explode( ',', $emails ) ) );
|
|
}
|
|
}
|