PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.3
4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 All 200 releases
← All changes | includes/Admin/ReportEmail.php +394 -426 4.5.63.5.3 View file →
@@ -1,13 +1,8 @@
1 1 <?php
2 -// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- weekly/monthly analytics aggregation; runs once per email send.
2 +
3 3 namespace WPDeveloper\BetterDocs\Admin;
4 4
5 -if ( ! defined( 'ABSPATH' ) ) {
6 - exit;
7 -}
8 -
9 -
10 5 use WP_Error;
11 6 use WP_Query;
12 7 use stdClass;
13 8 use WPDeveloper\BetterDocs\Utils\Base;
@@ -19,484 +14,457 @@
19 14 *
20 15 * @since 1.4.4
21 16 */
22 17 class ReportEmail extends Base {
23 - /**
24 - * Get a single Instance of Analytics
25 - * @var Settings
26 - */
27 - public $settings;
18 + /**
19 + * Get a single Instance of Analytics
20 + * @var Settings
21 + */
22 + public $settings;
28 23
29 - private static $current_timestamp = null;
30 - private static $current_date = null;
24 + private static $current_timestamp = null;
25 + private static $current_date = null;
31 26
32 - /**
33 - * Initially Invoked by Default.
34 - */
35 - public function __construct( Settings $settings ) {
36 - $this->settings = $settings;
27 + /**
28 + * Initially Invoked by Default.
29 + */
30 + public function __construct( Settings $settings ) {
31 + $this->settings = $settings;
37 32
38 - add_action( 'betterdocs::settings::saved', [ $this, 'after_save_settings' ] );
33 + add_action( 'betterdocs::settings::saved', [$this, 'after_save_settings'] );
39 34
40 - if ( $this->settings->get( 'enable_reporting', false ) ) {
41 - $this->init();
42 - }
43 - }
35 + if ( $this->settings->get( 'enable_reporting', false ) ) {
36 + $this->init();
37 + }
38 + }
44 39
45 - public function init() {
46 - add_filter( 'cron_schedules', [ $this, 'schedules_cron' ] );
47 - add_action( 'admin_init', [ $this, 'activate' ] );
48 - add_action( 'betterdocs_weekly_email_reporting', [ $this, 'send_email' ] );
49 - }
40 + public function init() {
41 + add_filter( 'cron_schedules', [$this, 'schedules_cron'] );
42 + add_action( 'admin_init', [$this, 'activate'] );
43 + add_action( 'betterdocs_weekly_email_reporting', [$this, 'send_email'] );
44 + }
50 45
51 - public function after_save_settings() {
52 - if ( $this->settings->get( 'enable_reporting', false ) ) {
53 - $this->activate();
54 - } else {
55 - $this->deactivate( true );
56 - }
57 - }
46 + public function after_save_settings() {
47 + if ( $this->settings->get( 'enable_reporting', false ) ) {
48 + $this->activate();
49 + } else {
50 + $this->deactivate( true );
51 + }
52 + }
58 53
59 - public function reporting( $request ) {
60 - if ( ! boolval( $request->get_param( 'disable_reporting' ) ) ) {
61 - if ( $request->has_param( 'reporting_email' ) ) {
62 - $email = $request->get_param( 'reporting_email' );
63 - }
64 - $email = $this->receiver_email_address( $email );
54 + public function reporting( $request ) {
55 + if ( ! boolval( $request->get_param( 'disable_reporting' ) ) ) {
56 + if ( $request->has_param( 'reporting_email' ) ) {
57 + $email = $request->get_param( 'reporting_email' );
58 + }
59 + $email = $this->receiver_email_address( $email );
65 60
66 - if ( ! empty( $email ) ) {
67 - $is_send = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $email );
68 - if ( $is_send && ! is_wp_error( $is_send ) ) {
69 - return [ 'message' => __( 'Successfully Sent an Email', 'betterdocs' ) ];
70 - } elseif ( is_wp_error( $is_send ) ) {
71 - return $is_send;
72 - } else {
73 - return $this->error( 'betterdocs_unknown_reason', __( 'Email cannot be sent for some reason.', 'betterdocs' ) );
74 - }
75 - }
76 - return $this->error( 'betterdocs_unknown_reason', __( 'Invalid email address.', 'betterdocs' ) );
77 - } else {
78 - return $this->error( 'betterdocs_disabled_reporting', __( 'You have to enable Reporting first.', 'betterdocs' ) );
79 - }
80 - }
61 + if ( ! empty( $email ) ) {
62 + $is_send = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $email );
63 + if ( $is_send && ! is_wp_error( $is_send ) ) {
64 + return ['message' => __( 'Successfully Sent an Email', 'betterdocs' )];
65 + } else if ( is_wp_error( $is_send ) ) {
66 + return $is_send;
67 + } else {
68 + return $this->error( 'betterdocs_unknown_reason', __( 'Email cannot be sent for some reason.', 'betterdocs' ) );
69 + }
70 + }
71 + return $this->error( 'betterdocs_unknown_reason', __( 'Invalid email address.', 'betterdocs' ) );
72 + } else {
73 + return $this->error( 'betterdocs_disabled_reporting', __( 'You have to enable Reporting first.', 'betterdocs' ) );
74 + }
75 + }
81 76
82 - public function error( $code, $message ) {
83 - return new WP_Error( $code, $message );
84 - }
77 + public function error( $code, $message ) {
78 + return new WP_Error( $code, $message );
79 + }
85 80
86 - private static function timestamps( $date = false ) {
87 - if ( is_null( self::$current_timestamp ) ) {
88 - self::$current_timestamp = current_time( 'timestamp' );
89 - }
90 - if ( $date ) {
91 - if ( is_null( self::$current_date ) ) {
92 - self::$current_date = current_time( 'Y-m-d' );
93 - }
94 - return self::$current_date;
95 - }
96 - return self::$current_timestamp;
97 - }
81 + private static function timestamps( $date = false ) {
82 + if ( is_null( self::$current_timestamp ) ) {
83 + self::$current_timestamp = current_time( 'timestamp' );
84 + }
85 + if ( $date ) {
86 + if ( is_null( self::$current_date ) ) {
87 + self::$current_date = current_time( 'Y-m-d' );
88 + }
89 + return self::$current_date;
90 + }
91 + return self::$current_timestamp;
92 + }
98 93
99 - public function create_date( $count = '-7days' ) {
100 - return gmdate( 'Y-m-d', strtotime( $count, self::timestamps() ) );
101 - }
94 + public function create_date( $count = '-7days' ) {
95 + return date( 'Y-m-d', strtotime( $count, self::timestamps() ) );
96 + }
102 97
103 - public function get_views( $start_date, $end_date = null ) {
104 - global $wpdb;
105 - $query = $wpdb->get_results(
106 - $wpdb->prepare(
107 - "SELECT sum(impressions) as views, sum(unique_visit) as unique_visit, sum(happy + sad + normal) as reactions
108 - FROM {$wpdb->prefix}betterdocs_analytics
109 - WHERE created_at BETWEEN %s AND %s",
110 - (string) $start_date,
111 - (string) $end_date
112 - )
113 - );
114 - return $query;
115 - }
98 + public function get_views( $start_date, $end_date = null ) {
99 + global $wpdb;
116 100
117 - public function get_search( $start_date, $end_date = null ) {
118 - global $wpdb;
119 - $query = $wpdb->get_results(
120 - $wpdb->prepare(
121 - "SELECT SUM(count + not_found_count) as search_count, SUM(count) as search_found, SUM(not_found_count) as search_not_found_count
122 - FROM {$wpdb->prefix}betterdocs_search_log as search_log
123 - WHERE search_log.created_at BETWEEN %s AND %s",
124 - (string) $start_date,
125 - (string) $end_date
126 - )
127 - );
101 + $query = $wpdb->get_results( "
102 + SELECT sum(impressions) as views, sum(unique_visit) as unique_visit, sum(happy + sad + normal) as reactions
103 + FROM {$wpdb->prefix}betterdocs_analytics
104 + WHERE (created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
105 + " );
106 + return $query;
107 + }
128 108
129 - return $query;
130 - }
109 + public function get_search( $start_date, $end_date = null ) {
110 + global $wpdb;
131 111
132 - public function count_new_docs( $start_date, $end_date = null ) {
133 - $args = [
134 - 'post_type' => 'docs',
135 - 'post_status' => 'publish',
136 - 'posts_per_page' => -1,
137 - 'date_query' => [
138 - [
139 - 'after' => $start_date,
140 - 'before' => $end_date,
141 - 'inclusive' => true
142 - ]
143 - ]
144 - ];
145 - $query = new WP_Query( $args );
112 + $query = $wpdb->get_results( "
113 + SELECT SUM(count + not_found_count) as search_count, SUM(count) as search_found, SUM(not_found_count) as search_not_found_count
114 + FROM {$wpdb->prefix}betterdocs_search_log as search_log
115 + WHERE (search_log.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
116 + " );
146 117
147 - return $query->found_posts;
148 - }
118 + return $query;
119 + }
149 120
150 - public function get_search_keywords( $start_date, $end_date = null ) {
151 - global $wpdb;
152 - $query = $wpdb->get_results(
153 - $wpdb->prepare(
154 - "SELECT search_keyword.keyword, search_log.keyword_id,
155 - SUM(search_log.count + search_log.not_found_count) as total_search,
156 - SUM(search_log.count) as count,
157 - SUM(search_log.not_found_count) as not_found
158 - FROM {$wpdb->prefix}betterdocs_search_keyword as search_keyword
159 - JOIN {$wpdb->prefix}betterdocs_search_log as search_log ON search_keyword.id = search_log.keyword_id
160 - WHERE search_log.created_at BETWEEN %s AND %s
161 - GROUP BY search_log.keyword_id
162 - ORDER BY count DESC LIMIT 5",
163 - (string) $start_date,
164 - (string) $end_date
165 - )
166 - );
121 + public function count_new_docs( $start_date, $end_date = null ) {
122 + $args = [
123 + 'post_type' => 'docs',
124 + 'post_status' => 'publish',
125 + 'posts_per_page' => -1,
126 + 'date_query' => [
127 + [
128 + 'after' => $start_date,
129 + 'before' => $end_date,
130 + 'inclusive' => true
131 + ]
132 + ]
133 + ];
134 + $query = new WP_Query( $args );
167 135
168 - return $query;
169 - }
136 + return $query->found_posts;
137 + }
170 138
171 - public function get_docs_items( $request ) {
172 - $prepared_post = new stdClass();
139 + public function get_search_keywords( $start_date, $end_date = null ) {
140 + global $wpdb;
141 + $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";
142 + $join = "FROM {$wpdb->prefix}betterdocs_search_keyword as search_keyword
143 + JOIN {$wpdb->prefix}betterdocs_search_log as search_log on search_keyword.id = search_log.keyword_id";
173 144
174 - if ( isset( $request->ID ) ) {
175 - $prepared_post->ID = $request->ID;
176 - }
145 + $query = $wpdb->get_results( "
146 + {$select}
147 + {$join}
148 + WHERE (search_log.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
149 + GROUP BY search_log.keyword_id
150 + ORDER BY count DESC LIMIT 5
151 + " );
177 152
178 - if ( isset( $request->post_title ) ) {
179 - $prepared_post->title = betterdocs()->template_helper->kses( $request->post_title );
180 - }
153 + return $query;
154 + }
181 155
182 - if ( isset( $request->total_views ) ) {
183 - $prepared_post->total_views = $request->total_views;
184 - }
156 + public function get_docs_items( $request ) {
157 + $prepared_post = new stdClass();
185 158
186 - if ( isset( $request->total_unique_visit ) ) {
187 - $prepared_post->total_unique_visit = $request->total_unique_visit;
188 - }
159 + if ( isset( $request->ID ) ) {
160 + $prepared_post->ID = $request->ID;
161 + }
189 162
190 - if ( isset( $request->total_reactions ) ) {
191 - $prepared_post->total_reactions = $request->total_reactions;
192 - }
163 + if ( isset( $request->post_title ) ) {
164 + $prepared_post->title = betterdocs()->template_helper->kses( $request->post_title );
165 + }
193 166
194 - if ( isset( $request->ID ) ) {
195 - $prepared_post->link = get_permalink( $request->ID );
196 - }
167 + if ( isset( $request->total_views ) ) {
168 + $prepared_post->total_views = $request->total_views;
169 + }
197 170
198 - return $prepared_post;
199 - }
171 + if ( isset( $request->total_unique_visit ) ) {
172 + $prepared_post->total_unique_visit = $request->total_unique_visit;
173 + }
200 174
201 - public function get_leading_docs( $start_date, $end_date = null ) {
202 - global $wpdb;
175 + if ( isset( $request->total_reactions ) ) {
176 + $prepared_post->total_reactions = $request->total_reactions;
177 + }
203 178
204 - $query = $wpdb->get_results(
205 - $wpdb->prepare(
206 - "SELECT docs.ID, docs.post_author, docs.post_title,
207 - SUM(analytics.impressions) as total_views,
208 - SUM(analytics.unique_visit) as total_unique_visit,
209 - SUM(analytics.happy + analytics.sad + analytics.normal) as total_reactions
210 - FROM {$wpdb->posts} as docs
211 - JOIN {$wpdb->prefix}betterdocs_analytics as analytics ON docs.ID = analytics.post_id
212 - WHERE post_type = %s AND post_status = %s
213 - AND analytics.created_at BETWEEN %s AND %s
214 - GROUP BY analytics.post_id
215 - ORDER BY total_views DESC LIMIT 5",
216 - 'docs',
217 - 'publish',
218 - (string) $start_date,
219 - (string) $end_date
220 - )
221 - );
179 + if ( isset( $request->ID ) ) {
180 + $prepared_post->link = get_permalink( $request->ID );
181 + }
222 182
223 - $docs = [];
224 - foreach ( $query as $key => $value ) {
225 - $docs[ $key ] = $this->get_docs_items( $value );
226 - }
183 + return $prepared_post;
184 + }
227 185
228 - return $docs;
229 - }
186 + public function get_leading_docs( $start_date, $end_date = null ) {
187 + global $wpdb;
230 188
231 - /**
232 - * Calculate Total BetterDocs Views
233 - *
234 - * @return array
235 - */
236 - public function get_data( $frequency = 'betterdocs_weekly' ) {
237 - if ( $frequency == 'betterdocs_daily' ) {
238 - $start_date = $this->create_date( 'last day' );
239 - $end_date = $this->create_date( 'last day' );
240 - $previous_start_date = $this->create_date( 'last day last day' );
241 - $previous_end_date = $this->create_date( 'last day last day' );
242 - }
189 + $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";
190 + $join = "FROM {$wpdb->prefix}posts as docs
191 + JOIN {$wpdb->prefix}betterdocs_analytics as analytics on docs.ID = analytics.post_id";
243 192
244 - if ( $frequency == 'betterdocs_weekly' ) {
245 - $start_date = $this->create_date( '-7days' );
246 - $end_date = $this->create_date( 'last day' );
247 - $previous_start_date = $this->create_date( '-14days' );
248 - $previous_end_date = $this->create_date( '-7days' );
249 - }
250 - if ( $frequency == 'betterdocs_monthly' ) {
251 - $previous_start_date = $this->create_date( 'first day of last month last month' );
252 - $previous_end_date = $this->create_date( 'last day of last month last month' );
253 - $start_date = $this->create_date( 'first day of last month' );
254 - $end_date = $this->create_date( 'last day of last month' );
255 - }
193 + $query = $wpdb->get_results( "
194 + {$select}
195 + {$join}
196 + WHERE post_type = 'docs' AND post_status = 'publish' AND (analytics.created_at BETWEEN '" . $start_date . "' AND '" . $end_date . "')
197 + GROUP BY analytics.post_id
198 + ORDER BY total_views DESC LIMIT 5
199 + " );
256 200
257 - $views_current_data = $this->get_views( $start_date, $end_date );
258 - $views_previous_data = $this->get_views( $previous_start_date, $previous_end_date );
259 - $search_current_data = $this->get_search( $start_date, $end_date );
260 - $search_previous_data = $this->get_search( $previous_start_date, $previous_end_date );
261 - $docs_current_data = $this->get_leading_docs( $start_date, $end_date );
262 - $docs_total_current_reactions = array_sum( array_column( $docs_current_data, 'total_reactions' ) );
263 - $search_keyword_data = $this->get_search_keywords( $start_date, $end_date );
264 - $count_new_docs_current = $this->count_new_docs( $start_date, $end_date );
265 - $count_new_docs_previous = $this->count_new_docs( $previous_start_date, $previous_end_date );
201 + $docs = [];
202 + foreach ( $query as $key => $value ) {
203 + $docs[$key] = $this->get_docs_items( $value );
204 + }
266 205
267 - $from_date = $start_date;
268 - $to_date = $frequency == 'betterdocs_daily' ? $start_date : $end_date;
206 + return $docs;
207 + }
269 208
270 - $data = [
271 - 'views' => [
272 - 'from_date' => $from_date,
273 - 'to_date' => $to_date,
274 - 'current_data' => $views_current_data,
275 - 'previous_data' => $views_previous_data
276 - ],
277 - 'search' => [
278 - 'from_date' => $from_date,
279 - 'to_date' => $to_date,
280 - 'current_data' => $search_current_data,
281 - 'previous_data' => $search_previous_data,
282 - 'keywords' => $search_keyword_data
283 - ],
284 - 'new_docs' => [
285 - 'from_date' => $from_date,
286 - 'to_date' => $to_date,
287 - 'current_data' => $count_new_docs_current,
288 - 'previous_data' => $count_new_docs_previous
289 - ],
290 - 'docs' => [
291 - 'from_date' => $from_date,
292 - 'to_date' => $to_date,
293 - 'current_data' => $docs_current_data,
294 - 'total_current_reactions' => $docs_total_current_reactions
295 - ]
296 - ];
297 - return $data;
298 - }
209 + /**
210 + * Calculate Total BetterDocs Views
211 + *
212 + * @return array
213 + */
214 + public function get_data( $frequency = 'betterdocs_weekly' ) {
215 + if ( $frequency == 'betterdocs_daily' ) {
216 + $start_date = $this->create_date( 'last day' );
217 + $end_date = $this->create_date( 'last day' );
218 + $previous_start_date = $this->create_date( 'last day last day' );
219 + $previous_end_date = $this->create_date( 'last day last day' );
220 + }
299 221
300 - /**
301 - * Adds a custom cron schedule for Weekly.
302 - *
303 - * @param array $schedules An array of non-default cron schedules.
304 - * @return array Filtered array of non-default cron schedules.
305 - */
306 - function schedules_cron( $schedules = [] ) {
307 - $schedules['betterdocs_weekly'] = [
308 - 'interval' => 604800,
309 - 'display' => __( 'Once Weekly', 'betterdocs' )
310 - ];
311 - $schedules['betterdocs_daily'] = [
312 - 'interval' => 86400,
313 - 'display' => __( 'Once Daily', 'betterdocs' )
314 - ];
315 - $schedules['betterdocs_monthly'] = [
316 - 'interval' => 2635200,
317 - 'display' => __( 'Once Monthly', 'betterdocs' )
318 - ];
319 - return $schedules;
320 - }
222 + if ( $frequency == 'betterdocs_weekly' ) {
223 + $start_date = $this->create_date( '-7days' );
224 + $end_date = $this->create_date( 'last day' );
225 + $previous_start_date = $this->create_date( '-14days' );
226 + $previous_end_date = $this->create_date( '-7days' );
227 + }
228 + if ( $frequency == 'betterdocs_monthly' ) {
229 + $previous_start_date = $this->create_date( 'first day of last month last month' );
230 + $previous_end_date = $this->create_date( 'last day of last month last month' );
231 + $start_date = $this->create_date( 'first day of last month' );
232 + $end_date = $this->create_date( 'last day of last month' );
233 + }
321 234
322 - /**
323 - * Set Email Receiver mail address
324 - * By Default, Admin Email Address
325 - * Admin can set Custom email from NotificationX Advanced Settings Panel
326 - *
327 - * @return string|array<string>
328 - */
329 - public function receiver_email_address( $email = '' ) {
330 - if ( empty( $email ) ) {
331 - $email = $this->settings->get( 'reporting_email', '' );
332 - if ( empty( $email ) ) {
333 - $email = get_option( 'admin_email' );
334 - }
335 - }
336 - if ( strpos( $email, ',' ) !== false ) {
337 - $email = str_replace( ' ', '', $email );
338 - $email = explode( ',', $email );
339 - } else {
340 - $email = trim( $email );
341 - }
342 - return $email;
343 - }
235 + $views_current_data = $this->get_views( $start_date, $end_date );
236 + $views_previous_data = $this->get_views( $previous_start_date, $previous_end_date );
237 + $search_current_data = $this->get_search( $start_date, $end_date );
238 + $search_previous_data = $this->get_search( $previous_start_date, $previous_end_date );
239 + $docs_current_data = $this->get_leading_docs( $start_date, $end_date );
240 + $docs_total_current_reactions = array_sum( array_column( $docs_current_data, 'total_reactions' ) );
241 + $search_keyword_data = $this->get_search_keywords( $start_date, $end_date );
242 + $count_new_docs_current = $this->count_new_docs( $start_date, $end_date );
243 + $count_new_docs_previous = $this->count_new_docs( $previous_start_date, $previous_end_date );
344 244
345 - /**
346 - * Set Email Subject
347 - * By Default, subject will be "Weekly Reporting for NotificationX"
348 - * Admin can set Custom Subject from NotificationX Advanced Settings Panel
349 - *
350 - * @return string
351 - */
352 - public function email_subject() {
353 - return wp_sprintf(
354 - // Translators: %s is replaced with the website name.
355 - __( 'Your Documentation Performance of %s Website', 'betterdocs' ),
356 - get_bloginfo( 'name' )
357 - );
358 - }
245 + $from_date = $start_date;
246 + $to_date = $frequency == 'betterdocs_daily' ? $start_date : $end_date;
359 247
360 - /**
361 - * Enable Cron Function
362 - * Hook: admin_init
363 - */
364 - public function activate() {
365 - $day = $this->settings->get( 'reporting_day', 'monday' );
366 - $frequency = $this->settings->get( 'reporting_frequency', 'betterdocs_weekly' );
248 + $data = [
249 + 'views' => [
250 + 'from_date' => $from_date,
251 + 'to_date' => $to_date,
252 + 'current_data' => $views_current_data,
253 + 'previous_data' => $views_previous_data
254 + ],
255 + 'search' => [
256 + 'from_date' => $from_date,
257 + 'to_date' => $to_date,
258 + 'current_data' => $search_current_data,
259 + 'previous_data' => $search_previous_data,
260 + 'keywords' => $search_keyword_data
261 + ],
262 + 'new_docs' => [
263 + 'from_date' => $from_date,
264 + 'to_date' => $to_date,
265 + 'current_data' => $count_new_docs_current,
266 + 'previous_data' => $count_new_docs_previous
267 + ],
268 + 'docs' => [
269 + 'from_date' => $from_date,
270 + 'to_date' => $to_date,
271 + 'current_data' => $docs_current_data,
272 + 'total_current_reactions' => $docs_total_current_reactions
273 + ]
274 + ];
275 + return $data;
276 + }
367 277
368 - if ( $frequency === 'betterdocs_weekly' ) {
369 - $datetime = strtotime( "next $day 9AM", current_time( 'timestamp' ) );
370 - $this->schedule_event( $datetime, $frequency, 'betterdocs_weekly_email_reporting' );
371 - }
372 - }
278 + /**
279 + * Adds a custom cron schedule for Weekly.
280 + *
281 + * @param array $schedules An array of non-default cron schedules.
282 + * @return array Filtered array of non-default cron schedules.
283 + */
284 + function schedules_cron( $schedules = [] ) {
285 + $schedules['betterdocs_weekly'] = [
286 + 'interval' => 604800,
287 + 'display' => __( 'Once Weekly', 'betterdocs' )
288 + ];
289 + $schedules['betterdocs_daily'] = [
290 + 'interval' => 86400,
291 + 'display' => __( 'Once Daily', 'betterdocs' )
292 + ];
293 + $schedules['betterdocs_monthly'] = [
294 + 'interval' => 2635200,
295 + 'display' => __( 'Once Monthly', 'betterdocs' )
296 + ];
297 + return $schedules;
298 + }
373 299
374 - /**
375 - * Execute Cron Function
376 - * Hook: admin_init
377 - */
378 - public function send_email( $frequency = 'betterdocs_weekly', $test = false, $email = null ) {
379 - // if ( ! $this->settings->get( 'enable_analytics', false ) && ! $test ) {
380 - // return $this->error( 'betterdocs_disabled_analytics', __( 'Analytics disabled. No data found.', 'betterdocs' ) );
381 - // }
300 + /**
301 + * Set Email Receiver mail address
302 + * By Default, Admin Email Address
303 + * Admin can set Custom email from NotificationX Advanced Settings Panel
304 + *
305 + * @return string|array<string>
306 + */
307 + public function receiver_email_address( $email = '' ) {
308 + if ( empty( $email ) ) {
309 + $email = $this->settings->get( 'reporting_email', '' );
310 + if ( empty( $email ) ) {
311 + $email = get_option( 'admin_email' );
312 + }
313 + }
314 + if ( strpos( $email, ',' ) !== false ) {
315 + $email = str_replace( ' ', '', $email );
316 + $email = explode( ',', $email );
317 + } else {
318 + $email = trim( $email );
319 + }
320 + return $email;
321 + }
382 322
383 - $data = $this->get_data( $frequency );
384 - if ( empty( $data ) && ! $test ) {
385 - return $this->error( 'betterdocs_no_reporting_data', __( 'No data found.', 'betterdocs' ) );
386 - }
323 + /**
324 + * Set Email Subject
325 + * By Default, subject will be "Weekly Reporting for NotificationX"
326 + * Admin can set Custom Subject from NotificationX Advanced Settings Panel
327 + *
328 + * @return string
329 + */
330 + public function email_subject() {
331 + return wp_sprintf( __( 'Your Documentation Performance of %s Website', 'betterdocs-pro' ), get_bloginfo( 'name' ) );
332 + }
387 333
388 - $to = null == $email ? $this->receiver_email_address() : $email;
389 - if ( empty( $to ) ) {
390 - return $this->error( 'betterdocs_reporting_email', __( 'No email found.', 'betterdocs' ) );
391 - }
334 + /**
335 + * Enable Cron Function
336 + * Hook: admin_init
337 + */
338 + public function activate() {
339 + $day = $this->settings->get( 'reporting_day', 'monday' );
340 + $frequency = $this->settings->get( 'reporting_frequency', 'betterdocs_weekly' );
392 341
393 - $subject = $this->email_subject();
342 + if ( $frequency === 'betterdocs_weekly' ) {
343 + $datetime = strtotime( "next $day 9AM", current_time( 'timestamp' ) );
344 + $this->schedule_event( $datetime, $frequency, 'betterdocs_weekly_email_reporting' );
345 + }
346 + }
394 347
395 - ob_start();
396 - betterdocs()->views->get( 'admin/email/header' );
348 + /**
349 + * Execute Cron Function
350 + * Hook: admin_init
351 + */
352 + public function send_email( $frequency = 'betterdocs_weekly', $test = false, $email = null ) {
353 + // if ( ! $this->settings->get( 'enable_analytics', false ) && ! $test ) {
354 + // return $this->error( 'betterdocs_disabled_analytics', __( 'Analytics disabled. No data found.', 'betterdocs' ) );
355 + // }
397 356
398 - betterdocs()->views->get(
399 - 'admin/email/body',
400 - [
401 - 'days' => $this->frequency( $frequency ),
402 - 'bloginfo' => get_bloginfo( 'name' ),
403 - 'frequency' => $frequency,
404 - 'args' => $data,
405 - 'report_email' => $this
406 - ]
407 - );
357 + $data = $this->get_data( $frequency );
358 + if ( empty( $data ) && ! $test ) {
359 + return $this->error( 'betterdocs_no_reporting_data', __( 'No data found.', 'betterdocs' ) );
360 + }
408 361
409 - betterdocs()->views->get( 'admin/email/footer' );
410 - $message = ob_get_clean();
411 - $admin_email = get_option( 'admin_email' );
412 - $headers = [ 'Content-Type: text/html; charset=UTF-8', "From: BetterDocs <{$admin_email}>" ];
362 + $to = null == $email ? $this->receiver_email_address() : $email;
363 + if ( empty( $to ) ) {
364 + return $this->error( 'betterdocs_reporting_email', __( 'No email found.', 'betterdocs' ) );
365 + }
413 366
414 - return wp_mail( $to, $subject, $message, $headers );
415 - }
367 + $subject = $this->email_subject();
416 368
417 - /**
418 - * Disable Cron Function
419 - * Hook: plugin_deactivation
420 - */
421 - public function deactivate( $clear_hook = 'betterdocs_weekly_email_reporting', $filter = null ) {
422 - if ( is_string( $clear_hook ) ) {
423 - $this->clear_scheduled_hook( $clear_hook );
424 - } elseif ( $clear_hook === true ) {
425 - $deactivate_hooks = [
426 - 'betterdocs_daily_email_reporting',
427 - 'betterdocs_weekly_email_reporting',
428 - 'betterdocs_monthly_email_reporting'
429 - ];
369 + ob_start();
370 + betterdocs()->views->get( 'admin/email/header' );
430 371
431 - array_walk(
432 - $deactivate_hooks,
433 - function ( $item ) use ( $filter ) {
434 - if ( ! ( $filter !== null && $filter === $item ) ) {
435 - $this->clear_scheduled_hook( $item );
436 - }
437 - }
438 - );
439 - }
440 - }
372 + betterdocs()->views->get( 'admin/email/body', [
373 + 'days' => $this->frequency( $frequency ),
374 + 'bloginfo' => get_bloginfo( 'name' ),
375 + 'frequency' => $frequency,
376 + 'args' => $data,
377 + 'report_email' => $this
378 + ] );
441 379
442 - public function schedule_event( $timestamp, $frequency, $hook ) {
443 - if ( ! wp_next_scheduled( $hook ) ) {
444 - wp_schedule_event( $timestamp, $frequency, $hook );
380 + betterdocs()->views->get( 'admin/email/footer' );
381 + $message = ob_get_clean();
382 + $admin_email = get_option( 'admin_email' );
383 + $headers = ['Content-Type: text/html; charset=UTF-8', "From: BetterDocs <{$admin_email}>"];
445 384
446 - $this->deactivate( true, $hook );
447 - }
448 - }
385 + return wp_mail( $to, $subject, $message, $headers );
386 + }
449 387
450 - public function clear_scheduled_hook( $hook ) {
451 - wp_clear_scheduled_hook( $hook );
452 - }
388 + /**
389 + * Disable Cron Function
390 + * Hook: plugin_deactivation
391 + */
392 + public function deactivate( $clear_hook = 'betterdocs_weekly_email_reporting', $filter = null ) {
393 + if ( is_string( $clear_hook ) ) {
394 + $this->clear_scheduled_hook( $clear_hook );
395 + } elseif ( $clear_hook === true ) {
396 + $deactivate_hooks = [
397 + 'betterdocs_daily_email_reporting',
398 + 'betterdocs_weekly_email_reporting',
399 + 'betterdocs_monthly_email_reporting'
400 + ];
453 401
454 - public function percentage( $previous, $current ) {
455 - if ( $previous == 0 ) {
456 - $factor = $current * 100;
457 - } elseif ( $current == 0 ) {
458 - $factor = $previous * 100;
459 - } else {
460 - $factor = ( ( (int) $current - (int) $previous ) / (int) $previous ) * 100;
461 - }
462 - return number_format( $factor, 2, '.', '' );
463 - }
402 + array_walk( $deactivate_hooks, function ( $item ) use ( $filter ) {
403 + if ( ! ( $filter !== null && $filter === $item ) ) {
404 + $this->clear_scheduled_hook( $item );
405 + }
406 + } );
407 + }
408 + }
464 409
465 - public function frequency( $frequency = 'betterdocs_weekly' ) {
466 - switch ( $frequency ) {
467 - case 'betterdocs_weekly':
468 - $days_ago = '7 days';
469 - break;
470 - case 'betterdocs_daily':
471 - $days_ago = '1 day';
472 - break;
473 - case 'betterdocs_monthly':
474 - $initial_timestamp = strtotime( 'first day of last month', current_time( 'timestamp' ) );
475 - $days_in_last_month = cal_days_in_month( CAL_GREGORIAN, (int) gmdate( 'm', $initial_timestamp ), (int) gmdate( 'Y', $initial_timestamp ) );
476 - $days_ago = $days_in_last_month . ' days';
477 - break;
478 - }
410 + public function schedule_event( $timestamp, $frequency, $hook ) {
411 + if ( ! wp_next_scheduled( $hook ) ) {
412 + wp_schedule_event( $timestamp, $frequency, $hook );
479 413
480 - return $days_ago;
481 - }
414 + $this->deactivate( true, $hook );
415 + }
416 + }
482 417
483 - public function test_email_report( $request ) {
484 - $email = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $request->get_param( 'reporting_email' ) );
418 + public function clear_scheduled_hook( $hook ) {
419 + wp_clear_scheduled_hook( $hook );
420 + }
485 421
486 - $response = [
487 - 'status' => 'success',
488 - 'data' => [
489 - 'context' => [
490 - 'test_report' => $email
491 - ]
492 - ]
493 - ];
422 + public function percentage( $previous, $current ) {
423 + if ( $previous == 0 ) {
424 + $factor = $current * 100;
425 + } elseif ( $current == 0 ) {
426 + $factor = $previous * 100;
427 + } else {
428 + $factor = ( ( (int)$current - (int)$previous ) / (int)$previous ) * 100;
429 + }
430 + return number_format( $factor, 2, '.', '' );
431 + }
494 432
495 - if ( $email ) {
496 - return $response;
497 - } else {
498 - $response['status'] = 'error';
499 - return $response;
500 - }
501 - }
433 + public function frequency( $frequency = 'betterdocs_weekly' ) {
434 + switch ( $frequency ) {
435 + case 'betterdocs_weekly':
436 + $days_ago = '7 days';
437 + break;
438 + case 'betterdocs_daily':
439 + $days_ago = '1 day';
440 + break;
441 + case 'betterdocs_monthly':
442 + $initial_timestamp = strtotime( 'first day of last month', current_time( 'timestamp' ) );
443 + $days_in_last_month = cal_days_in_month( CAL_GREGORIAN, date( 'm', $initial_timestamp ), date( 'Y', $initial_timestamp ) );
444 + $days_ago = $days_in_last_month . ' days';
445 + break;
446 + }
447 +
448 + return $days_ago;
449 + }
450 +
451 + public function test_email_report( $request ) {
452 + $email = $this->send_email( $request->get_param( 'reporting_frequency' ), true, $request->get_param( 'reporting_email' ) );
453 +
454 + $response = [
455 + 'status' => 'success',
456 + 'data' => [
457 + 'context' => [
458 + 'test_report' => $email
459 + ]
460 + ]
461 + ];
462 +
463 + if ( $email ) {
464 + return $response;
465 + } else {
466 + $response['status'] = 'error';
467 + return $response;
468 + }
469 + }
502 470 }