PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.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 All 203 releases
betterdocs / includes / Admin / NoticePointers.php

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

177 lines 4.8 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
15 public function __construct() {
16 add_action( 'admin_print_footer_scripts', [ $this, 'enqueue_notice' ] );
17 }
18
19 public function enqueue_notice() {
20 // Only show on BetterDocs screens
21 $screen = get_current_screen();
22
23 if ( ! $screen ) {
24 return;
25 }
26
27 // Check if we're on allowed pages
28 if ( ! $this->is_allowed_page( $screen ) ) {
29 return;
30 }
31
32 // Check basic conditions
33 if ( ! self::is_user_allowed() || self::is_dismissed() || ! self::is_campaign_time() || self::has_pro() ) {
34 return;
35 }
36
37 $this->enqueue_dependencies();
38
39 $pointer_content = '<h3>' . esc_html__( 'Black Friday Sale for BetterDocs', 'betterdocs' ) . '</h3>';
40 $pointer_content .= '<p>' . esc_html__( 'Create a high-converting knowledge base & FAQ powered by AI with Instant Answers, Advanced Analytics & more.', 'betterdocs' ) . '</p>';
41 $pointer_content .= sprintf(
42 '<p><a class="button button-primary" href="%s" target="_blank">%s</a></p>',
43 self::PROMOTION_URL,
44 esc_html__( 'Claim Offer', 'betterdocs' )
45 );
46
47 $allowed_tags = [
48 'h3' => [],
49 'p' => [],
50 'a' => [
51 'class' => [],
52 'target' => [ '_blank' ],
53 'href' => [],
54 ],
55 ];
56 ?>
57
58 <script>
59 jQuery( document ).ready( function( $ ) {
60 $( "#<?php echo esc_attr( self::BETTERDOCS_POINTER_ID ); ?>" ).pointer( {
61 content: '<?php echo wp_kses( $pointer_content, $allowed_tags ); ?>',
62 position: {
63 edge: <?php echo is_rtl() ? "'right'" : "'left'"; ?>,
64 align: "center"
65 },
66 close: function() {
67 // Send AJAX request to mark as dismissed
68 $.ajax({
69 url: ajaxurl,
70 type: 'POST',
71 data: {
72 action: 'betterdocs_dismiss_black_friday_pointer',
73 nonce: '<?php echo esc_js( wp_create_nonce( 'betterdocs_dismiss_pointer' ) ); ?>',
74 introduction_key: '<?php echo esc_attr( self::DISMISS_ACTION_KEY ); ?>'
75 }
76 });
77 }
78 } ).pointer( "open" );
79 } );
80 </script>
81 <?php
82 }
83
84 public static function should_display_notice(): bool {
85 return self::is_user_allowed() &&
86 ! self::is_dismissed() &&
87 self::is_campaign_time();
88 }
89
90 /**
91 * Check if current page is allowed to show the pointer
92 *
93 * @param WP_Screen $screen Current screen object
94 * @return bool
95 */
96 private function is_allowed_page( $screen ): bool {
97 // BetterDocs admin pages only — never the WP Dashboard or Plugins screen
98 // (WP.org guideline 11).
99 $betterdocs_screens = [
100 'toplevel_page_betterdocs-dashboard',
101 'betterdocs_page_betterdocs-admin',
102 'betterdocs_page_betterdocs-settings',
103 'betterdocs_page_betterdocs-analytics',
104 'betterdocs_page_betterdocs-glossaries',
105 'betterdocs_page_betterdocs-faq',
106 'betterdocs_page_betterdocs-ai-chatbot',
107 'edit-doc_category',
108 'edit-doc_tag',
109 'edit-knowledge_base',
110 ];
111
112 return in_array( $screen->id, $betterdocs_screens, true );
113 }
114
115 private static function is_user_allowed(): bool {
116 return current_user_can( 'manage_options' ) || current_user_can( 'edit_docs' );
117 }
118
119 private static function is_campaign_time() {
120 $start = new \DateTime( '2025-11-25 12:00:00', new \DateTimeZone( 'UTC' ) );
121 $end = new \DateTime( '2025-12-04 23:59:59', new \DateTimeZone( 'UTC' ) );
122 $now = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
123
124 return $now >= $start && $now <= $end;
125 }
126
127 private function enqueue_dependencies() {
128 wp_enqueue_script( 'wp-pointer' );
129 wp_enqueue_style( 'wp-pointer' );
130 }
131
132 private static function is_dismissed(): bool {
133 return self::get_introduction_meta( self::DISMISS_ACTION_KEY );
134 }
135
136 /**
137 * Get introduction meta for the current user
138 *
139 * @param string|null $key Optional. Specific key to retrieve.
140 * @return mixed
141 */
142 public static function get_introduction_meta( $key = null ) {
143 $user_id = get_current_user_id();
144 $introduction_meta = get_user_meta( $user_id, self::USER_META_KEY, true );
145
146 if ( ! is_array( $introduction_meta ) ) {
147 $introduction_meta = [];
148 }
149
150 if ( $key ) {
151 return isset( $introduction_meta[ $key ] ) ? $introduction_meta[ $key ] : false;
152 }
153
154 return $introduction_meta;
155 }
156
157 /**
158 * Set introduction meta for the current user
159 *
160 * @param string $key The introduction key to set.
161 * @return void
162 */
163 public static function set_introduction_viewed( $key ) {
164 $user_id = get_current_user_id();
165 $introduction_meta = self::get_introduction_meta();
166
167 $introduction_meta[ $key ] = true;
168
169 update_user_meta( $user_id, self::USER_META_KEY, $introduction_meta );
170 }
171
172 private static function has_pro(): bool {
173 return is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' );
174 }
175 }
176
177