PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.5.0
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.5.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 2 years ago Analytics 9 months ago Elementor 2 months ago Ends 2 months ago Gutenberg 2 months ago Includes 2 months ago Plugins 1 year ago Providers 2 months ago ThirdParty 9 months ago AutoLoader.php 2 years ago Compatibility.php 2 years ago Core.php 7 months ago CoreLegacy.php 9 months ago DisablerLegacy.php 2 years ago Loader.php 2 years ago MilestoneNotification.php 6 months ago RestAPI.php 3 months ago Shortcode.php 2 months ago index.html 7 years ago simple_html_dom.php 4 years ago
MilestoneNotification.php
516 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 // Check if Black Friday banner should be shown (until December 4, 2025)
149 $show_bfriday_banner = (time() < strtotime('2025-12-04 23:59:59'));
150
151 ?>
152 <div id="embedpress-milestone-container" style="display: none;">
153 <div class="milestone-overlay">
154 <div class="milestone-notification" onclick="event.stopPropagation()">
155 <!-- Header -->
156 <div class="milestone-header">
157 <h2 class="milestone-title"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 91.226 91.226">
158 <g transform="translate(0 0)">
159 <path d="M187.4,174.9v12.5H174.9V192.5h17.6V174.9Z" transform="translate(-101.271 -101.271)" fill="#25396F"></path>
160 <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>
161 <path d="M0,0V17.6H5.094V5.094H17.555V0Z" fill="#25396F"></path>
162 </g>
163 </svg> EmbedPress Milestone</h2>
164 <button class="milestone-close" onclick="hideEmbedPressMilestone(event)" aria-label="Close">
165 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
166 <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" />
167 </svg>
168 </button>
169 </div>
170
171 <?php if ($show_bfriday_banner): ?>
172 <div class="bfriday-deal-campaign">
173 <a href="https://embedpress.com/in/bfcm2025-unlock-advanced-analytics" target="_blank">
174 <img src="<?php echo esc_url(EMBEDPRESS_URL_ASSETS . 'images/bfcm2025-banner.png'); ?>" alt="Black Friday Sale">
175 </a>
176 </div>
177 <?php endif; ?>
178
179 <!-- Content -->
180 <div class="milestone-content">
181 <!-- Achievement Banner -->
182 <div class="milestone-achievement">
183 <h3 class="milestone-achievement-title">
184 <?php echo $data['emoji']; ?> <?php echo wp_kses_post($data['title']); ?>
185 </h3>
186 <p class="milestone-achievement-subtitle">
187 <?php echo wp_kses_post($data['subtitle']); ?>
188 </p>
189 <a href="<?php echo esc_url(admin_url('admin.php?page=embedpress-analytics')); ?>" class="milestone-link">
190 View Analytics
191 </a>
192 </div>
193
194 <!-- Stats Grid -->
195 <div class="milestone-stats">
196 <div class="milestone-stats-inner-wrapper">
197
198 <div class="milestone-stats-inner">
199 <?php foreach ($data['stats'] as $stat) : ?>
200 <div class="milestone-stat-card">
201 <div class="milestone-stat-label"><?php echo esc_html($stat['label']); ?></div>
202 <div class="milestone-stat-value"><?php echo esc_html($stat['value']); ?></div>
203 </div>
204 <?php endforeach; ?>
205 </div>
206
207 <!-- CTA Button -->
208 <a href="<?php echo esc_url('https://embedpress.com/in/unlock-advanced-analytics'); ?>" target="_blank" class="milestone-cta">
209 Unlock Pro Insights
210 </a>
211 </div>
212
213
214 </div>
215 </div>
216 </div>
217 </div>
218 </div>
219 <?php
220 }
221
222 /**
223 * Get milestone data
224 * Fetches real analytics data from the database to show user's embed performance
225 */
226 private function get_milestone_data()
227 {
228 // Get Analytics Manager instance
229 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
230
231 // Get real analytics data
232 $total_embeds = 0;
233 $total_views = 0;
234 $total_unique_viewers = 0;
235 $total_impressions = 0;
236
237 try {
238 // Get content count by type
239 $content_by_type = $analytics_manager->get_total_content_by_type();
240 $total_embeds = isset($content_by_type['total']) ? $content_by_type['total'] : 0;
241
242 // Get total views, impressions, and unique viewers from Data_Collector
243 $data_collector = new \EmbedPress\Includes\Classes\Analytics\Data_Collector();
244 $total_views = $data_collector->get_total_views();
245 $total_impressions = $data_collector->get_total_impressions();
246 $total_unique_viewers = $data_collector->get_total_unique_viewers();
247 } catch (\Exception $e) {
248 // Fallback to default values if there's an error
249 error_log('EmbedPress Milestone: Error fetching analytics data - ' . $e->getMessage());
250 }
251
252 // Format numbers for display
253 $embeds_formatted = $this->format_number($total_embeds);
254 $views_formatted = $this->format_number($total_views);
255 $unique_views_formatted = $this->format_number($total_unique_viewers);
256 $impressions_formatted = $this->format_number($total_impressions);
257
258 // Calculate total interactions (sum of all metrics)
259 $total_interactions = $total_embeds + $total_views + $total_unique_viewers + $total_impressions;
260
261 // Get milestone configuration based on total interactions
262 $milestone_config = $this->get_milestone_config($total_interactions);
263
264 return array_merge($milestone_config, [
265 'stats' => [
266 [
267 'label' => 'Total Embeds',
268 'value' => $embeds_formatted
269 ],
270 [
271 'label' => 'Total Views',
272 'value' => $views_formatted
273 ],
274 [
275 'label' => 'Unique Views',
276 'value' => $unique_views_formatted
277 ],
278 [
279 'label' => 'Total Impressions',
280 'value' => $impressions_formatted
281 ]
282 ]
283 ]);
284 }
285
286 /**
287 * Get milestone configuration based on total interactions
288 * Returns unique title, subtitle, and emoji for each milestone level
289 */
290 private function get_milestone_config($total_interactions)
291 {
292 // Define milestone levels with unique messages
293 $milestones = [
294 1000000 => [
295 'emoji' => '👑',
296 'title' => 'Legendary! <strong>1M+ interactions achieved!</strong>',
297 'subtitle' => 'You\'re an <strong>absolute legend</strong>! Your embeds are reaching millions. Pro analytics will help you scale to infinity.',
298 'level' => '1m'
299 ],
300 500000 => [
301 'emoji' => '💎',
302 'title' => 'Diamond Status! <strong>500K+ interactions!</strong>',
303 'subtitle' => 'You\'ve reached <strong>diamond tier</strong>! Your content is viral. Unlock Pro to maximize your massive reach.',
304 'level' => '500k'
305 ],
306 250000 => [
307 'emoji' => '🏆',
308 'title' => 'Champion! <strong>250K+ interactions unlocked!</strong>',
309 'subtitle' => 'You\'re a <strong>true champion</strong>! Your embeds are crushing it. Get Pro insights to dominate even more.',
310 'level' => '250k'
311 ],
312 100000 => [
313 'emoji' => '🌟',
314 'title' => 'Superstar! <strong>100K+ interactions reached!</strong>',
315 'subtitle' => 'You\'re a <strong>superstar</strong>! Your content is exploding. Upgrade to Pro for enterprise-level analytics.',
316 'level' => '100k'
317 ],
318 50000 => [
319 'emoji' => '',
320 'title' => 'Incredible! <strong>50K+ interactions achieved!</strong>',
321 'subtitle' => 'You\'re a <strong>Pro</strong>! Unlock advanced analytics to scale even further and dominate your niche.',
322 'level' => '50k'
323 ],
324 20000 => [
325 'emoji' => '🔥',
326 'title' => 'Amazing! <strong>20K+ interactions and counting!</strong>',
327 'subtitle' => 'Your embeds are <strong>on fire</strong>! Get Pro to unlock powerful insights and boost performance.',
328 'level' => '20k'
329 ],
330 10000 => [
331 'emoji' => '',
332 'title' => 'Fantastic! You\'ve reached <strong>10K</strong> interactions!',
333 'subtitle' => 'You\'re doing <strong>great</strong>! Upgrade to Pro to see detailed analytics and grow even faster.',
334 'level' => '10k'
335 ],
336 5000 => [
337 'emoji' => '🎯',
338 'title' => 'Awesome! <strong>5K interactions milestone unlocked!</strong>',
339 'subtitle' => 'Your content is <strong>resonating</strong>! Unlock Pro to discover what\'s working best.',
340 'level' => '5k'
341 ],
342 1000 => [
343 'emoji' => '🎉',
344 'title' => 'Congratulations! <strong>1K+ interactions reached!</strong>',
345 'subtitle' => 'Your embeds are <strong>gaining traction</strong>! Upgrade to Pro to see advanced analytics and improve performance.',
346 'level' => '1k'
347 ]
348 ];
349
350 // Find the appropriate milestone level
351 foreach ($milestones as $threshold => $config) {
352 if ($total_interactions >= $threshold) {
353 return $config;
354 }
355 }
356
357 // Default for users below 1K interactions
358 return [
359 'emoji' => '👋',
360 'title' => 'Welcome! Your <strong>embed journey</strong> has begun!',
361 'subtitle' => 'Start measuring your embed performance today. Gain deeper insights, monitor engagement, and level up with EmbedPress Pro.',
362 'level' => 'starter'
363 ];
364 }
365
366 /**
367 * Format number for display (e.g., 1000 -> 1K, 1000000 -> 1M)
368 *
369 * @param int $number
370 * @return string
371 */
372 private function format_number($number)
373 {
374 $number = (int) $number;
375
376 if ($number === 0) {
377 return '0';
378 }
379
380 if ($number >= 1000000) {
381 return round($number / 1000000, 1) . 'M';
382 }
383
384 if ($number >= 1000) {
385 return round($number / 1000, 1) . 'K';
386 }
387
388 return (string) $number;
389 }
390
391 /**
392 * Check if milestone should be shown
393 * Shows milestone when:
394 * 1. Site reaches a new milestone level
395 */
396 private function should_show_milestone()
397 {
398 // Check if milestone is disabled in settings
399 $g_settings = get_option(EMBEDPRESS_PLG_NAME);
400 $turn_off_milestone = isset($g_settings['turn_off_milestone']) ? intval($g_settings['turn_off_milestone']) : 0;
401 if (!$turn_off_milestone) {
402 return false;
403 }
404
405 // Check if Pro is active - don't show milestone for Pro users
406 $license_info = \EmbedPress\Includes\Classes\Helper::get_license_info();
407 if ($license_info['is_pro_active']) {
408 return false;
409 }
410
411 // Get Analytics Manager instance
412 $analytics_manager = \EmbedPress\Includes\Classes\Analytics\Analytics_Manager::get_instance();
413
414 // Get real analytics data
415 $total_embeds = 0;
416 $total_views = 0;
417 $total_unique_viewers = 0;
418 $total_impressions = 0;
419
420 try {
421 // Get content count by type
422 $content_by_type = $analytics_manager->get_total_content_by_type();
423 $total_embeds = isset($content_by_type['total']) ? $content_by_type['total'] : 0;
424
425 // Get total views, impressions, and unique viewers from Data_Collector
426 $data_collector = new \EmbedPress\Includes\Classes\Analytics\Data_Collector();
427 $total_views = $data_collector->get_total_views();
428 $total_impressions = $data_collector->get_total_impressions();
429 $total_unique_viewers = $data_collector->get_total_unique_viewers();
430 } catch (\Exception $e) {
431 error_log('EmbedPress Milestone: Error fetching analytics data - ' . $e->getMessage());
432 return false;
433 }
434
435 // Calculate total interactions
436 $total_interactions = $total_embeds + $total_views + $total_unique_viewers + $total_impressions;
437
438 // Determine current milestone level
439 $current_level = 'starter';
440 if ($total_interactions >= 50000) {
441 $current_level = '50k';
442 } elseif ($total_interactions >= 20000) {
443 $current_level = '20k';
444 } elseif ($total_interactions >= 10000) {
445 $current_level = '10k';
446 } elseif ($total_interactions >= 5000) {
447 $current_level = '5k';
448 } elseif ($total_interactions >= 1000) {
449 $current_level = '1k';
450 }
451
452 // Get the last seen milestone level (site-wide option)
453 $last_seen_level = get_option('embedpress_milestone_level', '');
454
455 // Show milestone if:
456 // 1. Site has never seen any milestone, OR
457 // 2. Site has reached a new milestone level
458 if (empty($last_seen_level) || $last_seen_level !== $current_level) {
459 // Check if this milestone is already showing (not yet dismissed)
460 $is_showing = get_option('is_embedpress_milestone_showing', false);
461 if ($is_showing) {
462 return true; // Still showing, don't reset
463 }
464
465 // Don't update here - only update when user closes the notification
466 // Store current level temporarily so we can update it later
467 update_option('embedpress_milestone_current_level', $current_level);
468 update_option('embedpress_milestone_current_trigger', 'milestone_level');
469 update_option('is_embedpress_milestone_showing', true);
470 return true;
471 }
472
473 return false;
474 }
475
476 /**
477 * AJAX handler to mark milestone as seen
478 */
479 public function ajax_mark_milestone_seen()
480 {
481 // Verify nonce
482 if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'embedpress_milestone_nonce')) {
483 wp_send_json_error('Invalid nonce');
484 return;
485 }
486
487 // Get the trigger type (version_update or milestone_level)
488 $trigger_type = get_option('embedpress_milestone_current_trigger', 'milestone_level');
489
490 // If triggered by version update, store the current version
491 if ($trigger_type === 'version_update') {
492 update_option('embedpress_last_milestone_version', EMBEDPRESS_VERSION);
493 }
494
495 // Get the current milestone level that was shown
496 $current_level = get_option('embedpress_milestone_current_level', '');
497
498 if (!empty($current_level)) {
499 // Mark this milestone level as seen (site-wide)
500 update_option('embedpress_milestone_level', $current_level);
501
502 // Clean up the temporary option
503 delete_option('embedpress_milestone_current_level');
504 }
505
506 // Clean up trigger type
507 delete_option('embedpress_milestone_current_trigger');
508
509 // Clear the "is showing" flag when user dismisses the milestone
510 // This allows the next milestone to be shown when conditions are met
511 delete_option('is_embedpress_milestone_showing');
512
513 wp_send_json_success();
514 }
515 }
516