PluginProbe
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce / 2.1.6
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce v2.1.6
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 / Campaign.php

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

1,065 lines 21.3 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 use \Hurrytimer\Utils\Helpers;
6
7 class Campaign
8 {
9
10 /**
11 * Campaign custom post ID
12 *
13 * @var int
14 */
15 private $id;
16
17 /**
18 * Campaign mode.
19 *
20 * @see C.php
21 *
22 * @var int
23 */
24 public $mode = C::MODE_REGULAR;
25
26 /**
27 * Evergreen duration array.
28 *
29 * @see getDuration()
30 *
31 * @var array
32 */
33 public $duration;
34
35 /**
36 * Restart option after expiration.
37 *
38 * @see \Hurrytimer\CampaignRestart
39 *
40 * @var int
41 */
42 public $restart;
43
44 /**
45 * Headline text.
46 *
47 * @var string
48 */
49 public $headline = "Hurry Up!";
50
51 /**
52 * Headline color.
53 *
54 * @var string
55 */
56 public $headlineColor = "#000";
57
58 /**
59 * Headline size.
60 *
61 * @var int
62 */
63 public $headlineSize = 30;
64
65 /**
66 * Headline position.
67 *
68 * @var int
69 */
70 public $headlinePosition = C::HEADLINE_POSITION_ABOVE_TIMER;
71
72 /**
73 * Headline visibility.
74 *
75 * @var boolean
76 */
77 public $headlineVisibility = C::YES;
78
79 public $headlineSpacing = 5;
80
81 /**
82 * Control labels visibility.
83 *
84 * @var string
85 */
86 public $labelVisibility = C::YES;
87
88 /**
89 * Show/hide days block.
90 *
91 * @var string
92 */
93 public $daysVisibility = C::YES;
94
95 /**
96 * Show/hide hours block.
97 *
98 * @var string
99 */
100 public $hoursVisibility = C::YES;
101
102 /**
103 * Show/hide minutes block.
104 *
105 * @var string
106 */
107 public $minutesVisibility = C::YES;
108
109 /**
110 * Show/hide seconds block.
111 *
112 * @var string
113 */
114 public $secondsVisibility = C::YES;
115
116 /**
117 * Regular compaign end datetime.
118 *
119 * @var string
120 */
121 public $endDatetime;
122
123 /**
124 * Labels texts.
125 *
126 * @var array
127 */
128 public $labels
129 = [
130 'days' => 'days',
131 'hours' => 'hrs',
132 'minutes' => 'mins',
133 'seconds' => 'secs',
134 ];
135
136 /**
137 * Digit color.
138 *
139 * @var string
140 */
141 public $digitColor = "#000";
142
143 /**
144 * Digit size.
145 *
146 * @var int
147 */
148 public $digitSize = 35;
149
150 /**
151 * Redirect action url.
152 *
153 * @var string
154 */
155 public $redirectUrl;
156
157 /**
158 * Label size.
159 *
160 * @var int
161 */
162 public $labelSize = 12;
163
164 /**
165 * Label color.
166 *
167 * @var string
168 */
169 public $labelColor = "#000";
170
171 /**
172 * End action.
173 *
174 * @var array
175 */
176 public $actions = [];
177
178 /**
179 * WooCommerce compaign position in product page.
180 *
181 * @var int
182 */
183 public $wcPosition = C::WC_POSITION_ABOVE_TITLE;
184
185 /**
186 * Enable/disable woocommerce integration.
187 *
188 * @var string
189 */
190 public $wcEnable = C::NO;
191
192 /**
193 * WooCommerce products selection.
194 *
195 * @var array
196 */
197 public $wcProductsSelection;
198
199 /**
200 * WooCommerce products selection type.
201 *
202 * @var int
203 */
204 public $wcProductsSelectionType;
205
206 /**
207 * Timer block border color.
208 *
209 * @var string
210 */
211 public $blockBorderColor = "";
212
213 /**
214 * Timer Block border width.
215 *
216 * @var int
217 */
218
219 public $blockBorderWidth = 0;
220
221 /**
222 * Timer block radius.
223 *
224 * @var int
225 */
226 public $blockBorderRadius = 0;
227
228 /**
229 * Block size.
230 *
231 * @var int
232 */
233
234 public $blockSize = 50;
235
236 /**
237 * Block background color.
238 *
239 * @var string
240 */
241 public $blockBgColor = '';
242
243 /**
244 * Block spacing.
245 *
246 * @var int
247 */
248 public $blockSpacing = 5;
249
250 /**
251 * Block padding.
252 *
253 * @var int
254 */
255 public $blockPadding = 0;
256
257 /**
258 * Block spearator visibility.
259 *
260 * @var boolean
261 */
262 public $blockSeparatorVisibility = C::YES;
263
264 /**
265 * Label case
266 *
267 * @var string
268 */
269 public $labelCase = C::TRANSFORM_UPPERCASE;
270
271 /**
272 * Custom CSS
273 *
274 * @var string
275 */
276 public $customCss = '';
277
278 /**
279 * Block elements display
280 * Values: block, inline
281 *
282 * @var string
283 */
284 public $blockDisplay = 'block';
285
286 /**
287 * Enable sticky bar.
288 */
289 public $enableSticky = C::NO;
290
291 /**
292 * Sticky bar background color.
293 *
294 * @var string
295 */
296 public $stickyBarBgColor = '#eee';
297
298 /**
299 * Sticky bar close button color.
300 *
301 * @var string
302 */
303 public $stickyBarCloseBtnColor = '#fff';
304
305 /**
306 * Sticky bar position.
307 * Values: top, bottom
308 *
309 * @var string
310 */
311 public $stickyBarPosition = 'top';
312
313 /**
314 * Sticky bar padding.
315 *
316 * @var integer
317 */
318 public $stickyBarPadding = 5;
319
320 /**
321 * Sticky bar display pages.
322 *
323 * @var array
324 */
325 public $stickyBarPages = [];
326
327 /**
328 * Where to display the sticky bar option
329 *
330 * @var string
331 */
332 public $stickyBarDisplayOn = 'all_pages';
333
334 /**
335 * Show sticky bar close button?
336 *
337 * @var string
338 */
339 public $stickyBarDismissible = C::YES;
340
341 /**
342 * CTA settings.
343 *
344 * @var array
345 */
346 public $callToAction
347 = [
348 'enabled' => C::NO,
349 'new_tab' => C::NO,
350 'url' => '',
351 'text' => 'Learn More',
352 'text_size' => 15,
353 'text_color' => '#fff',
354 'bg_color' => '#000',
355 'y_padding' => 10,
356 'x_padding' => 15,
357 'border_radius' => 3,
358 'spacing' => 5,
359 ];
360
361 /**
362 * Campaign elements display
363 * values: block,inline
364 *
365 * @var string
366 */
367 public $campaignDisplay = 'block';
368
369 /**
370 * Campaign aligments
371 * values: center,left,right
372 *
373 * @var string
374 */
375 public $campaignAlign = 'center';
376
377 /**
378 * Campaign spacing.
379 *
380 * @var integer
381 */
382 public $campaignSpacing = 10;
383
384 /**
385 * Campaign horizontal padding.
386 *
387 * @var integer
388 */
389 public $campaignXPadding = 10;
390
391 /**
392 * Campaign vertical padding.
393 *
394 * @var integer
395 */
396 public $campaignYPadding = 10;
397
398 public function __construct($id)
399 {
400
401 $this->id = $id;
402 }
403
404 /**
405 * Returns compaign post iD.
406 *
407 * @return int
408 */
409 public function getId()
410 {
411 return $this->id;
412 }
413
414 public function showStickyBarOn($pageId)
415 {
416
417
418 if ($this->enableSticky === C::NO) {
419 return true;
420 }
421
422 switch ($this->getStickyBarDisplayOn()) {
423 case 'all_pages':
424 return true;
425 case 'wc_products_pages':
426
427 if (function_exists('is_product') && is_product()) {
428 $wc_campaign = new WCCampaign();
429 return ($wc_campaign->hasActiveCampaign($this, $pageId));
430 }
431 return false;
432
433 case 'specific_pages':
434 $pages = $this->getStickyBarPages();
435 foreach ($pages as $page) {
436 if ($page == $pageId) {
437 return true;
438 }
439 }
440 }
441
442 return true;
443
444 }
445
446 public function getStickyBarPages()
447 {
448 return $this->getRawSetting('sticky_bar_pages');
449 }
450
451 public function getStickyBarDisplayOn()
452 {
453
454 // backward compat.
455 $all_pages = $this->getRawSetting('sticky_bar_show_on_all_pages', false);
456
457 if ($all_pages === C::YES) {
458 $this->setStickyBarDisplayOn('all_pages');
459 }
460
461 $this->deleteRawSetting('sticky_bar_show_on_all_pages');
462
463 $value = $this->getRawSetting('_hurryt_sticky_bar_display_on', false);
464 return !empty($value) ?: $this->stickyBarDisplayOn;
465 }
466
467 public function setStickyBarDisplayOn($value)
468 {
469 $this->storeRawSetting('_hurryt_sticky_bar_display_on', $value);
470 }
471
472 /**
473 * Get raw setting.
474 *
475 * @param string $name
476 * @param boolean
477 *
478 * @return mixed
479 */
480 public function getRawSetting($name, $useDefault = true)
481 {
482 $value = get_post_meta($this->id, $name, true);
483 if (!empty($value)) {
484 return $value;
485 }
486 if ($useDefault) {
487 return $this->{Helpers::snakeToCamelCase($name)};
488 }
489
490 return $value;
491 }
492
493 public function storeRawSetting($name, $value)
494 {
495 $value = !empty($value) ? $value : $this->{Helpers::snakeToCamelCase($name)};
496 update_post_meta($this->id, $name, $value);
497 }
498
499 /**
500 * Bulk save for compaign settings.
501 *
502 * @param $data
503 */
504 public function storeSettings($data)
505 {
506
507 foreach ($data as $prop => $value) {
508 $method = Helpers::snakeToCamelCase("set_{$prop}");
509 if (method_exists($this, $method)) {
510 $this->$method($value ?: $this->$prop);
511 } elseif (property_exists(__CLASS__, Helpers::snakeToCamelCase($prop))) {
512 $this->storeRawSetting($prop, $value);
513 }
514 }
515
516 self::buildCss();
517 }
518
519 /**
520 * Build User CSS,
521 * Then merge it with base one.
522 *
523 * @return void
524 */
525 public static function buildCss()
526 {
527
528 // Build and return CSS
529 ob_start();
530 include HURRYT_DIR . 'includes/css.php';
531 $css = ob_get_clean();
532 $base = file_get_contents(HURRYT_DIR . '/assets/css/base.css');
533
534 // Merge built and base css.
535 $base .= $css;
536
537 // Save to public file.
538 file_put_contents(HURRYT_DIR . '/assets/css/hurrytimer.css', $base);
539 }
540
541 /**
542 * Load settings from database,
543 * and set object props according their matched name.
544 */
545 public function loadSettings()
546 {
547
548 $reflection = new \ReflectionObject($this);
549 foreach ($reflection->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
550 $name = $prop->getName();
551 $method = 'get' . ucfirst($name);
552 if (method_exists($this, $method)) {
553 $this->{$name} = $this->$method();
554 } else {
555 $this->{$name} = $this->getRawSetting(Helpers::camelToSnakeCase($name));
556 }
557 }
558 }
559
560 /**
561 * Returns compaign headline.
562 *
563 * @return mixed
564 */
565 public function getHeadline()
566 {
567 return $this->id ? get_the_title($this->id) : $this->headline;
568 }
569
570 public function isPublished()
571 {
572 return get_post_status($this->id) === "publish";
573 }
574
575 public function isWcEnabled()
576 {
577 return $this->getWcEnable() === C::YES;
578 }
579
580 /**
581 * Check current countdown timer mode
582 *
583 * @return bool
584 */
585 public function isEvergreen()
586 {
587 return $this->getRawSetting('mode') == C::MODE_EVERGREEN;
588 }
589
590 public function isRegular()
591 {
592 return $this->getRawSetting('mode') == C::MODE_REGULAR;
593 }
594
595 /**
596 * Save compaign endtime for regular mode.
597 *
598 * @param $date
599 */
600 public function setEndDatetime($date)
601 {
602 $this->storeRawSetting('end_datetime', $date ?: $this->defaultEndDatetime());
603 }
604
605 /**
606 * Returns default end datetime for regular mode.
607 *
608 * @return false|string
609 */
610 private function defaultEndDatetime()
611 {
612 return date('Y-m-d h:i A', strtotime('+1 week'));
613 }
614
615 /**
616 * Save digit color.
617 *
618 * @param $color
619 */
620 public function setDigitColor($color)
621 {
622 $this->storeRawSetting('digit_color', $color);
623 }
624
625 /**
626 * Returns headline visibility.
627 *
628 * @return mixed
629 */
630
631 public function getHeadlineVisibility()
632 {
633 $meta = 'headline_visibility';
634
635 $value = $this->getRawSetting($meta, false);
636 if ($value === C::NO || $value === C::YES) {
637 return $value;
638 }
639
640 $legacyMeta = 'display_headline';
641 $legacyValue = filter_var($this->getLegacySetting($legacyMeta), FILTER_VALIDATE_BOOLEAN);
642 $legacyValue = $legacyValue ? C::YES : C::NO;
643
644 $this->storeRawSetting($meta, $legacyValue);
645
646 $this->deleteRawSetting($legacyMeta);
647
648 return $this->getRawSetting($meta);
649 }
650
651 /**
652 * Returns digit color.
653 * Backward compat with older versions.
654 *
655 * @return mixed
656 */
657 public function getDigitColor()
658 {
659 $value = $this->getRawSetting('digit_color', false);
660 if ($value) {
661 return $value;
662 }
663
664 $legacy = $this->getLegacySetting('text_color');
665 if (!$legacy) {
666 return $this->digitColor;
667 }
668
669 $this->setDigitColor($legacy);
670 if (!$this->getRawSetting('label_color', false)) {
671 $this->setLabelColor($legacy);
672 }
673
674 $this->deleteRawSetting('text_color');
675
676 return $this->getRawSetting('digit_color');
677 }
678
679 public function setLabelColor($color)
680 {
681 $this->storeRawSetting('label_color', $color);
682 }
683
684 /**
685 * Get label color
686 *
687 * @return mixed
688 */
689 public function getLabelColor()
690 {
691 $value = $this->getRawSetting('label_color', false);
692 if ($value) {
693 return $value;
694 }
695
696 $legacy = $this->getLegacySetting('text_color');
697 if (!$legacy) {
698 return $this->labelColor;
699 }
700
701 $this->setLabelColor($legacy);
702 if (!$this->getRawSetting('digit_color', false)) {
703 $this->setDigitColor($legacy);
704 }
705
706 $this->deleteRawSetting('text_color');
707
708 return $this->getRawSetting('label_color');
709
710 }
711
712 /**
713 *
714 * Return timer digit size.
715 * Backward comapt. with older versions.
716 *
717 * @return int
718 * @since 1.2.4
719 */
720 public function getDigitSize()
721 {
722 $meta = 'digit_size';
723 $value = $this->getRawSetting($meta, false);
724 if (!empty($value)) {
725 return $value;
726 }
727 $legacy = $this->getLegacySetting('text_size');
728
729 if (empty($legacy)) {
730 return $this->digitSize;
731 }
732
733 $this->setDigitSize($legacy);
734
735 $this->deleteRawSetting('text_size');
736
737 return $this->getRawSetting('digit_size');
738 }
739
740 /**
741 * Save timer digit size.
742 *
743 * @param $size
744 */
745 public function setDigitSize($size)
746 {
747 $this->storeRawSetting('digit_size', $size);
748 }
749
750 /**
751 * Save timer label size.
752 *
753 * @param $size
754 */
755 public function setLabelSize($size)
756 {
757 $this->storeRawSetting('label_size', $size);
758 }
759
760 public function setHeadlineSize($size)
761 {
762 $this->storeRawSetting('headline_size', $size);
763 }
764
765 /**
766 * Returns evergreen duration.
767 *
768 * @return array
769 */
770 public function getDuration()
771 {
772 $default = [0, 0, 0, 0];
773 $duration = $this->getRawSetting('duration');
774 if (is_array($duration)) {
775 $duration = array_merge($duration, $default);
776
777 return array_map('intval', $duration);
778 }
779
780 return $default;
781 }
782
783 /**
784 * Returns actions array.
785 *
786 * @return array
787 */
788 public function getActions()
789 {
790 $legacy = $this->getLegacySetting('end_action');
791 if ($legacy) {
792 $redirectUrl = $this->getLegacySetting('redirect_url');
793 $actions = [
794 [
795 'id' => intval($legacy),
796 'redirectUrl' => $redirectUrl,
797 ],
798 ];
799 $this->storeRawSetting('actions', $actions);
800 $this->deleteRawSetting('end_action');
801 $this->deleteRawSetting('redirect_url');
802
803 return $this->mergeActions($actions);
804 }
805
806 return $this->mergeActions($this->getRawSetting('actions'));
807 }
808
809 private function mergeActions($actions)
810 {
811 $defaults = [
812 [
813 'id' => C::ACTION_NONE,
814 'redirectUrl' => '',
815 'message' => '',
816 'wcStockStatus' => '',
817 ],
818 ];
819
820 if (count($actions) === 0) {
821 return $defaults;
822 }
823
824 return array_map(function ($action) use ($defaults) {
825 $action['id'] = (int) $action['id'];
826
827 return array_merge($defaults[0], $action);
828 }, $actions);
829 }
830
831 /**
832 * Returns evergreen duration in seconds.
833 *
834 * @return int
835 */
836 public function getDurationInSeconds()
837 {
838 list($d, $h, $m, $s) = $this->getDuration();
839
840 return $d * DAY_IN_SECONDS +
841 $h * HOUR_IN_SECONDS +
842 $m * MINUTE_IN_SECONDS +
843 $s;
844 }
845
846 /**
847 * Returns end datetime.
848 *
849 * @return string
850 */
851 public function getEndDatetime()
852 {
853 return $this->getRawSetting('end_datetime') ?: $this->defaultEndDatetime();
854 }
855
856 /**
857 * Returns compaign publish datetime.
858 *
859 * @return mixed
860 */
861 public function getStartTimestamp()
862 {
863 return get_the_date($this->id);
864 }
865
866 /**
867 * Returns position in WooCommerce product page.
868 *
869 * @return mixed
870 */
871 public function getWcPosition()
872 {
873 $legacy = $this->getLegacySetting('position');
874
875 if (!$legacy) {
876 return $this->getRawSetting('wc_position');
877 }
878 $this->storeRawSetting('wc_position', $legacy);
879 $this->deleteRawSetting('position');
880
881 return $legacy;
882 }
883
884 private function getLegacySetting($name)
885 {
886 return get_post_meta($this->id, $name, true);
887 }
888
889 /**
890 * Returns true if WooCommerce integration is enabled.
891 *
892 * @return mixed
893 */
894 public function getWcEnable()
895 {
896 $value = $this->getRawSetting('wc_enable', false);
897
898 if ($value === C::YES || $value === C::NO) {
899 return $value;
900 }
901
902 $legacy = filter_var($value, FILTER_VALIDATE_BOOLEAN);
903 if ($legacy) {
904 $this->storeRawSetting('wc_enable', C::YES);
905 } else {
906 $this->storeRawSetting('wc_enable', C::NO);
907 }
908
909 return $this->getRawSetting('wc_enable');
910 }
911
912 /**
913 * Returns true if label should be displayed.
914 *
915 * @return mixed
916 */
917 public function getLabelVisibility()
918 {
919 $meta = 'label_visibility';
920 $value = $this->getRawSetting($meta, false);
921 if ($value === C::NO || $value === C::YES) {
922 return $value;
923 }
924
925 $legacy = filter_var($this->getLegacySetting('display_labels'), FILTER_VALIDATE_BOOLEAN);
926 $legacy = $legacy ? C::YES : C::NO;
927 $this->storeRawSetting($meta, $legacy);
928 $this->deleteRawSetting('display_labels');
929
930 return $this->getRawSetting($meta);
931
932 }
933
934 /**
935 *
936 * Returns restart type.
937 *
938 * @return int
939 */
940 public function getRestart()
941 {
942 return $this->getRawSetting('restart') ?: C::RESTART_NONE;
943 }
944
945 /**
946 * Returns WooCommerce products selection type.
947 *
948 * @return string
949 */
950 public function getWcProductsSelectionType()
951 {
952 $legacy = $this->getLegacySetting('products_type');
953 if (!$legacy) {
954 return $this->getRawSetting('wc_products_selection_type');
955 }
956 $this->storeRawSetting('wc_products_selection_type', $legacy);
957 $this->deleteRawSetting('products_type');
958
959 return $legacy;
960 }
961
962 /**
963 * Delete setting item.
964 *
965 * @param $name
966 */
967 public function deleteRawSetting($name)
968 {
969 delete_post_meta($this->id, $name);
970 }
971
972 /**
973 * Returns products selection IDs.
974 *
975 * @return array
976 */
977 public function getWcProductsSelection()
978 {
979 $legacy = $this->getLegacySetting('products');
980 if (!$legacy) {
981 return $this->getRawSetting('wc_products_selection');
982 }
983 $this->storeRawSetting('wc_products_selection', $legacy);
984 $this->deleteRawSetting('products');
985
986 return $legacy;
987 }
988
989 /**
990 * Store custom labels.
991 *
992 * @param $labels
993 */
994 public function setLabels($labels)
995 {
996 $labels = array_merge($this->labels, array_filter($labels));
997 update_post_meta($this->id, 'labels', $labels);
998 }
999
1000 /**
1001 * Returns true if compaign can be published.
1002 *
1003 * @return bool
1004 */
1005 public function isActive()
1006 {
1007 return get_post_status($this->id) === "publish" || get_post_status($this->id) === "future";
1008
1009 }
1010
1011 /**
1012 * Returns trus if the compaign is scheduled.
1013 *
1014 * @return bool
1015 */
1016 public function isScheduled()
1017 {
1018 return get_post_status($this->getId()) === "future";
1019 }
1020
1021 /**
1022 * Returns true if fixed campaign datetime is expired.
1023 *
1024 * @return bool
1025 */
1026 public function isExpired()
1027 {
1028 $endDate = date_create($this->endDatetime)->format("Y-m-d H:i");
1029 $today = date_create(current_time("mysql"))->format("Y-m-d H:i");
1030
1031 return $endDate < $today;
1032 }
1033
1034 public function isDismissed()
1035 {
1036 return isset($_COOKIE[CookieDetection::COOKIE_PREFIX . $this->getId() . '_dismissed'])
1037 && $this->stickyBarDismissible === C::YES
1038 && $this->enableSticky === C::YES;
1039 }
1040
1041 /**
1042 * Returns compaign template wrapper.
1043 *
1044 * @param string
1045 *
1046 * @return string
1047 */
1048 public function wrapTemplate($content)
1049 {
1050 $campaignBuilder = new CampaignBuilder($this);
1051
1052 return $campaignBuilder->build($content);
1053 }
1054
1055 /*
1056 * Returns campaign template content.
1057 */
1058 public function buildTemplate()
1059 {
1060 $campaignBuilder = new CampaignBuilder($this);
1061
1062 return $campaignBuilder->template();
1063 }
1064 }
1065