PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / trunk
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant vtrunk
2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 All 59 releases
merchant / admin / classes / class-merchant-admin-menu.php

class-merchant-admin-menu.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant trunk, at admin/classes/class-merchant-admin-menu.php

602 lines 18.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Merchant_Admin_Menu Class.
4 */
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly
8 }
9
10 if ( ! class_exists( 'Merchant_Admin_Menu' ) ) {
11
12 class Merchant_Admin_Menu {
13 public $page_title = 'Merchant';
14 public $plugin_slug = 'merchant';
15 public $capability = 'manage_options';
16 public $priority = 58;
17 public $notifications = array();
18 public static $installed_plugins = array();
19 private static $instance = null;
20
21 /**
22 * Instance.
23 *
24 */
25 public static function instance() {
26 if ( is_null( self::$instance ) ) {
27 self::$instance = new self();
28 }
29 return self::$instance;
30 }
31
32 /**
33 * Constructor.
34 *
35 */
36 public function __construct() {
37 if ( function_exists( 'merchant_white_label_is_applied' ) && merchant_white_label_is_applied() ) {
38 // Register the pages, then drop their menu entries. The settings URL
39 // keeps working for the admin who turned White Label on, who would
40 // otherwise have no way back to the switch.
41 add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
42 add_action( 'admin_menu', array( $this, 'hide_branded_menu' ), 99999 );
43
44 return;
45 }
46
47 if( $this->is_patcher_page() ) {
48 add_action('admin_enqueue_scripts', array( $this, 'enqueue_patcher_scripts' ));
49 }
50
51 add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
52 add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
53 add_action( 'admin_enqueue_scripts', array( $this, 'analytics_assets' ) );
54 add_action( 'wp_dashboard_setup', array( $this, 'dashboard_analytics_widget' ) );
55 add_action( 'wp_ajax_merchant_notifications_read', array( $this, 'ajax_notifications_read' ) );
56 add_action('admin_footer', array( $this, 'footer_internal_scripts' ));
57 }
58
59 /**
60 * Hide Merchant's menu entries while White Label is applied.
61 *
62 * Removing the entries leaves the registered pages callable, so a direct
63 * URL still works — the same approach the aThemes White Label plugin uses.
64 *
65 * @return void
66 */
67 public function hide_branded_menu() {
68 remove_menu_page( $this->plugin_slug );
69 }
70
71 /**
72 * Add dashboard widget.
73 *
74 * @return void
75 */
76 public function dashboard_analytics_widget() {
77 if( class_exists( 'WooCommerce' ) ) {
78 wp_add_dashboard_widget(
79 'merchant_modules_revenue', // Widget slug.
80 esc_html__( 'Daily added revenue by Merchant', 'merchant' ), // Title.
81 array( $this, 'dashboard_analytics_widget_content' ) // Display function.
82 );
83 }
84 }
85
86 /**
87 * Dashboard widget content.
88 *
89 * @return void
90 */
91 public function dashboard_analytics_widget_content() {
92 $reports = new Merchant_Analytics_Data_Reports();
93 $date_ranges = $reports->get_last_and_previous_7_days_ranges();
94 ?>
95 <div class="merchant-analytics-widget widget-chart-section">
96 <div class="chart" data-period="<?php
97 echo esc_attr( wp_json_encode( $reports->get_revenue_chart_report( $date_ranges['recent_period']['start'], $date_ranges['recent_period']['end'] ) ) )
98 ?>"></div>
99 <div class="foot">
100 <div class="date-range">
101 <span>
102 <input type="text" class="date-range-input" readonly value="<?php
103 echo esc_attr( implode( ' - ', array_values( $date_ranges['recent_period'] ) ) ) ?>" placeholder="<?php
104 esc_attr_e( 'Select date range', 'merchant' ); ?>">
105 </span>
106 <span class="merchant-analytics-loading-spinner"></span>
107 </div>
108 <div class="analytics-link">
109 <a href="<?php echo esc_url( admin_url( 'admin.php?page=merchant&section=analytics' ) ); ?>"><?php
110 esc_html_e( 'View Full Analytics', 'merchant' ); ?></a>
111 </div>
112 </div>
113 </div>
114 <?php
115 }
116
117 /**
118 * Enqueue assets for analytics page.
119 *
120 * @return void
121 */
122 public function analytics_assets( $hook ) {
123 global $pagenow;
124 $section = sanitize_text_field( $_GET['section'] ?? '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
125
126 if (
127 ( $hook === 'toplevel_page_merchant' && $section !== 'settings' && class_exists( 'WooCommerce' ) )
128 || ( $pagenow === 'index.php' && class_exists( 'WooCommerce' ) )
129 ) {
130 wp_enqueue_style('date-picker', MERCHANT_URI . 'assets/vendor/air-datepicker/air-datepicker.css', array(), MERCHANT_VERSION, 'all' );
131 wp_enqueue_style( 'merchant-analytics', MERCHANT_URI . 'assets/css/admin/analytics.css', array(), MERCHANT_VERSION );
132 wp_enqueue_script('date-picker', MERCHANT_URI . 'assets/vendor/air-datepicker/air-datepicker.js', array( 'jquery' ), MERCHANT_VERSION, true );
133 wp_enqueue_script( 'apexcharts', MERCHANT_URI . 'assets/js/vendor/apexcharts.min.js', array( 'jquery' ), MERCHANT_VERSION, true );
134 wp_enqueue_script( 'merchant-analytics', MERCHANT_URI . 'assets/js/admin/analytics.js', array( 'jquery', 'apexcharts' ), MERCHANT_VERSION, true );
135 wp_localize_script( 'merchant-analytics', 'merchant_analytics', array(
136 'nonce' => wp_create_nonce( 'merchant' ),
137 'ajax_url' => admin_url( 'admin-ajax.php' ),
138 'currency_name' => get_woocommerce_currency(),
139 'currency_symbol' => get_woocommerce_currency_symbol(),
140 'labels' => array(
141 'orders' => esc_html__( 'orders', 'merchant' ),
142 'orders_aov' => esc_html__( 'Orders AOV', 'merchant' ),
143 ),
144 ) );
145
146 wp_localize_script( 'merchant-analytics', 'merchant_datepicker_locale', array(
147 wp_json_encode(
148 array(
149 'days' => array(
150 esc_html__( 'Sunday', 'merchant' ),
151 esc_html__( 'Monday', 'merchant' ),
152 esc_html__( 'Tuesday', 'merchant' ),
153 esc_html__( 'Wednesday', 'merchant' ),
154 esc_html__( 'Thursday', 'merchant' ),
155 esc_html__( 'Friday', 'merchant' ),
156 esc_html__( 'Saturday', 'merchant' ),
157 ),
158 'daysShort' => array(
159 esc_html__( 'Sun', 'merchant' ),
160 esc_html__( 'Mon', 'merchant' ),
161 esc_html__( 'Tue', 'merchant' ),
162 esc_html__( 'Wed', 'merchant' ),
163 esc_html__( 'Thu', 'merchant' ),
164 esc_html__( 'Fri', 'merchant' ),
165 esc_html__( 'Sat', 'merchant' ),
166 ),
167 'daysMin' => array(
168 esc_html__( 'Su', 'merchant' ),
169 esc_html__( 'Mo', 'merchant' ),
170 esc_html__( 'Tu', 'merchant' ),
171 esc_html__( 'We', 'merchant' ),
172 esc_html__( 'Th', 'merchant' ),
173 esc_html__( 'Fr', 'merchant' ),
174 esc_html__( 'Sa', 'merchant' ),
175 ),
176 'months' => array(
177 esc_html__( 'January', 'merchant' ),
178 esc_html__( 'February', 'merchant' ),
179 esc_html__( 'March', 'merchant' ),
180 esc_html__( 'April', 'merchant' ),
181 esc_html__( 'May', 'merchant' ),
182 esc_html__( 'June', 'merchant' ),
183 esc_html__( 'July', 'merchant' ),
184 esc_html__( 'August', 'merchant' ),
185 esc_html__( 'September', 'merchant' ),
186 esc_html__( 'October', 'merchant' ),
187 esc_html__( 'November', 'merchant' ),
188 esc_html__( 'December', 'merchant' ),
189 ),
190 'monthsShort' => array(
191 esc_html__( 'Jan', 'merchant' ),
192 esc_html__( 'Feb', 'merchant' ),
193 esc_html__( 'Mar', 'merchant' ),
194 esc_html__( 'Apr', 'merchant' ),
195 esc_html__( 'May', 'merchant' ),
196 esc_html__( 'Jun', 'merchant' ),
197 esc_html__( 'Jul', 'merchant' ),
198 esc_html__( 'Aug', 'merchant' ),
199 esc_html__( 'Sep', 'merchant' ),
200 esc_html__( 'Oct', 'merchant' ),
201 esc_html__( 'Nov', 'merchant' ),
202 esc_html__( 'Dec', 'merchant' ),
203 ),
204 'clear' => esc_html__( 'Clear', 'merchant' ),
205 )
206 ),
207 ) );
208 }
209 }
210
211 /**
212 * Is aThemes Patcher page.
213 *
214 * @return bool
215 */
216 public function is_patcher_page() {
217 global $pagenow;
218
219 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
220 return $pagenow === 'admin.php' && ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] === 'athemes-patcher-preview-mp' );
221 }
222
223 /**
224 * Enqueue aThemes Patcher preview scripts and styles.
225 *
226 * @return void
227 */
228 public function enqueue_patcher_scripts() {
229 wp_enqueue_style( 'wp-components' );
230 }
231
232 /**
233 * Include required classes.
234 *
235 * @return void
236 */
237 public function add_admin_menu() {
238 global $submenu;
239
240 // Dashboard.
241 add_menu_page(
242 $this->page_title,
243 $this->page_title,
244 $this->capability,
245 $this->plugin_slug,
246 array( $this, 'page_dashboard' ),
247 MERCHANT_URI . 'assets/images/merchant-logo.svg',
248 $this->priority
249 );
250
251 // Dashboard Sub Item.
252 add_submenu_page(
253 $this->plugin_slug,
254 esc_html__('Dashboard', 'merchant'),
255 esc_html__('Dashboard', 'merchant'),
256 $this->capability,
257 $this->plugin_slug,
258 '',
259 1
260 );
261
262 // All Modules.
263 add_submenu_page(
264 $this->plugin_slug,
265 esc_html__('Modules', 'merchant'),
266 esc_html__('Modules', 'merchant'),
267 $this->capability,
268 'admin.php?page=merchant&section=modules',
269 '',
270 2
271 );
272
273 if( class_exists( 'WooCommerce' ) ) {
274 // Campaigns.
275 add_submenu_page(
276 $this->plugin_slug,
277 esc_html__( 'Campaigns', 'merchant' ),
278 esc_html__( 'Campaigns', 'merchant' ),
279 $this->capability,
280 'admin.php?page=merchant&section=campaigns',
281 '',
282 3
283 );
284
285 // Analytics.
286 add_submenu_page(
287 $this->plugin_slug,
288 esc_html__( 'Analytics', 'merchant' ),
289 esc_html__( 'Analytics', 'merchant' ),
290 $this->capability,
291 'admin.php?page=merchant&section=analytics',
292 '',
293 4
294 );
295 }
296
297 // Settings.
298 add_submenu_page(
299 $this->plugin_slug,
300 esc_html__('Settings', 'merchant'),
301 esc_html__('Settings', 'merchant'),
302 $this->capability,
303 'admin.php?page=merchant&section=settings',
304 '',
305 5
306 );
307
308 // Add 'aThemes Patcher' link
309 add_submenu_page( // phpcs:ignore WPThemeReview.PluginTerritory.NoAddAdminPages.add_menu_pages_add_submenu_page
310 'merchant',
311 esc_html__('Patcher', 'merchant'),
312 esc_html__('Patcher', 'merchant'),
313 $this->capability,
314 'athemes-patcher-preview-mp',
315 array( $this, 'html_patcher' ),
316 6
317 );
318
319
320 // Add 'Upgrade' link.
321 if ( ! defined( 'MERCHANT_PRO_VERSION' ) ) {
322 $url = merchant_admin_upgrade_link(
323 'https://athemes.com/merchant-upgrade',
324 array(
325 'utm_source' => 'theme_submenu_page',
326 'utm_medium' => 'button',
327 'utm_campaign' => 'Merchant',
328 ),
329 'theme-submenu-page-upgrade-link'
330 );
331 add_submenu_page(
332 $this->plugin_slug,
333 esc_html__( 'Upgrade to Pro', 'merchant' ),
334 esc_html__( 'Upgrade to Pro', 'merchant' ),
335 $this->capability,
336 esc_url( $url ),
337 '',
338 7
339 );
340 }
341 }
342
343 /**
344 * Add admin bar menu.
345 *
346 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance.
347 */
348 public function add_admin_bar_menu( $wp_admin_bar ) {
349 // Check if the current user has the capability to manage options
350 if ( ! current_user_can( 'manage_options' ) ) {
351 return;
352 }
353
354 // Parent menu item (Dashboard)
355 $wp_admin_bar->add_node( array(
356 'id' => 'merchant-dashboard',
357 'title' => esc_html__( 'Merchant', 'merchant' ), // Use your plugin name or page title
358 'href' => admin_url( 'admin.php?page=merchant' ), // Link to the main dashboard
359 'meta' => array(
360 'title' => esc_html__( 'Merchant Dashboard', 'merchant' ),
361 ),
362 ) );
363
364 // Dashboard Sub Item
365 $wp_admin_bar->add_node( array(
366 'id' => 'merchant-dashboard-sub',
367 'parent' => 'merchant-dashboard',
368 'title' => esc_html__( 'Dashboard', 'merchant' ),
369 'href' => admin_url( 'admin.php?page=merchant' ),
370 'meta' => array(
371 'title' => esc_html__( 'Dashboard', 'merchant' ),
372 ),
373 ) );
374
375 // All Modules
376 $wp_admin_bar->add_node( array(
377 'id' => 'merchant-modules',
378 'parent' => 'merchant-dashboard',
379 'title' => esc_html__( 'Modules', 'merchant' ),
380 'href' => admin_url( 'admin.php?page=merchant&section=modules' ),
381 'meta' => array(
382 'title' => esc_html__( 'Modules', 'merchant' ),
383 ),
384 ) );
385
386 if( class_exists( 'WooCommerce' ) ) {
387 // Settings
388 $wp_admin_bar->add_node( array(
389 'id' => 'merchant-settings',
390 'parent' => 'merchant-dashboard',
391 'title' => esc_html__( 'Settings', 'merchant' ),
392 'href' => admin_url( 'admin.php?page=merchant&section=settings' ),
393 'meta' => array(
394 'title' => esc_html__( 'Settings', 'merchant' ),
395 ),
396 ) );
397
398 // Campaigns
399 $wp_admin_bar->add_node( array(
400 'id' => 'merchant-campaigns',
401 'parent' => 'merchant-dashboard',
402 'title' => esc_html__( 'Campaigns', 'merchant' ),
403 'href' => admin_url( 'admin.php?page=merchant&section=campaigns' ),
404 'meta' => array(
405 'title' => esc_html__( 'Campaigns', 'merchant' ),
406 ),
407 ) );
408 }
409
410 // Analytics
411 $wp_admin_bar->add_node( array(
412 'id' => 'merchant-analytics',
413 'parent' => 'merchant-dashboard',
414 'title' => esc_html__( 'Analytics', 'merchant' ),
415 'href' => admin_url( 'admin.php?page=merchant&section=analytics' ),
416 'meta' => array(
417 'title' => esc_html__( 'Analytics', 'merchant' ),
418 ),
419 ) );
420
421 // Upgrade to Pro (if not already defined)
422 if ( ! defined( 'MERCHANT_PRO_VERSION' ) ) {
423 $url = merchant_admin_upgrade_link(
424 'https://athemes.com/merchant-upgrade',
425 array(
426 'utm_source' => 'theme_submenu_page',
427 'utm_medium' => 'button',
428 'utm_campaign' => 'Merchant',
429 ),
430 'adminbar-submenu-page-upgrade-link'
431 );
432 $wp_admin_bar->add_node( array(
433 'id' => 'merchant-upgrade',
434 'parent' => 'merchant-dashboard',
435 'title' => esc_html__( 'Upgrade to Pro', 'merchant' ),
436 'href' => esc_url( $url ),
437 'meta' => array(
438 'title' => esc_html__( 'Upgrade to Pro', 'merchant' ),
439 'target' => '_blank', // Open link in a new tab
440 ),
441 ) );
442 }
443 }
444
445 /**
446 * Get Notifications
447 *
448 * @return array
449 */
450 public function get_notifications() {
451 $notifications = get_transient( 'merchant_notifications' );
452
453 if ( ! empty( $notifications ) ) {
454 $this->notifications = $notifications;
455 } else {
456
457 /**
458 * Hook: merchant_changelog_api_url
459 *
460 * @since 1.0
461 */
462 $response = wp_remote_get( apply_filters( 'merchant_changelog_api_url', 'https://athemes.com/wp-json/wp/v2/notifications?theme=7103&per_page=3' ) );
463
464 if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
465 $this->notifications = json_decode( wp_remote_retrieve_body( $response ) );
466 set_transient( 'merchant_notifications', $this->notifications, 24 * HOUR_IN_SECONDS );
467 }
468 }
469
470 return $this->notifications;
471 }
472
473 /**
474 * Check if the latest notification is read
475 *
476 * @return bool
477 */
478 public function is_latest_notification_read() {
479
480 if ( ! isset( $this->notifications ) || empty( $this->notifications ) ) {
481 return false;
482 }
483
484 $user_id = get_current_user_id();
485 $user_read_meta = get_user_meta( $user_id, 'merchant_dashboard_notifications_latest_read', true );
486
487 $last_notification_date = strtotime( is_string( $this->notifications[0]->post_date ) ? $this->notifications[0]->post_date : '' );
488 $last_notification_date_ondb = $user_read_meta ? strtotime( $user_read_meta ) : false;
489
490 if ( ! $last_notification_date_ondb ) {
491 return false;
492 }
493
494 if ( $last_notification_date > $last_notification_date_ondb ) {
495 return false;
496 }
497
498 return true;
499 }
500
501 /**
502 * Ajax notifications.
503 *
504 * @return void
505 */
506 public function ajax_notifications_read() {
507 check_ajax_referer( 'merchant', 'nonce' );
508
509 // Check current user capabilities
510 if ( ! current_user_can( 'manage_options' ) ) {
511 wp_send_json_error( 'You are not allowed to do this.' );
512 }
513
514 $latest_notification_date = ( isset( $_POST[ 'latest_notification_date' ] ) ) ? sanitize_text_field( wp_unslash( $_POST[ 'latest_notification_date' ] ) ) : false;
515
516 update_user_meta( get_current_user_id(), 'merchant_dashboard_notifications_latest_read', $latest_notification_date );
517
518 wp_send_json_success();
519 }
520
521 /**
522 * Get installed plugins
523 * Provide the installed plugins array into the installed plugins static property for memoization purposes.
524 *
525 * @return array
526 */
527 public static function get_installed_plugins() {
528 if ( empty( self::$installed_plugins ) ) {
529 if ( ! function_exists( 'get_plugins' ) ) {
530 require_once ABSPATH . 'wp-admin/includes/plugin.php';
531 }
532 self::$installed_plugins = get_plugins();
533 }
534 return self::$installed_plugins;
535 }
536
537 /**
538 * Include Page dashboard
539 *
540 * @return void
541 */
542 public function page_dashboard() {
543 self::get_installed_plugins();
544 require_once MERCHANT_DIR . 'admin/pages/page-dashboard.php';
545 }
546
547 /**
548 * Footer internal scripts
549 *
550 * @return void
551 */
552 public function footer_internal_scripts() {
553 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
554 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? str_replace( '/wp-admin/', '', $_SERVER['REQUEST_URI'] ) : '';
555 ?>
556 <style>
557 #adminmenu .toplevel_page_merchant .wp-submenu li.current a {
558 color: rgba(240, 246, 252, 0.7);
559 font-weight: 400;
560 }
561
562 #adminmenu .toplevel_page_merchant .wp-submenu li a[href="<?php echo $request_uri; //phpcs:ignore ?>"] {
563 color: #fff;
564 font-weight: 600;
565 }
566
567 #adminmenu .toplevel_page_merchant .wp-submenu a[href="https://athemes.com/merchant-upgrade?utm_source=theme_submenu_page&utm_medium=button&utm_campaign=Merchant"] {
568 background-color: green;
569 color: #FFF;
570 }
571 </style>
572 <script type="text/javascript">
573 document.addEventListener("DOMContentLoaded", function () {
574 const merchantUpsellMenuItem = document.querySelector('#adminmenu .toplevel_page_merchant .wp-submenu a[href="https://athemes.com/merchant-upgrade?utm_source=theme_submenu_page&utm_medium=button&utm_campaign=Merchant"]');
575
576 if (merchantUpsellMenuItem) {
577 merchantUpsellMenuItem.addEventListener('click', function (e) {
578 e.preventDefault();
579
580 const href = this.getAttribute('href');
581 window.open(href, '_blank');
582 });
583 }
584 });
585 </script>
586 <?php
587 }
588
589 /**
590 * HTML aThemes Patcher.
591 *
592 * @return void
593 */
594 public function html_patcher() {
595 require_once MERCHANT_DIR . 'admin/pages/page-patcher.php';
596 }
597 }
598
599 Merchant_Admin_Menu::instance();
600
601 }
602