setup(); $instance->hooks(); $instance->includes(); } return $instance; } function setup() { $this->dir = trailingslashit( plugin_dir_path( AISEEFILE ) ); $this->uri = trailingslashit( plugin_dir_url( AISEEFILE ) ); } function includes() { } function hooks() { add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) ); // add metaboxes add_action( 'admin_enqueue_scripts', array( $this, 'plugin_styles' ) ); // enqueue plugin styles but only on the specific screen add_action( 'wp_ajax_aisee_tag_cloud', array( $this, 'aisee_tag_cloud' ) ); // respond to ajax add_action( 'wp_ajax_nopriv_aisee_tag_cloud', '__return_false' ); // do not respont to ajax add_action( 'admin_init', array( $this, 'save_gsc_profile' ) ); add_action( 'wp_ajax_aisee_register', array( $this, 'aisee_register' ) ); // respond to ajax add_action( 'wp_ajax_nopriv_aisee_register', '__return_false' ); // do not respont to ajax add_action( 'wp_ajax_aisee_gsc_fetch', array( $this, 'aisee_gsc_fetch' ) ); // respond to ajax add_action( 'wp_ajax_nopriv_aisee_gsc_fetch', '__return_false' ); // do not respont to ajax add_action( 'wp_ajax_aisee_get_connect_link', array( $this, 'get_connect_link' ) ); // respond to ajax add_action( 'wp_ajax_nopriv_get_connect_link', '__return_false' ); // do not respont to ajax } function save_gsc_profile() { $aisee_action = isset( $_REQUEST['aisee-action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['aisee-action'] ) ) : ''; if ( 'oauth' === $aisee_action ) { $origin_nonce = isset( $_REQUEST['origin_nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['origin_nonce'] ) ) : ''; wp_verify_nonce( $origin_nonce, 'aisee_gscapi' ); $success = isset( $_REQUEST['success'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['success'] ) ) : ''; if ( current_user_can( 'activate_plugins' ) && '1' === $success ) { $aisee_reg = get_option( 'aiseeseo' ); if ( $aisee_reg ) { $aisee_reg['gsc'] = true; update_option( 'aiseeseo', $aisee_reg ); } } $post_id = isset( $_REQUEST['post'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['post'] ) ) : 0; $edit_link = $post_id ? get_edit_post_link( $post_id ) : ''; if ( $edit_link ) { wp_safe_redirect( html_entity_decode( $edit_link ), 302 ); exit; } } $revoke_action = isset( $_REQUEST['aisee-action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['aisee-action'] ) ) : ''; $revoke_success = isset( $_REQUEST['success'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['success'] ) ) : ''; if ( 'revoke' === $revoke_action && '1' === $revoke_success ) { $aisee_reg = get_option( 'aiseeseo' ); if ( $aisee_reg && ! empty( $aisee_reg['gsc'] ) ) { unset( $aisee_reg['gsc'] ); update_option( 'aiseeseo', $aisee_reg ); } } } function plugin_styles() { $screen = get_current_screen(); if ( in_array( $screen->post_type, get_post_types( array( 'public' => true ) ) ) ) { $css_path = $this->dir . 'assets/admin-styles.css'; $version = file_exists( $css_path ) ? (string) filemtime( $css_path ) : false; wp_enqueue_style( 'aisee-stylesheet', $this->uri . 'assets/admin-styles.css', array(), $version ); } } function stop_words() { return apply_filters( 'aisee_stop_words', array( 'I', 'I\'d', 'I\'ll', 'I\'m', 'I\'ve', 'a', 'about', 'above', 'after', 'again', 'against', 'all', 'am', 'an', 'and', 'any', 'are', 'aren\'t', 'as', 'at', 'be', 'because', 'been', 'before', 'being', 'below', 'between', 'both', 'but', 'by', 'can', 'can\'t', 'cannot', 'com', 'could', 'couldn\'t', 'did', 'didn\'t', 'do', 'does', 'doesn\'t', 'doing', 'don\'t', 'down', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'hadn\'t', 'has', 'hasn\'t', 'have', 'haven\'t', 'having', 'he', 'he\'d', 'he\'ll', 'he\'s', 'her', 'here', 'here\'s', 'hers', 'herself', 'him', 'himself', 'his', 'how', 'how\'s', 'i', 'i\'d', 'i\'ll', 'i\'m', 'i\'ve', 'if', 'in', 'into', 'is', 'isn\'t', 'it', 'it\'s', 'its', 'itself', 'let\'s', 'me', 'more', 'most', 'mustn\'t', 'my', 'myself', 'net', 'no', 'nor', 'not', 'of', 'off', 'on', 'once', 'only', 'or', 'org', 'other', 'ought', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'same', 'shan\'t', 'she', 'she\'d', 'she\'ll', 'she\'s', 'should', 'shouldn\'t', 'so', 'some', 'such', 'than', 'that', 'that\'s', 'the', 'their', 'theirs', 'them', 'themselves', 'then', 'there', 'there\'s', 'these', 'they', 'they\'d', 'they\'ll', 'they\'re', 'they\'ve', 'this', 'those', 'through', 'to', 'too', 'use', 'add', 'jan', 'feb', 'mar', 'apr', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec', 'under', 'until', 'up', 'very', 'was', 'wasn\'t', 'we', 'we\'d', 'we\'ll', 'we\'re', 'we\'ve', 'were', 'weren\'t', 'what', 'what\'s', 'when', 'when\'s', 'where', 'where\'s', 'which', 'while', 'who', 'who\'s', 'whom', 'why', 'why\'s', 'with', 'will', 'won\'t', 'would', 'wouldn\'t', 'www', 'you', 'you\'d', 'you\'ll', 'you\'re', 'you\'ve', 'your', 'yours', 'yourself', 'yourselves', 'http', 'https', 'io', 'get' ) ); } function add_meta_boxes() { foreach ( get_post_types( array( 'public' => true ) ) as $post_type ) { add_meta_box( 'aisee-gsc', __( 'AiSee Insights from Google™ Search Console', 'aisee-seo' ), array( $this, 'aisee_gsc_mb' ), $post_type, 'normal', 'high' ); add_meta_box( 'aisee-tag', __( 'AiSee Tag Cloud', 'aisee-seo' ), array( $this, 'aisee_tag_cloud_mb' ), $post_type, 'normal', 'high' ); } } function get_status() { return false; } function aisee_gsc_mb() { global $post; ?>
get_connectable_account() ) { ?>

Let's start setting up your AISee account to get search insights from Google™ Search Console.

Worry not, it's free and just takes a click!

is_connected() ) { echo '

'; echo 'Connect with Google™ Search Console'; echo '

'; } else { // we are set $meta = get_post_meta( $post->ID, '_aisee_keywords', true ); $html = ''; if ( $meta ) { $html = $this->generate_html( $meta ); } $keywords_div = '
' . $html . '

'; $allowed = array( 'div' => array( 'id' => array(), 'class' => array(), ), 'p' => array( 'id' => array(), 'class' => array(), ), 'table' => array( 'id' => array(), 'class' => array(), ), 'thead' => array( 'id' => array(), 'class' => array(), ), 'tbody' => array( 'id' => array(), 'class' => array(), ), 'tfoot' => array( 'id' => array(), 'class' => array(), ), 'tr' => array( 'id' => array(), 'class' => array(), ), 'th' => array( 'id' => array(), 'class' => array(), ), 'td' => array( 'id' => array(), 'class' => array(), ), ); echo wp_kses( $keywords_div, $allowed ); echo 'Fetch Data from Google™ Search Console'; echo '

'; ?> get_oauth_link( $id, 'aisee_gsc_fetch' ); $url = add_query_arg( 'cb', time(), $url ); $url = add_query_arg( 'status', $this->get_status(), $url ); $meta = get_post_meta( $id, '_aisee_keywords', true ); if ( $meta ) { if ( ( time() - strtotime( $meta['time'] ) ) >= ( 86400 * 15 ) ) { $meta = false; } } if ( ! $meta ) { $args = array( 'httpversion' => '1.1', 'compress' => true, 'headers' => array( 'aisee-gsc-fetch' => true, ), ); $response = wp_safe_remote_request( $url, $args ); if ( is_wp_error( $response ) ) { wp_send_json_error( $response->get_error_message() ); } $status_code = wp_remote_retrieve_response_code( $response ); if ( 200 != $status_code ) { wp_send_json_error( 'Failed to fetch response from AISee service. Error Code: ' . $status_code ); } $response = wp_remote_retrieve_body( $response ); if ( empty( $response ) || is_null( $response ) ) { wp_send_json_error( 'Empty server respose.' ); } $response = json_decode( $response, true ); if ( is_null( $response ) ) { // NULL if the json cannot be decoded / data is deeper than recursion limit. OR no data exists wp_send_json_error( 'Invalid server response.' ); } if ( isset( $response['success'] ) && $response['success'] == true ) { if ( ! empty( $response['data'] ) ) { $meta = array( 'time' => time(), 'keywords' => $response['data'], ); update_post_meta( $id, '_aisee_keywords', $meta ); $html = $this->generate_html( $meta ); wp_send_json_success( $html ); } else { wp_send_json_success( 'No keywords yet.' ); } } if ( isset( $data['success'] ) && $data['success'] != true ) { if ( isset( $data['data'] ) ) { wp_send_json_error( sanitize_text_field( $response['data'] ) ); } else { wp_send_json_error( 'Unknown error occurred on the server.' ); } } } else { $html = $this->generate_html( $meta ); wp_send_json_success( $html ); } } function generate_html( $meta ) { $html = ''; $keywords = ! empty( $meta['keywords'] ) ? $meta['keywords'] : false; if ( ! $keywords ) { return; } if ( count( $keywords ) ) { foreach ( $keywords as $key => $value ) { $html .= '' . $value['keys'] . '' . $value['clicks'] . '' . round( ( 100 * $value['ctr'] ), 2 ) . '%' . $value['impressions'] . '' . round( $value['position'], 2 ) . ''; } $html = '' . $html . '
Keyword PhraseClicksCTRImpressionsPosition
'; } else { $html = '
Keyword PhraseClicksCTRImpressionsPosition
No keywords found
'; } if ( ! empty( $meta['time'] ) ) { $fetched = wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), (int) $meta['time'] ); if ( $fetched ) { $html = '

Fetched On ' . $fetched . '.

' . $html . '

The data is refreshed every 15 days.

'; } } $html = wp_kses( $html, array( 'p' => array( 'id' => array(), 'class' => array(), ), 'table' => array( 'id' => array(), 'class' => array(), ), 'thead' => array( 'id' => array(), 'class' => array(), ), 'tbody' => array( 'id' => array(), 'class' => array(), ), 'tr' => array( 'id' => array(), 'class' => array(), ), 'th' => array( 'id' => array(), 'class' => array(), ), 'td' => array( 'id' => array(), 'class' => array(), ), 'tfoot' => array( 'id' => array(), 'class' => array(), ), ) ); return $html; } function is_connected() { return $this->get_setting( 'gsc' ); } function get_oauth_link( $id, $action = false ) { $statevars = array( 'site_url' => trailingslashit( get_site_url() ), 'return_url' => get_edit_post_link( $id ), 'permalink' => get_permalink( $id ), 'origin_nonce' => wp_create_nonce( 'aisee_gscapi' ), 'origin_ajaxurl' => admin_url( 'admin-ajax.php' ), ); $account = $this->get_connectable_account(); if ( ! $account ) { return; } $statevars = $this->encode( array_merge( $account, $statevars ) ); $auth = add_query_arg( $action, $statevars, AISEEAPIEPSL ); $auth = add_query_arg( 'aisee_action', $action, $auth ); return $auth; switch ( $action ) { case 'aisee_gsc_authenticate': return 'Connect with Google™ Search Console'; case 'aisee_gsc_fetch': return 'Fetch Data From Google™ Search Console'; } } function get_connect_link() { check_ajax_referer( 'get_connect_link', 'get_connect_link_nonce' ); $id = ! empty( $_REQUEST['post_id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['post_id'] ) ) : false; if ( ! $id ) { wp_send_json_error( 'Invalid post ID' ); } $account = $this->get_connectable_account(); if ( ! $account ) { wp_send_json_error( 'Account not setup' ); } $auth = $this->get_oauth_link( $id, 'aisee_gsc_authenticate' ); wp_send_json_success( 'Connect with Google™ Search Console' ); } function aisee_register() { check_ajax_referer( 'aisee_register', 'aisee_register_nonce' ); if ( empty( $_REQUEST['user'] ) ) { wp_send_json_error( 'Invalid details' ); } $firstname = ! empty( $_REQUEST['user']['fn'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['user']['fn'] ) ) : ''; $lastname = ! empty( $_REQUEST['user']['ln'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['user']['ln'] ) ) : ''; $useremail = ! empty( $_REQUEST['user']['email'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['user']['email'] ) ) : ''; if ( empty( $useremail ) ) { wp_send_json_error( 'Email missing' ); } if ( ! filter_var( $useremail, FILTER_VALIDATE_EMAIL ) ) { wp_send_json_error( 'Invalid email' ); } $args = array( 'user' => array( 'fn' => $firstname, 'ln' => $lastname, 'email' => $useremail, ), 'diag' => array( 'site_url' => trailingslashit( site_url() ), 'wp' => $wp_version, 'plugin_version' => $this->plugin_data['Version'], 'cachebust' => microtime(), ), ); $args = $this->encode( $args ); $url = add_query_arg( 'aisee_action', 'aisee_register', add_query_arg( 'p', '9', add_query_arg( 'reg_details', $args, AISEEAPIEPSL ) ) ); $response = wp_safe_remote_request( $url ); if ( is_wp_error( $response ) ) { wp_send_json_error( $response->get_error_message() ); } $status_code = wp_remote_retrieve_response_code( $response ); if ( 200 != $status_code ) { wp_send_json_error( 'Failed to fetch response from AISee service. Error Code: ' . $status_code ); } $response = wp_remote_retrieve_body( $response ); if ( empty( $response ) || is_null( $response ) ) { wp_send_json_error( 'No response from AISee Server. Registration Failed.' ); } $response = json_decode( $response, true ); if ( is_null( $response ) ) { wp_send_json_error( 'Invalid server response.' ); } if ( isset( $response['success'] ) && $response['success'] == true ) { if ( ! empty( $response['data']['ID'] ) && ! empty( $response['data']['user_email'] ) ) { update_option( 'aiseeseo', $response['data'] ); // response['data] needs validation wp_send_json_success( $this->get_oauth_link( isset( $_REQUEST['postid'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['postid'] ) ) : 0, 'aisee_gsc_authenticate' ) ); } else { wp_send_json_error( 'Invalid server response.' ); } } if ( isset( $data['success'] ) && $data['success'] != true ) { if ( isset( $data['data'] ) ) { wp_send_json_error( sanitize_text_field( $response['data'] ) ); } else { wp_send_json_error( 'Unknown error occurred on the server.' ); } } } function aisee_tag_cloud_mb() { ?>


Increase this to see a smaller tag cloud; decreasing results in a larger tag cloud

'; echo 'Generate Tag Cloud'; echo '

'; ?> get_error_message() ); } $status_code = wp_remote_retrieve_response_code( $response ); if ( 200 != $status_code ) { wp_send_json_error( 'Failed to fetch post content: ' . $status_code ); } $keywords = wp_remote_retrieve_body( $response ); if ( ! $keywords ) { wp_send_json_error( 'Encountered empty content.' ); } $keywords = sanitize_text_field( $keywords ); $stop = $this->stop_words(); $dom = new DOMDocument(); $dom->loadHTML( $keywords ); $_scripts = $dom->getElementsByTagName( 'script' ); $scripts = array(); foreach ( $_scripts as $script ) { $scripts[] = $script; } foreach ( $scripts as $script ) { $script->parentNode->removeChild( $script ); } $_styles = $dom->getElementsByTagName( 'style' ); $styles = array(); foreach ( $_styles as $style ) { $styles[] = $style; } foreach ( $styles as $style ) { $style->parentNode->removeChild( $style ); } $keywords = $dom->saveHTML(); $pattern = '/(&[a-zA-Z]+);/'; $keywords = preg_replace( $pattern, ' ', $keywords ); $keywords = urldecode( $keywords ); $keywords = strtolower( wp_strip_all_tags( $keywords ) ); $keywords = preg_replace( '/[^a-z0-9]/', ' ', $keywords ); $keywords = preg_replace( '/\s+/', ' ', $keywords ); $keywords = explode( ' ', $keywords ); $keywords = array_diff( $keywords, $stop ); $tags = array_count_values( $keywords ); $tags = array_filter( $tags, function ( $v, $k ) use( $trimlen ) { $k = preg_replace( '/\b\d+\b/', '', $k ); if ( $v == 1 ) { // remove words that occur only once; they have no weight return false; } if ( strlen( trim( $k ) ) && strlen( trim( $k ) ) < $trimlen ) { return false; } return ! empty( trim( $k ) ); }, ARRAY_FILTER_USE_BOTH ); arsort( $tags ); $newtags = array(); $avg = ( max( $tags ) + min( $tags ) ) / 2; $avg = $avg / 1.618; // fine-tune the scaling here foreach ( $tags as $key => $value ) { if ( ( $drop_percentage ) > ( ( $value * 100 ) / count( $tags ) ) ) { continue; } $newtags[] = '' . $key . ''; } for ( $i = 0; $i <= 49; $i++ ) { shuffle( $newtags ); } // arsort( $newtags ); $newtags = implode( ' ', $newtags ); // Turn the array into a plain string. Only contains aplha-numeric chars. wp_send_json_success( wp_kses( $newtags, array( 'span' => array( 'style' => array(), 'class' => array(), ), ) ) ); } function get_setting( $setting ) { $defaults = $this->defaults(); $settings = wp_parse_args( get_option( 'aiseeseo', $defaults ), $defaults ); return isset( $settings[ $setting ] ) ? $settings[ $setting ] : false; } function defaults() { // $defaults = array( // 'connection' => '', // ); $defaults = array(); return $defaults; } function sanitize( $settings ) { return $settings; } function get_connectable_account() { return get_option( 'aiseeseo' ); } function encode( $data ) { $data = strtr( base64_encode( json_encode( $data ) ), '+/=', '-_,' ); return $data; } function decode( $data ) { return json_decode( base64_decode( strtr( $data, '-_,', '+/=' ) ), true ); } /** * Developer-only debug helper. print_r is intentional here; output is escaped via esc_html(). * * @param mixed $str Value to dump. */ function llog( $str ) { echo '
';
		echo esc_html( print_r( $str, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r -- intentional debug helper; output escaped.
		echo '
'; } } function aisee() { return AISee::get_instance(); } // Let's roll! aisee();