PluginProbe
Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code / 5.2.0
Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code v5.2.0
5.5.3 3.1.0 3.2.0 3.2.1 3.3.0 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.6.0 3.7.0 3.8.0 3.8.1 3.8.2 3.8.3 4.0.0 4.0.2 4.0.3 4.0.4 4.0.5 4.1.0 4.1.1 All 78 releases
copy-the-code / includes / class-welcome.php

class-welcome.php in Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code 5.2.0, at includes/class-welcome.php

347 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Welcome Notice
4 *
5 * Handles the welcome/onboarding experience for new installs and upgrades.
6 *
7 * @package CTC
8 * @since 5.0.0
9 */
10
11 namespace CTC;
12
13 /**
14 * Welcome Class
15 *
16 * Manages welcome notices and onboarding for new users.
17 *
18 * @since 5.0.0
19 */
20 class Welcome {
21
22 /**
23 * Instance
24 *
25 * @var Welcome|null
26 */
27 private static $instance = null;
28
29 /**
30 * Option key for tracking welcome notice dismissal.
31 *
32 * @var string
33 */
34 const NOTICE_DISMISSED_OPTION = 'ctc_welcome_notice_dismissed';
35
36 /**
37 * Option key for tracking first install.
38 *
39 * @var string
40 */
41 const FIRST_INSTALL_OPTION = 'ctc_first_install_version';
42
43 /**
44 * Get instance.
45 *
46 * @return Welcome
47 */
48 public static function get() {
49 if ( null === self::$instance ) {
50 self::$instance = new self();
51 }
52 return self::$instance;
53 }
54
55 /**
56 * Constructor.
57 */
58 private function __construct() {
59 // Track first install.
60 $this->maybe_set_first_install();
61
62 // Admin hooks.
63 add_action( 'admin_notices', [ $this, 'render_welcome_notice' ] );
64 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_notice_scripts' ] );
65 add_action( 'wp_ajax_ctc_dismiss_welcome_notice', [ $this, 'ajax_dismiss_notice' ] );
66
67 // Hook into updater for upgrade notices.
68 add_action( 'ctc/updater/after', [ $this, 'on_version_update' ], 10, 2 );
69 }
70
71 /**
72 * Set first install version if not set.
73 *
74 * @since 5.0.0
75 */
76 private function maybe_set_first_install() {
77 if ( ! get_option( self::FIRST_INSTALL_OPTION ) ) {
78 update_option( self::FIRST_INSTALL_OPTION, CTC_VER );
79 }
80 }
81
82 /**
83 * Check if this is a fresh install (no previous version).
84 *
85 * @return bool
86 */
87 public function is_fresh_install() {
88 $saved_version = get_option( Updater::VERSION_OPTION, '' );
89 return empty( $saved_version ) || '0.0.0' === $saved_version;
90 }
91
92 /**
93 * Check if user upgraded from a version before 5.0.0.
94 *
95 * @return bool
96 */
97 public function is_upgrade_to_5() {
98 $first_install = get_option( self::FIRST_INSTALL_OPTION, '' );
99 return ! empty( $first_install ) && version_compare( $first_install, '5.0.0', '<' );
100 }
101
102 /**
103 * Check if welcome notice should be shown.
104 *
105 * @return bool
106 */
107 public function should_show_notice() {
108 // Don't show if dismissed.
109 if ( get_option( self::NOTICE_DISMISSED_OPTION ) ) {
110 return false;
111 }
112
113 // Don't show on the Global Injector page.
114 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
115 if ( isset( $_GET['page'] ) && 'ctc-global-injector' === $_GET['page'] ) {
116 return false;
117 }
118
119 // Only show to users who can manage options.
120 if ( ! current_user_can( 'manage_options' ) ) {
121 return false;
122 }
123
124 return true;
125 }
126
127 /**
128 * Get the welcome message based on install type.
129 *
130 * @return array{title: string, message: string, type: string}
131 */
132 private function get_welcome_content() {
133 if ( $this->is_fresh_install() ) {
134 return [
135 'title' => __( 'Thanks for installing Copy Anything to Clipboard!', 'ctc' ),
136 'message' => __( 'Add copy-to-clipboard buttons to any element on your site in seconds. The new Global Injector makes it easier than ever — no coding required.', 'ctc' ),
137 'type' => 'fresh',
138 ];
139 }
140
141 // Upgrade message.
142 return [
143 'title' => __( 'Welcome to Copy Anything to Clipboard!', 'ctc' ),
144 'message' => __( 'This major update introduces the powerful Global Injector with visual style presets, display conditions, and live preview. Your existing settings have been preserved.', 'ctc' ),
145 'type' => 'upgrade',
146 ];
147 }
148
149 /**
150 * Render the welcome admin notice.
151 *
152 * @since 5.0.0
153 */
154 public function render_welcome_notice() {
155 if ( ! $this->should_show_notice() ) {
156 return;
157 }
158
159 $content = $this->get_welcome_content();
160 $global_injector_url = admin_url( 'admin.php?page=ctc-global-injector' );
161 $docs_url = 'https://docs.clipboard.agency/getting-started';
162
163 ?>
164 <div class="notice notice-info is-dismissible ctc-welcome-notice" id="ctc-welcome-notice">
165 <div class="ctc-welcome-notice-content">
166 <div class="ctc-welcome-notice-icon">
167 <span class="dashicons dashicons-clipboard"></span>
168 </div>
169 <div class="ctc-welcome-notice-text">
170 <p class="ctc-welcome-notice-title">
171 <strong><?php echo esc_html( $content['title'] ); ?></strong>
172 <?php if ( 'fresh' === $content['type'] ) : ?>
173 <span class="ctc-welcome-emoji">🎉</span>
174 <?php else : ?>
175 <span class="ctc-welcome-emoji">🚀</span>
176 <?php endif; ?>
177 </p>
178 <p class="ctc-welcome-notice-message"><?php echo esc_html( $content['message'] ); ?></p>
179 <p class="ctc-welcome-notice-actions">
180 <a href="<?php echo esc_url( $global_injector_url ); ?>" class="button button-primary">
181 <?php esc_html_e( 'Get Started', 'ctc' ); ?>
182 </a>
183 <a href="<?php echo esc_url( $docs_url ); ?>" class="button button-secondary" target="_blank" rel="noopener noreferrer">
184 <?php esc_html_e( 'View Documentation', 'ctc' ); ?>
185 <span class="dashicons dashicons-external" style="font-size: 14px; line-height: 1.8;"></span>
186 </a>
187 <?php if ( 'upgrade' === $content['type'] ) : ?>
188 <a href="https://clipboard.agency/changelog/" class="ctc-welcome-link" target="_blank" rel="noopener noreferrer">
189 <?php esc_html_e( "See what's new", 'ctc' ); ?>
190 </a>
191 <?php endif; ?>
192 </p>
193 </div>
194 </div>
195 </div>
196 <?php
197 }
198
199 /**
200 * Enqueue notice scripts and styles.
201 *
202 * @since 5.0.0
203 */
204 public function enqueue_notice_scripts() {
205 if ( ! $this->should_show_notice() ) {
206 return;
207 }
208
209 // Inline styles for the notice.
210 $styles = '
211 #ctc-welcome-notice {
212 padding: 12px 12px 12px 0;
213 border-left-color: #2271b1;
214 }
215 #ctc-welcome-notice .ctc-welcome-notice-content {
216 display: flex;
217 align-items: flex-start;
218 gap: 12px;
219 }
220 #ctc-welcome-notice .ctc-welcome-notice-icon {
221 flex-shrink: 0;
222 width: 40px;
223 height: 40px;
224 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
225 border-radius: 8px;
226 display: flex;
227 align-items: center;
228 justify-content: center;
229 margin-left: 12px;
230 }
231 #ctc-welcome-notice .ctc-welcome-notice-icon .dashicons {
232 color: #fff;
233 font-size: 20px;
234 width: 20px;
235 height: 20px;
236 }
237 #ctc-welcome-notice .ctc-welcome-notice-text {
238 flex: 1;
239 }
240 #ctc-welcome-notice .ctc-welcome-notice-title {
241 margin: 0 0 4px 0;
242 font-size: 14px;
243 }
244 #ctc-welcome-notice .ctc-welcome-emoji {
245 margin-left: 4px;
246 }
247 #ctc-welcome-notice .ctc-welcome-notice-message {
248 margin: 0 0 12px 0;
249 color: #50575e;
250 }
251 #ctc-welcome-notice .ctc-welcome-notice-actions {
252 display: flex;
253 align-items: center;
254 gap: 8px;
255 flex-wrap: wrap;
256 margin: 0;
257 }
258 #ctc-welcome-notice .ctc-welcome-notice-actions .button-primary {
259 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
260 border-color: #667eea;
261 }
262 #ctc-welcome-notice .ctc-welcome-notice-actions .button-primary:hover {
263 background: linear-gradient(135deg, #5a6fd6 0%, #6a4190 100%);
264 border-color: #5a6fd6;
265 }
266 #ctc-welcome-notice .ctc-welcome-link {
267 color: #2271b1;
268 text-decoration: none;
269 font-weight: 500;
270 margin-left: 8px;
271 }
272 #ctc-welcome-notice .ctc-welcome-link:hover {
273 color: #135e96;
274 }
275 ';
276
277 wp_add_inline_style( 'wp-admin', $styles );
278
279 // Inline script for handling dismissal.
280 $script = "
281 jQuery(document).ready(function($) {
282 $('#ctc-welcome-notice').on('click', '.notice-dismiss', function() {
283 $.ajax({
284 url: ajaxurl,
285 type: 'POST',
286 data: {
287 action: 'ctc_dismiss_welcome_notice',
288 nonce: '" . wp_create_nonce( 'ctc_dismiss_welcome_notice' ) . "'
289 }
290 });
291 });
292 });
293 ";
294
295 wp_add_inline_script( 'jquery', $script );
296 }
297
298 /**
299 * AJAX handler for dismissing the welcome notice.
300 *
301 * @since 5.0.0
302 */
303 public function ajax_dismiss_notice() {
304 // Verify nonce.
305 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'ctc_dismiss_welcome_notice' ) ) {
306 wp_send_json_error( 'Invalid nonce' );
307 }
308
309 // Check permissions.
310 if ( ! current_user_can( 'manage_options' ) ) {
311 wp_send_json_error( 'Insufficient permissions' );
312 }
313
314 // Mark as dismissed.
315 update_option( self::NOTICE_DISMISSED_OPTION, true );
316
317 wp_send_json_success();
318 }
319
320 /**
321 * Handle version updates - reset notice for major upgrades.
322 *
323 * @since 5.0.0
324 *
325 * @param string $from_version Previous version.
326 * @param string $to_version New version.
327 */
328 public function on_version_update( $from_version, $to_version ) {
329 // Show welcome notice again for major version upgrades.
330 $from_major = explode( '.', $from_version )[0];
331 $to_major = explode( '.', $to_version )[0];
332
333 if ( $from_major !== $to_major ) {
334 delete_option( self::NOTICE_DISMISSED_OPTION );
335 }
336 }
337
338 /**
339 * Reset welcome notice (useful for testing).
340 *
341 * @since 5.0.0
342 */
343 public static function reset_notice() {
344 delete_option( self::NOTICE_DISMISSED_OPTION );
345 }
346 }
347