PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.4.4
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.4.4
4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / MilestoneNotification.php
embedpress / EmbedPress Last commit date
AMP 3 years ago Analytics 10 months ago Elementor 8 months ago Ends 8 months ago Gutenberg 8 months ago Includes 8 months ago Plugins 1 year ago Providers 8 months ago ThirdParty 10 months ago AutoLoader.php 3 years ago Compatibility.php 3 years ago Core.php 8 months ago CoreLegacy.php 10 months ago DisablerLegacy.php 3 years ago Loader.php 3 years ago MilestoneNotification.php 8 months ago RestAPI.php 8 months ago Shortcode.php 8 months ago index.html 7 years ago simple_html_dom.php 5 years ago
MilestoneNotification.php
468 lines
1 <?php
2
3 /**
4 * Milestone Notification for WordPress Admin Dashboard
5 *
6 * Displays a beautiful animated notification on the main WordPress dashboard (/wp-admin/)
7 * showing milestone achievements and encouraging premium upgrades.
8 *
9 * Features:
10 * - Automatically appears on dashboard after 2 seconds
11 * - Slides in from bottom-right with smooth animation
12 * - Fully responsive design
13 * - Close on button click, overlay click, or Escape key
14 * - Customizable milestone data and stats
15 *
16 * Usage:
17 * - Automatically initialized in embedpress.php
18 * - Only loads on WordPress dashboard (index.php)
19 * - Customize data in get_milestone_data() method
20 * - Control display logic in should_show_milestone() method
21 *
22 * @package EmbedPress
23 * @author EmbedPress <help@embedpress.com>
24 * @copyright Copyright (C) 2023 WPDeveloper. All rights reserved.
25 * @license GPLv3 or later
26 * @since 1.0.0
27 */
28
29 namespace EmbedPress;
30
31 defined('ABSPATH') or die("No direct script access allowed.");
32
33 class MilestoneNotification
34 {
35 /**
36 * Initialize the milestone notification
37 */
38 public static function init()
39 {
40 $instance = new self();
41
42 // Hook into admin footer to inject the notification
43 add_action('admin_footer', [$instance, 'render_milestone_notification']);
44
45 // Enqueue styles and scripts
46 add_action('admin_enqueue_scripts', [$instance, 'enqueue_assets']);
47
48 // AJAX handler to mark milestone as seen
49 add_action('wp_ajax_embedpress_mark_milestone_seen', [$instance, 'ajax_mark_milestone_seen']);
50 }
51
52 /**
53 * Enqueue CSS and JS for milestone notification
54 */
55 public function enqueue_assets($hook)
56 {
57 // Only load on main dashboard page
58 if ($hook !== 'index.php') {
59 return;
60 }
61
62 // Enqueue the milestone CSS
63 wp_enqueue_style(
64 'embedpress-milestone',
65 EMBEDPRESS_PLUGIN_DIR_URL . 'assets/css/admin.build.css',
66 [],
67 EMBEDPRESS_VERSION
68 );
69
70 // Enqueue inline script for milestone functionality
71 wp_add_inline_script('jquery', $this->get_milestone_script());
72 }
73
74 /**
75 * Get the JavaScript for milestone functionality
76 */
77 private function get_milestone_script()
78 {
79 return "
80 jQuery(document).ready(function($) {
81 // Auto-show milestone after 2 seconds
82 setTimeout(function() {
83 showEmbedPressMilestone();
84 }, 2000);
85 });
86
87 function showEmbedPressMilestone() {
88 var container = document.getElementById('embedpress-milestone-container');
89 if (!container) return;
90
91 container.style.display = 'block';
92
93 // Trigger animation
94 setTimeout(function() {
95 var overlay = container.querySelector('.milestone-overlay');
96 var notification = container.querySelector('.milestone-notification');
97
98 if (overlay) overlay.classList.add('milestone-overlay--visible');
99 if (notification) notification.classList.add('milestone-notification--visible');
100 }, 100);
101 }
102
103 function hideEmbedPressMilestone(event) {
104 if (event) event.preventDefault();
105
106 var container = document.getElementById('embedpress-milestone-container');
107 if (!container) return;
108
109 var overlay = container.querySelector('.milestone-overlay');
110 var notification = container.querySelector('.milestone-notification');
111
112 if (overlay) overlay.classList.remove('milestone-overlay--visible');
113 if (notification) notification.classList.remove('milestone-notification--visible');
114
115 // Remove from DOM after animation
116 setTimeout(function() {
117 container.style.display = 'none';
118 }, 400);
119
120 // Mark milestone as seen via AJAX
121 jQuery.post(ajaxurl, {
122 action: 'embedpress_mark_milestone_seen',
123 nonce: '" . wp_create_nonce('embedpress_milestone_nonce') . "'
124 });
125 }
126 ";
127 }
128
129 /**
130 * Render the milestone notification HTML
131 */
132 public function render_milestone_notification()
133 {
134 // Only show on main dashboard
135 $screen = get_current_screen();
136 if (!$screen || $screen->id !== 'dashboard') {
137 return;
138 }
139
140 // Check if milestone should be shown
141 if (!$this->should_show_milestone()) {
142 return;
143 }
144
145 // Get milestone data
146 $data = $this->get_milestone_data();
147
148 ?>
149 <div id="embedpress-milestone-container" style="display: none;">
150 <div class="milestone-overlay">
151 <div class="milestone-notification" onclick="event.stopPropagation()">
152 <!-- Header -->
153 <div class="milestone-header">
154 <h2 class="milestone-title"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 91.226 91.226">
155 <g transform="translate(0 0)">
156 <path d="M187.4,174.9v12.5H174.9V192.5h17.6V174.9Z" transform="translate(-101.271 -101.271)" fill="#25396F"></path>
157 <path d="M88.255,38.749A22.6,22.6,0,0,0,71.163,27.383,22.279,22.279,0,0,0,58.912,29.4c-.421.21-.884.421-1.305.674A22.538,22.538,0,0,0,46.915,43.338h0L34.622,78.405a12.808,12.808,0,0,1-5.767,7.241c-.21.126-.463.253-.716.379A12.309,12.309,0,0,1,21.53,87.12a12.181,12.181,0,0,1-9.177-6.1A12.027,12.027,0,0,1,11.3,71.838a12.16,12.16,0,0,1,5.767-7.283c.253-.126.463-.253.716-.379a12.243,12.243,0,0,1,6.609-1.095c.084,0,.168.042.253.042l-2.526,7.367a.955.955,0,0,0,.589,1.221l6.525,2.1a.91.91,0,0,0,1.179-.589l5.641-16.039a1.536,1.536,0,0,0-.084-1.221,1.445,1.445,0,0,0-.968-.8l-5.936-1.726a1.5,1.5,0,0,0-.421-.084l-.547-.168v.042c-.842-.21-1.684-.337-2.526-.463a22.488,22.488,0,0,0-12.293,2.021c-.463.21-.884.463-1.305.674A22.524,22.524,0,0,0,1.2,69.017,22.242,22.242,0,0,0,3.175,86.109,22.6,22.6,0,0,0,20.267,97.476a22.279,22.279,0,0,0,12.25-2.021c.421-.21.884-.421,1.305-.674A22.417,22.417,0,0,0,44.473,81.563h0L56.85,46.5v-.126c1.389-3.536,3.157-5.767,5.725-7.2.21-.126.463-.253.716-.379A12.309,12.309,0,0,1,69.9,37.7a12.069,12.069,0,0,1,4.462,22.564c-.253.126-.463.253-.716.379A12.393,12.393,0,0,1,67,61.735a11.96,11.96,0,0,1-2.063-.421h-.084l-3.789-1.137a.756.756,0,0,0-.968.505L57.144,69.06a.8.8,0,0,0,.547,1.052l4.673,1.347a20,20,0,0,0,3.452.674,22.342,22.342,0,0,0,12.25-2.021h.042c.463-.21.884-.463,1.347-.674A22.671,22.671,0,0,0,88.255,38.749Z" transform="translate(-0.186 -15.764)" fill="#25396F"></path>
158 <path d="M0,0V17.6H5.094V5.094H17.555V0Z" fill="#25396F"></path>
159 </g>
160 </svg> EmbedPress Milestone</h2>
161 <button class="milestone-close" onclick="hideEmbedPressMilestone(event)" aria-label="Close">
162 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
163 <path d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z" fill="currentColor" />
164 </svg>
165 </button>
166 </div>
167
168 <!-- Content -->
169 <div class="milestone-content">
170 <!-- Achievement Banner -->
171 <div class="milestone-achievement">
172 <h3 class="milestone-achievement-title">
173 <?php echo $data['emoji']; ?> <?php echo wp_kses_post($data['title']); ?>
174 </h3>
175 <p class="milestone-achievement-subtitle">
176 <?php echo wp_kses_post($data['subtitle']); ?>
177 </p>
178 <a href="<?php echo esc_url(admin_url('admin.php?page=embedpress-analytics')); ?>" class="milestone-link">
179 View Analytics
180 </a>
181 </div>
182
183 <!-- Stats Grid -->
184 <div class="milestone-stats">
185 <div class="milestone-stats-inner-wrapper">
186
187 <div class="milestone-stats-inner">
188 <?php foreach ($data['stats'] as $stat) : ?>
189 <div class="milestone-stat-card">
190 <div class="milestone-stat-label"><?php echo esc_html($stat['label']); ?></div>
191 <div class="milestone-stat-value"><?php echo esc_html($stat['value']); ?></div>
192 </div>
193 <?php endforeach; ?>
194 </div>
195
196 <!-- CTA Button -->
197 <a href="<?php echo esc_url('https://embedpress.com/in/unlock-advanced-analytics'); ?>" target="_blank" class="milestone-cta">
198 Unlock Pro Insights
199 </a>
200 </div>
201
202
203 </div>
204 </div>
205 </div>
206 </div>
207 </div>
208 <?php
209 }
210
211 /**
212 * Get milestone data
213 * Fetches real analytics data from the database to show user's embed performance
214 */
215 private function get_milestone_data()
216 {
217 // Get Analytics Manager instance
218 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
219
220 // Get real analytics data
221 $total_embeds = 0;
222 $total_views = 0;
223 $total_unique_viewers = 0;
224 $total_impressions = 0;
225
226 try {
227 // Get content count by type
228 $content_by_type = $analytics_manager->get_total_content_by_type();
229 $total_embeds = isset($content_by_type['total']) ? $content_by_type['total'] : 0;
230
231 // Get total views, impressions, and unique viewers from Data_Collector
232 $data_collector = new \EmbedPress\Includes\Classes\Analytics\Data_Collector();
233 $total_views = $data_collector->get_total_views();
234 $total_impressions = $data_collector->get_total_impressions();
235 $total_unique_viewers = $data_collector->get_total_unique_viewers();
236 } catch (\Exception $e) {
237 // Fallback to default values if there's an error
238 error_log('EmbedPress Milestone: Error fetching analytics data - ' . $e->getMessage());
239 }
240
241 // Format numbers for display
242 $embeds_formatted = $this->format_number($total_embeds);
243 $views_formatted = $this->format_number($total_views);
244 $unique_views_formatted = $this->format_number($total_unique_viewers);
245 $impressions_formatted = $this->format_number($total_impressions);
246
247 // Calculate total interactions (sum of all metrics)
248 $total_interactions = $total_embeds + $total_views + $total_unique_viewers + $total_impressions;
249
250 // Get milestone configuration based on total interactions
251 $milestone_config = $this->get_milestone_config($total_interactions);
252
253 return array_merge($milestone_config, [
254 'stats' => [
255 [
256 'label' => 'Total Embeds',
257 'value' => $embeds_formatted
258 ],
259 [
260 'label' => 'Total Views',
261 'value' => $views_formatted
262 ],
263 [
264 'label' => 'Unique Views',
265 'value' => $unique_views_formatted
266 ],
267 [
268 'label' => 'Total Impressions',
269 'value' => $impressions_formatted
270 ]
271 ]
272 ]);
273 }
274
275 /**
276 * Get milestone configuration based on total interactions
277 * Returns unique title, subtitle, and emoji for each milestone level
278 */
279 private function get_milestone_config($total_interactions)
280 {
281 // Define milestone levels with unique messages
282 $milestones = [
283 1000000 => [
284 'emoji' => '👑',
285 'title' => 'Legendary! <strong>1M+ interactions achieved!</strong>',
286 'subtitle' => 'You\'re an <strong>absolute legend</strong>! Your embeds are reaching millions. Pro analytics will help you scale to infinity.',
287 'level' => '1m'
288 ],
289 500000 => [
290 'emoji' => '💎',
291 'title' => 'Diamond Status! <strong>500K+ interactions!</strong>',
292 'subtitle' => 'You\'ve reached <strong>diamond tier</strong>! Your content is viral. Unlock Pro to maximize your massive reach.',
293 'level' => '500k'
294 ],
295 250000 => [
296 'emoji' => '🏆',
297 'title' => 'Champion! <strong>250K+ interactions unlocked!</strong>',
298 'subtitle' => 'You\'re a <strong>true champion</strong>! Your embeds are crushing it. Get Pro insights to dominate even more.',
299 'level' => '250k'
300 ],
301 100000 => [
302 'emoji' => '🌟',
303 'title' => 'Superstar! <strong>100K+ interactions reached!</strong>',
304 'subtitle' => 'You\'re a <strong>superstar</strong>! Your content is exploding. Upgrade to Pro for enterprise-level analytics.',
305 'level' => '100k'
306 ],
307 50000 => [
308 'emoji' => '',
309 'title' => 'Incredible! <strong>50K+ interactions achieved!</strong>',
310 'subtitle' => 'You\'re a <strong>Pro</strong>! Unlock advanced analytics to scale even further and dominate your niche.',
311 'level' => '50k'
312 ],
313 20000 => [
314 'emoji' => '🔥',
315 'title' => 'Amazing! <strong>20K+ interactions and counting!</strong>',
316 'subtitle' => 'Your embeds are <strong>on fire</strong>! Get Pro to unlock powerful insights and boost performance.',
317 'level' => '20k'
318 ],
319 10000 => [
320 'emoji' => '',
321 'title' => 'Fantastic! You\'ve reached <strong>10K</strong> interactions!',
322 'subtitle' => 'You\'re doing <strong>great</strong>! Upgrade to Pro to see detailed analytics and grow even faster.',
323 'level' => '10k'
324 ],
325 5000 => [
326 'emoji' => '🎯',
327 'title' => 'Awesome! <strong>5K interactions milestone unlocked!</strong>',
328 'subtitle' => 'Your content is <strong>resonating</strong>! Unlock Pro to discover what\'s working best.',
329 'level' => '5k'
330 ],
331 1000 => [
332 'emoji' => '🎉',
333 'title' => 'Congratulations! <strong>1K+ interactions reached!</strong>',
334 'subtitle' => 'Your embeds are <strong>gaining traction</strong>! Upgrade to Pro to see advanced analytics and improve performance.',
335 'level' => '1k'
336 ]
337 ];
338
339 // Find the appropriate milestone level
340 foreach ($milestones as $threshold => $config) {
341 if ($total_interactions >= $threshold) {
342 return $config;
343 }
344 }
345
346 // Default for users below 1K interactions
347 return [
348 'emoji' => '👋',
349 'title' => 'Welcome! Your <strong>embed journey</strong> has begun!',
350 'subtitle' => 'Start measuring your embed performance today. Gain deeper insights, monitor engagement, and level up with EmbedPress Pro.',
351 'level' => 'starter'
352 ];
353 }
354
355 /**
356 * Format number for display (e.g., 1000 -> 1K, 1000000 -> 1M)
357 *
358 * @param int $number
359 * @return string
360 */
361 private function format_number($number)
362 {
363 $number = (int) $number;
364
365 if ($number === 0) {
366 return '0';
367 }
368
369 if ($number >= 1000000) {
370 return round($number / 1000000, 1) . 'M';
371 }
372
373 if ($number >= 1000) {
374 return round($number / 1000, 1) . 'K';
375 }
376
377 return (string) $number;
378 }
379
380 /**
381 * Check if milestone should be shown
382 * Shows milestone only when site reaches a new level (site-wide, not per-user)
383 */
384 private function should_show_milestone()
385 {
386 // Get Analytics Manager instance
387 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
388
389 // Get real analytics data
390 $total_embeds = 0;
391 $total_views = 0;
392 $total_unique_viewers = 0;
393 $total_impressions = 0;
394
395 try {
396 // Get content count by type
397 $content_by_type = $analytics_manager->get_total_content_by_type();
398 $total_embeds = isset($content_by_type['total']) ? $content_by_type['total'] : 0;
399
400 // Get total views, impressions, and unique viewers from Data_Collector
401 $data_collector = new \EmbedPress\Includes\Classes\Analytics\Data_Collector();
402 $total_views = $data_collector->get_total_views();
403 $total_impressions = $data_collector->get_total_impressions();
404 $total_unique_viewers = $data_collector->get_total_unique_viewers();
405 } catch (\Exception $e) {
406 error_log('EmbedPress Milestone: Error fetching analytics data - ' . $e->getMessage());
407 return false;
408 }
409
410 // Calculate total interactions
411 $total_interactions = $total_embeds + $total_views + $total_unique_viewers + $total_impressions;
412
413 // Determine current milestone level
414 $current_level = 'starter';
415 if ($total_interactions >= 50000) {
416 $current_level = '50k';
417 } elseif ($total_interactions >= 20000) {
418 $current_level = '20k';
419 } elseif ($total_interactions >= 10000) {
420 $current_level = '10k';
421 } elseif ($total_interactions >= 5000) {
422 $current_level = '5k';
423 } elseif ($total_interactions >= 1000) {
424 $current_level = '1k';
425 }
426
427 // Get the last seen milestone level (site-wide option)
428 $last_seen_level = get_option('embedpress_milestone_level', '');
429
430 // Show milestone if:
431 // 1. Site has never seen any milestone, OR
432 // 2. Site has reached a new milestone level
433 if (empty($last_seen_level) || $last_seen_level !== $current_level) {
434 // Don't update here - only update when user closes the notification
435 // Store current level temporarily so we can update it later
436 update_option('embedpress_milestone_current_level', $current_level);
437 return true;
438 }
439
440 return false;
441 }
442
443 /**
444 * AJAX handler to mark milestone as seen
445 */
446 public function ajax_mark_milestone_seen()
447 {
448 // Verify nonce
449 if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'embedpress_milestone_nonce')) {
450 wp_send_json_error('Invalid nonce');
451 return;
452 }
453
454 // Get the current milestone level that was shown
455 $current_level = get_option('embedpress_milestone_current_level', '');
456
457 if (!empty($current_level)) {
458 // Mark this milestone level as seen (site-wide)
459 update_option('embedpress_milestone_level', $current_level);
460
461 // Clean up the temporary option
462 delete_option('embedpress_milestone_current_level');
463 }
464
465 wp_send_json_success();
466 }
467 }
468