File: //proc/self/cwd/wp-content/plugins/cornerstone/includes/classes/Services/Validation.php
<?php
namespace Themeco\Cornerstone\Services;
use DomainException;
use Themeco\Cornerstone\Util\AdminAjax;
use function Cornerstone\TGMA\cs_install_plugin;
use function Cornerstone\TGMA\cs_plugin_activate;
use function Cornerstone\TGMA\cs_plugin_deactivate;
use function Cornerstone\TGMA\cs_plugin_installed;
class Validation implements Service {
private $ajaxValidation;
private $ajaxRevoke;
private $ajaxRefresh;
private $ajaxInstall;
private $ajaxActivate;
public $code;
private $routes;
public function __construct(
AdminAjax $ajaxValidation,
AdminAjax $ajaxRevoke,
AdminAjax $ajaxRefresh,
AdminAjax $ajaxInstall,
AdminAjax $ajaxActivate,
Routes $routes
) {
$this->ajaxValidation = $ajaxValidation;
$this->ajaxRevoke = $ajaxRevoke;
$this->ajaxRefresh = $ajaxRefresh;
$this->ajaxInstall = $ajaxInstall;
$this->ajaxActivate = $ajaxActivate;
$this->routes = $routes;
}
public function setup() {
if ( ! is_admin() && cs_is_rest_request()) return;
$this->ajaxValidation->setAction( 'validation' )->setHandler( [ $this, 'ajaxValidationHandler'] )->start();
$this->ajaxRevoke->setAction( 'validation_revoke' )->setHandler( [ $this, 'ajaxRevokeHandler'] )->start();
$this->ajaxRefresh->setAction( 'validation_refresh' )->setHandler( [ $this, 'ajaxRefresh'] )->start();
add_action( 'admin_enqueue_scripts', array( $this, 'add_script_data' ), -100 );
$this->ajaxInstall->setAction( 'extensions_install' )->setHandler( [ $this, 'ajax_tgmpa_install_plugin'] )->start();
$this->ajaxActivate->setAction( 'extensions_activate' )->setHandler( [ $this, 'ajax_activate_plugin'] )->start();
// Extension AJAX
$this->routes->add_route('post', 'extensions_install', [$this, 'installPlugin']);
$this->routes->add_route('post', 'extensions_deactivate', [$this, 'deactivatePlugin']);
// Validation
$this->routes->add_route('post', 'validation', [$this, 'validationHandler']);
$this->routes->add_route('post', 'validation-revoke', [$this, 'validationRevoke']);
$this->routes->add_route('post', 'validation-refresh', [$this, 'ajaxRefresh']);
// This one is unused currrently
//$this->ajaxValidation->setAction( 'extensions_deactivate' )->setHandler( [ $this, 'ajax_deactivate_plugin'] )->start();
}
// @TODO remove
public function add_script_data() {
cornerstone( 'Admin' )->add_script_data( 'cs-validation', array( $this, 'script_data' ) );
cornerstone( 'Admin' )->add_script_data( 'cs-validation-revoke', array( $this, 'script_data_revoke' ) );
cornerstone( 'Admin' )->add_script_data( 'x-extension', [ $this, 'extensions_data' ] );
}
public function script_data() {
return array(
'verifying' => csi18n('admin.validation-verifying'),
'error' => csi18n('admin.validation-couldnt-verify'),
'notices' => array(
'validation-complete' => csi18n('admin.validation-congrats'),
),
'errorButton' => csi18n('admin.validation-go-back'),
);
}
public function script_data_revoke() {
return array(
'confirm' => csi18n('admin.validation-revoke-confirm'),
'accept' => csi18n('admin.validation-revoke-accept'),
'decline' => csi18n('admin.validation-revoke-decline'),
'revoking' => csi18n('admin.validation-revoking'),
'notices' => array(
'validation-revoked' => sprintf( csi18n('admin.validation-revoked'), 'https://theme.co/account/dashboard/' )
)
);
}
/**
* For extension installing
*/
public function extensions_data() {
return [
'maxPlugins' => array_values(apply_filters("cs_max_get_plugins", [])),
'pluginsURI' => admin_url( 'plugins.php' ),
'error' => __( 'Error encountered.', '__x__' ),
'activate' => __( 'Activate', '__x__' ),
'activated' => __( 'Installed & Activated', '__x__' ),
'errorBack' => __( 'Go Back', '__x__' ),
'installing' => __( 'Installing…', '__x__' ),
'activating' => __('Activating…', '__x__' ),
'waiting-to-install' => __( 'Waiting to install…', '__x__' ),
'waiting-to-activate' => __( 'Waiting to activate…', '__x__' ),
];
}
// @TODO remove
public function ajaxValidationHandler() {
if ( ! current_user_can( 'manage_options' ) || ! isset( $_POST['code'] ) || ! $_POST['code'] ) {
wp_send_json_error( array( 'message' => 'No purchase code specified.' ) );
return;
}
$this->code = sanitize_text_field( $_POST['code'] );
$validator = tco_common()->validator( $this->code, 'cornerstone' );
$validator->run();
if ( $validator->has_connection_error() ) {
wp_send_json_error( array( 'message' => $validator->connection_error_details() ) );
return;
}
$response = $this->get_validation_response( $validator );
if ( isset( $response['complete'] ) && $response['complete'] ) {
$this->update_validation( $this->code );
} else {
$this->update_validation( false );
}
wp_send_json_success( $response );
}
public function validationHandler($params) {
$this->assertCanManageOptions();
// Check code
$code = cs_get_array_value($params, 'license_key', '');
if (empty($code)) {
throw new DomainException(__('No purchase code specified', 'cornerstone'));
}
// Validate code
$this->code = sanitize_text_field( $code );
$validationType = defined('X_SLUG')
? X_SLUG
: 'cornerstone';
$validator = tco_common()->validator( $this->code, $validationType );
$validator->run();
if ( $validator->has_connection_error() ) {
wp_send_json_error( array( 'message' => $validator->connection_error_details() ) );
return;
}
$response = $this->get_validation_response( $validator );
if ( isset( $response['complete'] ) && $response['complete'] ) {
$this->update_validation( $this->code );
} else {
$this->update_validation( false );
$message = strip_tags($response['message']);
// html_entity_decode wasn't working for some reason
// got fed up
$message = str_replace(''', '\'', $message);
//$message = html_entity_decode($message);
throw new DomainException($message);
}
wp_send_json_success( $response );
}
private function getThemecoDomain() {
return !defined("THEMECO_DOMAIN")
? "https://theme.co"
: \THEMECO_DOMAIN;
}
public function get_validation_response( $validator ) {
$domain = $this->getThemecoDomain();
// Purchase code is not valid
if ( ! $validator->is_valid() ) {
return array(
'message' => csi18n('admin.validation-msg-invalid'),
'button' => csi18n('admin.validation-go-back'),
'dismiss' => true,
);
}
// Valid, but the purchase code isn't associated with an account.
if ( ! $validator->is_verified() ) {
return array(
'message' => csi18n('admin.validation-msg-new-code'),
'button' => csi18n('admin.validation-login'),
'url' => add_query_arg( $this->out_params(), $domain . '/docs/product-validation/' )
);
}
// Purchase code linked to an account, but doesn't have a site
if ( ! $validator->has_site() ) {
return array(
'message' => csi18n('admin.validation-msg-cant-link'),
'button' => csi18n('admin.validation-manage-licenses'),
'url' => $domain . '/account/dashboard/',
'dismiss' => true,
'newTab' => true
);
}
// Purchase code linked, and site exists, but doesn't match this site.
if ( ! $validator->site_match() ) {
return array(
'message' => csi18n('admin.validation-msg-in-use'),
'button' => csi18n('admin.validation-manage-licenses'),
'url' => $domain . '/account/dashboard/',
'dismiss' => true,
'newTab' => true
);
}
return array(
'complete' => true,
'message' => csi18n('admin.validation-congrats')
);
}
public function out_params() {
return array(
'code' => $this->code,
'product' => 'cornerstone',
'siteurl' => tco_common()->get_site_url(),
'return-url' => esc_url( admin_url( 'admin.php?page=cornerstone-home' ) )
);
}
public function assertCanManageOptions() {
if (!current_user_can('manage_options')) {
throw new DomainException('Cannot manage options on this account');
}
}
public function validationRevoke($params = []) {
$this->assertCanManageOptions();
$this->update_validation( false );
wp_send_json_success();
exit;
}
// @TODO remove
public function ajaxRevokeHandler() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error();
return;
}
$this->update_validation( false );
wp_send_json_success();
}
public function update_validation( $code ) {
// Since we use pre_option in framework cornerstone
// it was easier to manually update and delete if X is installed
// All this code is also used in standalone
$isX = defined('X_VERSION');
if ( $code ) {
update_option( 'cs_product_validation_key', $code );
if ($isX) {
update_option( 'x_product_validation_key', $code );
}
} else {
delete_option( 'cs_product_validation_key' );
if ($isX) {
delete_option( 'x_product_validation_key' );
}
}
// Pass api key to args
add_filter( 'themeco_update_api', function($args) use ($code) {
$args['api-key'] = $code;
return $args;
});
if (!$code) {
delete_site_option('x_extension_list');
}
tco_common()->updates()->refresh();
}
public function preload_key() {
$key = '';
if ( isset( $_REQUEST['tco-key'] ) ) {
$key = esc_html( $_REQUEST['tco-key'] );
}
return $key;
}
/**
* Refresh packages and max
*/
public function ajaxRefresh() {
add_filter( 'themeco_update_api', function($args) {
$args['api-key'] = get_option("cs_product_validation_key", "");
return $args;
});
tco_common()->updates()->refresh(true);
wp_send_json_success([]);
}
/**
* Description overlay for plugins
*/
public function preview_overlay( $box_class ) {
$no = tco_common()->admin_icon( 'no' );
$how = _e( 'How do I unlock this feature?', '__x__' );
$howToUnlock = printf( __('overview', 'how-do-i-unlock' ), 'data-tco-focus="validation-input"');
echo <<<HTML
<div class="tco-overlay tco-overlay-box-content">
<a class="tco-overlay-close" href="#" data-tco-toggle="{$box_class} .tco-overlay">{$no}</a>
<h4 class="tco-box-content-title">{$how}</h4>
<p>{$howToUnlock}</p>
</div>
HTML;
}
/**
* Install and activate plugin AJAX
*/
public function installPlugin($params) {
do_action('cs_dashboard_extension_before_install');
$this->assertPluginSlug($params);
// Check if installed and install if not
if (!cs_plugin_installed($params['slug'])) {
// Install
$install = cs_install_plugin($params['slug']);
if ( is_wp_error( $install ) ) {
throw new DomainException($install->get_error_message());
}
}
// Activate
$activate = cs_plugin_activate($params['slug']);
if ( is_wp_error( $activate ) ) {
throw new DomainException($activate->get_error_message());
}
return [ 'success' => true ];
}
/**
* Deactivate plugin AJAX
*/
public function deactivatePlugin($params) {
do_action('cs_dashboard_extension_before_deactivate');
$this->assertPluginSlug($params);
$deactivate = cs_plugin_deactivate($params['slug']);
if ( is_wp_error( $deactivate ) ) {
throw new DomainException($deactivate->get_error_message());
}
return [ 'success' => true ];
}
private function assertPluginSlug($params) {
if (!current_user_can( 'activate_plugins' )) {
throw new DomainException('Current user cannot activate or deactivate plugins');
}
if (empty($params['slug'])) {
throw new DomainException('Plugin slug is not valid');
}
}
/**
* Install plugin
*/
public function ajax_tgmpa_install_plugin() {
$plugin = isset( $_POST['slug'] ) ? $_POST['slug'] : null;
do_action("cs_tgma_install_plugin", $plugin);
}
/**
* Activate plugin
*/
public function ajax_activate_plugin() {
if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) || ! $_POST['plugin'] ) {
wp_send_json_error( array( 'message' => 'No plugin specified' ) );
return;
}
do_action("cs_tgma_activate_plugin", $_POST['plugin']);
}
/**
* Deactivate plugin
* not used currently
*/
public function ajax_deactivate_plugin() {
if ( ! current_user_can( 'activate_plugins' ) || ! isset( $_POST['plugin'] ) || ! $_POST['plugin'] ) {
wp_send_json_error( array( 'message' => 'No plugin specified' ) );
}
// @TODO
//wp_send_json_error( array( 'message' => 'No plugin specified' ) );
//$deactivate = \deactivate_plugin( $_POST['plugin'] );;
//if ( is_wp_error( $deactivate ) ) {
//wp_send_json_error( array( 'message' => $deactivate->get_error_message() ) );
//}
//wp_send_json_success( array( 'plugin' => $_POST['plugin'] ) );
}
}