File "UserInterface.php"
Full Path: /home/vantageo/public_html/cache/cache/cache/cache/cache/cache/cache/.wp-cli/wp-content/plugins/ajax-search-for-woocommerce/includes/Analytics/UserInterface.php
File size: 22.17 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace DgoraWcas\Analytics;
use DgoraWcas\Helpers;
use DgoraWcas\Multilingual;
// Exit if accessed directly
if ( !defined( 'ABSPATH' ) ) {
exit;
}
class UserInterface {
const SECTION_ID = 'dgwt_wcas_analytics';
const LOAD_INTERFACE_NONCE = 'analytics-load-interface';
const LOAD_MORE_CRITICAL_SEARCHES_NONCE = 'analytics-load-more-critical-searches';
const LOAD_MORE_AUTOCOMPLETE_NONCE = 'analytics-load-more-autocomplete';
const LOAD_MORE_SEARCH_PAGE_NONCE = 'analytics-load-more-search-page';
const CRITICAL_CHECK_NONCE = 'analytics-critical-check';
const EXCLUDE_CRITICAL_PHRASE_NONCE = 'analytics-exclude-critical-phrase';
const RESET_STATS_NONCE = 'analytics-reset-stats';
const EXPORT_STATS_CSV_NONCE = 'analytics-export-stats-csv';
const CSS_CLASS_PLACEHOLDER = 'js-dgwt-wcas-stats-placeholder';
const CRITICAL_SEARCHES_LOAD_LIMIT = 10;
const TABLE_ROW_LIMIT_LIMIT = 10;
/**
* @var Analytics
*/
private $analytics;
/**
* Constructor
*
* @param Analytics $analytics
*/
public function __construct( Analytics $analytics ) {
$this->analytics = $analytics;
}
/**
* Init the class
*
* @return void
*/
public function init() {
// Draw settings page
add_filter( 'dgwt/wcas/settings/sections', array($this, 'addSettingsSection') );
add_filter( 'dgwt/wcas/settings', array($this, 'addSettingsTab') );
add_filter( 'dgwt/wcas/scripts/admin/localize', array($this, 'localizeSettings') );
// AJAX callbacks
add_action( 'wp_ajax_dgwt_wcas_load_stats_interface', array($this, 'loadInterface') );
add_action( 'wp_ajax_dgwt_wcas_laod_more_critical_searches', array($this, 'loadMoreCriticalSearches') );
add_action( 'wp_ajax_dgwt_wcas_laod_more_autocomplete', array($this, 'loadMoreAutocomplete') );
add_action( 'wp_ajax_dgwt_wcas_laod_more_search_page', array($this, 'loadMoreSearchPage') );
add_action( 'wp_ajax_dgwt_wcas_check_critical_phrase', array($this, 'checkCriticalPhrase') );
add_action( 'wp_ajax_dgwt_wcas_exclude_critical_phrase', array($this, 'excludeCriticalPhrase') );
add_action( 'wp_ajax_dgwt_wcas_reset_stats', array($this, 'resetStats') );
add_action( 'wp_ajax_dgwt_wcas_export_stats_csv', array($this, 'exportStats') );
if ( $this->analytics->isModuleEnabled() ) {
add_action( DGWT_WCAS_SETTINGS_KEY . '-form_end_' . self::SECTION_ID, array($this, 'tabContent') );
}
}
/**
* Content of "Analytics" tab on Settings page
*
* @param array $sections
*
* @return array
*/
public function addSettingsSection( $sections ) {
$sections[28] = array(
'id' => self::SECTION_ID,
'title' => __( 'Analytics', 'ajax-search-for-woocommerce' ),
);
return $sections;
}
/**
* Add "Analytics" tab on Settings page
*
* @param array $settings
*
* @return array
*/
public function addSettingsTab( $settings ) {
$searchAnalyticsLink = 'https://fibosearch.com/documentation/features/fibosearch-analytics/';
$settings[self::SECTION_ID] = apply_filters( 'dgwt/wcas/settings/section=analytics', array(
100 => array(
'name' => 'analytics_head',
'label' => __( 'Search Analytics', 'ajax-search-for-woocommerce' ),
'type' => 'head',
'class' => 'dgwt-wcas-sgs-header',
),
110 => array(
'name' => 'analytics_enabled',
'label' => __( 'Enable search analytics', 'ajax-search-for-woocommerce' ) . ' ' . Helpers::createQuestionMark( 'enable_search_analytics', sprintf( __( 'Search analytics system helps to eliminate search phrases that don’t return any results. Also, allows to explore trending keywords. <a target="_blank" href="%s">Find our more</a> how to use and customize FiboSearch Analytics.', 'ajax-search-for-woocommerce' ), $searchAnalyticsLink ) ),
'type' => 'checkbox',
'class' => 'dgwt-wcas-options-cb-toggle js-dgwt-wcas-cbtgroup-analytics-critial-searches-widget',
'size' => 'small',
'default' => 'off',
),
120 => array(
'name' => 'analytics_critical_searches_widget_enabled',
'label' => __( 'Show widget with critical searches in Dashboard', 'ajax-search-for-woocommerce' ),
'type' => 'checkbox',
'class' => 'js-dgwt-wcas-cbtgroup-analytics-critial-searches-widget',
'size' => 'small',
'default' => 'off',
),
) );
return $settings;
}
/**
* Pass data to JavaScript on the settings page
*
* @param array $localize
*
* @return array
*/
public function localizeSettings( $localize ) {
$localize['analytics'] = array(
'nonce' => array(
'analytics_load_interface' => wp_create_nonce( self::LOAD_INTERFACE_NONCE ),
'load_more_critical_searches' => wp_create_nonce( self::LOAD_MORE_CRITICAL_SEARCHES_NONCE ),
'load_more_autocomplete' => wp_create_nonce( self::LOAD_MORE_AUTOCOMPLETE_NONCE ),
'load_more_search_page' => wp_create_nonce( self::LOAD_MORE_SEARCH_PAGE_NONCE ),
'check_critical_phrase' => wp_create_nonce( self::CRITICAL_CHECK_NONCE ),
'exclude_critical_phrase' => wp_create_nonce( self::EXCLUDE_CRITICAL_PHRASE_NONCE ),
'reset_stats' => wp_create_nonce( self::RESET_STATS_NONCE ),
'export_stats_csv' => wp_create_nonce( self::EXPORT_STATS_CSV_NONCE ),
),
'enabled' => $this->analytics->isModuleEnabled(),
'images' => array(
'placeholder' => DGWT_WCAS_URL . 'assets/img/admin-stats-placeholder.png',
),
'labels' => array(
'reset_stats_confirm' => __( 'Are you sure you want to reset stats?', 'ajax-search-for-woocommerce' ),
),
);
return $localize;
}
/**
* Load content for "Analytics" tab on Settings page
*
* @return void
*/
public function tabContent() {
if ( Multilingual::isMultilingual() ) {
echo $this->getLanguageSwitcher();
}
echo '<div class="dgwt-wcas-analytics-body ' . self::CSS_CLASS_PLACEHOLDER . '"></div>';
}
/**
* Get HTML of language switcher
*
* @return string
*/
private function getLanguageSwitcher() {
$vars = array(
'multilingual' => array(
'is-multilingual' => true,
'current-lang' => Multilingual::getCurrentLanguage(),
'langs' => array(),
),
);
foreach ( Multilingual::getLanguages() as $lang ) {
$vars['multilingual']['langs'][$lang] = Multilingual::getLanguageField( $lang, 'name' );
}
ob_start();
require DGWT_WCAS_DIR . 'partials/admin/stats/langs.php';
return ob_get_clean();
}
/**
* Load an interface (AJAX callback)
*
* @return void
*/
public function loadInterface() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::LOAD_INTERFACE_NONCE );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( sanitize_key( $_REQUEST['lang'] ) ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
$data = array(
'html' => '',
);
ob_start();
$vars = $this->getVars( $lang );
require DGWT_WCAS_DIR . 'partials/admin/stats/stats.php';
$data['html'] = ob_get_clean();
wp_send_json_success( $data );
}
/**
* Load more critical searches
*
* @return void
*/
public function loadMoreCriticalSearches() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::LOAD_MORE_CRITICAL_SEARCHES_NONCE );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( sanitize_key( $_REQUEST['lang'] ) ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
$offset = ( !empty( $_REQUEST['loaded'] ) ? absint( $_REQUEST['loaded'] ) : 0 );
$html = '';
$data = new Data();
if ( !empty( $lang ) ) {
$data->setLang( $lang );
}
$total = $data->getTotalCriticalSearches();
$critical = $data->getCriticalSearches( self::CRITICAL_SEARCHES_LOAD_LIMIT, $offset );
if ( !empty( $critical ) ) {
ob_start();
$i = $offset + 1;
foreach ( $critical as $row ) {
require DGWT_WCAS_DIR . 'partials/admin/stats/critical-searches-row.php';
$i++;
}
$html = ob_get_clean();
}
$toLoad = $total - $offset - count( $critical );
$more = min( self::CRITICAL_SEARCHES_LOAD_LIMIT, $toLoad );
$data = array(
'html' => $html,
'more' => $more,
'more_label' => '',
);
if ( $more > 0 ) {
$data['more_label'] = sprintf( _n(
'load another %d phrase',
'load another %d phrases',
$more,
'ajax-search-for-woocommerce'
), $more );
}
wp_send_json_success( $data );
}
/**
* Load more autocomplete searches with results
*
* @return void
*/
public function loadMoreAutocomplete() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::LOAD_MORE_AUTOCOMPLETE_NONCE );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( sanitize_key( $_REQUEST['lang'] ) ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
// Autocomplete
$data = new Data();
if ( !empty( $lang ) ) {
$data->setLang( $lang );
}
$data->setContext( 'autocomplete' );
$phrases = $data->getPhrasesWithResults( 100 );
ob_start();
$i = 1;
foreach ( $phrases as $row ) {
require DGWT_WCAS_DIR . 'partials/admin/stats/ac-searches-row.php';
$i++;
}
$html = ob_get_clean();
$data = array(
'html' => $html,
);
wp_send_json_success( $data );
}
/**
* Load more search page searches with results
*
* @return void
*/
public function loadMoreSearchPage() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::LOAD_MORE_SEARCH_PAGE_NONCE );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( sanitize_key( $_REQUEST['lang'] ) ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
// Search page
$data = new Data();
if ( !empty( $lang ) ) {
$data->setLang( $lang );
}
$data->setContext( 'search-results-page' );
$phrases = $data->getPhrasesWithResults( 100 );
ob_start();
$i = 1;
foreach ( $phrases as $row ) {
require DGWT_WCAS_DIR . 'partials/admin/stats/sp-searches-row.php';
$i++;
}
$html = ob_get_clean();
$data = array(
'html' => $html,
);
wp_send_json_success( $data );
}
/**
* Check if the phrase returns results
*
* @return void
*/
public function checkCriticalPhrase() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::CRITICAL_CHECK_NONCE );
$data = array(
'html' => '',
'status' => '',
);
$phrase = ( !empty( $_REQUEST['phrase'] ) ? $_REQUEST['phrase'] : '' );
if ( empty( $phrase ) ) {
wp_send_json_error( 'empty phrase' );
}
if ( !dgoraAsfwFs()->is_premium() ) {
$res = DGWT_WCAS()->nativeSearch->getSearchResults( $phrase, true, 'autocomplete' );
if ( is_array( $res ) && isset( $res['total'] ) ) {
$total = absint( $res['total'] );
if ( $total > 0 ) {
$data['status'] = 'with-results';
$data['html'] = $this->getCriticalPhraseMessage( $data['status'], $total );
} else {
$data['status'] = 'without-results';
$data['html'] = $this->getCriticalPhraseMessage( $data['status'] );
}
} else {
$data['status'] = 'error';
$data['html'] = $this->getCriticalPhraseMessage( $data['status'] );
}
} else {
}
wp_send_json_success( $data );
}
/**
* Check critical phrase - messages on response
*
* @param string $context
* @param int $total
*
* @return string
*/
public function getCriticalPhraseMessage( $context = '' ) {
$html = '';
//This phrase returns X products.
switch ( $context ) {
case 'with-results':
$html = '<p>';
$html .= '<b class="dgwt-wcas-analytics-text-good">' . __( "Perfect!", 'ajax-search-for-woocommerce' ) . '</b>';
$html .= ' ' . __( "It's sorted.", 'ajax-search-for-woocommerce' );
$html .= ' ' . __( 'This phrase returns some results.', 'ajax-search-for-woocommerce' );
$html .= ' ' . __( 'Click the button below to remove this phrase from the list.', 'ajax-search-for-woocommerce' );
$html .= '<button class="button button-small dgwt-wcas-analytics-btn-mark js-dgwt-wcas-analytics-exclude-phrase"><span class="dashicons dashicons-yes"></span> ' . __( 'Mark this phrase as resolved', 'ajax-search-for-woocommerce' ) . '</button>';
$html .= '</p>';
break;
case 'without-results':
$html = '<p>';
$html .= '<b class="dgwt-wcas-analytics-text-poorly">' . __( "Poor!", 'ajax-search-for-woocommerce' ) . '</b>';
$html .= ' ' . __( "Still this phrase doesn't return any results. Learn how to fix it.", 'ajax-search-for-woocommerce' );
$html .= '</p>';
break;
case 'wrong-index':
$html = '<p>';
$html .= __( "Can't check the status. The search index hasn't been completed. Go to the Indexer tab and wait until the search index is completed.", 'ajax-search-for-woocommerce' );
$html .= '<button class="button button-small dgwt-wcas-analytics-btn-mark js-dgwt-wcas-analytics-check-indexer">' . __( 'Check the indexer status', 'ajax-search-for-woocommerce' ) . '</button>';
$html .= '</p>';
break;
case 'error':
$html = '<p>';
$html .= __( 'Something went wrong', 'ajax-search-for-woocommerce' );
$html .= '</p>';
break;
}
return $html;
}
/**
* Unmark a phrase as critical. AJAX callback
*
* @return void
*/
public function excludeCriticalPhrase() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::EXCLUDE_CRITICAL_PHRASE_NONCE );
$phrase = ( !empty( $_REQUEST['phrase'] ) ? $_REQUEST['phrase'] : '' );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( $_REQUEST['lang'] ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
if ( !empty( $phrase ) ) {
$data = new Data();
if ( Multilingual::isMultilingual() && !empty( $lang ) ) {
$data->setLang( $lang );
}
if ( $data->markAsSolved( $phrase ) ) {
wp_send_json_success( '<p>' . __( 'This phrase has been resolved! This row will disappear after refreshing the page.', 'ajax-search-for-woocommerce' ) . '</p>' );
}
}
wp_send_json_error( 'empty phrase' );
}
/**
* Reset stats. AJAX callback
*
* @return void
*/
public function resetStats() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::RESET_STATS_NONCE );
Database::wipeAllRecords();
wp_send_json_success();
}
/**
* Export stats. AJAX callback
*
* @return void
*/
public function exportStats() {
if ( !current_user_can( ( Helpers::shopManagerHasAccess() ? 'manage_woocommerce' : 'manage_options' ) ) ) {
wp_die( -1, 403 );
}
check_ajax_referer( self::EXPORT_STATS_CSV_NONCE );
if ( !class_exists( 'WC_CSV_Exporter', false ) ) {
require_once WC_ABSPATH . 'includes/export/abstract-wc-csv-exporter.php';
}
$exporter = new CSVExporter();
$context = ( isset( $_GET['context'] ) ? sanitize_key( $_GET['context'] ) : '' );
$exporter->set_context( $context );
$lang = ( !empty( $_REQUEST['lang'] ) && Multilingual::isLangCode( sanitize_key( $_REQUEST['lang'] ) ) ? sanitize_key( $_REQUEST['lang'] ) : '' );
if ( !empty( $lang ) ) {
$exporter->set_lang( $lang );
}
$exporter->export();
}
/**
* Prepare vars for the view
*
* @param string $lang
*
* @return array
*/
private function getVars( $lang = '' ) {
$data = new Data();
if ( Multilingual::isMultilingual() ) {
$data->setLang( $lang );
}
$mainUrl = 'https://fibosearch.com/lack-of-queries-insight-really-hurts-your-sales/';
$vars = array(
'days' => $this->getExpirationInDays(),
'autocomplete' => array(),
'search-page' => array(),
'critical-searches' => array(),
'critical-searches-total' => 0,
'critical-searches-more' => 0,
'returning-results-percent' => 0,
'returning-results-percent-poorly' => false,
'links' => array(
'synonyms' => $mainUrl . '#synonyms',
'support' => 'https://fibosearch.com/contact/',
),
'table-info' => Helpers::getTableInfo( Database::getTableName() ),
);
// Autocomplete
$data->setContext( 'autocomplete' );
$vars['autocomplete'] = array(
'with-results' => $data->getPhrasesWithResults( self::TABLE_ROW_LIMIT_LIMIT ),
'total-with-results-uniq' => $data->getTotalSearches( true, true ),
'total-without-results-uniq' => $data->getTotalSearches( false, true ),
'total-with-results' => $data->getTotalSearches( true ),
'total-without-results' => $data->getTotalSearches( false ),
'total-results' => 0,
);
$vars['autocomplete']['total-results-uniq'] = $vars['autocomplete']['total-with-results-uniq'] + $vars['autocomplete']['total-without-results-uniq'];
$vars['autocomplete']['total-results'] = $vars['autocomplete']['total-with-results'] + $vars['autocomplete']['total-without-results'];
// WooCommerce Search Results Page
$data->setContext( 'search-results-page' );
$vars['search-page'] = array(
'with-results' => $data->getPhrasesWithResults( self::TABLE_ROW_LIMIT_LIMIT ),
'total-with-results-uniq' => $data->getTotalSearches( true, true ),
'total-without-results-uniq' => $data->getTotalSearches( false, true ),
'total-with-results' => $data->getTotalSearches( true ),
'total-without-results' => $data->getTotalSearches( false ),
'total-results' => 0,
);
$vars['search-page']['total-results-uniq'] = $vars['search-page']['total-with-results-uniq'] + $vars['search-page']['total-without-results-uniq'];
$vars['search-page']['total-results'] = $vars['search-page']['total-with-results'] + $vars['search-page']['total-without-results'];
// Common
$vars['total'] = $vars['autocomplete']['total-results'];
if ( $vars['total'] > 0 ) {
$vars['returning-results-percent'] = round( $vars['autocomplete']['total-with-results'] * 100 / $vars['total'] );
$vars['returning-results-percent-satisfying'] = $data->isSearchesReturningResutlsSatisfying( $vars['returning-results-percent'] );
}
// Critical searches
$critical = $data->getCriticalSearches( self::CRITICAL_SEARCHES_LOAD_LIMIT );
if ( !empty( $critical ) ) {
$vars['critical-searches'] = $critical;
$vars['critical-searches-total'] = $data->getTotalCriticalSearches();
$toLoad = $vars['critical-searches-total'] - count( $critical );
$vars['critical-searches-more'] = min( self::CRITICAL_SEARCHES_LOAD_LIMIT, $toLoad );
if ( $vars['critical-searches-total'] < self::CRITICAL_SEARCHES_LOAD_LIMIT ) {
$vars['critical-searches-more'] = 0;
}
}
return $vars;
}
/**
* The records will be removed from the database after passing X days
*
* @return int
*/
public function getExpirationInDays() {
$days = Maintenance::ANALYTICS_EXPIRATION_IN_DAYS;
if ( defined( 'DGWT_WCAS_ANALYTICS_EXPIRATION_IN_DAYS' ) && intval( DGWT_WCAS_ANALYTICS_EXPIRATION_IN_DAYS ) > 0 ) {
$days = intval( DGWT_WCAS_ANALYTICS_EXPIRATION_IN_DAYS );
}
return $days;
}
}