PluginProbe
WPC Countdown Timer for WooCommerce / trunk
WPC Countdown Timer for WooCommerce vtrunk
3.2.2 3.2.1 3.2.0 2.3.2 2.3.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 3.0.0 All 55 releases
wpc-countdown-timer / wpc-countdown-timer.php

wpc-countdown-timer.php in WPC Countdown Timer for WooCommerce trunk, at wpc-countdown-timer.php

1,372 lines 85.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WPC Countdown Timer for WooCommerce
4 Plugin URI: https://wpclever.net/
5 Description: WPC Countdown Timer helps you display countdown timer in single product pages and shop page.
6 Version: 3.2.2
7 Author: WPClever
8 Author URI: https://wpclever.net
9 Text Domain: wpc-countdown-timer
10 Domain Path: /languages/
11 Requires Plugins: woocommerce
12 Requires at least: 5.9
13 Tested up to: 7.0
14 WC requires at least: 3.0
15 WC tested up to: 10.9
16 License: GPLv2 or later
17 License URI: http://www.gnu.org/licenses/gpl-2.0.html
18 */
19
20 defined( 'ABSPATH' ) || exit;
21
22 ! defined( 'WOOCT_VERSION' ) && define( 'WOOCT_VERSION', '3.2.2' );
23 ! defined( 'WOOCT_LITE' ) && define( 'WOOCT_LITE', __FILE__ );
24 ! defined( 'WOOCT_FILE' ) && define( 'WOOCT_FILE', __FILE__ );
25 ! defined( 'WOOCT_URI' ) && define( 'WOOCT_URI', plugin_dir_url( __FILE__ ) );
26 ! defined( 'WOOCT_DIR' ) && define( 'WOOCT_DIR', plugin_dir_path( __FILE__ ) );
27 ! defined( 'WOOCT_SUPPORT' ) && define( 'WOOCT_SUPPORT', 'https://wpclever.net/support?utm_source=support&utm_medium=wooct&utm_campaign=wporg' );
28 ! defined( 'WOOCT_REVIEWS' ) && define( 'WOOCT_REVIEWS', 'https://wordpress.org/support/plugin/wpc-countdown-timer/reviews/' );
29 ! defined( 'WOOCT_CHANGELOG' ) && define( 'WOOCT_CHANGELOG', 'https://wordpress.org/plugins/wpc-countdown-timer/#developers' );
30 ! defined( 'WOOCT_DISCUSSION' ) && define( 'WOOCT_DISCUSSION', 'https://wordpress.org/support/plugin/wpc-countdown-timer' );
31
32 // WPC Core
33 require_once __DIR__ . '/includes/wpc-core/wpc-core.php';
34 wpc_core_register( [
35 'file' => __FILE__,
36 'version' => WOOCT_VERSION,
37 'prefix' => 'wooct',
38 ] );
39
40 if ( ! function_exists( 'wooct_init' ) ) {
41 add_action( 'plugins_loaded', 'wooct_init', 11 );
42
43 function wooct_init() {
44 if ( ! function_exists( 'WC' ) || ! version_compare( WC()->version, '3.0', '>=' ) ) {
45 add_action( 'admin_notices', 'wooct_notice_wc' );
46
47 return null;
48 }
49
50 if ( ! class_exists( 'WPCleverWooct' ) && class_exists( 'WC_Product' ) ) {
51 class WPCleverWooct {
52 protected static $instance = null;
53 protected static $settings = [];
54 protected static $localization = [];
55
56 public static function instance() {
57 if ( is_null( self::$instance ) ) {
58 self::$instance = new self();
59 }
60
61 return self::$instance;
62 }
63
64 function __construct() {
65 self::$settings = (array) get_option( 'wooct_settings', [] );
66 self::$localization = (array) get_option( 'wooct_localization', [] );
67
68 // Init
69
70 // Settings
71 add_action( 'admin_init', [ $this, 'register_settings' ] );
72 add_filter( 'pre_update_option', [ $this, 'last_saved' ], 10, 2 );
73 add_action( 'admin_menu', [ $this, 'admin_menu' ] );
74
75 // Enqueue scripts
76 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
77
78 // Enqueue backend scripts
79 add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
80
81 // Add settings link
82 add_filter( 'plugin_action_links', [ $this, 'action_links' ], 10, 2 );
83 add_filter( 'plugin_row_meta', [ $this, 'row_meta' ], 10, 2 );
84
85 // Product data tabs
86 add_filter( 'woocommerce_product_data_tabs', [ $this, 'product_data_tabs' ] );
87 add_action( 'woocommerce_product_data_panels', [ $this, 'product_data_panels' ] );
88 add_action( 'woocommerce_process_product_meta', [ $this, 'process_product_meta' ] );
89
90 // Variation
91 add_action( 'woocommerce_product_after_variable_attributes', [
92 $this,
93 'variation_settings'
94 ], 99, 3 );
95 add_action( 'woocommerce_save_product_variation', [ $this, 'save_variation_settings' ], 99, 2 );
96 add_action( 'woocommerce_after_variations_table', [ $this, 'after_variations_table' ] );
97
98 // Product columns
99 add_filter( 'manage_edit-product_columns', [ $this, 'product_columns' ] );
100 add_action( 'manage_product_posts_custom_column', [ $this, 'product_custom_column' ], 10, 2 );
101
102 // Product class
103 add_filter( 'woocommerce_post_class', [ $this, 'post_class' ], 99, 2 );
104
105 // Countdown on archive
106 $pos_archive = self::get_setting( 'position_archive', 'above_add_to_cart' );
107
108 switch ( $pos_archive ) {
109 case 'under_title':
110 add_action( 'woocommerce_shop_loop_item_title', [ $this, 'show_countdown' ], 11 );
111 break;
112 case 'under_rating':
113 add_action( 'woocommerce_after_shop_loop_item_title', [ $this, 'show_countdown' ], 6 );
114 break;
115 case 'under_price':
116 add_action( 'woocommerce_after_shop_loop_item_title', [ $this, 'show_countdown' ], 11 );
117 break;
118 case 'above_add_to_cart':
119 add_action( 'woocommerce_after_shop_loop_item', [ $this, 'show_countdown' ], 9 );
120 break;
121 case 'under_add_to_cart':
122 add_action( 'woocommerce_after_shop_loop_item', [ $this, 'show_countdown' ], 11 );
123 break;
124 }
125
126 // Countdown on single
127 $pos_single = self::get_setting( 'position_single', '29' );
128
129 if ( ! empty( $pos_single ) ) {
130 add_action( 'woocommerce_single_product_summary', [
131 $this,
132 'show_countdown_single'
133 ], $pos_single );
134 }
135
136 // Shortcode
137 add_shortcode( 'wooct_product', [ $this, 'shortcode_product' ] );
138
139 // Preview
140 add_action( 'wp_ajax_wooct_preview', [ $this, 'ajax_preview' ] );
141
142 // WPC Variation Duplicator
143 add_action( 'wpcvd_duplicated', [ $this, 'duplicate_variation' ], 99, 2 );
144
145 // WPC Variation Bulk Editor
146 add_action( 'wpcvb_bulk_update_variation', [ $this, 'bulk_update_variation' ], 99, 2 );
147 }
148 function register_settings() {
149 // settings
150 register_setting( 'wooct_settings', 'wooct_settings', [
151 'type' => 'array',
152 'sanitize_callback' => [ $this, 'sanitize_array' ],
153 ] );
154
155 // localization
156 register_setting( 'wooct_localization', 'wooct_localization', [
157 'type' => 'array',
158 'sanitize_callback' => [ $this, 'sanitize_array' ],
159 ] );
160 }
161
162 function last_saved( $value, $option ) {
163 if ( $option == 'wooct_settings' || $option == 'wooct_localization' ) {
164 $value['_last_saved'] = current_time( 'timestamp' );
165 $value['_last_saved_by'] = get_current_user_id();
166 }
167
168 return $value;
169 }
170
171 function admin_menu() {
172 add_submenu_page( 'wpclever', esc_html__( 'WPC Countdown Timer', 'wpc-countdown-timer' ), esc_html__( 'Countdown Timer', 'wpc-countdown-timer' ), 'manage_options', 'wpclever-wooct', [
173 $this,
174 'admin_menu_content'
175 ] );
176 }
177
178 function admin_menu_content() {
179 $active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ?? '' ) ) : 'settings';
180 ?>
181 <div class="wpclever_settings_page wrap">
182 <div class="wpclever_settings_page_header">
183 <a class="wpclever_settings_page_header_logo" href="https://wpclever.net/"
184 target="_blank" title="Visit wpclever.net"></a>
185 <div class="wpclever_settings_page_header_text">
186 <div class="wpclever_settings_page_title"><?php echo esc_html__( 'WPC Countdown Timer', 'wpc-countdown-timer' ) . ' ' . esc_html( WOOCT_VERSION ) . ' ' . ( defined( 'WOOCT_PREMIUM' ) ? '<span class="premium" style="display: none">' . esc_html__( 'Premium', 'wpc-countdown-timer' ) . '</span>' : '' ); ?></div>
187 <div class="wpclever_settings_page_desc about-text">
188 <p>
189 <?php printf( /* translators: stars */ esc_html__( 'Thank you for using our plugin! If you are satisfied, please reward it a full five-star %s rating.', 'wpc-countdown-timer' ), '<span style="color:#ffb900">&#9733;&#9733;&#9733;&#9733;&#9733;</span>' ); ?>
190 <br/>
191 <a href="<?php echo esc_url( WOOCT_REVIEWS ); ?>"
192 target="_blank"><?php esc_html_e( 'Reviews', 'wpc-countdown-timer' ); ?></a>
193 |
194 <a href="<?php echo esc_url( WOOCT_CHANGELOG ); ?>"
195 target="_blank"><?php esc_html_e( 'Changelog', 'wpc-countdown-timer' ); ?></a>
196 |
197 <a href="<?php echo esc_url( WOOCT_DISCUSSION ); ?>"
198 target="_blank"><?php esc_html_e( 'Discussion', 'wpc-countdown-timer' ); ?></a>
199 </p>
200 </div>
201 </div>
202 </div>
203 <h2></h2>
204 <?php if ( isset( $_GET['settings-updated'] ) && sanitize_text_field( wp_unslash( $_GET['settings-updated'] ?? '' ) ) ) { ?>
205 <div class="notice notice-success is-dismissible">
206 <p><?php esc_html_e( 'Settings updated.', 'wpc-countdown-timer' ); ?></p>
207 </div>
208 <?php } ?>
209 <div class="wpclever_settings_page_nav">
210 <h2 class="nav-tab-wrapper">
211 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=settings' ) ); ?>"
212 class="<?php echo $active_tab === 'settings' ? 'nav-tab nav-tab-active' : 'nav-tab'; ?>">
213 <?php esc_html_e( 'Settings', 'wpc-countdown-timer' ); ?>
214 </a>
215 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=localization' ) ); ?>"
216 class="<?php echo $active_tab === 'localization' ? 'nav-tab nav-tab-active' : 'nav-tab'; ?>">
217 <?php esc_html_e( 'Localization', 'wpc-countdown-timer' ); ?>
218 </a>
219 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=shortcode' ) ); ?>"
220 class="<?php echo $active_tab === 'shortcode' ? 'nav-tab nav-tab-active' : 'nav-tab'; ?>">
221 <?php esc_html_e( 'Shortcode [...]', 'wpc-countdown-timer' ); ?>
222 </a>
223 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=premium' ) ); ?>"
224 class="<?php echo $active_tab === 'premium' ? 'nav-tab nav-tab-active' : 'nav-tab'; ?>"
225 style="color: #c9356e">
226 <?php esc_html_e( 'Premium Version', 'wpc-countdown-timer' ); ?>
227 </a>
228 <a href="<?php echo esc_url( admin_url( 'admin.php?page=wpclever-kit' ) ); ?>"
229 class="nav-tab">
230 <?php esc_html_e( 'Essential Kit', 'wpc-countdown-timer' ); ?>
231 </a>
232 </h2>
233 </div>
234 <div class="wpclever_settings_page_content">
235 <?php if ( $active_tab === 'settings' ) {
236 $pos_archive = self::get_setting( 'position_archive', 'above_add_to_cart' );
237 $pos_single = self::get_setting( 'position_single', '29' );
238 ?>
239 <form method="post" action="options.php">
240 <table class="form-table">
241 <tr class="heading">
242 <th colspan="2">
243 <?php esc_html_e( 'General', 'wpc-countdown-timer' ); ?>
244 </th>
245 </tr>
246 <tr>
247 <th scope="row"><?php esc_html_e( 'Position on archive', 'wpc-countdown-timer' ); ?></th>
248 <td>
249 <label> <select name="wooct_settings[position_archive]">
250 <option value="under_title" <?php selected( $pos_archive, 'under_title' ); ?>><?php esc_html_e( 'Under title', 'wpc-countdown-timer' ); ?></option>
251 <option value="under_rating" <?php selected( $pos_archive, 'under_rating' ); ?>><?php esc_html_e( 'Under rating', 'wpc-countdown-timer' ); ?></option>
252 <option value="under_price" <?php selected( $pos_archive, 'under_price' ); ?>><?php esc_html_e( 'Under price', 'wpc-countdown-timer' ); ?></option>
253 <option value="above_add_to_cart" <?php selected( $pos_archive, 'above_add_to_cart' ); ?>><?php esc_html_e( 'Above add to cart', 'wpc-countdown-timer' ); ?></option>
254 <option value="under_add_to_cart" <?php selected( $pos_archive, 'under_add_to_cart' ); ?>><?php esc_html_e( 'Under add to cart', 'wpc-countdown-timer' ); ?></option>
255 <option value="0" <?php selected( $pos_archive, '0' ); ?>><?php esc_html_e( 'None (hide it)', 'wpc-countdown-timer' ); ?></option>
256 </select> </label>
257 <p class="description"><?php echo sprintf( /* translators: shortcode */ esc_html__( 'You also can use shortcode %s to show the countdown timer for current product.', 'wpc-countdown-timer' ), '<code>[wooct_product]</code>' ); ?></p>
258 </td>
259 </tr>
260 <tr>
261 <th scope="row"><?php esc_html_e( 'Position on single', 'wpc-countdown-timer' ); ?></th>
262 <td>
263 <label> <select name="wooct_settings[position_single]">
264 <option value="6" <?php selected( $pos_single, '6' ); ?>><?php esc_html_e( 'Under title', 'wpc-countdown-timer' ); ?></option>
265 <option value="11" <?php selected( $pos_single, '11' ); ?>><?php esc_html_e( 'Under price & rating', 'wpc-countdown-timer' ); ?></option>
266 <option value="21" <?php selected( $pos_single, '21' ); ?>><?php esc_html_e( 'Under excerpt', 'wpc-countdown-timer' ); ?></option>
267 <option value="29" <?php selected( $pos_single, '29' ); ?>><?php esc_html_e( 'Above add to cart', 'wpc-countdown-timer' ); ?></option>
268 <option value="31" <?php selected( $pos_single, '31' ); ?>><?php esc_html_e( 'Under add to cart', 'wpc-countdown-timer' ); ?></option>
269 <option value="41" <?php selected( $pos_single, '41' ); ?>><?php esc_html_e( 'Under meta', 'wpc-countdown-timer' ); ?></option>
270 <option value="51" <?php selected( $pos_single, '51' ); ?>><?php esc_html_e( 'Under sharing', 'wpc-countdown-timer' ); ?></option>
271 <option value="0" <?php selected( $pos_single, '0' ); ?>><?php esc_html_e( 'None (hide it)', 'wpc-countdown-timer' ); ?></option>
272 </select> </label>
273 <p class="description"><?php echo sprintf( /* translators: shortcode */ esc_html__( 'You also can use shortcode %s to show the countdown timer for current product.', 'wpc-countdown-timer' ), '<code>[wooct_product]</code>' ); ?></p>
274 </td>
275 </tr>
276 <tr>
277 <th>
278 <?php esc_html_e( 'Default above text', 'wpc-countdown-timer' ); ?>
279 </th>
280 <td>
281 <label>
282 <input type="text" name="wooct_settings[text_above]"
283 class="large-text"
284 value="<?php echo esc_attr( self::get_setting( 'text_above' ) ); ?>"/>
285 </label>
286 </td>
287 </tr>
288 <tr>
289 <th>
290 <?php esc_html_e( 'Default under text', 'wpc-countdown-timer' ); ?>
291 </th>
292 <td>
293 <label>
294 <input type="text" name="wooct_settings[text_under]"
295 class="large-text"
296 value="<?php echo esc_attr( self::get_setting( 'text_under' ) ); ?>"/>
297 </label>
298 </td>
299 </tr>
300 <tr>
301 <th>
302 <?php esc_html_e( 'Default ended text', 'wpc-countdown-timer' ); ?>
303 </th>
304 <td>
305 <label>
306 <input type="text" name="wooct_settings[text_ended]"
307 class="large-text"
308 value="<?php echo esc_attr( self::get_setting( 'text_ended' ) ); ?>"/>
309 </label>
310 </td>
311 </tr>
312 <tr class="submit">
313 <th colspan="2">
314 <div class="wpclever_submit">
315 <?php
316 settings_fields( 'wooct_settings' );
317 submit_button( '', 'primary', 'submit', false );
318
319 if ( function_exists( 'wpc_last_saved' ) ) {
320 wpc_last_saved( self::get_settings() );
321 }
322 ?>
323 </div>
324 <a style="display: none;" class="wpclever_export"
325 data-key="wooct_settings"
326 data-name="settings"
327 href="#"><?php esc_html_e( 'import / export', 'wpc-countdown-timer' ); ?></a>
328 </th>
329 </tr>
330 </table>
331 </form>
332 <?php } elseif ( $active_tab === 'localization' ) {
333 $zero_plural = self::localization( 'zero_plural', 'yes' );
334 ?>
335 <form method="post" action="options.php">
336 <table class="form-table">
337 <tr class="heading">
338 <th scope="row"><?php esc_html_e( 'General', 'wpc-countdown-timer' ); ?></th>
339 <td>
340 <?php esc_html_e( 'Leave blank to use the default text and its equivalent translation in multiple languages.', 'wpc-countdown-timer' ); ?>
341 </td>
342 </tr>
343 <tr>
344 <th scope="row"><?php esc_html_e( 'Zero is plural?', 'wpc-countdown-timer' ); ?></th>
345 <td>
346 <label> <select name="wooct_localization[zero_plural]">
347 <option value="yes" <?php selected( $zero_plural, 'yes' ); ?>><?php esc_html_e( 'Yes', 'wpc-countdown-timer' ); ?></option>
348 <option value="no" <?php selected( $zero_plural, 'no' ); ?>><?php esc_html_e( 'No', 'wpc-countdown-timer' ); ?></option>
349 </select> </label>
350 </td>
351 </tr>
352 <tr>
353 <th scope="row"><?php esc_html_e( 'Day', 'wpc-countdown-timer' ); ?></th>
354 <td>
355 <label>
356 <input type="text" name="wooct_localization[day]"
357 placeholder="<?php esc_attr_e( 'Day', 'wpc-countdown-timer' ); ?>"
358 value="<?php echo esc_attr( self::localization( 'day' ) ); ?>"/>
359 </label>
360 </td>
361 </tr>
362 <tr>
363 <th scope="row"><?php esc_html_e( 'Days', 'wpc-countdown-timer' ); ?></th>
364 <td>
365 <label>
366 <input type="text" name="wooct_localization[days]"
367 placeholder="<?php esc_attr_e( 'Days', 'wpc-countdown-timer' ); ?>"
368 value="<?php echo esc_attr( self::localization( 'days' ) ); ?>"/>
369 </label>
370 </td>
371 </tr>
372 <tr>
373 <th scope="row"><?php esc_html_e( 'Hour', 'wpc-countdown-timer' ); ?></th>
374 <td>
375 <label>
376 <input type="text" name="wooct_localization[hour]"
377 placeholder="<?php esc_attr_e( 'Hour', 'wpc-countdown-timer' ); ?>"
378 value="<?php echo esc_attr( self::localization( 'hour' ) ); ?>"/>
379 </label>
380 </td>
381 </tr>
382 <tr>
383 <th scope="row"><?php esc_html_e( 'Hours', 'wpc-countdown-timer' ); ?></th>
384 <td>
385 <label>
386 <input type="text" name="wooct_localization[hours]"
387 placeholder="<?php esc_attr_e( 'Hours', 'wpc-countdown-timer' ); ?>"
388 value="<?php echo esc_attr( self::localization( 'hours' ) ); ?>"/>
389 </label>
390 </td>
391 </tr>
392 <tr>
393 <th scope="row"><?php esc_html_e( 'Minute', 'wpc-countdown-timer' ); ?></th>
394 <td>
395 <label>
396 <input type="text" name="wooct_localization[minute]"
397 placeholder="<?php esc_attr_e( 'Minute', 'wpc-countdown-timer' ); ?>"
398 value="<?php echo esc_attr( self::localization( 'minute' ) ); ?>"/>
399 </label>
400 </td>
401 </tr>
402 <tr>
403 <th scope="row"><?php esc_html_e( 'Minutes', 'wpc-countdown-timer' ); ?></th>
404 <td>
405 <label>
406 <input type="text" name="wooct_localization[minutes]"
407 placeholder="<?php esc_attr_e( 'Minutes', 'wpc-countdown-timer' ); ?>"
408 value="<?php echo esc_attr( self::localization( 'minutes' ) ); ?>"/>
409 </label>
410 </td>
411 </tr>
412 <tr>
413 <th scope="row"><?php esc_html_e( 'Second', 'wpc-countdown-timer' ); ?></th>
414 <td>
415 <label>
416 <input type="text" name="wooct_localization[second]"
417 placeholder="<?php esc_attr_e( 'Second', 'wpc-countdown-timer' ); ?>"
418 value="<?php echo esc_attr( self::localization( 'second' ) ); ?>"/>
419 </label>
420 </td>
421 </tr>
422 <tr>
423 <th scope="row"><?php esc_html_e( 'Seconds', 'wpc-countdown-timer' ); ?></th>
424 <td>
425 <label>
426 <input type="text" name="wooct_localization[seconds]"
427 placeholder="<?php esc_attr_e( 'Seconds', 'wpc-countdown-timer' ); ?>"
428 value="<?php echo esc_attr( self::localization( 'seconds' ) ); ?>"/>
429 </label>
430 </td>
431 </tr>
432 <tr class="submit">
433 <th colspan="2">
434 <div class="wpclever_submit">
435 <?php
436 settings_fields( 'wooct_localization' );
437 submit_button( '', 'primary', 'submit', false );
438
439 if ( function_exists( 'wpc_last_saved' ) ) {
440 wpc_last_saved( get_option( 'wooct_localization', [] ) );
441 }
442 ?>
443 </div>
444 <a style="display: none;" class="wpclever_export"
445 data-key="wooct_localization"
446 data-name="settings"
447 href="#"><?php esc_html_e( 'import / export', 'wpc-countdown-timer' ); ?></a>
448 </th>
449 </tr>
450 </table>
451 </form>
452 <?php } elseif ( $active_tab === 'shortcode' ) { ?>
453 <table class="form-table wooct_shortcode_builder wooct_time_form">
454 <tr>
455 <th><?php esc_html_e( 'Preview', 'wpc-countdown-timer' ); ?></th>
456 <td>
457 <div class="wooct_preview">
458 <div class="wooct_preview_inner"></div>
459 </div>
460 </td>
461 </tr>
462 <tr>
463 <th><?php esc_html_e( 'Shortcode', 'wpc-countdown-timer' ); ?></th>
464 <td>
465 <label>
466 <textarea class="wooct_shortcode" style="width: 100%"
467 readonly><?php esc_html_e( 'Configure the below options to build shortcode and you can place it where you want.', 'wpc-countdown-timer' ); ?></textarea>
468 </label>
469 <p class="description" style="color: #c9356e">
470 * This feature only available on Premium Version. Click
471 <a href="https://wpclever.net/downloads/wpc-countdown-timer?utm_source=pro&utm_medium=wooct&utm_campaign=wporg"
472 target="_blank">here</a> to buy, just $29!
473 </p>
474 </td>
475 </tr>
476 <?php self::configure_form(); ?>
477 </table>
478 <?php } elseif ( $active_tab == 'premium' ) { ?>
479 <div class="wpclever_settings_page_content_text">
480 <p>
481 Get the Premium Version just $29!
482 <a href="https://wpclever.net/downloads/wpc-countdown-timer?utm_source=pro&utm_medium=wooct&utm_campaign=wporg"
483 target="_blank">https://wpclever.net/downloads/wpc-countdown-timer</a>
484 </p>
485 <p><strong>Extra features for Premium Version:</strong></p>
486 <ul style="margin-bottom: 0">
487 <li>- Build your custom countdown timer to place everywhere you want by using
488 shortcode builder.
489 </li>
490 <li>- Configure countdown timer on a variation basis.</li>
491 <li>- Get the lifetime update & premium support.</li>
492 </ul>
493 </div>
494 <?php } ?>
495 </div><!-- /.wpclever_settings_page_content -->
496 <div class="wpclever_settings_page_suggestion">
497 <div class="wpclever_settings_page_suggestion_label">
498 <span class="dashicons dashicons-yes-alt"></span> Suggestion
499 </div>
500 <div class="wpclever_settings_page_suggestion_content">
501 <div>
502 To display custom engaging real-time messages on any wished positions, please
503 install
504 <a href="https://wordpress.org/plugins/wpc-smart-messages/" target="_blank">WPC
505 Smart Messages</a> plugin. It's free!
506 </div>
507 <div>
508 Wanna save your precious time working on variations? Try our brand-new free plugin
509 <a href="https://wordpress.org/plugins/wpc-variation-bulk-editor/" target="_blank">WPC
510 Variation Bulk Editor</a> and
511 <a href="https://wordpress.org/plugins/wpc-variation-duplicator/" target="_blank">WPC
512 Variation Duplicator</a>.
513 </div>
514 </div>
515 </div>
516 </div>
517 <?php
518 }
519
520 function configure_form( $post_id = 0, $is_variation = false ) {
521 $active = get_post_meta( $post_id, 'wooct_active', true ) ?: 'no';
522 $style = get_post_meta( $post_id, 'wooct_style', true ) ?: apply_filters( 'wooct_default_style', '01' );
523 $color = get_post_meta( $post_id, 'wooct_color', true ) ?: '#ff6600';
524 $time = get_post_meta( $post_id, 'wooct_time', true ) ?: 'custom';
525 $time_start = get_post_meta( $post_id, 'wooct_time_start', true ) ?: '';
526 $time_end = get_post_meta( $post_id, 'wooct_time_end', true ) ?: '';
527 $text_above = get_post_meta( $post_id, 'wooct_text_above', true ) ?: '';
528 $text_under = get_post_meta( $post_id, 'wooct_text_under', true ) ?: '';
529 $text_ended = get_post_meta( $post_id, 'wooct_text_ended', true ) ?: '';
530 $default_style = apply_filters( 'wooct_default_style', '01' );
531 $styles = apply_filters( 'wooct_styles', [
532 '01' => esc_html__( 'Style 01 (flat)', 'wpc-countdown-timer' ),
533 '02' => esc_html__( 'Style 02 (square)', 'wpc-countdown-timer' ),
534 '03' => esc_html__( 'Style 03 (rounded)', 'wpc-countdown-timer' ),
535 '04' => esc_html__( 'Style 04 (light flipper)', 'wpc-countdown-timer' ),
536 '05' => esc_html__( 'Style 05 (dark flipper)', 'wpc-countdown-timer' ),
537 '06' => esc_html__( 'Style 06 (rounded)', 'wpc-countdown-timer' ),
538 '07' => esc_html__( 'Style 07 (animated)', 'wpc-countdown-timer' ),
539 ] );
540
541 if ( empty( $style ) ) {
542 $style = $default_style;
543 }
544
545 if ( $is_variation ) {
546 $name = '_v[' . $post_id . ']';
547 $tr = '<p class="form-field form-row">';
548 $_tr = '</p>';
549 $th = '<label>';
550 $_th = '</label>';
551 $td = $_td = '';
552 } else {
553 $name = '';
554 $tr = '<tr>';
555 $_tr = '</tr>';
556 $th = '<th>';
557 $_th = '</th>';
558 $td = '<td>';
559 $_td = '</td>';
560 }
561
562 if ( $is_variation ) {
563 ?>
564 <p class="form-field form-row" style="color: #c9356e">
565 * This feature only available on Premium Version. Click
566 <a href="https://wpclever.net/downloads/wpc-countdown-timer?utm_source=pro&utm_medium=wooct&utm_campaign=wporg"
567 target="_blank">here</a> to buy, just $29!
568 </p>
569 <?php
570 }
571
572 if ( $post_id ) {
573 echo $tr;
574 echo $th . esc_html__( 'Active', 'wpc-countdown-timer' ) . $_th;
575 echo $td;
576 echo '<label class="wooct-switch">';
577 echo '<input type="checkbox" name="' . esc_attr( 'wooct_active' . $name ) . '" class="wooct_active" value="yes" ' . checked( $active, 'yes', false ) . '/>';
578 echo '<span class="wooct-slider"></span>';
579 echo '</label>';
580 echo $_td;
581 echo $_tr;
582
583 echo $tr;
584 echo $th . esc_html__( 'Time', 'wpc-countdown-timer' ) . $_th;
585 echo $td;
586 echo '<select name="' . esc_attr( 'wooct_time' . $name ) . '" class="wooct_time">';
587 echo '<option value="custom" ' . selected( $time, 'custom', false ) . '>' . esc_html__( 'Custom', 'wpc-countdown-timer' ) . '</option>';
588 echo '<option value="sale" ' . selected( $time, 'sale', false ) . '>' . esc_html__( 'Sale price dates', 'wpc-countdown-timer' ) . '</option>';
589 echo '</select>';
590 echo '<span class="woocommerce-help-tip" data-tip="' . esc_attr__( 'If you choose sale price dates, please check your scheduled sale price in the General tab.', 'wpc-countdown-timer' ) . '"></span>';
591 echo $_td;
592 echo $_tr;
593 }
594
595 if ( $is_variation ) {
596 echo '<p class="form-field form-row wooct_show_if_custom">';
597 } else {
598 echo '<tr class="wooct_show_if_custom">';
599 }
600
601 echo $th . esc_html__( 'Start time', 'wpc-countdown-timer' ) . $_th;
602 echo $td;
603 echo '<input name="' . esc_attr( 'wooct_time_start' . $name ) . '" value="' . esc_attr( $time_start ) . '" class="wooct_time_start wooct_date_time wooct_date_time_input wooct_picker" type="text" readonly="readonly"/>';
604 echo $_td;
605 echo $_tr;
606
607 if ( $is_variation ) {
608 echo '<p class="form-field form-row wooct_show_if_custom">';
609 } else {
610 echo '<tr class="wooct_show_if_custom">';
611 }
612
613 echo $th . esc_html__( 'End time', 'wpc-countdown-timer' ) . $_th;
614 echo $td;
615 echo '<input name="' . esc_attr( 'wooct_time_end' . $name ) . '" value="' . esc_attr( $time_end ) . '" class="wooct_time_end wooct_date_time wooct_date_time_input wooct_picker" type="text" readonly="readonly"/>';
616 echo $_td;
617 echo $_tr;
618
619 echo $tr;
620 echo $th . esc_html__( 'Above text', 'wpc-countdown-timer' ) . $_th;
621 echo $td . '<input name="' . esc_attr( 'wooct_text_above' . $name ) . '" value="' . esc_attr( $text_above ) . '" class="wooct_text_above" type="text" style="width: 100%"/>' . $_td;
622 echo $_tr;
623
624 echo $tr;
625 echo $th . esc_html__( 'Under text', 'wpc-countdown-timer' ) . $_th;
626 echo $td . '<input name="' . esc_attr( 'wooct_text_under' . $name ) . '" value="' . esc_attr( $text_under ) . '" class="wooct_text_under" type="text" style="width: 100%"/>' . $_td;
627 echo $_tr;
628
629 echo $tr;
630 echo $th . esc_html__( 'Ended text', 'wpc-countdown-timer' ) . $_th;
631 echo $td . '<input name="' . esc_attr( 'wooct_text_ended' . $name ) . '" value="' . esc_attr( $text_ended ) . '" class="wooct_text_ended" type="text" style="width: 100%"/>' . $_td;
632 echo $_tr;
633
634 echo $tr;
635 echo $th . esc_html__( 'Style', 'wpc-countdown-timer' ) . $_th;
636 echo $td . '<select name="' . esc_attr( 'wooct_style' . $name ) . '" class="wooct_style">';
637
638 foreach ( $styles as $k => $s ) {
639 echo '<option value="' . esc_attr( $k ) . '" ' . selected( $style, $k, false ) . '>' . esc_html( $s ) . '</option>';
640 }
641
642 echo '</select>' . $_td;
643 echo $_tr;
644
645 echo $tr;
646 echo $th . esc_html__( 'Color', 'wpc-countdown-timer' ) . $_th;
647 echo $td . '<input type="text" name="' . esc_attr( 'wooct_color' . $name ) . '" class="wooct_color" value="' . esc_attr( $color ) . '"/>' . $_td;
648 echo $_tr;
649 }
650
651 function shortcode_product( $attrs ) {
652 $countdown = '';
653
654 $attrs = shortcode_atts( [
655 'id' => null
656 ], $attrs, 'wooct_product' );
657
658 if ( ! $attrs['id'] ) {
659 global $product;
660
661 if ( $product && $product->get_id() ) {
662 $attrs['id'] = $product->get_id();
663 }
664 }
665
666 if ( $attrs['id'] ) {
667 $active = apply_filters( 'wooct_active', get_post_meta( $attrs['id'], 'wooct_active', true ) ?: 'no', $attrs['id'] );
668
669 if ( $active === 'yes' ) {
670 $style = get_post_meta( $attrs['id'], 'wooct_style', true ) ?: apply_filters( 'wooct_default_style', '01' );
671 $text_above = get_post_meta( $attrs['id'], 'wooct_text_above', true ) ?: self::get_setting( 'text_above', '' );
672 $text_under = get_post_meta( $attrs['id'], 'wooct_text_under', true ) ?: self::get_setting( 'text_under', '' );
673 $text_ended = get_post_meta( $attrs['id'], 'wooct_text_ended', true ) ?: self::get_setting( 'text_ended', '' );
674 $color = get_post_meta( $attrs['id'], 'wooct_color', true ) ?: self::get_setting( 'color', '#ff6600' );
675 $time = get_post_meta( $attrs['id'], 'wooct_time', true ) ?: 'custom';
676
677 if ( $time === 'sale' ) {
678 $time_start = ( $date = get_post_meta( $attrs['id'], '_sale_price_dates_from', true ) ) ? wp_date( 'm/d/Y H:i:s', $date ) : '';
679 $time_end = ( $date = get_post_meta( $attrs['id'], '_sale_price_dates_to', true ) ) ? wp_date( 'm/d/Y H:i:s', $date ) : '';
680 } else {
681 $time_start = get_post_meta( $attrs['id'], 'wooct_time_start', true ) ?: '';
682 $time_end = get_post_meta( $attrs['id'], 'wooct_time_end', true ) ?: '';
683 }
684
685 $countdown = self::get_countdown( $style, $time_start, $time_end, $text_above, $text_under, $text_ended, $color, $attrs['id'] );
686 }
687 }
688
689 return $countdown;
690 }
691
692 function show_countdown() {
693 echo do_shortcode( '[wooct_product]' );
694 }
695
696 function ajax_preview() {
697 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'wooct-security' ) ) {
698 die( 'Permissions check failed!' );
699 }
700
701 $style = sanitize_text_field( wp_unslash( $_POST['style'] ?? '' ) );
702 $time_start = sanitize_text_field( wp_unslash( $_POST['time_start'] ?? '' ) );
703 $time_end = sanitize_text_field( wp_unslash( $_POST['time_end'] ?? '' ) );
704 $text_above = sanitize_text_field( wp_unslash( $_POST['text_above'] ?? '' ) );
705 $text_under = sanitize_text_field( wp_unslash( $_POST['text_under'] ?? '' ) );
706 $text_ended = sanitize_text_field( wp_unslash( $_POST['text_ended'] ?? '' ) );
707 $color = sanitize_hex_color( wp_unslash( $_POST['color'] ?? '' ) );
708
709 echo wp_kses_post( self::get_countdown( $style, $time_start, $time_end, $text_above, $text_under, $text_ended, $color ) );
710
711 wp_die();
712 }
713
714 function show_countdown_single() {
715 global $product;
716
717 echo '<div class="wooct-wrap-single" data-id="' . esc_attr( $product->get_id() ) . '">';
718 echo do_shortcode( '[wooct_product]' );
719 echo '</div>';
720 }
721
722 function enqueue_scripts() {
723 // moment - use WordPress core's built-in moment.js
724 wp_enqueue_script( 'moment' );
725
726 // jquery.countdown
727 if ( self::localization( 'zero_plural', 'yes' ) === 'yes' ) {
728 wp_enqueue_script( 'jquery.countdown', WOOCT_URI . 'assets/libs/jquery.countdown/jquery.countdown_zp.js', [ 'jquery' ], WOOCT_VERSION, true );
729 } else {
730 wp_enqueue_script( 'jquery.countdown', WOOCT_URI . 'assets/libs/jquery.countdown/jquery.countdown.js', [ 'jquery' ], WOOCT_VERSION, true );
731 }
732
733 // flipper
734 wp_enqueue_style( 'flipper', WOOCT_URI . 'assets/libs/flipper/style.css', [], WOOCT_VERSION );
735 wp_enqueue_script( 'flipper', WOOCT_URI . 'assets/libs/flipper/jquery.flipper-responsive.js', [ 'jquery' ], WOOCT_VERSION, true );
736
737 // frontend
738 wp_enqueue_style( 'wooct-frontend', WOOCT_URI . 'assets/css/frontend.css', [], WOOCT_VERSION );
739 wp_enqueue_script( 'wooct-frontend', WOOCT_URI . 'assets/js/frontend.js', [ 'jquery' ], WOOCT_VERSION, true );
740
741 // localization
742 $day = self::localization( 'day', esc_html__( 'Day', 'wpc-countdown-timer' ) );
743 $days = self::localization( 'days', esc_html__( 'Days', 'wpc-countdown-timer' ) );
744 $hour = self::localization( 'hour', esc_html__( 'Hour', 'wpc-countdown-timer' ) );
745 $hours = self::localization( 'hours', esc_html__( 'Hours', 'wpc-countdown-timer' ) );
746 $minute = self::localization( 'minute', esc_html__( 'Minute', 'wpc-countdown-timer' ) );
747 $minutes = self::localization( 'minutes', esc_html__( 'Minutes', 'wpc-countdown-timer' ) );
748 $second = self::localization( 'second', esc_html__( 'Second', 'wpc-countdown-timer' ) );
749 $seconds = self::localization( 'seconds', esc_html__( 'Seconds', 'wpc-countdown-timer' ) );
750
751 // format
752 $format_01 = '<span>%D %!D:' . $day . ',' . $days . ';</span> <span>%H</span>:<span>%M</span>:<span>%S</span>';
753 $format_02 = '<span><span>%D</span><span>%!D:' . $day . ',' . $days . ';</span></span><span><span>%H</span><span>%!H:' . $hour . ',' . $hours . ';</span></span><span><span>%M</span><span>%!M:' . $minute . ',' . $minutes . ';</span></span><span><span>%S</span><span>%!S:' . $second . ',' . $seconds . ';</span></span>';
754 $format_06 = '<span><span>%D</span><span>d</span></span><span><span>%H</span><span>h</span></span><span><span>%M</span><span>m</span></span><span><span>%S</span><span>s</span></span>';
755 $format_07 = '<div class="d c100"><span class="text"><span>%D</span><span>d</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="h c100"><span class="text"><span>%H</span><span>h</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="m c100"><span class="text"><span>%M</span><span>m</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="s c100"><span class="text"><span>%S</span><span>s</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div>';
756
757 wp_localize_script( 'wooct-frontend', 'wooct_vars', [
758 'timezone' => get_option( 'timezone_string' ),
759 'gmt_offset' => (float) get_option( 'gmt_offset' ),
760 // default
761 'timer_format' => apply_filters( 'wooct_timer_format', $format_01 ),
762 // flat
763 'timer_format_01' => apply_filters( 'wooct_timer_format_01', $format_01 ),
764 // square
765 'timer_format_02' => apply_filters( 'wooct_timer_format_02', $format_02 ),
766 // rounded
767 'timer_format_03' => apply_filters( 'wooct_timer_format_03', $format_02 ),
768 'timer_format_06' => apply_filters( 'wooct_timer_format_06', $format_06 ),
769 'timer_format_07' => apply_filters( 'wooct_timer_format_07', $format_07 ),
770 ]
771 );
772 }
773
774 function admin_enqueue_scripts() {
775 // wpcdpk
776 wp_enqueue_style( 'wpcdpk', WOOCT_URI . 'assets/libs/wpcdpk/css/datepicker.css', [], WOOCT_VERSION );
777 wp_enqueue_script( 'wpcdpk', WOOCT_URI . 'assets/libs/wpcdpk/js/datepicker.js', [ 'jquery' ], WOOCT_VERSION, true );
778
779 // moment - use WordPress core's built-in moment.js
780 wp_enqueue_script( 'moment' );
781
782 // jquery.countdown
783 if ( self::localization( 'zero_plural', 'yes' ) === 'yes' ) {
784 wp_enqueue_script( 'jquery.countdown', WOOCT_URI . 'assets/libs/jquery.countdown/jquery.countdown_zp.js', [ 'jquery' ], WOOCT_VERSION, true );
785 } else {
786 wp_enqueue_script( 'jquery.countdown', WOOCT_URI . 'assets/libs/jquery.countdown/jquery.countdown.js', [ 'jquery' ], WOOCT_VERSION, true );
787 }
788
789 // flipper
790 wp_enqueue_style( 'flipper', WOOCT_URI . 'assets/libs/flipper/style.css', [], WOOCT_VERSION );
791 wp_enqueue_script( 'flipper', WOOCT_URI . 'assets/libs/flipper/jquery.flipper-responsive.js', [ 'jquery' ], WOOCT_VERSION, true );
792
793 // frontend for preview
794 wp_enqueue_style( 'wooct-frontend', WOOCT_URI . 'assets/css/frontend.css', [], WOOCT_VERSION );
795 wp_enqueue_script( 'wooct-frontend', WOOCT_URI . 'assets/js/frontend.js', [ 'jquery' ], WOOCT_VERSION, true );
796
797 // localization
798 $day = self::localization( 'day', esc_html__( 'Day', 'wpc-countdown-timer' ) );
799 $days = self::localization( 'days', esc_html__( 'Days', 'wpc-countdown-timer' ) );
800 $hour = self::localization( 'hour', esc_html__( 'Hour', 'wpc-countdown-timer' ) );
801 $hours = self::localization( 'hours', esc_html__( 'Hours', 'wpc-countdown-timer' ) );
802 $minute = self::localization( 'minute', esc_html__( 'Minute', 'wpc-countdown-timer' ) );
803 $minutes = self::localization( 'minutes', esc_html__( 'Minutes', 'wpc-countdown-timer' ) );
804 $second = self::localization( 'second', esc_html__( 'Second', 'wpc-countdown-timer' ) );
805 $seconds = self::localization( 'seconds', esc_html__( 'Seconds', 'wpc-countdown-timer' ) );
806
807 // format
808 $format_01 = '<span>%D %!D:' . $day . ',' . $days . ';</span> <span>%H</span>:<span>%M</span>:<span>%S</span>';
809 $format_02 = '<span><span>%D</span><span>%!D:' . $day . ',' . $days . ';</span></span><span><span>%H</span><span>%!H:' . $hour . ',' . $hours . ';</span></span><span><span>%M</span><span>%!M:' . $minute . ',' . $minutes . ';</span></span><span><span>%S</span><span>%!S:' . $second . ',' . $seconds . ';</span></span>';
810 $format_06 = '<span><span>%D</span><span>d</span></span><span><span>%H</span><span>h</span></span><span><span>%M</span><span>m</span></span><span><span>%S</span><span>s</span></span>';
811 $format_07 = '<div class="d c100"><span class="text"><span>%D</span><span>d</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="h c100"><span class="text"><span>%H</span><span>h</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="m c100"><span class="text"><span>%M</span><span>m</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div><div class="s c100"><span class="text"><span>%S</span><span>s</span></span><div class="slice"><div class="bar"></div><div class="fill"></div></div></div>';
812
813 // backend
814 wp_enqueue_style( 'wp-color-picker' );
815 wp_enqueue_style( 'wooct-backend', WOOCT_URI . 'assets/css/backend.css', [], WOOCT_VERSION );
816 wp_enqueue_script( 'wooct-backend', WOOCT_URI . 'assets/js/backend.js', [
817 'jquery',
818 'wp-color-picker',
819 'jquery-ui-dialog',
820 ], WOOCT_VERSION, true );
821 wp_localize_script( 'wooct-backend', 'wooct_vars', [
822 'nonce' => wp_create_nonce( 'wooct-security' ),
823 'timezone' => get_option( 'timezone_string' ),
824 'gmt_offset' => (float) get_option( 'gmt_offset' ),
825 // default
826 'timer_format' => apply_filters( 'wooct_timer_format', $format_01 ),
827 // flat
828 'timer_format_01' => apply_filters( 'wooct_timer_format_01', $format_01 ),
829 // square
830 'timer_format_02' => apply_filters( 'wooct_timer_format_02', $format_02 ),
831 // rounded
832 'timer_format_03' => apply_filters( 'wooct_timer_format_03', $format_02 ),
833 'timer_format_06' => apply_filters( 'wooct_timer_format_06', $format_06 ),
834 'timer_format_07' => apply_filters( 'wooct_timer_format_07', $format_07 ),
835 ]
836 );
837 }
838
839 function action_links( $links, $file ) {
840 static $plugin;
841
842 if ( ! isset( $plugin ) ) {
843 $plugin = plugin_basename( __FILE__ );
844 }
845
846 if ( $plugin === $file ) {
847 $settings = '<a href="' . esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=settings' ) ) . '">' . esc_html__( 'Settings', 'wpc-countdown-timer' ) . '</a>';
848 $links['premium'] = '<a href="' . esc_url( admin_url( 'admin.php?page=wpclever-wooct&tab=premium' ) ) . '">' . esc_html__( 'Premium Version', 'wpc-countdown-timer' ) . '</a>';
849 array_unshift( $links, $settings );
850 }
851
852 return (array) $links;
853 }
854
855 function row_meta( $links, $file ) {
856 static $plugin;
857
858 if ( ! isset( $plugin ) ) {
859 $plugin = plugin_basename( __FILE__ );
860 }
861
862 if ( $plugin === $file ) {
863 $row_meta = [
864 'support' => '<a href="' . esc_url( WOOCT_DISCUSSION ) . '" target="_blank">' . esc_html__( 'Community support', 'wpc-countdown-timer' ) . '</a>',
865 ];
866
867 return array_merge( $links, $row_meta );
868 }
869
870 return (array) $links;
871 }
872
873 function product_data_tabs( $tabs ) {
874 $tabs['wooct'] = [
875 'label' => esc_html__( 'Countdown', 'wpc-countdown-timer' ),
876 'target' => 'wooct_settings',
877 ];
878
879 return $tabs;
880 }
881
882 function product_data_panels() {
883 global $post, $thepostid, $product_object;
884
885 if ( $product_object instanceof WC_Product ) {
886 $product_id = $product_object->get_id();
887 } elseif ( is_numeric( $thepostid ) ) {
888 $product_id = $thepostid;
889 } elseif ( $post instanceof WP_Post ) {
890 $product_id = $post->ID;
891 } else {
892 $product_id = 0;
893 }
894
895 if ( ! $product_id ) {
896 ?>
897 <div id='wooct_settings' class='panel woocommerce_options_panel wooct_panel'>
898 <p style="padding: 0 12px; color: #c9356e"><?php esc_html_e( 'Product wasn\'t returned.', 'wpc-countdown-timer' ); ?></p>
899 </div>
900 <?php
901 return;
902 }
903 ?>
904 <div id='wooct_settings' class='panel woocommerce_options_panel wooct_panel'>
905 <div class="wooct_current_time">
906 <?php esc_html_e( 'Current time', 'wpc-countdown-timer' ); ?>
907 <code><?php echo esc_html( current_time( 'm/d/Y' ) ); ?></code>
908 <code><?php echo esc_html( current_time( 'h:i a' ) ); ?></code>
909 <a href="<?php echo esc_url( admin_url( 'options-general.php' ) ); ?>"
910 target="_blank"><?php esc_html_e( 'Date/time settings', 'wpc-countdown-timer' ); ?></a>
911 </div>
912 <div class="wooct_preview">
913 <span><?php esc_html_e( 'Preview', 'wpc-countdown-timer' ); ?></span>
914 <div class="wooct_preview_inner"></div>
915 </div>
916 <div class="wooct_table">
917 <table class="wooct_time_form">
918 <?php self::configure_form( absint( $product_id ) ); ?>
919 </table>
920 </div>
921 </div>
922 <?php
923 }
924
925 function process_product_meta( $post_id ) {
926 if ( ! isset( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['woocommerce_meta_nonce'] ) ), 'woocommerce_save_data' ) ) {
927 return;
928 }
929
930 if ( isset( $_POST['wooct_active'] ) ) {
931 update_post_meta( $post_id, 'wooct_active', sanitize_text_field( wp_unslash( $_POST['wooct_active'] ?? '' ) ) );
932 } else {
933 delete_post_meta( $post_id, 'wooct_active' );
934 }
935
936 if ( isset( $_POST['wooct_time'] ) ) {
937 update_post_meta( $post_id, 'wooct_time', sanitize_text_field( wp_unslash( $_POST['wooct_time'] ?? '' ) ) );
938 } else {
939 delete_post_meta( $post_id, 'wooct_time' );
940 }
941
942 if ( isset( $_POST['wooct_time_start'] ) ) {
943 update_post_meta( $post_id, 'wooct_time_start', sanitize_text_field( wp_unslash( $_POST['wooct_time_start'] ?? '' ) ) );
944 } else {
945 delete_post_meta( $post_id, 'wooct_time_start' );
946 }
947
948 if ( isset( $_POST['wooct_time_end'] ) ) {
949 update_post_meta( $post_id, 'wooct_time_end', sanitize_text_field( wp_unslash( $_POST['wooct_time_end'] ?? '' ) ) );
950 } else {
951 delete_post_meta( $post_id, 'wooct_time_end' );
952 }
953
954 if ( isset( $_POST['wooct_text_above'] ) ) {
955 update_post_meta( $post_id, 'wooct_text_above', sanitize_text_field( wp_unslash( $_POST['wooct_text_above'] ?? '' ) ) );
956 } else {
957 delete_post_meta( $post_id, 'wooct_text_above' );
958 }
959
960 if ( isset( $_POST['wooct_text_under'] ) ) {
961 update_post_meta( $post_id, 'wooct_text_under', sanitize_text_field( wp_unslash( $_POST['wooct_text_under'] ?? '' ) ) );
962 } else {
963 delete_post_meta( $post_id, 'wooct_text_under' );
964 }
965
966 if ( isset( $_POST['wooct_text_ended'] ) ) {
967 update_post_meta( $post_id, 'wooct_text_ended', sanitize_text_field( wp_unslash( $_POST['wooct_text_ended'] ?? '' ) ) );
968 } else {
969 delete_post_meta( $post_id, 'wooct_text_ended' );
970 }
971
972 if ( isset( $_POST['wooct_style'] ) ) {
973 update_post_meta( $post_id, 'wooct_style', sanitize_text_field( wp_unslash( $_POST['wooct_style'] ?? '' ) ) );
974 } else {
975 delete_post_meta( $post_id, 'wooct_style' );
976 }
977
978 if ( isset( $_POST['wooct_color'] ) ) {
979 update_post_meta( $post_id, 'wooct_color', sanitize_text_field( wp_unslash( $_POST['wooct_color'] ?? '' ) ) );
980 } else {
981 delete_post_meta( $post_id, 'wooct_color' );
982 }
983 }
984
985 function variation_settings( $loop, $variation_data, $variation ) {
986 ?>
987 <div class="form-row form-row-full wooct-variation-settings">
988 <label><?php esc_html_e( 'WPC Countdown Timer', 'wpc-countdown-timer' ); ?></label>
989 <div class="wooct-variation-wrap wooct_time_form">
990 <?php self::configure_form( absint( $variation->ID ), true ); ?>
991 </div>
992 </div>
993 <?php
994 }
995
996 function save_variation_settings( $post_id ) {
997 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Security already verified by WooCommerce before firing this hook.
998 if ( isset( $_POST['wooct_active_v'][ $post_id ] ) ) {
999 update_post_meta( $post_id, 'wooct_active', sanitize_text_field( wp_unslash( ( $_POST['wooct_active_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1000 } else {
1001 delete_post_meta( $post_id, 'wooct_active' );
1002 }
1003
1004 if ( isset( $_POST['wooct_time_v'][ $post_id ] ) ) {
1005 update_post_meta( $post_id, 'wooct_time', sanitize_text_field( wp_unslash( ( $_POST['wooct_time_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1006 } else {
1007 delete_post_meta( $post_id, 'wooct_time' );
1008 }
1009
1010 if ( isset( $_POST['wooct_time_start_v'][ $post_id ] ) ) {
1011 update_post_meta( $post_id, 'wooct_time_start', sanitize_text_field( wp_unslash( ( $_POST['wooct_time_start_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1012 } else {
1013 delete_post_meta( $post_id, 'wooct_time_start' );
1014 }
1015
1016 if ( isset( $_POST['wooct_time_end_v'][ $post_id ] ) ) {
1017 update_post_meta( $post_id, 'wooct_time_end', sanitize_text_field( wp_unslash( ( $_POST['wooct_time_end_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1018 } else {
1019 delete_post_meta( $post_id, 'wooct_time_end' );
1020 }
1021
1022 if ( isset( $_POST['wooct_text_above_v'][ $post_id ] ) ) {
1023 update_post_meta( $post_id, 'wooct_text_above', sanitize_text_field( wp_unslash( ( $_POST['wooct_text_above_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1024 } else {
1025 delete_post_meta( $post_id, 'wooct_text_above' );
1026 }
1027
1028 if ( isset( $_POST['wooct_text_under_v'][ $post_id ] ) ) {
1029 update_post_meta( $post_id, 'wooct_text_under', sanitize_text_field( wp_unslash( ( $_POST['wooct_text_under_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1030 } else {
1031 delete_post_meta( $post_id, 'wooct_text_under' );
1032 }
1033
1034 if ( isset( $_POST['wooct_text_ended_v'][ $post_id ] ) ) {
1035 update_post_meta( $post_id, 'wooct_text_ended', sanitize_text_field( wp_unslash( ( $_POST['wooct_text_ended_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1036 } else {
1037 delete_post_meta( $post_id, 'wooct_text_ended' );
1038 }
1039
1040 if ( isset( $_POST['wooct_style_v'][ $post_id ] ) ) {
1041 update_post_meta( $post_id, 'wooct_style', sanitize_text_field( wp_unslash( ( $_POST['wooct_style_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1042 } else {
1043 delete_post_meta( $post_id, 'wooct_style' );
1044 }
1045
1046 if ( isset( $_POST['wooct_color_v'][ $post_id ] ) ) {
1047 update_post_meta( $post_id, 'wooct_color', sanitize_text_field( wp_unslash( ( $_POST['wooct_color_v'] ?? [] )[ $post_id ] ?? '' ) ) );
1048 } else {
1049 delete_post_meta( $post_id, 'wooct_color' );
1050 }
1051 }
1052
1053 function after_variations_table() {
1054 global $product;
1055
1056 echo '<div class="wooct-wrap-variation" data-id="' . esc_attr( $product->get_id() ) . '"></div>';
1057 }
1058
1059 function check_time_start( $start = '' ) {
1060 if ( ! empty( $start ) ) {
1061 if ( ! is_numeric( $start ) ) {
1062 $start = strtotime( $start );
1063 }
1064
1065 if ( current_time( 'timestamp' ) < $start ) {
1066 return false;
1067 }
1068 }
1069
1070 return true;
1071 }
1072
1073 function check_time_end( $end ) {
1074 if ( ! empty( $end ) ) {
1075 if ( ! is_numeric( $end ) ) {
1076 $end = strtotime( $end );
1077 }
1078
1079 if ( current_time( 'timestamp' ) < $end ) {
1080 return true;
1081 }
1082 }
1083
1084 return false;
1085 }
1086
1087 function post_class( $classes, $product ) {
1088 if ( $product->is_type( 'variation' ) && $product->get_parent_id() ) {
1089 $product_id = $product->get_parent_id();
1090 } else {
1091 $product_id = $product->get_id();
1092 }
1093
1094 $active = get_post_meta( $product_id, 'wooct_active', true ) ?: 'no';
1095 $time = get_post_meta( $product_id, 'wooct_time', true ) ?: '';
1096
1097 if ( $time === 'sale' ) {
1098 $time_start = ( $date = get_post_meta( $product_id, '_sale_price_dates_from', true ) ) ? wp_date( 'm/d/Y H:i:s', $date ) : '';
1099 $time_end = ( $date = get_post_meta( $product_id, '_sale_price_dates_to', true ) ) ? wp_date( 'm/d/Y H:i:s', $date ) : '';
1100 } else {
1101 $time_start = get_post_meta( $product_id, 'wooct_time_start', true ) ?: '';
1102 $time_end = get_post_meta( $product_id, 'wooct_time_end', true ) ?: '';
1103 }
1104
1105 if ( $active === 'yes' ) {
1106 $classes[] = 'wooct-active';
1107 }
1108
1109 if ( ! self::check_time_end( $time_end ) ) {
1110 $classes[] = 'wooct-ended';
1111 } elseif ( self::check_time_start( $time_start ) ) {
1112 $classes[] = 'wooct-running';
1113 }
1114
1115 return $classes;
1116 }
1117
1118 function get_countdown( $style, $time_start, $time_end, $text_above, $text_under, $text_ended, $color = '', $product_id = 0 ) {
1119 $countdown = '';
1120 $css = '';
1121 $style = apply_filters( 'wooct_style', $style, $product_id );
1122 $color = apply_filters( 'wooct_color', $color, $product_id );
1123 $time_start = apply_filters( 'wooct_time_start', $time_start, $product_id );
1124 $time_end = apply_filters( 'wooct_time_end', $time_end, $product_id );
1125 $text_above = apply_filters( 'wooct_text_above', $text_above, $product_id );
1126 $text_under = apply_filters( 'wooct_text_under', $text_under, $product_id );
1127 $text_ended = apply_filters( 'wooct_text_ended', $text_ended, $product_id );
1128
1129 if ( ! $product_id ) {
1130 $key = uniqid();
1131 } else {
1132 $key = $product_id;
1133 }
1134
1135 if ( is_numeric( $time_start ) ) {
1136 $time_start = wp_date( 'm/d/Y H:i:s', $time_start );
1137 }
1138
1139 if ( is_numeric( $time_end ) ) {
1140 $time_end = wp_date( 'm/d/Y H:i:s', $time_end );
1141 }
1142
1143 if ( ! empty( $time_end ) && self::check_time_start( $time_start ) ) {
1144 if ( ! empty( $color ) ) {
1145 switch ( $style ) {
1146 case '07':
1147 $css = '.wooct-countdown.wooct-style-07.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer .c100 .bar, .wooct-countdown.wooct-style-07.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer .c100 .fill { border-color: ' . esc_attr( $color ) . '} .wooct-countdown.wooct-style-07.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer .c100 > span.text > span:first-child { color: ' . esc_attr( $color ) . '; }';
1148
1149 break;
1150 case '06':
1151 $css = '.wooct-countdown.wooct-style-06.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span { border-top-color: ' . esc_attr( $color ) . '; border-bottom-color: ' . esc_attr( $color ) . '; border-left-color: ' . esc_attr( $color ) . '; } .wooct-countdown.wooct-style-06.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span span:first-child { color: ' . esc_attr( $color ) . '; }';
1152
1153 break;
1154 case '03':
1155 $css = '.wooct-countdown.wooct-style-03.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span { border-color: ' . esc_attr( $color ) . '; } .wooct-countdown.wooct-style-03.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span span:first-child { color: ' . esc_attr( $color ) . '; }';
1156
1157 break;
1158 case '02':
1159 $css = '.wooct-countdown.wooct-style-02.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span { border-color: ' . esc_attr( $color ) . '; } .wooct-countdown.wooct-style-02.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer > span span:first-child { color: ' . esc_attr( $color ) . '; }';
1160
1161 break;
1162 case '01':
1163 $css = '.wooct-countdown.wooct-style-01.wooct-countdown-' . esc_attr( $key ) . ' .wooct-timer { color: ' . esc_attr( $color ) . '; }';
1164
1165 break;
1166 }
1167 }
1168
1169 if ( ! self::check_time_end( $time_end ) ) {
1170 if ( ! empty( $text_ended ) ) {
1171 $class = 'wooct-countdown wooct-countdown-' . esc_attr( $key ) . ' wooct-ended wooct-style-' . esc_attr( $style );
1172 $countdown .= '<div class="' . esc_attr( apply_filters( 'wooct_class_ended', $class ) ) . '">';
1173 $countdown .= '<div class="wooct-text-ended">' . wp_kses_post( $text_ended ) . '</div>';
1174
1175 if ( ! empty( $css ) ) {
1176 $countdown .= '<div class="wooct-css"><style>' . $css . '</style></div>';
1177 }
1178
1179 $countdown .= '</div>';
1180 }
1181 } else {
1182 $class = 'wooct-countdown wooct-countdown-' . esc_attr( $key ) . ' wooct-running wooct-style-' . esc_attr( $style ) . ' ' . ( $style === '04' || $style === '05' ? 'wooct-flipper' : '' );
1183 $countdown .= '<div class="' . esc_attr( apply_filters( 'wooct_class', $class ) ) . '" data-css="' . esc_attr( $css ) . '" data-style="' . esc_attr( $style ) . '" data-timer="' . esc_attr( $time_end ) . '" data-ended="' . esc_attr( $text_ended ) . '">';
1184
1185 if ( ! empty( $text_above ) ) {
1186 $countdown .= '<div class="wooct-text-above">' . wp_kses_post( $text_above ) . '</div>';
1187 }
1188
1189 if ( $style === '04' || $style === '05' ) {
1190 // flipper
1191 $days = self::localization( 'days', esc_html__( 'Days', 'wpc-countdown-timer' ) );
1192 $hours = self::localization( 'hours', esc_html__( 'Hours', 'wpc-countdown-timer' ) );
1193 $minutes = self::localization( 'minutes', esc_html__( 'Minutes', 'wpc-countdown-timer' ) );
1194 $seconds = self::localization( 'seconds', esc_html__( 'Seconds', 'wpc-countdown-timer' ) );
1195 $template = apply_filters( 'wooct_flipper_template', 'dd|HH|ii|ss' );
1196 $labels = apply_filters( 'wooct_flipper_labels', $days . '|' . $hours . '|' . $minutes . '|' . $seconds );
1197 $countdown .= '<div class="wooct-timer flipper ' . ( $style === '05' ? 'flipper-dark' : '' ) . '" data-reverse="true" data-datetime="' . esc_attr( $time_end ) . '" data-template="' . esc_attr( $template ) . '" data-labels="' . esc_attr( $labels ) . '"></div>';
1198 } else {
1199 $countdown .= '<div class="wooct-timer">' . $time_end . '</div>';
1200 }
1201
1202 if ( ! empty( $text_under ) ) {
1203 $countdown .= '<div class="wooct-text-under">' . wp_kses_post( $text_under ) . '</div>';
1204 }
1205
1206 if ( ! empty( $css ) ) {
1207 $countdown .= '<div class="wooct-css"><style>' . $css . '</style></div>';
1208 }
1209
1210 $countdown .= '</div>';
1211 }
1212 }
1213
1214 return apply_filters( 'wooct_countdown', $countdown, $style, $time_start, $time_end, $text_above, $text_under, $text_ended, $color, $product_id );
1215 }
1216
1217 function product_columns( $columns ) {
1218 $columns['wooct'] = esc_html__( 'Countdown', 'wpc-countdown-timer' );
1219
1220 return $columns;
1221 }
1222
1223 function product_custom_column( $column, $postid ) {
1224 if ( $column === 'wooct' ) {
1225 $active = get_post_meta( $postid, 'wooct_active', true ) ?: 'no';
1226 $time_start = get_post_meta( $postid, 'wooct_time_start', true ) ?: '';
1227 $time_end = get_post_meta( $postid, 'wooct_time_end', true ) ?: '';
1228
1229 if ( ( $active === 'yes' ) && ! empty( $time_end ) ) {
1230 if ( self::check_time_start( $time_start ) && self::check_time_end( $time_end ) ) {
1231 echo '<span class="wooct-icon running"><span class="dashicons dashicons-clock"></span></span>';
1232 } else {
1233 echo '<span class="wooct-icon"><span class="dashicons dashicons-clock"></span></span>';
1234 }
1235 }
1236 }
1237 }
1238
1239 function duplicate_variation( $old_variation_id, $new_variation_id ) {
1240 if ( $active = get_post_meta( $old_variation_id, 'wooct_active', true ) ) {
1241 update_post_meta( $new_variation_id, 'wooct_active', $active );
1242 }
1243
1244 if ( $time = get_post_meta( $old_variation_id, 'wooct_time', true ) ) {
1245 update_post_meta( $new_variation_id, 'wooct_time', $time );
1246 }
1247
1248 if ( $time_start = get_post_meta( $old_variation_id, 'wooct_time_start', true ) ) {
1249 update_post_meta( $new_variation_id, 'wooct_time_start', $time_start );
1250 }
1251
1252 if ( $time_end = get_post_meta( $old_variation_id, 'wooct_time_end', true ) ) {
1253 update_post_meta( $new_variation_id, 'wooct_time_end', $time_end );
1254 }
1255
1256 if ( $text_above = get_post_meta( $old_variation_id, 'wooct_text_above', true ) ) {
1257 update_post_meta( $new_variation_id, 'wooct_text_above', $text_above );
1258 }
1259
1260 if ( $text_under = get_post_meta( $old_variation_id, 'wooct_text_under', true ) ) {
1261 update_post_meta( $new_variation_id, 'wooct_text_under', $text_under );
1262 }
1263
1264 if ( $text_ended = get_post_meta( $old_variation_id, 'wooct_text_ended', true ) ) {
1265 update_post_meta( $new_variation_id, 'wooct_text_ended', $text_ended );
1266 }
1267
1268 if ( $style = get_post_meta( $old_variation_id, 'wooct_style', true ) ) {
1269 update_post_meta( $new_variation_id, 'wooct_style', $style );
1270 }
1271
1272 if ( $style = get_post_meta( $old_variation_id, 'wooct_color', true ) ) {
1273 update_post_meta( $new_variation_id, 'wooct_color', $style );
1274 }
1275 }
1276
1277 function bulk_update_variation( $variation_id, $fields ) {
1278 if ( ! empty( $fields['wooct_active_v'] ) && ( $fields['wooct_active_v'] !== 'wpcvb_no_change' ) ) {
1279 update_post_meta( $variation_id, 'wooct_active', sanitize_text_field( $fields['wooct_active_v'] ) );
1280 }
1281
1282 if ( ! empty( $fields['wooct_time_v'] ) && ( $fields['wooct_time_v'] !== 'wpcvb_no_change' ) ) {
1283 update_post_meta( $variation_id, 'wooct_time', sanitize_text_field( $fields['wooct_time_v'] ) );
1284 }
1285
1286 if ( ! empty( $fields['wooct_time_start_v'] ) ) {
1287 update_post_meta( $variation_id, 'wooct_time_start', sanitize_text_field( $fields['wooct_time_start_v'] ) );
1288 }
1289
1290 if ( ! empty( $fields['wooct_time_end_v'] ) ) {
1291 update_post_meta( $variation_id, 'wooct_time_end', sanitize_text_field( $fields['wooct_time_end_v'] ) );
1292 }
1293
1294 if ( ! empty( $fields['wooct_text_above_v'] ) ) {
1295 update_post_meta( $variation_id, 'wooct_text_above', sanitize_text_field( $fields['wooct_text_above_v'] ) );
1296 }
1297
1298 if ( ! empty( $fields['wooct_text_under_v'] ) ) {
1299 update_post_meta( $variation_id, 'wooct_text_under', sanitize_text_field( $fields['wooct_text_under_v'] ) );
1300 }
1301
1302 if ( ! empty( $fields['wooct_text_ended_v'] ) ) {
1303 update_post_meta( $variation_id, 'wooct_text_ended', sanitize_text_field( $fields['wooct_text_ended_v'] ) );
1304 }
1305
1306 if ( ! empty( $fields['wooct_style_v'] ) && ( $fields['wooct_style_v'] !== 'wpcvb_no_change' ) ) {
1307 update_post_meta( $variation_id, 'wooct_style', sanitize_text_field( $fields['wooct_style_v'] ) );
1308 }
1309
1310 if ( ! empty( $fields['wooct_color_v'] ) && ( $fields['wooct_color_v'] !== 'wpcvb_no_change' ) ) {
1311 update_post_meta( $variation_id, 'wooct_color', sanitize_text_field( $fields['wooct_color_v'] ) );
1312 }
1313 }
1314
1315 function sanitize_array( $arr ) {
1316 foreach ( (array) $arr as $k => $v ) {
1317 if ( is_array( $v ) ) {
1318 $arr[ $k ] = self::sanitize_array( $v );
1319 } else {
1320 $arr[ $k ] = sanitize_post_field( 'post_content', $v, 0, 'db' );
1321 }
1322 }
1323
1324 return $arr;
1325 }
1326
1327 public static function get_settings() {
1328 return apply_filters( 'wooct_get_settings', self::$settings );
1329 }
1330
1331 public static function get_setting( $name, $default = false ) {
1332 if ( ! empty( self::$settings ) && isset( self::$settings[ $name ] ) ) {
1333 $setting = self::$settings[ $name ];
1334 } else {
1335 $setting = get_option( 'wooct_' . $name, $default );
1336 }
1337
1338 return apply_filters( 'wooct_get_setting', $setting, $name, $default );
1339 }
1340
1341 public static function localization( $key = '', $default = '' ) {
1342 if ( ! empty( $key ) && ! empty( self::$localization[ $key ] ) ) {
1343 $str = self::$localization[ $key ];
1344 } else {
1345 $str = get_option( 'wooct_localization_' . $key );
1346
1347 if ( empty( $str ) ) {
1348 $str = $default;
1349 }
1350 }
1351
1352 return apply_filters( 'wooct_localization_' . $key, $str );
1353 }
1354 }
1355
1356 return WPCleverWooct::instance();
1357 }
1358
1359 return null;
1360 }
1361 }
1362
1363 if ( ! function_exists( 'wooct_notice_wc' ) ) {
1364 function wooct_notice_wc() {
1365 ?>
1366 <div class="error">
1367 <p><strong>WPC Countdown Timer</strong> require WooCommerce version 3.0 or greater.</p>
1368 </div>
1369 <?php
1370 }
1371 }
1372