File "class-keywords.php"
Full Path: /home/diablzlo/glucosebalnce.com/wp-content/plugins/seo-by-rank-math-pro/includes/modules/analytics/class-keywords.php
File size: 23.68 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* The Analytics Module
*
* @since 2.0.0
* @package RankMathPro
* @subpackage RankMathPro\modules
* @author Rank Math <support@rankmath.com>
*/
namespace RankMathPro\Analytics;
use WP_REST_Request;
use RankMath\Traits\Cache;
use RankMath\Traits\Hooker;
use RankMath\Analytics\Stats;
use RankMath\Helper;
use RankMath\Helpers\Param;
use RankMath\Helpers\DB as DB_Helper;
defined( 'ABSPATH' ) || exit;
/**
* Keywords class.
*/
class Keywords {
use Hooker;
use Cache;
/**
* Main instance
*
* Ensure only one instance is loaded or can be loaded.
*
* @return Keywords
*/
public static function get() {
static $instance;
if ( is_null( $instance ) && ! ( $instance instanceof Keywords ) ) {
$instance = new Keywords();
$instance->setup();
}
return $instance;
}
/**
* Initialize filter.
*/
public function setup() {
$this->filter( 'rank_math/analytics/keywords', 'add_keyword_position_graph' );
$this->filter( 'rank_math/analytics/keywords_overview', 'add_winning_losing_data' );
$this->action( 'save_post', 'add_post_focus_keyword' );
$this->action( 'init', 'get_post_type_list', 99 );
}
/**
* Get accessible post type lists to auto add the focus keywords.
*/
public function get_post_type_list() {
if ( 'rank-math-analytics' !== Param::get( 'page' ) ) {
return;
}
$post_types = array_map(
function ( $post_type ) {
return 'attachment' === $post_type ? false : Helper::get_post_type_label( $post_type );
},
Helper::get_accessible_post_types()
);
Helper::add_json( 'postTypes', array_filter( $post_types ) );
Helper::add_json( 'autoAddFK', Helper::get_settings( 'general.auto_add_focus_keywords', [] ) );
}
/**
* Get keywords position data to show it in the graph.
*
* @param array $rows Rows.
* @return array
*/
public function add_keyword_position_graph( $rows ) {
$history = $this->get_graph_data_for_keywords( \array_keys( $rows ) );
$rows = Stats::get()->set_query_position( $rows, $history );
return $rows;
}
/**
* Get winning and losing keywords data.
*
* @param array $data Data.
* @return array
*/
public function add_winning_losing_data( $data ) {
$data['winningKeywords'] = $this->get_winning_keywords();
$data['losingKeywords'] = $this->get_losing_keywords();
if ( empty( $data['winningKeywords'] ) ) {
$data['winningKeywords']['response'] = 'No Data';
}
if ( empty( $data['losingKeywords'] ) ) {
$data['losingKeywords']['response'] = 'No Data';
}
return $data;
}
/**
* Extract keywords that can be added by removing the empty and the duplicate keywords.
*
* @param string $keywords Comma Separated Keyword List.
*
* @return array Keywords that can be added.
*/
public function extract_addable_track_keyword( $keywords ) {
global $wpdb;
// Split keywords.
$keywords_to_add = array_filter( array_map( 'trim', explode( ',', $keywords ) ) );
$keywords_to_check = array_filter( array_map( 'mb_strtolower', explode( ',', $keywords ) ) );
// Check if keywords already exists.
$keywords_joined = "'" . join( "', '", array_map( 'esc_sql', $keywords_to_add ) ) . "'";
$data = DB_Helper::get_results( "SELECT keyword FROM {$wpdb->prefix}rank_math_analytics_keyword_manager as km WHERE km.keyword IN ( $keywords_joined )" );
// Filter out non-existing keywords.
foreach ( $data as $row ) {
$key = array_search( mb_strtolower( $row->keyword ), $keywords_to_check, true );
if ( false !== $key ) {
unset( $keywords_to_add[ $key ] );
}
}
return $keywords_to_add;
}
/**
* Add keyword to Rank Tracker.
*
* @param array $keywords Keyword List.
*/
public function add_track_keyword( $keywords ) {
foreach ( $keywords as $add_keyword ) {
DB::keywords()->insert(
[
'keyword' => $add_keyword,
'collection' => 'uncategorized',
'is_active' => true,
],
[ '%s', '%s', '%d' ]
);
}
delete_transient( Stats::get()->get_cache_key( 'tracked_keywords_summary', Stats::get()->days . 'days' ) );
}
/**
* Remove a keyword from Rank Tracker.
*
* @param string $keyword Keyword to remove.
*/
public function remove_track_keyword( $keyword ) {
DB::keywords()->where( 'keyword', $keyword )
->delete();
delete_transient( Stats::get()->get_cache_key( 'tracked_keywords_summary', Stats::get()->days . 'days' ) );
}
/**
* Delete all tracked keywords.
*/
public function delete_all_tracked_keywords() {
DB::keywords()->delete();
delete_transient( Stats::get()->get_cache_key( 'tracked_keywords_summary', Stats::get()->days . 'days' ) );
}
/**
* Get tracked keywords count.
*
* @return int Total keywords count
*/
public function get_tracked_keywords_count() {
$total = DB::keywords()
->selectCount( 'DISTINCT(keyword)', 'total' )
->where( 'is_active', 1 )
->getVar();
return (int) $total;
}
/**
* Get keywords quota.
*
* @return array Keywords usage info.
*/
public function get_tracked_keywords_quota() {
$quota = (array) get_option(
'rank_math_keyword_quota',
[
'taken' => 0,
'available' => 0,
]
);
return $quota;
}
/**
* Get tracked keywords summary.
*
* @return array Keywords usage info.
*/
public function get_tracked_keywords_summary() {
$cache_key = 'tracked_keywords_summary';
$cache_group = 'tracked_keywords_summary';
$summary = $this->get_cache( $cache_key, $cache_group );
if ( empty( $summary ) ) {
$summary = $this->get_tracked_keywords_quota();
$summary['total'] = $this->get_tracked_keywords_count();
$this->set_cache( $cache_key, $summary, $cache_group, DAY_IN_SECONDS );
}
return $summary;
}
/**
* Get winning tracked keywords.
*
* @return array Top 5 winning tracked keywords data.
*/
public function get_tracked_winning_keywords() {
return $this->get_tracked_keywords(
[
'offset' => 0,
'perpage' => 5,
'where' => 'WHERE COALESCE( ROUND( t1.position - COALESCE( t2.position, 100 ), 0 ), 0 ) < 0',
]
);
}
/**
* Get losing tracked keywords.
*
* @return array Top 5 losing tracked keywords data.
*/
public function get_tracked_losing_keywords() {
return $this->get_tracked_keywords(
[
'order' => 'DESC',
'offset' => 0,
'perpage' => 5,
'where' => 'WHERE COALESCE( ROUND( t1.position - COALESCE( t2.position, 100 ), 0 ), 0 ) > 0',
]
);
}
/**
* Get tracked keywords rows.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return array Tracked keywords data.
*/
public function get_tracked_keywords_rows( WP_REST_Request $request ) {
$per_page = 25;
$cache_args = $request->get_params();
$cache_args['per_page'] = $per_page;
$cache_group = 'rank_math_rest_tracked_keywords_rows';
$cache_key = $this->generate_hash( $cache_args );
$result = $this->get_cache( $cache_key, $cache_group );
if ( ! empty( $result ) ) {
return $result;
}
$page = ! empty( $request->get_param( 'page' ) ) ? $request->get_param( 'page' ) : 1;
$orderby = ! empty( $request->get_param( 'orderby' ) ) ? $request->get_param( 'orderby' ) : 'default';
$order = ! empty( $request->get_param( 'order' ) ) ? strtoupper( $request->get_param( 'order' ) ) : 'DESC';
$keyword = ! empty( $request->get_param( 'search' ) ) ? filter_var( urldecode( $request->get_param( 'search' ) ), FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_BACKTICK ) : '';
$offset = ( $page - 1 ) * $per_page;
$args = wp_parse_args(
[
'dimension' => 'query',
'limit' => "LIMIT {$offset}, {$per_page}",
'keyword' => $keyword,
]
);
switch ( $orderby ) {
case 'impressions':
case 'clicks':
case 'ctr':
case 'position':
$args['orderBy'] = $orderby;
$args['order'] = $order;
break;
case 'query':
$args['orderBy'] = 'keyword';
$args['order'] = $order;
break;
}
$data = $this->get_tracked_keywords_data( $args );
$data = Stats::get()->set_dimension_as_key( $data );
$history = $this->get_graph_data_for_keywords( \array_keys( $data ) );
$data = Stats::get()->set_query_position( $data, $history );
if ( 'default' === $orderby ) {
uasort(
$data,
function ( $a, $b ) use ( $orderby ) {
if ( false === array_key_exists( 'position', $a ) ) {
$a['position'] = [ 'total' => 0 ];
}
if ( false === array_key_exists( 'position', $b ) ) {
$b['position'] = [ 'total' => 0 ];
}
if ( 0 === intval( $b['position']['total'] ) ) {
return 0;
}
return $a['position']['total'] > $b['position']['total'] ? 1 : -1;
}
);
}
$result = [
'rowsData' => $data,
];
// get total rows by search.
$args = wp_parse_args(
[
'dimension' => 'query',
'limit' => 'LIMIT 10000',
'keyword' => $keyword,
]
);
if ( empty( $data ) ) {
$result['response'] = 'No Data';
} elseif ( $keyword ) {
$search_data = $this->get_tracked_keywords_data( $args );
$result['total'] = count( $search_data );
$this->set_cache( $cache_key, $result, $cache_group, DAY_IN_SECONDS );
}
return $result;
}
/**
* Get keyword rows from keyword manager table.
*
* @param array $args Array of arguments.
* @return array
*/
public function get_tracked_keywords_data( $args = [] ) {
global $wpdb;
Helper::enable_big_selects_for_queries();
$args = wp_parse_args(
$args,
[
'dimension' => 'query',
'order' => 'ASC',
'orderBy' => 'diffPosition1',
'objects' => false,
'where' => '',
'sub_where' => '',
'dates' => ' AND created BETWEEN %s AND %s',
'limit' => 'LIMIT 5',
'keyword' => '',
]
);
$where = $args['where'];
$limit = $args['limit'];
$dimension = $args['dimension'];
$sub_where = $args['sub_where'];
$dates = $args['dates'];
$keyword = trim( $args['keyword'] );
$order = sprintf( 'ORDER BY %s %s', $args['orderBy'], $args['order'] );
$dates_query = sprintf( " AND created BETWEEN '%s' AND '%s' ", Stats::get()->start_date, Stats::get()->end_date );
// Step1. Get most recent data row id for each keyword.
$where_like_keyword = $wpdb->prepare( ' WHERE keyword LIKE %s', '%' . $wpdb->esc_like( $keyword ) . '%' );
if ( empty( $keyword ) ) {
$where_like_keyword = '';
}
$ids = DB_Helper::get_results( // phpcs:disable -- The $dates_query, $where_like_keyword are sanitized.
$wpdb->prepare(
"SELECT MAX(id) as id
FROM {$wpdb->prefix}rank_math_analytics_gsc
WHERE 1 = 1 {$dates_query}
AND %i IN (SELECT DISTINCT keyword FROM {$wpdb->prefix}rank_math_analytics_keyword_manager {$where_like_keyword} GROUP BY %i)
GROUP BY query",
$dimension,
$dimension
)
); // phpcs:enable
// Step2. Get id list from above result.
$ids = wp_list_pluck( $ids, 'id' );
$ids_where = " AND id IN ('" . join( "', '", $ids ) . "')";
// Step3. Get most recent data row id for each keyword (for comparison).
$dates_query = sprintf( " AND created BETWEEN '%s' AND '%s' ", Stats::get()->compare_start_date, Stats::get()->compare_end_date );
$old_ids = DB_Helper::get_results( // phpcs:disable -- The $dates_query, $where_like_keyword are sanitized.
$wpdb->prepare(
"SELECT MAX(id) as id
FROM {$wpdb->prefix}rank_math_analytics_gsc
WHERE 1 = 1 {$dates_query}
AND %i IN (SELECT DISTINCT keyword FROM {$wpdb->prefix}rank_math_analytics_keyword_manager {$where_like_keyword} GROUP BY %i)
GROUP BY query",
$dimension,
$dimension,
)
); // phpcs:enable
// Step4. Get id list from above result.
$old_ids = wp_list_pluck( $old_ids, 'id' );
$old_ids_where = " AND id IN ('" . join( "', '", $old_ids ) . "')";
// Step5. Get most performing keywords first based on id list from above.
$where_like_keyword1 = $wpdb->prepare( ' WHERE km.keyword LIKE %s', '%' . $wpdb->esc_like( $keyword ) . '%' );
if ( empty( $keyword ) ) {
$where_like_keyword1 = '';
}
$positions = DB_Helper::get_results( // phpcs:disable -- The $ids_where, $old_ids_where, $where_like_keyword1, $where, $order, $limit are sanitized.
$wpdb->prepare(
"SELECT DISTINCT(km.keyword) as %i, COALESCE(t.position, 0) as position, COALESCE(t.diffPosition, 0) as diffPosition, COALESCE(t.diffPosition, 100) as diffPosition1, COALESCE(t.impressions, 0) as impressions, COALESCE(t.diffImpressions, 0) as diffImpressions, COALESCE(t.clicks, 0) as clicks, COALESCE(t.diffClicks, 0) as diffClicks, COALESCE(t.ctr, 0) as ctr, COALESCE(t.diffCtr, 0) as diffCtr
FROM {$wpdb->prefix}rank_math_analytics_keyword_manager km
LEFT JOIN (
SELECT
t1.%i as %i, ROUND( t1.position, 0 ) as position, ROUND( t1.impressions, 0 ) as impressions, ROUND( t1.clicks, 0 ) as clicks, ROUND( t1.ctr, 0 ) as ctr,
COALESCE( ROUND( t1.position - COALESCE( t2.position, 100 ), 0 ), 0 ) as diffPosition,
COALESCE( ROUND( t1.impressions - COALESCE( t2.impressions, 100 ), 0 ), 0 ) as diffImpressions,
COALESCE( ROUND( t1.clicks - COALESCE( t2.clicks, 100 ), 0 ), 0 ) as diffClicks,
COALESCE( ROUND( t1.ctr - COALESCE( t2.ctr, 100 ), 0 ), 0 ) as diffCtr
FROM
(SELECT a.%i, a.position, a.impressions,a.clicks,a.ctr FROM {$wpdb->prefix}rank_math_analytics_gsc AS a
WHERE 1 = 1{$ids_where}) AS t1
LEFT JOIN
(SELECT a.%i, a.position, a.impressions,a.clicks,a.ctr FROM {$wpdb->prefix}rank_math_analytics_gsc AS a
WHERE 1 = 1{$old_ids_where}) AS t2
ON t1.%i = t2.%i) AS t on t.%i = km.keyword
{$where_like_keyword1}
{$where}
{$order}
{$limit}",
$dimension,
$dimension,
$dimension,
$dimension,
$dimension,
$dimension,
$dimension,
$dimension,
),
ARRAY_A
); // phpcs:enable
// Step6. Get keywords list from above results.
$keywords = array_column( $positions, 'query' );
$keywords = array_map( 'esc_sql', $keywords );
$keywords = array_map( 'strtolower', $keywords );
$keywords = '(\'' . join( '\', \'', $keywords ) . '\')';
// step7. Get other metrics data.
$metrics = DB_Helper::get_results( // phpcs:disable -- The $dates, $keywords are sanitized.
$wpdb->prepare(
"SELECT t1.%i as %i, t1.clicks, t1.impressions, t1.ctr,
COALESCE( t1.clicks - t2.clicks, 0 ) as diffClicks,
COALESCE( t1.impressions - t2.impressions, 0 ) as diffImpressions,
COALESCE( t1.ctr - t2.ctr, 0 ) as diffCtr
FROM
( SELECT %i, SUM( clicks ) as clicks, SUM(impressions) as impressions, AVG(position) as position, AVG(ctr) as ctr FROM {$wpdb->prefix}rank_math_analytics_gsc WHERE 1 = 1{$dates} AND %i IN {$keywords} GROUP BY %i) as t1
LEFT JOIN
( SELECT %i, SUM( clicks ) as clicks, SUM(impressions) as impressions, AVG(position) as position, AVG(ctr) as ctr FROM {$wpdb->prefix}rank_math_analytics_gsc WHERE 1 = 1{$dates} AND %i IN {$keywords} GROUP BY %i) as t2
ON t1.query = t2.query",
$dimension,
$dimension,
$dimension,
Stats::get()->start_date,
Stats::get()->end_date,
$dimension,
$dimension,
$dimension,
Stats::get()->compare_start_date,
Stats::get()->compare_end_date,
$dimension,
$dimension,
),
ARRAY_A
); // phpcs:enable
// Step8. Merge above two results.
$positions = Stats::get()->set_dimension_as_key( $positions, $dimension );
$metrics = Stats::get()->set_dimension_as_key( $metrics, $dimension );
$data = Stats::get()->get_merged_metrics( $positions, $metrics );
$data = $this->sort_data( $data, $args['orderBy'], $args['order'] );
// Step9. Construct return data.
foreach ( $data as $keyword => $row ) {
$data[ $keyword ]['graph'] = [];
$data[ $keyword ]['clicks'] = [
'total' => (int) $data[ $keyword ]['clicks'],
'difference' => (int) $data[ $keyword ]['diffClicks'],
];
$data[ $keyword ]['impressions'] = [
'total' => (int) $data[ $keyword ]['impressions'],
'difference' => (int) $data[ $keyword ]['diffImpressions'],
];
$data[ $keyword ]['position'] = [
'total' => (float) $data[ $keyword ]['position'],
'difference' => (float) $data[ $keyword ]['diffPosition'],
];
$data[ $keyword ]['ctr'] = [
'total' => (float) $data[ $keyword ]['ctr'],
'difference' => (float) $data[ $keyword ]['diffCtr'],
];
unset(
$data[ $keyword ]['diffClicks'],
$data[ $keyword ]['diffImpressions'],
$data[ $keyword ]['diffPosition'],
$data[ $keyword ]['diffCtr']
);
}
return $data;
}
/**
* Get tracked keywords data.
*
* @param array $data The data to sort.
* @param string $order_by The column to sort by.
* @param string $order The order to sort by.
*/
public function sort_data( $data, $order_by, $order ) {
$order_by = 'keyword' === $order_by ? 'query' : $order_by;
$sort_order = 'ASC' === $order ? SORT_ASC : SORT_DESC;
$sort_column = in_array( $order_by, [ 'query', 'clicks', 'impressions', 'position', 'ctr' ], true ) ? $order_by : 'position';
$sort_data = array_column( $data, $sort_column );
array_multisort( $sort_data, $sort_order, $data );
return $data;
}
/**
* Get tracked keywords.
*
* @param array $args Array of arguments.
* @return array
*/
public function get_tracked_keywords( $args = [] ) {
global $wpdb;
$args = wp_parse_args(
$args,
[
'dimension' => 'query',
'order' => 'ASC',
'orderBy' => 'diffPosition',
'offset' => 0,
'perpage' => 20000,
'sub_where' => " AND query IN ( SELECT keyword from {$wpdb->prefix}rank_math_analytics_keyword_manager )",
]
);
$data = Stats::get()->get_analytics_data( $args );
$history = $this->get_graph_data_for_keywords( \array_keys( $data ) );
$data = Stats::get()->set_query_position( $data, $history );
// Add remaining keywords.
if ( 5 !== $args['perpage'] ) {
$rows = DB::keywords()->get();
foreach ( $rows as $row ) {
if ( ! isset( $data[ $row->keyword ] ) ) {
$data[ $row->keyword ] = [
'query' => $row->keyword,
'graph' => [],
'clicks' => [
'total' => 0,
'difference' => 0,
],
'impressions' => [
'total' => 0,
'difference' => 0,
],
'position' => [
'total' => 0,
'difference' => 0,
],
'ctr' => [
'total' => 0,
'difference' => 0,
],
'pageviews' => [
'total' => 0,
'difference' => 0,
],
];
}
}
}
return $data;
}
/**
* Get most recent day's keywords.
*
* @return array
*/
public function get_recent_keywords() {
global $wpdb;
$data = DB_Helper::get_results( // phpcs:ignore -- DB call is required.
$wpdb->prepare(
"SELECT query
FROM {$wpdb->prefix}rank_math_analytics_gsc
WHERE DATE(created) = (SELECT MAX(DATE(created)) FROM {$wpdb->prefix}rank_math_analytics_gsc WHERE created BETWEEN %s AND %s)
GROUP BY query",
Stats::get()->start_date,
Stats::get()->end_date
)
);
return $data;
}
/**
* Get top 5 winning keywords.
*
* @return array
*/
public function get_winning_keywords() {
$cache_key = Stats::get()->get_cache_key( 'winning_keywords', Stats::get()->days . 'days' );
$cache = get_transient( $cache_key );
if ( false !== $cache ) {
return $cache;
}
// Get most recent day's keywords only.
$keywords = $this->get_recent_keywords();
$keywords = wp_list_pluck( $keywords, 'query' );
$keywords = array_map( 'strtolower', $keywords );
$data = Stats::get()->get_analytics_data(
[
'order' => 'ASC',
'dimension' => 'query',
'where' => 'WHERE COALESCE( ROUND( t1.position - COALESCE( t2.position, 100 ), 0 ), 0 ) < 0',
]
);
$history = $this->get_graph_data_for_keywords( \array_keys( $data ) );
$data = Stats::get()->set_query_position( $data, $history );
set_transient( $cache_key, $data, DAY_IN_SECONDS );
return $data;
}
/**
* Get top 5 losing keywords.
*
* @return array
*/
public function get_losing_keywords() {
$cache_key = Stats::get()->get_cache_key( 'losing_keywords', Stats::get()->days . 'days' );
$cache = get_transient( $cache_key );
if ( false !== $cache ) {
return $cache;
}
// Get most recent day's keywords only.
$keywords = $this->get_recent_keywords();
$keywords = wp_list_pluck( $keywords, 'query' );
$keywords = array_map( 'strtolower', $keywords );
$data = Stats::get()->get_analytics_data(
[
'dimension' => 'query',
'where' => 'WHERE COALESCE( ROUND( t1.position - COALESCE( t2.position, 100 ), 0 ), 0 ) > 0',
]
);
$history = $this->get_graph_data_for_keywords( \array_keys( $data ) );
$data = Stats::get()->set_query_position( $data, $history );
set_transient( $cache_key, $data, DAY_IN_SECONDS );
return $data;
}
/**
* Get keywords graph data.
*
* @param array $keywords Keywords to get data for.
* @param string $sub_query Database sub-query.
*
* @return array
*/
public function get_graph_data_for_keywords( $keywords, $sub_query = '' ) {
global $wpdb;
$intervals = Stats::get()->get_intervals();
$sql_daterange = Stats::get()->get_sql_date_intervals( $intervals );
$keywords = \array_map( 'esc_sql', $keywords );
$keywords = '(\'' . join( '\', \'', $keywords ) . '\')';
$data = DB_Helper::get_results( // phpcs:disable -- The $sql_daterange, $keywords, $sub_query are sanitized.
$wpdb->prepare(
"SELECT a.query, a.position, t.max_created AS date, t.range_group
FROM {$wpdb->prefix}rank_math_analytics_gsc AS a
INNER JOIN (
SELECT
query,
{$sql_daterange},
MAX(created) AS max_created
FROM {$wpdb->prefix}rank_math_analytics_gsc
WHERE created BETWEEN %s AND %s
AND query IN {$keywords}
{$sub_query}
GROUP BY query, range_group
ORDER BY max_created ASC
) t
ON a.query = t.query AND a.created = t.max_created
ORDER BY a.created ASC",
Stats::get()->start_date,
Stats::get()->end_date
)
); // phpcs:enable
$data = Stats::get()->filter_graph_rows( $data );
return array_map( [ Stats::get(), 'normalize_graph_rows' ], $data );
}
/**
* Get pages by keyword.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_keyword_pages( WP_REST_Request $request ) {
global $wpdb;
$keyword = esc_sql( $request->get_param( 'query' ) );
$data = DB_Helper::get_results( // phpcs:ignore -- Direct DB query required.
$wpdb->prepare(
"SELECT DISTINCT g.page
FROM {$wpdb->prefix}rank_math_analytics_gsc as g
WHERE g.query = %s AND g.created BETWEEN %s AND %s
ORDER BY g.created DESC",
$keyword,
Stats::get()->start_date,
Stats::get()->end_date
)
);
$pages = wp_list_pluck( $data, 'page' );
$console = Stats::get()->get_analytics_data(
[
'action' => 'get_keyword_pages',
'keyword' => $keyword,
'objects' => true,
'pageview' => true,
'sub_where' => " AND page IN ('" . join( "', '", $pages ) . "') AND query = '" . $keyword . "'",
]
);
return $console;
}
/**
* Add focus keywords to Rank Tracker.
*
* @param int $post_id Post ID.
* @return mixed
*/
public function add_post_focus_keyword( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
$auto_add_fks = Helper::get_settings( 'general.auto_add_focus_keywords', [] );
if (
empty( $auto_add_fks['enable_auto_import'] ) ||
empty( $auto_add_fks['post_types'] ) ||
! in_array( get_post_type( $post_id ), $auto_add_fks['post_types'], true )
) {
return;
}
$focus_keyword = Helper::get_post_meta( 'focus_keyword', $post_id );
if ( empty( $focus_keyword ) ) {
return;
}
$keywords_data = [];
$keywords = explode( ',', $focus_keyword );
if ( ! empty( $auto_add_fks['secondary_keyword'] ) ) {
$keywords_data = $keywords;
} else {
$keywords_data[] = current( $keywords );
}
DB::bulk_insert_query_focus_keyword_data( $keywords_data );
}
}