PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.0
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 3.5.2 All 199 releases
betterdocs / includes / Admin / NoticePointers.php

NoticePointers.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.8.0, at includes/Admin/NoticePointers.php

199 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\Admin;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 class NoticePointers {
10 const PROMOTION_URL = 'https://betterdocs.co/bfcm-wp-admin-pointer ';
11 const BETTERDOCS_POINTER_ID = 'toplevel_page_betterdocs-dashboard';
12 const DISMISS_ACTION_KEY = 'betterdocs_black_friday_pointer_2025';
13 const USER_META_KEY = 'betterdocs_introduction_meta';
14 const PRIORITY = 4; // Priority for this pointer (lower number = higher priority)
15
16 public function __construct() {
17 add_action( 'admin_print_footer_scripts', [ $this, 'enqueue_notice' ] );
18 }
19
20 public function enqueue_notice() {
21 // Only show on specific pages: dashboard and BetterDocs screens
22 $screen = get_current_screen();
23
24 if ( ! $screen ) {
25 return;
26 }
27
28 // Check if we're on allowed pages
29 if ( ! $this->is_allowed_page( $screen ) ) {
30 return;
31 }
32
33 // For common pages (dashboard, plugins), check priority FIRST
34 $is_common_page = in_array( $screen->id, [ 'dashboard', 'plugins' ], true );
35 if ( $is_common_page ) {
36 $current_priority = get_option( '_wpdeveloper_plugin_pointer_priority', 999 );
37
38 // If priority is greater than 4, update it to 4
39 if ( $current_priority > 4 ) {
40 update_option( '_wpdeveloper_plugin_pointer_priority', 4 );
41 $current_priority = 4;
42 }
43
44 // If priority is not 4, don't display on common pages
45 if ( $current_priority != 4 ) {
46 return;
47 }
48 }
49
50 // Check basic conditions
51 if ( ! self::is_user_allowed() || self::is_dismissed() || ! self::is_campaign_time() || self::has_pro() ) {
52 return;
53 }
54
55 $this->enqueue_dependencies();
56
57 $pointer_content = '<h3>' . esc_html__( 'Black Friday Sale for BetterDocs', 'betterdocs' ) . '</h3>';
58 $pointer_content .= '<p>' . esc_html__( 'Create a high-converting knowledge base & FAQ powered by AI with Instant Answers, Advanced Analytics & more.', 'betterdocs' ) . '</p>';
59 $pointer_content .= sprintf(
60 '<p><a class="button button-primary" href="%s" target="_blank">%s</a></p>',
61 self::PROMOTION_URL,
62 esc_html__( 'Claim Offer', 'betterdocs' )
63 );
64
65 $allowed_tags = [
66 'h3' => [],
67 'p' => [],
68 'a' => [
69 'class' => [],
70 'target' => [ '_blank' ],
71 'href' => [],
72 ],
73 ];
74 ?>
75
76 <script>
77 jQuery( document ).ready( function( $ ) {
78 $( "#<?php echo esc_attr( self::BETTERDOCS_POINTER_ID ); ?>" ).pointer( {
79 content: '<?php echo wp_kses( $pointer_content, $allowed_tags ); ?>',
80 position: {
81 edge: <?php echo is_rtl() ? "'right'" : "'left'"; ?>,
82 align: "center"
83 },
84 close: function() {
85 // Send AJAX request to mark as dismissed
86 $.ajax({
87 url: ajaxurl,
88 type: 'POST',
89 data: {
90 action: 'betterdocs_dismiss_black_friday_pointer',
91 nonce: '<?php echo esc_js( wp_create_nonce( 'betterdocs_dismiss_pointer' ) ); ?>',
92 introduction_key: '<?php echo esc_attr( self::DISMISS_ACTION_KEY ); ?>'
93 }
94 });
95 }
96 } ).pointer( "open" );
97 } );
98 </script>
99 <?php
100 }
101
102 public static function should_display_notice(): bool {
103 return self::is_user_allowed() &&
104 ! self::is_dismissed() &&
105 self::is_campaign_time();
106 }
107
108 /**
109 * Check if current page is allowed to show the pointer
110 *
111 * @param WP_Screen $screen Current screen object
112 * @return bool
113 */
114 private function is_allowed_page( $screen ): bool {
115 // Dashboard
116 if ( $screen->id === 'dashboard' || $screen->id === 'plugins' ) {
117 return true;
118 }
119
120 // BetterDocs admin pages
121 $betterdocs_screens = [
122 'toplevel_page_betterdocs-dashboard',
123 'betterdocs_page_betterdocs-admin',
124 'betterdocs_page_betterdocs-settings',
125 'betterdocs_page_betterdocs-analytics',
126 'betterdocs_page_betterdocs-glossaries',
127 'betterdocs_page_betterdocs-faq',
128 'betterdocs_page_betterdocs-ai-chatbot',
129 'edit-doc_category',
130 'edit-doc_tag',
131 'edit-knowledge_base',
132 ];
133
134 return in_array( $screen->id, $betterdocs_screens, true );
135 }
136
137 private static function is_user_allowed(): bool {
138 return current_user_can( 'manage_options' ) || current_user_can( 'edit_docs' );
139 }
140
141 private static function is_campaign_time() {
142 $start = new \DateTime( '2025-11-25 12:00:00', new \DateTimeZone( 'UTC' ) );
143 $end = new \DateTime( '2025-12-04 23:59:59', new \DateTimeZone( 'UTC' ) );
144 $now = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
145
146 return $now >= $start && $now <= $end;
147 }
148
149 private function enqueue_dependencies() {
150 wp_enqueue_script( 'wp-pointer' );
151 wp_enqueue_style( 'wp-pointer' );
152 }
153
154 private static function is_dismissed(): bool {
155 return self::get_introduction_meta( self::DISMISS_ACTION_KEY );
156 }
157
158 /**
159 * Get introduction meta for the current user
160 *
161 * @param string|null $key Optional. Specific key to retrieve.
162 * @return mixed
163 */
164 public static function get_introduction_meta( $key = null ) {
165 $user_id = get_current_user_id();
166 $introduction_meta = get_user_meta( $user_id, self::USER_META_KEY, true );
167
168 if ( ! is_array( $introduction_meta ) ) {
169 $introduction_meta = [];
170 }
171
172 if ( $key ) {
173 return isset( $introduction_meta[ $key ] ) ? $introduction_meta[ $key ] : false;
174 }
175
176 return $introduction_meta;
177 }
178
179 /**
180 * Set introduction meta for the current user
181 *
182 * @param string $key The introduction key to set.
183 * @return void
184 */
185 public static function set_introduction_viewed( $key ) {
186 $user_id = get_current_user_id();
187 $introduction_meta = self::get_introduction_meta();
188
189 $introduction_meta[ $key ] = true;
190
191 update_user_meta( $user_id, self::USER_META_KEY, $introduction_meta );
192 }
193
194 private static function has_pro(): bool {
195 return is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' );
196 }
197 }
198
199