PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 4.6.2
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v4.6.2
4.6.2 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 / Includes / Classes / FeatureNotices.php
embedpress / EmbedPress / Includes / Classes Last commit date
Analytics 1 month ago Database 2 months ago DynamicFieldResolver.php 1 month ago Elementor_Enhancer.php 6 months ago EmbedPress_Core_Installer.php 6 years ago EmbedPress_Notice.php 3 months ago EmbedPress_Plugin_Usage_Tracker.php 1 month ago Extend_CustomPlayer_Controls.php 2 months ago Extend_Elementor_Controls.php 1 year ago FeatureNoticeManager.php 3 weeks ago FeatureNotices.php 4 days ago FeaturePreviewModal.php 3 weeks ago Feature_Enhancer.php 1 month ago GoogleReviewsAdminPage.php 3 weeks ago GoogleReviewsApify.php 3 weeks ago GoogleReviewsManaged.php 3 weeks ago GoogleReviewsRenderer.php 3 weeks ago GoogleReviewsRestController.php 3 weeks ago GoogleReviewsStore.php 3 weeks ago Helper.php 1 week ago Pdf_Thumbnail_Handler.php 3 months ago PermalinkHelper.php 11 months ago View_Count_Display.php 1 month ago
FeatureNotices.php
384 lines
1 <?php
2
3 namespace EmbedPress\Includes\Classes;
4
5 /**
6 * Feature Notices Registration
7 *
8 * This file contains all feature notice registrations for EmbedPress.
9 * Add your feature notices here to keep them organized in one place.
10 *
11 * @package EmbedPress
12 * @since 4.1.0
13 */
14
15 (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
16
17 class FeatureNotices
18 {
19
20 /**
21 * Singleton instance
22 * @var FeatureNotices
23 */
24 private static $instance = null;
25
26 /**
27 * Get singleton instance
28 *
29 * @return FeatureNotices
30 */
31 public static function get_instance()
32 {
33 if (self::$instance === null) {
34 self::$instance = new self();
35 }
36 return self::$instance;
37 }
38
39 /**
40 * Constructor
41 */
42 private function __construct()
43 {
44 // Register all notices
45 add_action('init', [$this, 'register_all_notices']);
46 }
47
48 /**
49 * Register all feature notices
50 *
51 * Add your feature notices here. Each notice should have a unique ID.
52 *
53 * @return void
54 */
55 public function register_all_notices()
56 {
57 $notice_manager = FeatureNoticeManager::get_instance();
58
59 // ========================================
60 // ACTIVE NOTICES
61 // ========================================
62 // Note: Notices only show on Dashboard page (/wp-admin/index.php)
63 // Any action (Skip, Close, or Click Button) = Permanently dismiss
64
65 // Analytics Dashboard Feature Notice
66 $notice_manager->register_notice('analytics_dashboard_2024', [
67 'title' => 'New Features',
68 'icon' => '<svg width="11" height="13" viewBox="0 0 11 13" fill="none" xmlns="http://www.w3.org/2000/svg">
69 <path d="M0 1.61956C1.26645e-05 1.53091 0.0177073 1.44315 0.0520487 1.36142C0.0863901 1.27968 0.136689 1.20562 0.2 1.14356C0.926563 0.431321 1.89723 0.0227172 2.91444 0.000919081C3.93164 -0.0208791 4.91893 0.345767 5.67533 1.02623L5.90933 1.2449C6.39562 1.67096 7.02013 1.90585 7.66667 1.90585C8.3132 1.90585 8.93771 1.67096 9.424 1.2449L9.59 1.09356C9.99667 0.771563 10.608 1.0289 10.6633 1.54423L10.6667 1.61956V7.61956C10.6667 7.70822 10.649 7.79598 10.6146 7.87771C10.5803 7.95944 10.53 8.03351 10.4667 8.09556C9.7401 8.8078 8.76943 9.21641 7.75223 9.23821C6.73502 9.26 5.74774 8.89336 4.99133 8.2129L4.75733 7.99423C4.28636 7.58157 3.68518 7.3478 3.05915 7.33391C2.43311 7.32001 1.82216 7.52687 1.33333 7.91823V12.2862C1.33314 12.4561 1.26808 12.6196 1.15143 12.7431C1.03479 12.8667 0.875365 12.9411 0.705737 12.951C0.536109 12.961 0.36908 12.9058 0.238778 12.7967C0.108476 12.6877 0.0247357 12.533 0.00466665 12.3642L0 12.2862V1.61956Z" fill="#25396F"/>
70 </svg>',
71 'message' => '🥳 New In EmbedPress: Introducing, Analytics dashboard to track every embed performance; see total counts, views, clicks, geo insights, etc.',
72 'button_text' => 'View Analytics',
73 'button_url' => admin_url('admin.php?page=embedpress-analytics'),
74 'skip_text' => 'Skip',
75 'screens' => [], // Empty = show on all admin pages
76 'capability' => 'manage_options',
77 'start_date' => '2024-01-01',
78 'end_date' => '2025-10-31',
79 'priority' => 10,
80 // 'dismissible' => false,
81 'type' => 'info', // info, success, warning, error
82 ]);
83
84 // ========================================
85 // EXAMPLE NOTICES (Commented Out)
86 // ========================================
87
88 /*
89 // Example: New Feature Announcement
90 $notice_manager->register_notice('new_feature_example', [
91 'title' => 'New Features',
92 'icon' => '🚀',
93 'message' => '<strong>Exciting Update!</strong> We\'ve added amazing new features to EmbedPress.',
94 'button_text' => 'Learn More',
95 'button_url' => 'https://embedpress.com/features',
96 'button_target' => '_blank',
97 'skip_text' => 'Maybe Later',
98 'screens' => ['toplevel_page_embedpress'], // Show only on EmbedPress pages
99 'capability' => 'manage_options',
100 'priority' => 5,
101 'type' => 'success',
102 ]);
103 */
104
105 /*
106 // Example: Limited Time Offer
107 $notice_manager->register_notice('black_friday_2024', [
108 'title' => 'Limited Time Offer',
109 'icon' => '🎁',
110 'message' => '<strong>Black Friday Sale!</strong> Get 50% off on EmbedPress Pro. Offer ends soon!',
111 'button_text' => 'Claim Discount',
112 'button_url' => 'https://embedpress.com/pricing',
113 'button_target' => '_blank',
114 'skip_text' => 'Not Interested',
115 'start_date' => '2024-11-25',
116 'end_date' => '2024-12-02',
117 'priority' => 1, // Higher priority (lower number = shown first)
118 'type' => 'warning',
119 ]);
120 */
121
122 /*
123 // Example: Important Update Notice
124 $notice_manager->register_notice('important_update_2024', [
125 'title' => 'Important Update',
126 'icon' => '⚠️',
127 'message' => '<strong>Action Required:</strong> Please update your settings to ensure compatibility with the latest version.',
128 'button_text' => 'Update Settings',
129 'button_url' => admin_url('admin.php?page=embedpress#/settings'),
130 'skip_text' => 'Remind Me Later',
131 'priority' => 1,
132 'type' => 'warning',
133 ]);
134 */
135
136 /*
137 // Example: Success/Milestone Notice
138 $notice_manager->register_notice('milestone_100k', [
139 'title' => 'Thank You!',
140 'icon' => '🎊',
141 'message' => '<strong>We did it!</strong> EmbedPress has reached 100,000+ active installations. Thank you for being part of our journey!',
142 'button_text' => 'Share Your Feedback',
143 'button_url' => 'https://wordpress.org/support/plugin/embedpress/reviews/',
144 'button_target' => '_blank',
145 'skip_text' => 'Close',
146 'start_date' => '2024-01-01',
147 'end_date' => '2024-12-31',
148 'priority' => 15,
149 'type' => 'success',
150 ]);
151 */
152
153 // ========================================
154 // "WHAT'S NEW" FEATURE PREVIEW MODAL
155 // ========================================
156 // The big post-update split modal (preview + copy). One feature set
157 // per release; edit copy/CTA/media here without touching the renderer.
158 $this->register_feature_previews();
159 }
160
161 /**
162 * Register the post-update "What's New" feature preview modal sets.
163 *
164 * One entry per release. The modal fires once on the dashboard when the
165 * set's `version` is newer than the user's seen-version, then stamps the
166 * version so it never re-shows. Single feature => no nav; 2+ => carousel.
167 *
168 * Media `type` accepts: 'image', 'gif', 'video' (relative paths resolve
169 * against assets/images/), or 'html' for an inline CSS demo.
170 *
171 * @return void
172 */
173 public function register_feature_previews()
174 {
175 if (!class_exists('\\EmbedPress\\Includes\\Classes\\FeaturePreviewModal')) {
176 return;
177 }
178
179 $version = defined('EMBEDPRESS_VERSION') ? EMBEDPRESS_VERSION : '0.0.0';
180 $modal = FeaturePreviewModal::get_instance();
181
182 // Which releases actually announce something. The modal is opt-IN per
183 // version: a release only shows it when its version is listed here AND
184 // the $features array below describes that release.
185 //
186 // Why an allowlist instead of a bare `'show_if' => true`: the feature
187 // slides are hand-written per release, so a patch that ships no new
188 // features (4.6.1, 4.6.2 — bug fixes and security hardening) would
189 // otherwise re-announce the PREVIOUS release's copy under a new version
190 // number. Defaulting to "off" makes the safe case automatic and the
191 // announcement deliberate.
192 //
193 // To announce a new release: rewrite $features for it, then add its
194 // version here. Patch releases with no user-facing features: add
195 // nothing — they stay silent, along with the menu "New" badge.
196 $announced_versions = [
197 '4.6.0', // Google Reviews + PDF flipbook Highlight Links
198 ];
199
200 $is_announced = in_array($version, $announced_versions, true);
201
202 // Feature slides for this release. Two slides → the modal auto-switches
203 // to a carousel (dots + Back/Next). Demos are inline HTML (no assets).
204 $features = [
205 [
206 'eyebrow' => sprintf(__('New in %s', 'embedpress'), $version),
207 'title' => __('Embed Google Business reviews', 'embedpress'),
208 'desc' => __('Showcase your Google reviews anywhere — Gutenberg block, Elementor widget, or shortcode. Pick a place, choose a layout, and you’re live. No Google API keys required.', 'embedpress'),
209 'media' => [
210 'type' => 'html',
211 'html' => $this->preview_demo_google_reviews(),
212 ],
213 'cta' => [
214 'label' => __('Set up Google Reviews →', 'embedpress'),
215 'url' => admin_url('admin.php?page=embedpress-google-reviews'),
216 ],
217 ],
218 [
219 'eyebrow' => sprintf(__('New in %s', 'embedpress'), $version),
220 'title' => __('Highlight links in 3D PDF Flipbooks', 'embedpress'),
221 'desc' => __('Make hyperlinks inside your PDF 3D Flipbooks stand out, so readers never miss a clickable link.', 'embedpress'),
222 'media' => [
223 // Real product capture of link-highlighting in a 3D
224 // Flipbook, hosted on the CDN. Full URL passes through
225 // resolve_media_src() unchanged; preloaded in <head> and
226 // shown behind a shimmer while it downloads.
227 'type' => 'gif',
228 'src' => 'https://cloud.zoobbe.com/backgrounds/pdf-3d-flipbook-d.gif',
229 ],
230 'cta' => [
231 'label' => __('View documentation →', 'embedpress'),
232 'url' => 'https://embedpress.com/docs/turn-embedded-pdf-into-a-3d-flip-book/',
233 'external' => true,
234 ],
235 ],
236 ];
237
238 // 4.6.0 release set. Versioned id so a fresh release is a fresh
239 // announcement. Demos are inline, on-brand HTML (no asset files).
240 $modal->register('whatsnew_' . str_replace('.', '_', $version), [
241 'version' => $version,
242 // Master switch for THIS release's modal. Set to false to ship the
243 // release without the modal (e.g. a refactor-only version), or pass
244 // a callable for conditional gating, e.g.:
245 // 'show_if' => function () { return ! function_exists('embedpress_pro_load'); }, // non-Pro only
246 //
247 // Driven by the $announced_versions allowlist above — true only for
248 // releases that actually ship user-facing features. Bug-fix and
249 // security patches (4.6.1, 4.6.2) resolve to false, so both the
250 // modal and the menu "New" badge stay silent.
251 'show_if' => $is_announced,
252 'changelog_url' => 'https://embedpress.com/changelog/',
253 // When usage tracking is NOT yet enabled, the bottom link becomes
254 // "What we collect" → the privacy policy (replacing the changelog
255 // link). Users who already opted in keep the normal changelog link.
256 'whatwe_collect_url' => FeaturePreviewModal::is_tracking_enabled()
257 ? ''
258 : 'https://wpdeveloper.com/privacy-policy',
259 'features' => $features,
260 ]);
261 }
262
263 /**
264 * Inline placeholder demo for the sample feature — a clean, on-brand mock
265 * of the "Display Rules" control (role / login / schedule toggles).
266 *
267 * Uses EmbedPress brand colors only: brand purple #5945b0 (+ #7c3aed
268 * gradient), success green #00cc76 for the "on" schedule toggle, and the
269 * dark preview-panel tones. Real releases should swap this for a screenshot
270 * or GIF via 'media' => ['type' => 'image', 'src' => '…'].
271 *
272 * @return string
273 */
274 private function preview_demo_display_rules()
275 {
276 $row = function ($on, $label, $color, $pill = '') {
277 $knob = $on
278 ? 'right:2px'
279 : 'left:2px';
280 $bg = $on ? $color : '#3a3550';
281 $pill_html = $pill
282 ? '<span style="margin-left:auto;font-size:11px;font-weight:600;color:#9a8be0;background:rgba(89,69,176,.22);padding:3px 9px;border-radius:999px">' . esc_html($pill) . '</span>'
283 : '';
284 return '<div style="display:flex;align-items:center;gap:10px;background:#1b1928;border:1px solid #2a2740;border-radius:10px;padding:11px 13px;margin-bottom:9px">'
285 . '<span style="width:30px;height:17px;border-radius:9px;background:' . $bg . ';position:relative;flex-shrink:0"><span style="position:absolute;top:2px;' . $knob . ';width:13px;height:13px;border-radius:50%;background:#fff"></span></span>'
286 . '<span style="font-size:12px;color:#dfe3f0">' . esc_html($label) . '</span>'
287 . $pill_html
288 . '</div>';
289 };
290
291 return '<div style="width:262px;font-family:inherit">'
292 . '<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;color:#c7cce0;font-size:12px;font-weight:600">'
293 . '<span style="width:18px;height:18px;border-radius:5px;background:#5945b0;display:inline-flex;align-items:center;justify-content:center;color:#fff;font-size:10px">&#10022;</span>'
294 . esc_html__('Display Rules', 'embedpress') . '</div>'
295 . $row(true, __('User role', 'embedpress'), '#5945b0', __('Members', 'embedpress'))
296 . $row(false, __('Logged-in only', 'embedpress'), '#5945b0')
297 . $row(true, __('Schedule by date', 'embedpress'), '#00cc76')
298 . '</div>';
299 }
300
301 /**
302 * Animated, LIGHT demo for the Google Reviews feature — a 3-step loop that
303 * tells the feature story: (1) search for a place, (2) click the result,
304 * (3) the reviews animate in. The keyframe animations live in
305 * static/css/feature-preview-modal.css (.ep-grdemo-* classes) because the
306 * modal runs this markup through wp_kses_post, which strips <style>; class
307 * attributes survive, so the CSS does the motion.
308 *
309 * @return string
310 */
311 private function preview_demo_google_reviews()
312 {
313 $stars = '<span class="ep-grdemo-stars">'
314 . str_repeat('<span>&#9733;</span>', 5) . '</span>';
315
316 // The same icons our place picker uses (GoogleReviews.jsx). Inline SVG
317 // survives because the modal allows a small SVG tag set for plugin-built
318 // demo markup (FeaturePreviewModal::demo_allowed_html()).
319 $search_icon = '<svg class="ep-grdemo-search-ico" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>';
320 $pin_icon = '<svg class="ep-grdemo-pin" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>';
321
322 // Per-card stagger is done via CSS (adjacent-sibling chains) — NOT an
323 // inline animation-delay, which kses strips.
324 $review = function ($initial, $name, $text) use ($stars) {
325 return '<div class="ep-grdemo-review">'
326 . '<div class="ep-grdemo-review-head">'
327 . '<span class="ep-grdemo-avatar">' . esc_html($initial) . '</span>'
328 . '<span class="ep-grdemo-name">' . esc_html($name) . '</span>'
329 . $stars
330 . '</div>'
331 . '<div class="ep-grdemo-text">' . esc_html($text) . '</div>'
332 . '</div>';
333 };
334
335 return '<div class="ep-grdemo">'
336 // ── Phase A: our place-search picker — input (text types in) +
337 // the suggestion dropdown that gets clicked. Mirrors the real
338 // .ep-gr-search / .ep-gr-suggestion markup. ──
339 . '<div class="ep-grdemo-phase ep-grdemo-phase--search">'
340 . '<div class="ep-grdemo-label">' . esc_html__('Search for a place', 'embedpress') . '</div>'
341 . '<div class="ep-grdemo-search">'
342 . $search_icon
343 . '<span class="ep-grdemo-typed">' . esc_html__('Sydney Opera House', 'embedpress') . '</span>'
344 . '<span class="ep-grdemo-caret"></span>'
345 . '</div>'
346 . '<div class="ep-grdemo-suggest">'
347 . '<div class="ep-grdemo-result">'
348 . $pin_icon
349 . '<span class="ep-grdemo-result-text"><strong>' . esc_html__('Sydney Opera House', 'embedpress') . '</strong>'
350 . '<small>' . esc_html__('Bennelong Point, Sydney NSW, Australia', 'embedpress') . '</small></span>'
351 . '<span class="ep-grdemo-cursor"></span>'
352 . '</div>'
353 . '</div>'
354 . '</div>'
355 // ── Phase B: the reviews our block renders — summary + cards. ──
356 . '<div class="ep-grdemo-phase ep-grdemo-phase--reviews">'
357 . '<div class="ep-grdemo-summary"><b>4.8</b>' . $stars
358 . '<span class="ep-grdemo-count">2,341 ' . esc_html__('reviews', 'embedpress') . '</span></div>'
359 . $review('A', __('Aisha K.', 'embedpress'), __('Breathtaking venue and a flawless experience — the guided tour was the trip highlight.', 'embedpress'))
360 . $review('M', __('Marco T.', 'embedpress'), __('A must-see. The architecture is stunning from every angle, day or night.', 'embedpress'))
361 . $review('L', __('Liam P.', 'embedpress'), __('Incredible acoustics and a stunning harbour view — booked tickets for the evening show.', 'embedpress'))
362 . '</div>'
363 . '</div>';
364 }
365
366 /**
367 * Helper method to get admin URL for EmbedPress pages
368 *
369 * @param string $page_type The page type (e.g., 'analytics', 'settings')
370 * @return string
371 */
372 private function get_embedpress_url($page_type = '')
373 {
374 $url = admin_url('admin.php?page=embedpress');
375 if (!empty($page_type)) {
376 $url .= '&page_type=' . $page_type;
377 }
378 return $url;
379 }
380 }
381
382 // Initialize the class
383 FeatureNotices::get_instance();
384