*/ final class Ajax { /** * The ID of this plugin. * * @since 2.0.0 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * All ajax events * * @since 2.0.0 * @access private * @var array $events All ajax events. */ private $events; /** * Api class * * @since 2.0.0 * @access private * @var Api $api Api class. */ private $api; /** * Cron class * * @since 2.0.0 * @access private * @var Cron $cron Cron class. */ private $cron; /** * Initialize the class and set its properties. * * @since 2.0.0 * @param string $plugin_name The name of this plugin. */ public function __construct( $plugin_name ) { $this->plugin_name = $plugin_name; $this->api = new Api(); $this->cron = new Cron(); $this->events = array( 'set_custom_var' => 'set_custom_var', 'toggle_feature' => 'toggle_feature', 'get_adstxt' => 'get_adstxt', 'get_adstxt_custom' => 'get_adstxt_custom', 'set_adstxt' => 'set_adstxt', 'check_adstxt' => 'check_adstxt', 'set_presized_div' => 'set_presized_div', 'get_articles_by_keywords' => 'get_articles_by_keywords', 'add_no_pub' => 'add_no_pub', 'remove_no_pub' => 'remove_no_pub', 'check_url_no_pub' => 'check_url_no_pub', 'url_exists' => 'url_exists', 'enabled_debug' => 'enabled_debug', 'toggle_fast_cmp' => 'toggle_fast_cmp', 'options_fast_cmp' => 'options_fast_cmp', 'get_cmp_vendors' => 'get_cmp_vendors', 'login' => 'login', 'logout' => 'logout', 'create_account' => 'create_account', 'create_website' => 'create_website', 'create_organization' => 'create_organization', 'update_currency' => 'update_currency', 'get_logs' => 'get_logs', 'set_badges' => 'set_badges', 'set_auto_update' => 'set_auto_update', 'save_billing_status' => 'save_billing_status', 'update_onboarding_status' => 'update_onboarding_status', 'get_contract_preview' => 'get_contract_preview', 'sign_contract' => 'sign_contract', 'sync_data' => 'sync_data', ); add_filter( 'posts_where', array( $this, 'search_post_title' ), 10, 2 ); } /** * Dispatch ajax request * * @since 2.0.0 * @return void */ public function dispatch() { if ( $this->security_check() !== true ) { return; } $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $action = isset( $_POST['action_actirise'] ) ? sanitize_text_field( wp_unslash( $_POST['action_actirise'] ) ) : null; if ( is_null( $action ) ) { $error = new WP_Error( '404', 'Action empty' ); wp_send_json_error( $error ); } if ( ! array_key_exists( $action, $this->events ) ) { $error = new WP_Error( '404', 'Action not found' ); wp_send_json_error( $error ); } $method = $this->events[ $action ]; if ( ! method_exists( $this, $method ) ) { $error = new WP_Error( '404', 'Method not found' ); wp_send_json_error( $error ); } $this->$method(); } /** * Filter for search post title by LIKE * * @since 2.0.0 * @param string $where * @param \WP_Query $wp_query * @return string */ public function search_post_title( $where, $wp_query ) { /** @var \wpdb $wpdb */ global $wpdb; $title = $wp_query->get( 'search_title' ); if ( $title ) { /** @var string $title_sql */ $title_sql = esc_sql( $wpdb->esc_like( $title ) ); // @phpstan-ignore argument.type $where .= ' AND ' . $wpdb->posts . ".post_title LIKE '%" . $title_sql . "%'"; } return $where; } /** * Save custom var * * @since 2.0.0 * @return void */ private function set_custom_var() { $post_data = $this->get_sanitized_post_data( array( 'customVar' ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } /** @var string $custom_var */ $custom_var = $post_data['customVar']; $json_custom_var = json_decode( stripslashes( $custom_var ) ); if ( ! is_array( $json_custom_var ) ) { $error = new WP_Error( '500', 'Need array' ); wp_send_json_error( $error ); } /** @var array<\stdClass> $json_custom_var */ foreach ( $json_custom_var as $custom ) { Options::update( $custom->name, $custom->value ); // @phpstan-ignore argument.type } wp_send_json( array( 'success' => true, ) ); } /** * Enabled or disabled feature * * @since 2.0.0 * @return void */ private function toggle_feature() { $post_data = $this->get_sanitized_post_data( array( 'feature', 'feature_value' ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } if ( ! in_array( $post_data['feature'], array( 'adstxt', 'presizeddiv' ), true ) ) { $error = new WP_Error( '500', 'Feature not found' ); wp_send_json_error( $error ); } if ( $post_data['feature'] === 'adstxt' ) { $path_ads_txt = ABSPATH . 'ads.txt'; if ( $post_data['feature_value'] === 'true' ) { AdsTxt::update_file(); $this->cron->update_adstxt(); if ( Options::get( 'adstxt-existing', false ) ) { wp_send_json( array( 'success' => false, ) ); } } else { $this->cron->check_adstxt(); } } Logger::add_log_action( 'Feature ' . $post_data['feature'] . ' set to ' . $post_data['feature_value'] ); Options::update( $post_data['feature'] . '-active', filter_var( $post_data['feature_value'], FILTER_VALIDATE_BOOLEAN ) ); wp_send_json( array( 'success' => true, ) ); } /** * Get ads.txt * * @since 2.0.0 * @return void */ private function get_adstxt() { if ( ! Options::get( 'settings-uuid' ) || ! Options::get( 'settings-uuid-type', 'boot' ) ) { $error = new WP_Error( '500', 'Error' ); wp_send_json_error( $error ); } $response = AdsTxt::get_from_api(); if ( false !== $response ) { wp_send_json( array( 'success' => true, 'data' => $response, ) ); } else { Logger::add_log( 'get_adstxt false', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error' ); wp_send_json_error( $error ); } } /** * Get ads.txt custom * * @since 2.0.0 * @return void */ private function get_adstxt_custom() { $adstxt_custom = Options::get( 'adstxt-custom', array() ); wp_send_json( array( 'success' => true, 'data' => ! $adstxt_custom ? array() : $adstxt_custom, ) ); } /** * Set ads.txt * * @since 2.0.0 * @return void */ private function set_adstxt() { $post_data = $this->get_sanitized_post_data( array( 'adsTxtCustom' ) ); if ( in_array( null, $post_data, true ) || empty( $post_data['adsTxtCustom'] ) ) { Helpers::send_error( '500', 'Post empty' ); } Options::update( 'adstxt-custom', $post_data['adsTxtCustom'] ); Logger::add_log_action( 'Ads.txt custom update' ); AdsTxt::update_file(); wp_send_json( array( 'success' => true, ) ); } /** * Check ads.txt lines * * @since 2.7.0 * @return void */ private function check_adstxt() { $post_data = $this->get_sanitized_post_data( array( 'force' ) ); /** @var string $force */ $force = $post_data['force']; $response = AdsTxt::check_from_api( $force ); wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Get settings * * @since 2.0.0 * @return void */ private function set_presized_div() { $post_data = $this->get_sanitized_post_data( array( 'presizedDiv' ) ); /** @var string $presized_div_data */ $presized_div_data = $post_data['presizedDiv']; Logger::add_log_action( 'Presized div ' . wp_json_encode( stripslashes( $presized_div_data ) ) ); if ( in_array( null, $post_data, true ) || empty( $presized_div_data ) ) { Helpers::send_error( '500', 'Post empty' ); } /** @var array $presized_div_post */ $presized_div_post = json_decode( stripslashes( $presized_div_data ) ); $presized_div = array(); foreach ( $presized_div_post as $key => $value ) { $presized_div[] = array( 'slotName' => $value->slotName, 'active' => $value->active, ); } Options::update( 'presizeddiv-selected', $presized_div ); wp_send_json( array( 'success' => true, ) ); } /** * Get page, post, category, tag by keywords * * @since 2.0.0 * @return void */ private function get_articles_by_keywords() { $post_data = $this->get_sanitized_post_data( array( 'keywords' ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } /** @var string $keywords */ $keywords = $post_data['keywords']; $query_page = new \WP_Query( array( 'post_type' => 'any', 'search_title' => $keywords, 'cache_result' => false, 'orderby' => 'post_date', ) ); /** @var array<\WP_Post> $post */ $post = $query_page->posts; $result = array(); foreach ( $post as $page ) { if ( $page->post_type !== 'attachment' ) { $image = get_the_post_thumbnail_url( $page->ID ); if ( has_excerpt( $page ) ) { $page->post_content = wp_strip_all_tags( get_the_excerpt( $page ), true ); } if ( $page->post_type === 'page' ) { $page->post_content = 'article'; } $result[] = array( 'id' => $page->ID, 'guid' => get_permalink( $page->ID ), 'title' => $page->post_title, 'publishedDate' => $page->post_date, 'summary' => substr( $page->post_content, 0, 100 ), 'image' => $image, 'type' => $page->post_type, ); } } $count = count( $result ); $query_terms = get_terms( array( 'taxonomy' => array( 'post_tag', 'category' ), 'name__like' => $keywords, ) ); $result_terms = array(); /** @var array<\WP_Term> $query_terms */ foreach ( $query_terms as &$terms ) { $term_link = get_term_link( $terms ); if ( is_wp_error( $term_link ) ) { continue; } $result_terms[] = array( 'id' => $terms->term_id, 'title' => $terms->name, 'summary' => substr( $terms->description, 0, 100 ), 'type' => $terms->taxonomy, 'url' => $term_link, ); } $count += count( $result_terms ); wp_send_json( array( 'page' => $result, 'taxonomy' => $result_terms, 'count' => $count, 'keywords' => $keywords, 'success' => true, ) ); } /** * Add no pub item * * @since 2.0.0 * @return void */ private function add_no_pub() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'article' => isset( $_POST['article'] ) ? sanitize_text_field( wp_unslash( $_POST['article'] ) ) : null, 'summary' => isset( $_POST['summary'] ) ? sanitize_text_field( wp_unslash( $_POST['summary'] ) ) : null, ); if ( is_null( $post_data['article'] ) || is_null( $post_data['summary'] ) ) { if ( is_null( $post_data['article'] ) ) { Logger::add_log( 'add_no_pub post_data is null for article', 'admin/include/ajax', 'error' ); } if ( is_null( $post_data['summary'] ) ) { Logger::add_log( 'add_no_pub post_data is null for summary', 'admin/include/ajax', 'error' ); } $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } /** @var \stdClass $article */ $article = json_decode( stripslashes( $post_data['article'] ) ); /** @var string $summary */ $summary = stripslashes( $post_data['summary'] ); $article->summary = $summary; /** @var array<\stdClass> $no_pub */ $no_pub = Options::get( 'nopub', array() ); $no_pub[] = $article; foreach ( $no_pub as $key => $value ) { if ( ! isset( $value->url ) ) { unset( $no_pub[ $key ] ); } } Options::update( 'nopub', $no_pub ); wp_send_json( array( 'success' => true, ) ); } /** * Remove no pub item * * @since 2.0.0 * @return void */ private function remove_no_pub() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'id' => isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : null, 'type' => isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : null, ); if ( is_null( $post_data['id'] ) || is_null( $post_data['type'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } /** @var int $id */ $id = intval( $post_data['id'] ); /** @var string $type */ $type = $post_data['type']; /** @var array<\stdClass> $no_pub */ $no_pub = Options::get( 'nopub', array() ); /** @var array $no_pub */ foreach ( $no_pub as $key => $value ) { if ( ! isset( $value->url ) ) { unset( $no_pub[ $key ] ); } } /** @var array $no_pub */ foreach ( $no_pub as $key => $value ) { if ( $value->id === $id && $value->type === $type ) { unset( $no_pub[ $key ] ); } } Options::update( 'nopub', $no_pub ); wp_send_json( array( 'success' => true, ) ); } /** * Check if url is valid and get informations (post, page, tag, category) * * @since 2.0.0 * @return void */ private function check_url_no_pub() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'url' => isset( $_POST['url'] ) ? sanitize_text_field( wp_unslash( $_POST['url'] ) ) : null, ); if ( is_null( $post_data['url'] ) ) { Logger::add_log( 'check_url_no_pub post_data is null for url', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $url = $post_data['url']; $result = new \stdClass(); $post = url_to_postid( $url ); if ( $post !== 0 ) { $post = get_post( $post ); if ( $post !== null ) { $result->id = $post->ID; $result->title = $post->post_title; $result->publishedDate = $post->post_date; $result->summary = $post->post_type === 'page' ? '' : substr( $post->post_content, 0, 100 ); $result->image = get_the_post_thumbnail_url( $post->ID ); $result->type = $post->post_type; } else { Logger::add_log( 'check_url_no_pub post is null for:' . $url, 'admin/include/ajax', 'error' ); } } else { Logger::add_log( 'check_url_no_pub url_to_postid is 0 for:' . $url, 'admin/include/ajax', 'error' ); } $slug = explode( '/', $url ); $slug = array_filter( $slug ); if ( ! empty( $slug ) ) { $slug = end( $slug ); $category = get_term_by( 'slug', $slug, 'category' ); if ( $category !== false ) { /** @var \WP_Term $category */ $result->id = $category->term_id; $result->title = $category->name; $result->publishedDate = ''; $result->summary = $category->description; $result->image = null; $result->type = 'category'; } $tag = get_term_by( 'slug', $slug, 'post_tag' ); if ( $tag !== false ) { /** @var \WP_Term $tag */ $result->id = $tag->term_id; $result->title = $tag->name; $result->publishedDate = ''; $result->summary = $tag->description; $result->image = null; $result->type = 'post_tag'; } } wp_send_json( array( 'success' => true, 'result' => $result, ) ); } /** * Check if url exist * * @since 2.0.0 * @return void */ private function url_exists() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'id' => isset( $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ) : null, 'type' => isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : null, ); if ( is_null( $post_data['id'] ) || is_null( $post_data['type'] ) ) { if ( is_null( $post_data['id'] ) ) { Logger::add_log( 'url_exists post_data is null for id', 'admin/include/ajax', 'error' ); } if ( is_null( $post_data['type'] ) ) { Logger::add_log( 'url_exists post_data is null for type', 'admin/include/ajax', 'error' ); } $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } /** @var int $id */ $id = $post_data['id']; $type = $post_data['type']; $exist = false; if ( $type === 'category' || $type === 'post_tag' ) { $terms = get_term_by( 'ID', $id, $type ); if ( $terms !== false ) { $exist = true; } } else { $post = get_post( $id ); if ( $post !== 0 && $post !== null ) { if ( $post->post_status !== 'trash' ) { $exist = true; } } } wp_send_json( array( 'success' => true, 'exist' => $exist, ) ); } /** * Set debug mode * * @since 2.0.0 * @return void */ private function enabled_debug() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'debug' => isset( $_POST['debug'] ) ? sanitize_text_field( wp_unslash( $_POST['debug'] ) ) : null, ); if ( is_null( $post_data['debug'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $debug = $post_data['debug']; Options::update( 'debug-enabled', $debug ); wp_send_json( array( 'success' => true, ) ); } /** * Toggle fast cmp feature * * @since 2.2.0 * @return void */ private function toggle_fast_cmp() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'enabled' => isset( $_POST['enabled'] ) ? sanitize_text_field( wp_unslash( $_POST['enabled'] ) ) : null, ); if ( is_null( $post_data['enabled'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $fast_cmp_enabled = $post_data['enabled']; Options::update( 'fastcmp-enabled', $fast_cmp_enabled ); Logger::add_log_action( 'Feature CMP set to ' . $fast_cmp_enabled ); Logger::add_log_action( 'Feature CMP set to ' . ( $fast_cmp_enabled ? 'true' : 'false' ) ); wp_send_json( array( 'success' => true, ) ); } /** * Update options for fast cmp * * @since 2.2.0 * @return void */ private function options_fast_cmp() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'options' => isset( $_POST['options'] ) ? sanitize_text_field( wp_unslash( $_POST['options'] ) ) : null, ); if ( is_null( $post_data['options'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } /** @var array $options */ $options = json_decode( $post_data['options'] ); foreach ( $options as $name => $value ) { if ( $name === 'consentV2' ) { Logger::add_log_action( 'Change consent mode V2: ' . ( $value ? 'true' : 'false' ) ); } /** @var string $value */ Options::update( 'fastcmp-' . $name, $value ); } wp_send_json( array( 'success' => true, ) ); } /** * Login to API v2 * * @since 2.3.15 * @return void */ private function login() { $post_data = $this->get_sanitized_post_data( array( 'email', 'password' ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } $response = $this->api->post( 'api', 'authentication_token', $post_data ); $validated_response = $this->validate_api_response( $response, 'Error while login' ); /** @var string $token */ $token = $validated_response['token']; /** @var string $user */ $user = $validated_response['user']; Options::update( 'auth-token', $token ); $user_id = $this->extract_user_id( $user ); $user_role = $this->get_user_role( $user_id, $token ); $currency = $validated_response['currency']; $api_token_response = $this->api->post( 'api', 'api_tokens', array( 'name' => 'wordpress' ), $token ); $api_token = $this->validate_api_response( $api_token_response, 'Error while login api token', false ); $uuid = $this->get_organization_uuid( $token ); $organizations = array(); $organization_managers = array(); if ( $uuid === '' && in_array( $user_role, array( 'organization_manager', 'admin' ), true ) ) { $organizations = $this->get_organizations( $token ); } elseif ( $uuid === '' ) { $organization_managers = $this->get_organization_managers( $token, $user ); } else { Options::update( 'settings-uuid', $uuid, true ); Options::update( 'settings-uuid-type', 'universal', true ); Options::update( 'settings-analytics-token', $api_token['token'], true ); Options::update( 'website-exists', true ); Options::delete( 'auth-token' ); Core::check_website_status(); $this->cron->update_adstxt(); $this->cron->check_presized_div(); if ( ACTIRISE_CRON === 'true' ) { $this->cron->schedule(); } } wp_send_json( array( 'success' => true, 'data' => array( 'auth_token' => $token, 'token' => $api_token['token'], 'uuid' => $uuid, 'userId' => $user_id, 'userRole' => $user_role, 'currency' => $currency, 'managers' => $organization_managers, 'organizations' => $organizations, 'onboardingStatus' => Options::get( 'onboarding-status' ), 'contractType' => Options::get( 'contract-type', 'essential' ), 'contractStatus' => Options::get( 'contract-status' ), 'adsServing' => Options::get( 'ads-serving' ), 'type' => Options::get( 'settings-uuid-type' ), 'presizedDiv' => Options::get( 'presizeddiv-selected', array() ), 'adstxt' => Options::get( 'adstxt-actirise', '' ), 'customv' => array( 'custom1' => Options::get( 'custom1', 'author_ID' ), 'custom2' => Options::get( 'custom2', 'category_0_slug' ), 'custom3' => Options::get( 'custom3', 'post_ID' ), 'custom4' => Options::get( 'custom4', '' ), 'custom5' => Options::get( 'custom5', '' ), ), ), ) ); } /** * Logout from API v2 * * @since 2.0.0 * @return void */ private function logout() { Options::delete( 'settings-analytics-token' ); Options::delete( 'settings-analytics-userid' ); wp_send_json( array( 'success' => true, ) ); } /** * Create new account with organization and website * * @since 2.5.0 * @return void */ private function create_account() { $post_data = $this->get_sanitized_post_data( array( 'firstname', 'lastname', 'email', 'password', 'type', 'companyName', 'jobTitle', 'address', 'zipCode', 'city', 'country', 'website', 'registrationID', ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } /** @var string $organization_type */ $organization_type = $post_data['type']; $company_name = $post_data['companyName'] ? $post_data['companyName'] : $post_data['firstname'] . ' ' . $post_data['lastname']; $organization_type_iri = $this->get_organization_type_iri( $organization_type ); $country_iri = $this->get_country_iri( $post_data['country'] ); $website_domain = wp_parse_url( get_bloginfo( 'url' ) ); if ( is_array( $website_domain ) && isset( $website_domain['host'] ) ) { $website_domain = $website_domain['host']; } $args = array( 'user' => array( 'firstname' => $post_data['firstname'], 'lastname' => $post_data['lastname'], 'email' => $post_data['email'], 'plainPassword' => $post_data['password'], 'currency' => 'USD', ), 'organization' => array( 'name' => $company_name, 'type' => $organization_type_iri, 'address' => $post_data['address'], 'postalCode' => $post_data['zipCode'], 'city' => $post_data['city'], 'country' => $country_iri, 'website' => $post_data['website'] ? $post_data['website'] : get_bloginfo( 'url' ), ), 'websites' => array( array( 'domain' => $website_domain, 'name' => get_bloginfo( 'name' ), ), ), ); if ( $post_data['type'] === 'company' ) { $args['user']['jobTitle'] = $post_data['jobTitle']; $args['organization']['localRegistrationId'] = $post_data['registrationID']; } $response = $this->api->post( 'api', 'wordpress/account', $args ); if ( is_wp_error( $response ) ) { Logger::add_log( 'Error while create account wp_e', 'admin/include/ajax', 'error' ); wp_send_json_error( array( 'response' => $response, 'status' => $response->get_error_code(), ) ); } if ( ! is_array( $response ) ) { Logger::add_log( 'Error while create account not_a', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error while create_account not_a' ); wp_send_json_error( array( $error, $response ) ); } Options::update( 'settings-uuid', $response['organization']['uuid'], true ); Options::update( 'settings-uuid-type', 'universal', true ); Options::update( 'settings-analytics-token', $response['token'], true ); Options::update( 'website-exists', true ); Options::update( 'onboarding-status', 'approval', true ); $this->cron->update_adstxt(); if ( ACTIRISE_CRON === 'true' ) { $this->cron->schedule(); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Create new website * * @since 2.5.0 * @return void */ private function create_website() { $post_data = $this->get_sanitized_post_data( array( 'organization' ) ); if ( $post_data['organization'] === null ) { Helpers::send_error( '500', 'Post empty' ); } $website_domain = wp_parse_url( get_bloginfo( 'url' ) ); if ( is_array( $website_domain ) && isset( $website_domain['host'] ) ) { $website_domain = $website_domain['host']; } $args = array( 'domain' => $website_domain, 'name' => get_bloginfo( 'name' ), 'websiteProduct' => '/v2.0/website_products/3', 'organization' => $post_data['organization'], ); /** @var string $token */ $token = Options::get( 'auth-token', '' ); $response = $this->api->post( 'api', 'websites', $args, $token ); if ( is_wp_error( $response ) ) { Logger::add_log( 'Error while register wp_e', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error while register wp_e' ); wp_send_json_error( array( $error, $response, $args ) ); } if ( ! is_array( $response ) ) { Logger::add_log( 'Error while register not_a', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error while register not_a' ); wp_send_json_error( array( $error, $response ) ); } $api_token_response = $this->api->post( 'api', 'api_tokens', array( 'name' => 'wordpress' ), $token ); $api_token = $this->validate_api_response( $api_token_response, 'Error while login api token', false ); $uuid = $this->get_organization_uuid( $token ); Options::update( 'settings-uuid', $uuid, true ); Options::update( 'settings-uuid-type', 'universal', true ); Options::update( 'settings-analytics-token', $api_token['token'] ); Options::update( 'website-exists', true ); Options::update( 'onboarding-status', 'approval' ); Options::delete( 'auth-token' ); $this->cron->update_adstxt(); if ( ACTIRISE_CRON === 'true' ) { $this->cron->schedule(); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Create new organization * * @since 2.5.0 * @return void */ private function create_organization() { $post_data = $this->get_sanitized_post_data( array( 'name', 'address', 'city', 'country', 'registrationID', 'website', 'zipCode', ) ); if ( in_array( null, $post_data, true ) ) { Helpers::send_error( '500', 'Post empty' ); } $organization_type_iri = $this->get_organization_type_iri( 'company' ); $country_iri = $this->get_country_iri( $post_data['country'] ); /** @var string $token */ $token = Options::get( 'auth-token', '' ); $args = array( 'name' => $post_data['name'], 'type' => $organization_type_iri, 'address' => $post_data['address'], 'city' => $post_data['city'], 'country' => $country_iri, 'localRegistrationId' => $post_data['registrationID'], 'website' => $post_data['website'], 'postalCode' => $post_data['zipCode'], ); $response_organization = $this->api->post( 'api', 'organizations', $args, $token, true ); if ( is_wp_error( $response_organization ) ) { Logger::add_log( 'Error while create_organization wp_e', 'admin/include/ajax', 'error' ); wp_send_json_error( array( 'response' => $response_organization, 'status' => $response_organization->get_error_code(), ) ); } if ( ! is_array( $response_organization ) ) { Logger::add_log( 'Error while create organization not_a', 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error while create organization not_a' ); wp_send_json_error( array( $error, $response_organization ) ); } $website_domain = wp_parse_url( get_bloginfo( 'url' ) ); if ( is_array( $website_domain ) && isset( $website_domain['host'] ) ) { $website_domain = $website_domain['host']; } $args = array( 'domain' => $website_domain, 'name' => get_bloginfo( 'name' ), 'websiteProduct' => '/v2.0/website_products/3', 'organization' => $response_organization['@id'], ); $response = $this->api->post( 'api', 'websites', $args, $token ); $api_token_response = $this->api->post( 'api', 'api_tokens', array( 'name' => 'wordpress' ), $token ); $api_token = $this->validate_api_response( $api_token_response, 'Error while login api token', false ); Options::update( 'settings-uuid', $response_organization['uuid'] ); Options::update( 'settings-uuid-type', 'universal', true ); Options::update( 'settings-analytics-token', $api_token['token'] ); Options::update( 'website-exists', true ); Options::update( 'onboarding-status', 'approval' ); $this->cron->update_adstxt(); if ( ACTIRISE_CRON === 'true' ) { $this->cron->schedule(); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Update currency settings * * @since 2.5.0 * @return void */ private function update_currency() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'currency' => isset( $_POST['currency'] ) ? sanitize_text_field( wp_unslash( $_POST['currency'] ) ) : null, ); if ( $post_data['currency'] === null ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } /** @var string $user_id */ $user_id = Options::get( 'settings-analytics-userid', '' ); /** @var string $token */ $token = Options::get( 'settings-analytics-token', '' ); if ( $user_id !== '' && $token !== '' ) { $response = $this->api->patch( 'api', 'users/' . $user_id, array( 'currency' => $post_data['currency'], ), $token ); if ( is_wp_error( $response ) ) { Logger::add_log( 'Error while updating currency ' . $response->get_error_code(), 'admin/include/ajax', 'error' ); $error = new WP_Error( '500', 'Error while updating currency' ); wp_send_json_error( $error ); } } Options::update( 'currency', $post_data['currency'] ); Logger::add_log_action( 'Currency set to ' . $post_data['currency'] ); wp_send_json( array( 'success' => true, 'data' => $post_data['currency'], ) ); } /** * Get logs * * @since 2.5.0 * @return void */ private function get_logs() { $logs = Logger::get_logs(); $logs_actions = Logger::get_logs_action(); wp_send_json( array( 'success' => true, 'data' => array( 'logs' => $logs, 'logs_action' => $logs_actions, ), ) ); } /** * Update badge settings * * @since 2.6.8 * @return void */ private function set_badges() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'type' => isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : null, 'value' => isset( $_POST['value'] ) ? sanitize_text_field( wp_unslash( $_POST['value'] ) ) : null, ); if ( empty( $post_data['type'] ) || empty( $post_data['value'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $value = json_decode( stripslashes( $post_data['value'] ) ); Options::update( $post_data['type'], $value ); wp_send_json( array( 'success' => true, ) ); } /** * Set auto update settings * * @since 2.6.5 * @return void */ private function set_auto_update() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'autoUpdate' => isset( $_POST['autoUpdate'] ) ? sanitize_text_field( wp_unslash( $_POST['autoUpdate'] ) ) : null, ); if ( is_null( $post_data['autoUpdate'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $this->cron->set_auto_update( $post_data['autoUpdate'] === 'true' ); Logger::add_log_action( 'Auto update set to ' . $post_data['autoUpdate'] ); wp_send_json( array( 'success' => true, ) ); } /** * Update onboarding status * * @since 2.5.0 * @return void */ private function update_onboarding_status() { $post_data = $this->get_sanitized_post_data( array( 'status' ) ); if ( $post_data['status'] === null ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $statuses = array( 'premium_io', 'ads', 'cmp', 'activation', 'congrats', ); $status_index = array_search( $post_data['status'], $statuses, true ); if ( $status_index === false || $status_index === count( $statuses ) - 1 ) { $error = new WP_Error( '400', 'Invalid or final status' ); wp_send_json_error( $error ); } $next_status = $statuses[$status_index + 1]; $trial_end_date = null; if ( $next_status === 'ads' ) { $this->cron->update_adstxt(); } if ( $post_data['status'] === 'activation' ) { Options::update( 'activation-time', time() ); $website = Helpers::get_website_info(); if ( $website['adsServing'] === false ) { /** @var string $token */ $token = Options::get( 'settings-analytics-token', '' ); $response_config = $this->api->post( 'api', 'wordpress/default_configs', array( 'website' => $website['@id'] ), $token ); if ( is_wp_error( $response_config ) ) { Logger::add_log( 'update_onboarding_status default_configs error', 'admin/include/ajax', 'error' ); Helpers::send_error( '500', 'Error while activating Actirise' ); return; } } if ( isset( $website['trialEndDate'] ) ) { $trial_end_date = $website['trialEndDate']; } } Options::update( 'onboarding-status', $next_status ); wp_send_json( array( 'success' => true, 'status' => $next_status, 'trialEndDate' => $trial_end_date, ) ); } /** * Get contract preview * * @since 2.7.0 * @return void */ private function get_contract_preview() { $website = Helpers::get_website_info(); /** @var string $website_id */ $website_id = $website['@id']; $endpoint = str_replace( '/v2.0/', '', $website_id ) . '/contract'; /** @var string $token */ $token = Options::get( 'settings-analytics-token', '' ); $response = $this->api->get( 'api', $endpoint, array(), $token ); if ( is_wp_error( $response ) ) { Helpers::send_error( '500', 'Error while get_contract_preview' ); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Sign contract * * @since 2.7.0 * @return void */ private function sign_contract() { $website = Helpers::get_website_info(); /** @var string $token */ $token = Options::get( 'settings-analytics-token', '' ); $response = $this->api->post( 'api', 'websites_contracts_signed', array( 'websites' => array( $website['@id'] ) ), $token ); if ( is_wp_error( $response ) ) { Helpers::send_error( '500', 'Error while signing contract' ); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Get mandatory vendors for CMP * * @since 2.7.0 * @return void */ private function get_cmp_vendors() { /** @var string $token */ $token = Options::get( 'settings-analytics-token', '' ); $response = $this->api->get( 'api', 'cmp_vendors', array(), $token ); if ( is_wp_error( $response ) || ! is_array( $response ) ) { Helpers::send_error( '500', 'Error while get_cmp_vendors' ); } wp_send_json( array( 'success' => true, 'data' => $response, ) ); } /** * Save platform billing status * * @since 2.7.0 * @return void */ private function save_billing_status() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'billingStatus' => isset( $_POST['billingStatus'] ) ? sanitize_text_field( wp_unslash( $_POST['billingStatus'] ) ) : null, ); if ( $post_data['billingStatus'] === null ) { $error = new WP_Error( '500', 'Billing status is null' ); wp_send_json_error( $error ); } $billing_status = $post_data['billingStatus']; Options::update( 'billing-status', $billing_status ); wp_send_json( array( 'success' => true, ) ); } /** * Sync data * * @since 2.6.8 * @return void */ private function sync_data() { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $post_data = array( 'feature' => isset( $_POST['feature'] ) ? sanitize_text_field( wp_unslash( $_POST['feature'] ) ) : null, ); if ( is_null( $post_data['feature'] ) ) { $error = new WP_Error( '500', 'Post empty' ); wp_send_json_error( $error ); } $response = null; if ( $post_data['feature'] === 'adstxt' ) { $this->cron->update_adstxt(); $response = AdsTxt::get_adstxt(); } if ( $post_data['feature'] === 'presized_div' ) { $this->cron->check_presized_div(); $response = Options::get( 'presizeddiv-selected', array() ); } if ( $post_data['feature'] === 'fastcmp' ) { $this->cron->get_fast_cmp(); $response = Options::get( 'fastcmp-vendors', array() ); } wp_send_json( array( $response, ) ); } /** * Security check for ajax request * * @since 2.4.0 * @return bool */ private function security_check() { if ( false === check_ajax_referer( $this->plugin_name . '-settings', 'nonce', true ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } if ( ! current_user_can( 'manage_options' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } return true; } /** * Get sanitized post data for every requests * * @since 2.7.0 * @param array $keys * @return array */ private function get_sanitized_post_data( $keys ) { $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, 'actirise-settings' ) ) { $error = new WP_Error( '403', 'Security check is not valid' ); wp_send_json_error( $error ); } $data = array(); foreach ( $keys as $key ) { $data[$key] = isset( $_POST[$key] ) ? sanitize_text_field( wp_unslash( $_POST[$key] ) ) : null; } return $data; } /** * Validate api response on auth routes * * @since 2.7.0 * @param mixed $response * @param string $error_message * @param bool $return_error * @return array */ private function validate_api_response( $response, $error_message, $return_error = true ) { $is_error = is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['token'] ); if ( $is_error && $return_error === true ) { Helpers::send_error( '500', $error_message ); } elseif ( $is_error && $return_error === false ) { $response = array( 'token' => '' ); } if ( is_array( $response ) ) { return $response; } return array(); } /** * Get organization uuid if website exists * * @since 2.7.0 * @param string $token * @return string */ private function get_organization_uuid( $token ) { $response = $this->api->get( 'api', 'organizations', array( 'websites.domain' => rawurlencode( Helpers::get_server_details()['host'] ), 'itemsPerPage' => 1, 'page' => 1, ), $token ); if ( is_wp_error( $response ) || ! is_array( $response ) || empty( $response ) ) { return ''; } if ( isset( $response[0]['uuid'] ) && is_string( $response[0]['uuid'] ) ) { return $response[0]['uuid']; } return ''; } /** * Get organization IRI * * @since 2.7.0 * @param string $type * @return string */ private function get_organization_type_iri( $type ) { $organization_type_iri = ''; $response = $this->api->get( 'api', 'organization_types', array(), false, true ); if ( is_wp_error( $response ) || ! is_array( $response ) || ! is_array( $response['hydra:member'] ) ) { Helpers::send_error( '500', 'Error while get organization_types' ); } if ( is_array( $response ) && is_array( $response['hydra:member'] ) ) { foreach ( $response['hydra:member'] as $organization_type ) { if ( is_array( $organization_type ) && is_string( $organization_type['value'] ) && strtolower( $organization_type['value'] ) === $type ) { if ( is_string( $organization_type['@id'] ) ) { $organization_type_iri = $organization_type['@id']; } } } } return $organization_type_iri; } /** * Get country IRI * * @since 2.7.0 * @param mixed $country_code * @return string */ private function get_country_iri( $country_code ) { $country_iri = ''; $response = $this->api->get( 'api', 'countries', array( 'code' => $country_code ), false, true ); if ( is_wp_error( $response ) || ! is_array( $response ) || ! is_array( $response['hydra:member'] ) ) { Helpers::send_error( '500', 'Error while get_country_iri' ); } if ( is_array( $response ) && is_array( $response['hydra:member'] ) ) { foreach ( $response['hydra:member'] as $country ) { if ( is_array( $country ) && $country['code'] === $country_code ) { if ( is_string( $country['@id'] ) ) { $country_iri = $country['@id']; } } } } return $country_iri; } /** * Get user role * * @since 2.7.0 * @param string $token * @param string $user_id * @return string */ private function get_user_role( $user_id, $token ) { $user_role = 'user'; $response_user = $this->api->get( 'api', 'users/' . $user_id, array(), $token ); if ( is_array( $response_user ) && ! empty( $response_user['userGroups'][0]['role']['name'] && is_string( $response_user['userGroups'][0]['role']['name'] ) ) ) { $user_role = $response_user['userGroups'][0]['role']['name']; } return $user_role; } /** * Fetches organizations * * @since 2.7.0 * @param string $token * @return array> */ private function get_organizations( $token ) { $response = $this->api->get( 'api', 'organizations', array(), $token, true ); if ( ! is_array( $response ) || empty( $response['hydra:member'] ) ) { return array(); } if ( is_array( $response['hydra:member'] ) ) { return array_map( function ( $org ) { return array( 'name' => $org['name'], 'value' => $org['@id'], ); }, $response['hydra:member'] ); } return array(); } /** * Fetches organization managers * * @since 2.7.0 * @param string $token * @param string $user_iri * @return array */ private function get_organization_managers( $token, $user_iri ) { $response = $this->api->get( 'api', 'users', array( 'roles' => 'organization_manager' ), $token, true ); if ( ! is_array( $response ) || empty( $response['hydra:member'] ) ) { return array(); } if ( is_array( $response['hydra:member'] ) ) { $filtered_managers = array_filter( $response['hydra:member'], function ( $manager ) use ( $user_iri ) { return isset( $manager['@id'] ) && $manager['@id'] !== $user_iri; } ); return array_map( function ( $manager ) { return $manager['firstName'] . ' ' . $manager['lastName']; }, $filtered_managers ); } return array(); } /** * Extract user id from iri * * @since 2.7.0 * @param string $user_iri * @return string */ private function extract_user_id( $user_iri ) { $user_parts = explode( '/', $user_iri ); return end( $user_parts ); } }