Current File : /home/pacjaorg/www/copwordpres/wp-content/plugins/betterdocs/includes/Admin/ReportEmail.php |
<?php
namespace WPDeveloper\BetterDocs\Admin;
use WP_Error;
use WP_Query;
use stdClass;
use WPDeveloper\BetterDocs\Utils\Base;
use WPDeveloper\BetterDocs\Utils\Views;
use WPDeveloper\BetterDocs\Core\Settings;
/**
* This class is responsible for sending weekly email with reports
*
* @since 1.4.4
*/
class ReportEmail extends Base {
/**
* Get a single Instance of Analytics
* @var Settings
*/
public $settings;
private static $current_timestamp = null;
private static $current_date = null;
/**
* Initially Invoked by Default.
*/
public function __construct( Settings $settings ) {
$this->settings = $settings;
add_action( 'betterdocs::settings::saved', [$this, 'after_save_settings'] );
if ( $this->settings->get( 'enable_reporting', false ) ) {
$this->init();
}
}
public function init() {
add_filter( 'cron_schedules', [$this, 'schedules_cron'] );
add_action( 'admin_init', [$this, 'activate'] );
add_action( 'betterdocs_weekly_email_reporting', [$this, 'send_email'] );
}
public function after_save_settings() {
if ( $this->settings->get( 'enable_reporting', false ) ) {
$this->activate();
} else {
$this->deactivate( true );
}
}
public function reporting( $request ) {
if ( ! boolval( $request->get_param( 'disable_reporting' ) ) ) {
if ( $request->has_param( 'reporting_email' ) ) {
$email = $request->get_param( 'reporting_email' );
}
$email = $this->receiver_email_address( $email );
if ( ! empty( $email ) ) {
$is_send = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $email );
if ( $is_send && ! is_wp_error( $is_send ) ) {
return ['message' => __( 'Successfully Sent an Email', 'betterdocs' )];
} else if ( is_wp_error( $is_send ) ) {
return $is_send;
} else {
return $this->error( 'betterdocs_unknown_reason', __( 'Email cannot be sent for some reason.', 'betterdocs' ) );
}
}
return $this->error( 'betterdocs_unknown_reason', __( 'Invalid email address.', 'betterdocs' ) );
} else {
return $this->error( 'betterdocs_disabled_reporting', __( 'You have to enable Reporting first.', 'betterdocs' ) );
}
}
public function error( $code, $message ) {
return new WP_Error( $code, $message );
}
private static function timestamps( $date = false ) {
if ( is_null( self::$current_timestamp ) ) {
self::$current_timestamp = current_time( 'timestamp' );
}
if ( $date ) {
if ( is_null( self::$current_date ) ) {
self::$current_date = current_time( 'Y-m-d' );
}
return self::$current_date;
}
return self::$current_timestamp;
}
public function create_date( $count = '-7days' ) {
return date( 'Y-m-d', strtotime( $count, self::timestamps() ) );
}
public function get_views( $start_date, $end_date = null ) {
global $wpdb;
$query = $wpdb->get_results( "
SELECT sum(impressions) as views, sum(unique_visit) as unique_visit, sum(happy + sad + normal) as reactions
FROM {$wpdb->prefix}betterdocs_analytics
WHERE (created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
" );
return $query;
}
public function get_search( $start_date, $end_date = null ) {
global $wpdb;
$query = $wpdb->get_results( "
SELECT SUM(count + not_found_count) as search_count, SUM(count) as search_found, SUM(not_found_count) as search_not_found_count
FROM {$wpdb->prefix}betterdocs_search_log as search_log
WHERE (search_log.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
" );
return $query;
}
public function count_new_docs( $start_date, $end_date = null ) {
$args = [
'post_type' => 'docs',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => [
[
'after' => $start_date,
'before' => $end_date,
'inclusive' => true
]
]
];
$query = new WP_Query( $args );
return $query->found_posts;
}
public function get_search_keywords( $start_date, $end_date = null ) {
global $wpdb;
$select = "SELECT search_keyword.keyword, search_log.keyword_id, SUM(search_log.count + search_log.not_found_count) as total_search, SUM(search_log.count) as count, SUM(search_log.not_found_count) as not_found";
$join = "FROM {$wpdb->prefix}betterdocs_search_keyword as search_keyword
JOIN {$wpdb->prefix}betterdocs_search_log as search_log on search_keyword.id = search_log.keyword_id";
$query = $wpdb->get_results( "
{$select}
{$join}
WHERE (search_log.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
GROUP BY search_log.keyword_id
ORDER BY count DESC LIMIT 5
" );
return $query;
}
public function get_docs_items( $request ) {
$prepared_post = new stdClass();
if ( isset( $request->ID ) ) {
$prepared_post->ID = $request->ID;
}
if ( isset( $request->post_title ) ) {
$prepared_post->title = betterdocs()->template_helper->kses( $request->post_title );
}
if ( isset( $request->total_views ) ) {
$prepared_post->total_views = $request->total_views;
}
if ( isset( $request->total_unique_visit ) ) {
$prepared_post->total_unique_visit = $request->total_unique_visit;
}
if ( isset( $request->total_reactions ) ) {
$prepared_post->total_reactions = $request->total_reactions;
}
if ( isset( $request->ID ) ) {
$prepared_post->link = get_permalink( $request->ID );
}
return $prepared_post;
}
public function get_leading_docs( $start_date, $end_date = null ) {
global $wpdb;
$select = "SELECT docs.ID, docs.post_author, docs.post_title, SUM(analytics.impressions) as total_views, SUM(analytics.unique_visit) as total_unique_visit, SUM(analytics.happy + analytics.sad + analytics.normal) as total_reactions";
$join = "FROM {$wpdb->prefix}posts as docs
JOIN {$wpdb->prefix}betterdocs_analytics as analytics on docs.ID = analytics.post_id";
$query = $wpdb->get_results( "
{$select}
{$join}
WHERE post_type = 'docs' AND post_status = 'publish' AND (analytics.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
GROUP BY analytics.post_id
ORDER BY total_views DESC LIMIT 5
" );
$docs = [];
foreach ( $query as $key => $value ) {
$docs[$key] = $this->get_docs_items( $value );
}
return $docs;
}
/**
* Calculate Total BetterDocs Views
*
* @return array
*/
public function get_data( $frequency = 'betterdocs_weekly' ) {
if ( $frequency == 'betterdocs_daily' ) {
$start_date = $this->create_date( 'last day' );
$end_date = $this->create_date( 'last day' );
$previous_start_date = $this->create_date( 'last day last day' );
$previous_end_date = $this->create_date( 'last day last day' );
}
if ( $frequency == 'betterdocs_weekly' ) {
$start_date = $this->create_date( '-7days' );
$end_date = $this->create_date( 'last day' );
$previous_start_date = $this->create_date( '-14days' );
$previous_end_date = $this->create_date( '-7days' );
}
if ( $frequency == 'betterdocs_monthly' ) {
$previous_start_date = $this->create_date( 'first day of last month last month' );
$previous_end_date = $this->create_date( 'last day of last month last month' );
$start_date = $this->create_date( 'first day of last month' );
$end_date = $this->create_date( 'last day of last month' );
}
$views_current_data = $this->get_views( $start_date, $end_date );
$views_previous_data = $this->get_views( $previous_start_date, $previous_end_date );
$search_current_data = $this->get_search( $start_date, $end_date );
$search_previous_data = $this->get_search( $previous_start_date, $previous_end_date );
$docs_current_data = $this->get_leading_docs( $start_date, $end_date );
$docs_total_current_reactions = array_sum( array_column( $docs_current_data, 'total_reactions' ) );
$search_keyword_data = $this->get_search_keywords( $start_date, $end_date );
$count_new_docs_current = $this->count_new_docs( $start_date, $end_date );
$count_new_docs_previous = $this->count_new_docs( $previous_start_date, $previous_end_date );
$from_date = $start_date;
$to_date = $frequency == 'betterdocs_daily' ? $start_date : $end_date;
$data = [
'views' => [
'from_date' => $from_date,
'to_date' => $to_date,
'current_data' => $views_current_data,
'previous_data' => $views_previous_data
],
'search' => [
'from_date' => $from_date,
'to_date' => $to_date,
'current_data' => $search_current_data,
'previous_data' => $search_previous_data,
'keywords' => $search_keyword_data
],
'new_docs' => [
'from_date' => $from_date,
'to_date' => $to_date,
'current_data' => $count_new_docs_current,
'previous_data' => $count_new_docs_previous
],
'docs' => [
'from_date' => $from_date,
'to_date' => $to_date,
'current_data' => $docs_current_data,
'total_current_reactions' => $docs_total_current_reactions
]
];
return $data;
}
/**
* Adds a custom cron schedule for Weekly.
*
* @param array $schedules An array of non-default cron schedules.
* @return array Filtered array of non-default cron schedules.
*/
function schedules_cron( $schedules = [] ) {
$schedules['betterdocs_weekly'] = [
'interval' => 604800,
'display' => __( 'Once Weekly', 'betterdocs' )
];
$schedules['betterdocs_daily'] = [
'interval' => 86400,
'display' => __( 'Once Daily', 'betterdocs' )
];
$schedules['betterdocs_monthly'] = [
'interval' => 2635200,
'display' => __( 'Once Monthly', 'betterdocs' )
];
return $schedules;
}
/**
* Set Email Receiver mail address
* By Default, Admin Email Address
* Admin can set Custom email from NotificationX Advanced Settings Panel
*
* @return string|array<string>
*/
public function receiver_email_address( $email = '' ) {
if ( empty( $email ) ) {
$email = $this->settings->get( 'reporting_email', '' );
if ( empty( $email ) ) {
$email = get_option( 'admin_email' );
}
}
if ( strpos( $email, ',' ) !== false ) {
$email = str_replace( ' ', '', $email );
$email = explode( ',', $email );
} else {
$email = trim( $email );
}
return $email;
}
/**
* Set Email Subject
* By Default, subject will be "Weekly Reporting for NotificationX"
* Admin can set Custom Subject from NotificationX Advanced Settings Panel
*
* @return string
*/
public function email_subject() {
return wp_sprintf( __( 'Your Documentation Performance of %s Website', 'betterdocs-pro' ), get_bloginfo( 'name' ) );
}
/**
* Enable Cron Function
* Hook: admin_init
*/
public function activate() {
$day = $this->settings->get( 'reporting_day', 'monday' );
$frequency = $this->settings->get( 'reporting_frequency', 'betterdocs_weekly' );
if ( $frequency === 'betterdocs_weekly' ) {
$datetime = strtotime( "next $day 9AM", current_time( 'timestamp' ) );
$this->schedule_event( $datetime, $frequency, 'betterdocs_weekly_email_reporting' );
}
}
/**
* Execute Cron Function
* Hook: admin_init
*/
public function send_email( $frequency = 'betterdocs_weekly', $test = false, $email = null ) {
// if ( ! $this->settings->get( 'enable_analytics', false ) && ! $test ) {
// return $this->error( 'betterdocs_disabled_analytics', __( 'Analytics disabled. No data found.', 'betterdocs' ) );
// }
$data = $this->get_data( $frequency );
if ( empty( $data ) && ! $test ) {
return $this->error( 'betterdocs_no_reporting_data', __( 'No data found.', 'betterdocs' ) );
}
$to = null == $email ? $this->receiver_email_address() : $email;
if ( empty( $to ) ) {
return $this->error( 'betterdocs_reporting_email', __( 'No email found.', 'betterdocs' ) );
}
$subject = $this->email_subject();
ob_start();
betterdocs()->views->get( 'admin/email/header' );
betterdocs()->views->get( 'admin/email/body', [
'days' => $this->frequency( $frequency ),
'bloginfo' => get_bloginfo( 'name' ),
'frequency' => $frequency,
'args' => $data,
'report_email' => $this
] );
betterdocs()->views->get( 'admin/email/footer' );
$message = ob_get_clean();
$admin_email = get_option( 'admin_email' );
$headers = ['Content-Type: text/html; charset=UTF-8', "From: BetterDocs <{$admin_email}>"];
return wp_mail( $to, $subject, $message, $headers );
}
/**
* Disable Cron Function
* Hook: plugin_deactivation
*/
public function deactivate( $clear_hook = 'betterdocs_weekly_email_reporting', $filter = null ) {
if ( is_string( $clear_hook ) ) {
$this->clear_scheduled_hook( $clear_hook );
} elseif ( $clear_hook === true ) {
$deactivate_hooks = [
'betterdocs_daily_email_reporting',
'betterdocs_weekly_email_reporting',
'betterdocs_monthly_email_reporting'
];
array_walk( $deactivate_hooks, function ( $item ) use ( $filter ) {
if ( ! ( $filter !== null && $filter === $item ) ) {
$this->clear_scheduled_hook( $item );
}
} );
}
}
public function schedule_event( $timestamp, $frequency, $hook ) {
if ( ! wp_next_scheduled( $hook ) ) {
wp_schedule_event( $timestamp, $frequency, $hook );
$this->deactivate( true, $hook );
}
}
public function clear_scheduled_hook( $hook ) {
wp_clear_scheduled_hook( $hook );
}
public function percentage( $previous, $current ) {
if ( $previous == 0 ) {
$factor = $current * 100;
} elseif ( $current == 0 ) {
$factor = $previous * 100;
} else {
$factor = ( ( (int)$current - (int)$previous ) / (int)$previous ) * 100;
}
return number_format( $factor, 2, '.', '' );
}
public function frequency( $frequency = 'betterdocs_weekly' ) {
switch ( $frequency ) {
case 'betterdocs_weekly':
$days_ago = '7 days';
break;
case 'betterdocs_daily':
$days_ago = '1 day';
break;
case 'betterdocs_monthly':
$initial_timestamp = strtotime( 'first day of last month', current_time( 'timestamp' ) );
$days_in_last_month = cal_days_in_month( CAL_GREGORIAN, date( 'm', $initial_timestamp ), date( 'Y', $initial_timestamp ) );
$days_ago = $days_in_last_month . ' days';
break;
}
return $days_ago;
}
public function test_email_report( $request ) {
$email = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $request->get_param( 'reporting_email' ) );
$response = [
'status' => 'success',
'data' => [
'context' => [
'test_report' => $email
]
]
];
if ( $email ) {
return $response;
} else {
$response['status'] = 'error';
return $response;
}
}
}