PluginProbe
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce / 2.3.4
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce v2.3.4
2.15.0 trunk 1.0.0 1.0.1 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.2 2.1.3 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 All 62 releases
hurrytimer / includes / Frontend.php

Frontend.php in HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce 2.3.4, at includes/Frontend.php

321 lines 9.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Hurrytimer;
4
5 /**
6 * The public-facing functionality of the plugin.
7 *
8 * @link http://nabillemsieh.com
9 * @since 1.0.0
10 *
11 * @package Hurrytimer
12 * @subpackage Hurrytimer/public
13 */
14 class Frontend
15 {
16 /**
17 * The ID of this plugin.
18 *
19 * @since 1.0.0
20 * @access private
21 * @var string $plugin_name The ID of this plugin.
22 */
23 private $plugin_name;
24
25 /**
26 * The version of this plugin.
27 *
28 * @since 1.0.0
29 * @access private
30 * @var string $version The current version of this plugin.
31 */
32 private $version;
33
34 /**
35 * Initialize the class and set its properties.
36 *
37 * @param string $plugin_name The name of the plugin.
38 * @param string $version The version of this plugin.
39 *
40 * @since 1.0.0
41 *
42 */
43 public function __construct( $plugin_name, $version )
44 {
45 $this->plugin_name = $plugin_name;
46 $this->version = $version;
47 }
48
49 function init()
50 {
51
52 // Enqueue CSS and JS.
53 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_styles' ] );
54 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
55
56 // Display campaign in sticky bar.
57 add_action( 'wp_footer', [ $this, 'render_sticky_bar' ] );
58 add_action( 'wp_footer', [ $this, 'run_in_background' ] );
59
60 // Display campaign on product page.
61 add_action( 'wp', [ $this, 'render_on_product_page' ] );
62
63 // Change stock status for recurring/onetime campaign via Ajax.
64 add_action( 'wp_ajax_change_stock_status', [ $this, 'ajax_change_stock_status' ] );
65 add_action( 'wp_ajax_nopriv_change_stock_status', [ $this, 'ajax_change_stock_status' ] );
66
67 // Log evergreen campaign start time for each visitor.
68 add_action( 'wp_ajax_hurryt/update_timestamp', [ $this, 'ajax_save_evergreen_start_time' ] );
69 add_action( 'wp_ajax_nopriv_hurryt/update_timestamp', [ $this, 'ajax_save_evergreen_start_time' ] );
70
71 // Return next recurrence.
72 add_action( 'wp_ajax_next_recurrence', [ $this, 'ajax_next_recurrence' ] );
73 add_action( 'wp_ajax_nopriv_next_recurrence', [ $this, 'ajax_next_recurrence' ] );
74
75 // Check before rendering campaign.
76 add_action( 'hurryt_pre_render', [ $this, 'pre_render_shortcode' ] );
77
78 // Check actions for expired recurring and onetime campaigns
79 // This only concerns shortcodes inserted in post editor.
80 // Fallback to shortcode callback
81 add_action( 'wp', [ $this, 'check_post_shortcode' ] );
82
83 }
84
85 function run_in_background()
86 {
87
88 // At this time, all campagins with the "Expire coupon" action
89 // should run in background.
90 $campaigns = get_posts( [
91 'post_type' => HURRYT_POST_TYPE,
92 'numberposts' => -1,
93 'post_status' => 'publish'
94 ] );
95
96 foreach ( $campaigns as $campaign ) {
97 $campaign = new Campaign( $campaign->ID );
98
99 $campaign->loadSettings();
100 $action = $campaign->get_action( C::ACTION_EXPIRE_COUPON );
101
102 if ( !empty( $action ) ) {
103 echo do_shortcode( '[hurrytimer id=' . $campaign->get_id() . ' run_in_background=true]' );
104 }
105
106 }
107 }
108
109 /**
110 * Check if there is shortcode in the current post.
111 */
112 function check_post_shortcode()
113 {
114 global $post;
115 if ( is_singular() && is_a( $post, 'WP_Post' )
116 && has_shortcode( $post->post_content, 'hurrytimer' ) && !( defined( 'DOING_AJAX' ) && DOING_AJAX )
117 ) {
118 $campaigns_ids = hurryt_parse_campaigns( $post->post_content );
119 foreach ( $campaigns_ids as $id ) {
120 do_action( 'hurryt_pre_render', hurryt_get_campaign( $id ) );
121 }
122 }
123 }
124
125 /**
126 * @param $campaign Campaign
127 */
128 function pre_render_shortcode( $campaign )
129 {
130 if ( $campaign->is_running() && $campaign->is_expired() ) {
131 ( new ActionManager( $campaign ) )->run();
132 }
133 }
134
135
136 public function ajax_next_recurrence()
137 {
138 check_ajax_referer( 'hurryt', 'nonce' );
139 $campaign_id = absint( $_GET[ 'id' ] );
140 if ( !get_post( $campaign_id )
141 || get_post_type( $campaign_id ) !== HURRYT_POST_TYPE
142 ) {
143 die( -1 );
144 }
145
146 $campaign = new Campaign( $campaign_id );
147 $endDate = $campaign->get_current_recurrence_end_date();
148 wp_send_json_success( [
149 'endTimestamp' => $endDate ? $endDate->getBrowserTimestamp() : null,
150 ] );
151 }
152
153 /**
154 * Uses ajax to save start time for the given visitor.
155 * This used to bypass cookie cache.
156 */
157 public function ajax_save_evergreen_start_time()
158 {
159 check_ajax_referer( 'hurryt', 'nonce' );
160 if ( !isset( $_POST[ 'timestamp' ] ) || !isset( $_POST[ 'cid' ] ) ) {
161 wp_die();
162 }
163
164 $evergreen_campaign = new EvergreenCampaign( intval( $_POST[ 'cid' ] ) );
165 $evergreen_campaign->setEndDate( filter_input( INPUT_POST, 'timestamp' ) );
166 wp_die( 'Success!' );
167 }
168
169 public function render_sticky_bar()
170 {
171 $campaigns = get_posts( [
172 'post_type' => HURRYT_POST_TYPE,
173 'numberposts' => -1,
174 'post_status' => 'publish',
175 'meta_key' => 'enable_sticky',
176 'meta_value' => C::YES,
177 'suppress_filters' => false,
178 ] );
179 foreach ( $campaigns as $post ) {
180 echo do_shortcode( sprintf( '[hurrytimer id="%d" sticky="true" ]', $post->ID ) );
181 }
182
183 }
184
185 /**
186 * Apply change stock status
187 */
188 public function ajax_change_stock_status()
189 {
190 check_ajax_referer( 'hurryt', 'nonce' );
191 if ( !isset( $_POST[ 'campaign_id' ], $_POST[ 'status' ] ) ) {
192 die( -1 );
193 }
194 $id = intval( $_POST[ 'campaign_id' ] );
195 $status = sanitize_key( $_POST[ 'status' ] );
196 $wc_campaign = new WCCampaign();
197 $campaign = new Campaign( $id );
198 $wc_campaign->change_stock_status( $campaign, $status );
199 die();
200 }
201
202 /**
203 * Maybe display campaign on current product page.
204 */
205 public function render_on_product_page()
206 {
207 global $post;
208 if ( hurryt_is_woocommerce_activated() && is_product() ) {
209 $wc_campaign = new WCCampaign();
210 $wc_campaign->run( $post->ID );
211 }
212
213 }
214
215 /**
216 * Register the stylesheets for the public-facing side of the site.
217 *
218 * @since 1.0.0
219 */
220 public function enqueue_styles()
221 {
222 // Using hashed filename for cache busting.
223 wp_enqueue_style( $this->plugin_name, CSS_Builder::get_instance()->get_build_url() );
224 }
225
226 /**
227 * Register the JavaScript for the public-facing side of the site.
228 *
229 * @since 1.0.0
230 */
231 public function enqueue_scripts()
232 {
233
234 wp_enqueue_script( 'jquery' );
235
236 wp_enqueue_script(
237 'hurryt-cookie',
238 HURRYT_URL . 'assets/js/cookie.min.js',
239 [],
240 '3.14.1',
241 true
242 );
243 wp_enqueue_script(
244 'hurryt-countdown',
245 HURRYT_URL . 'assets/js/jquery.countdown.min.js',
246 [ 'jquery' ],
247 '2.2.0',
248 true
249 );
250 wp_enqueue_script(
251 $this->plugin_name,
252 HURRYT_URL . 'assets/js/hurrytimer.js',
253 [ 'jquery', 'hurryt-countdown', 'hurryt-cookie' ],
254 defined( 'WP_DEBUG' ) && WP_DEBUG ? time() : $this->version,
255 true
256 );
257
258
259 // TODO: Refactor
260 $disable_actions = hurryt_is_admin_area() && hurryt_settings()[ 'disable_actions' ];
261 $disable_actions = filter_var( apply_filters( 'hurryt_disable_actions', $disable_actions ),
262 FILTER_VALIDATE_BOOLEAN );
263
264 wp_localize_script( $this->plugin_name, 'hurrytimer_ajax_object', [
265 'ajax_url' => admin_url( 'admin-ajax.php' ),
266 'ajax_nonce' => wp_create_nonce( 'hurryt' ),
267 'disable_actions' => $disable_actions,
268 'methods'=> [
269 'COOKIE'=> C::DETECTION_METHOD_COOKIE,
270 'IP'=> C::DETECTION_METHOD_IP,
271 'USER_SESSION'=> C::DETECTION_METHOD_USER_SESSION
272 ],
273 'actionsOptions' => [
274 'none' => C::ACTION_NONE,
275 'hide' => C::ACTION_HIDE,
276 'redirect' => C::ACTION_REDIRECT,
277 'stockStatus' => C::ACTION_CHANGE_STOCK_STATUS,
278 'hideAddToCartButton' => C::ACTION_HIDE_ADD_TO_CART_BUTTON,
279 'displayMessage' => C::ACTION_DISPLAY_MESSAGE,
280 'expire_coupon' => C::ACTION_EXPIRE_COUPON,
281 ],
282 'restartOptions' => [
283 'none' => C::RESTART_NONE,
284 'immediately' => C::RESTART_IMMEDIATELY,
285 'afterReload' => C::RESTART_AFTER_RELOAD,
286 ],
287 'COOKIEPATH' => defined( 'COOKIEPATH' ) ? COOKIEPATH : '',
288 'COOKIE_DOMAIN' => defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '',
289 'redirect_no_back' => apply_filters( 'hurryt_redirect_no_back', true ),
290 'expire_coupon_message' => $this->get_coupon_expired_message()
291 ] );
292 }
293
294
295 /**
296 * Get WooCommerce coupon expired message.
297 *
298 *
299 * TODO: move to /integration/woocommerce
300 *
301 * @return string
302 * @since 2.3
303 */
304 function get_coupon_expired_message()
305 {
306
307 if ( !hurryt_is_woocommerce_activated() ) {
308 return '';
309 }
310
311 try {
312 return ( new \WC_Coupon() )->get_coupon_error( \WC_Coupon::E_WC_COUPON_EXPIRED );
313
314 } catch ( \Exception $e ) {
315 return '';
316 }
317
318 }
319
320 }
321