PluginProbe
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce / 2.2.16
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce v2.2.16
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.2.16, at includes/Campaign.php

1,363 lines 29.7 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 Carbon\Carbon;
6 use Carbon\CarbonPeriod;
7 use Hurrytimer\Utils\Helpers;
8
9 class Campaign
10 {
11
12 /**
13 * Campaign custom post ID
14 *
15 * @var int
16 */
17 private $id;
18
19 /**
20 * Campaign mode.
21 *
22 * @see C.php
23 *
24 * @var int
25 */
26 public $mode = C::MODE_REGULAR;
27
28 /**
29 * Evergreen duration array.
30 *
31 * @see getDuration()
32 *
33 * @var array
34 */
35 public $duration;
36
37 /**
38 * Recurrence duration
39 *
40 * @var int
41 */
42 public $recurringDuration;
43
44 /**
45 * Recurrence start date/time
46 *
47 * @var string
48 */
49 public $recurringStartTime;
50
51 /**
52 * Recurrence end option
53 *
54 * @var int
55 */
56 public $recurringEnd = C::RECURRING_END_NEVER;
57
58 /**
59 * Recurrence frequency
60 *
61 * @see C
62 * @var string
63 */
64 public $recurringFrequency = C::RECURRING_DAILY;
65
66 /**
67 * Recurrence interval
68 *
69 * @var int
70 */
71 public $recurringInterval = 1;
72
73 /**
74 * Recurrence count
75 *
76 * @var int
77 */
78 public $recurringCount = 2;
79
80 /**
81 * Recurrence end date/time
82 *
83 * @var
84 */
85 public $recurringUntil;
86
87 /**
88 * Recurrence allowed days
89 *
90 * @var array
91 */
92 public $recurringDays = [ 0, 1, 2, 3, 4, 5, 6 ];
93
94 /**
95 * Recurrence timezone
96 *
97 * @todo Not used
98 * @var mixed|string|void
99 */
100 public $recurringTimezone;
101
102 /**
103 * Restart option after expiration.
104 *
105 * @see \Hurrytimer\CampaignRestart
106 *
107 * @var int
108 */
109 public $restart;
110
111 /**
112 * Headline text.
113 *
114 * @var string
115 */
116 public $headline = "Hurry Up!";
117
118 /**
119 * Headline color.
120 *
121 * @var string
122 */
123 public $headlineColor = "#000";
124
125 /**
126 * Headline size.
127 *
128 * @var int
129 */
130 public $headlineSize = 30;
131
132 /**
133 * Headline position.
134 *
135 * @var int
136 */
137 public $headlinePosition = C::HEADLINE_POSITION_ABOVE_TIMER;
138
139 /**
140 * Headline visibility.
141 *
142 * @var boolean
143 */
144 public $headlineVisibility = C::YES;
145
146 public $headlineSpacing = 5;
147
148 /**
149 * Control labels visibility.
150 *
151 * @var string
152 */
153 public $labelVisibility = C::YES;
154
155 /**
156 * Show/hide days block.
157 *
158 * @var string
159 */
160 public $daysVisibility = C::YES;
161
162 /**
163 * Show/hide hours block.
164 *
165 * @var string
166 */
167 public $hoursVisibility = C::YES;
168
169 /**
170 * Show/hide minutes block.
171 *
172 * @var string
173 */
174 public $minutesVisibility = C::YES;
175
176 /**
177 * Show/hide seconds block.
178 *
179 * @var string
180 */
181 public $secondsVisibility = C::YES;
182
183 /**
184 * Regular compaign end datetime.
185 *
186 * @var string
187 */
188 public $endDatetime;
189
190 /**
191 * Labels texts.
192 *
193 * @var array
194 */
195 public $labels
196 = [
197 'days' => 'days',
198 'hours' => 'hrs',
199 'minutes' => 'mins',
200 'seconds' => 'secs',
201 ];
202
203 /**
204 * Digit color.
205 *
206 * @var string
207 */
208 public $digitColor = "#000";
209
210 /**
211 * Digit size.
212 *
213 * @var int
214 */
215 public $digitSize = 35;
216
217 /**
218 * Redirect action url.
219 *
220 * @var string
221 */
222 public $redirectUrl;
223
224 /**
225 * Label size.
226 *
227 * @var int
228 */
229 public $labelSize = 12;
230
231 /**
232 * Label color.
233 *
234 * @var string
235 */
236 public $labelColor = "#000";
237
238 /**
239 * End action.
240 *
241 * @var array
242 */
243 public $actions = [];
244
245 /**
246 * WooCommerce compaign position in product page.
247 *
248 * @var int
249 */
250 public $wcPosition = C::WC_POSITION_ABOVE_TITLE;
251
252 /**
253 * Enable/disable woocommerce integration.
254 *
255 * @var string
256 */
257 public $wcEnable = C::NO;
258
259 /**
260 * WooCommerce products selection.
261 *
262 * @var array
263 */
264 public $wcProductsSelection;
265
266 /**
267 * WooCommerce products selection type.
268 *
269 * @var int
270 */
271 public $wcProductsSelectionType;
272
273 public $wcConditions;
274
275 /**
276 * Timer block border color.
277 *
278 * @var string
279 */
280 public $blockBorderColor = "";
281
282 /**
283 * Timer Block border width.
284 *
285 * @var int
286 */
287
288 public $blockBorderWidth = 0;
289
290 /**
291 * Timer block radius.
292 *
293 * @var int
294 */
295 public $blockBorderRadius = 0;
296
297 /**
298 * Block size.
299 *
300 * @var int
301 */
302
303 public $blockSize = 50;
304
305 /**
306 * Block background color.
307 *
308 * @var string
309 */
310 public $blockBgColor = '';
311
312 /**
313 * Block spacing.
314 *
315 * @var int
316 */
317 public $blockSpacing = 5;
318
319 /**
320 * Block padding.
321 *
322 * @var int
323 */
324 public $blockPadding = 0;
325
326 /**
327 * Block spearator visibility.
328 *
329 * @var boolean
330 */
331 public $blockSeparatorVisibility = C::YES;
332
333 /**
334 * Label case
335 *
336 * @var string
337 */
338 public $labelCase = C::TRANSFORM_UPPERCASE;
339
340 /**
341 * Custom CSS
342 *
343 * @var string
344 */
345 public $customCss = '';
346
347 /**
348 * Block elements display
349 * Values: block, inline
350 *
351 * @var string
352 */
353 public $blockDisplay = 'block';
354
355 /**
356 * Enable sticky bar.
357 */
358 public $enableSticky = C::NO;
359
360 /**
361 * Sticky bar background color.
362 *
363 * @var string
364 */
365 public $stickyBarBgColor = '#eee';
366
367 /**
368 * Sticky bar close button color.
369 *
370 * @var string
371 */
372 public $stickyBarCloseBtnColor = '#fff';
373
374 /**
375 * Sticky bar position.
376 * Values: top, bottom
377 *
378 * @var string
379 */
380 public $stickyBarPosition = 'top';
381
382 /**
383 * Sticky bar padding.
384 *
385 * @var integer
386 */
387 public $stickyBarPadding = 5;
388
389 /**
390 * Sticky bar display pages.
391 *
392 * @var array
393 */
394 public $stickyBarPages = [];
395
396 /**
397 * Where to display the sticky bar option
398 *
399 * @var string
400 */
401 public $stickyBarDisplayOn = 'all_pages';
402
403 /**
404 * Show sticky bar close button?
405 *
406 * @var string
407 */
408 public $stickyBarDismissible = C::YES;
409
410 /**
411 * CTA settings.
412 *
413 * @var array
414 */
415 public $callToAction
416 = [
417 'enabled' => C::NO,
418 'new_tab' => C::NO,
419 'url' => '',
420 'text' => 'Learn More',
421 'text_size' => 15,
422 'text_color' => '#fff',
423 'bg_color' => '#000',
424 'y_padding' => 10,
425 'x_padding' => 15,
426 'border_radius' => 3,
427 'spacing' => 5,
428 ];
429
430 /**
431 * Campaign elements display
432 * values: block,inline
433 *
434 * @var string
435 */
436 public $campaignDisplay = 'block';
437
438 /**
439 * Campaign aligments
440 * values: center,left,right
441 *
442 * @var string
443 */
444 public $campaignAlign = 'center';
445
446 /**
447 * Campaign spacing.
448 *
449 * @var integer
450 */
451 public $campaignSpacing = 10;
452
453 /**
454 * Campaign horizontal padding.
455 *
456 * @var integer
457 */
458 public $campaignXPadding = 10;
459
460 /**
461 * Campaign vertical padding.
462 *
463 * @var integer
464 */
465 public $campaignYPadding = 10;
466
467 public function __construct( $id )
468 {
469 // Default recurring timezone.
470 $this->recurringTimezone = Utils\Helpers::getSiteTimezone();
471 $this->recurringStartTime = Carbon::now( hurryt_tz() )->format( 'Y-m-d h:i A' );
472 $this->id = $id;
473 }
474
475 /**
476 * Returns compaign post iD.
477 *
478 * @return int
479 */
480 public function getId()
481 {
482 return $this->id;
483 }
484
485 public function showStickyBarOn( $pageId )
486 {
487 if ( $this->enableSticky === C::NO ) {
488 return true;
489 }
490
491 $can_show = false;
492 switch ( $this->getStickyBarDisplayOn() ) {
493 case 'all_pages':
494 $can_show = true;
495 break;
496 case 'wc_products_pages':
497 if ( function_exists( 'is_product' ) && is_product() ) {
498 $wc_campaign = new WCCampaign();
499 $can_show = ( $wc_campaign->hasActiveCampaign( $this, $pageId ) );
500 } else {
501 $can_show = false;
502 }
503 break;
504 case 'specific_pages':
505 $pages = $this->getStickyBarPages();
506 $can_show = in_array( $pageId, $pages );
507 break;
508 }
509
510 return apply_filters( 'hurryt_show_sticky_bar', $can_show, $this->getId() );
511
512 }
513
514 public function getStickyBarPages()
515 {
516 $pagesIds = $this->getRawSetting( 'sticky_bar_pages' );
517
518 return array_filter( array_map( 'intval', $pagesIds ) );
519 }
520
521 public function setStickyBarPages( $value )
522 {
523 $this->storeRawSetting( 'sticky_bar_pages', $value );
524 }
525
526 public function getStickyBarDisplayOn()
527 {
528
529 // backward compat.
530 $all_pages = $this->getRawSetting( 'sticky_bar_show_on_all_pages', false );
531
532 if ( $all_pages === C::YES ) {
533 $this->setStickyBarDisplayOn( 'all_pages' );
534 }
535
536 $this->deleteRawSetting( 'sticky_bar_show_on_all_pages' );
537
538 $value = $this->getRawSetting( '_hurryt_sticky_bar_display_on', false );
539
540 return ! empty( $value ) ? $value : $this->stickyBarDisplayOn;
541 }
542
543 public function setStickyBarDisplayOn( $value )
544 {
545 $this->storeRawSetting( '_hurryt_sticky_bar_display_on', $value );
546 }
547
548 /**
549 * Get raw setting.
550 *
551 * @param string $name
552 * @param boolean
553 *
554 * @return mixed
555 */
556 public function getRawSetting( $name, $useDefault = true )
557 {
558 $value = get_post_meta( $this->id, $name, true );
559 if ( ! empty( $value ) ) {
560 return $value;
561 }
562 if ( $useDefault ) {
563 return $this->{Helpers::snakeToCamelCase( $name )};
564 }
565
566 return $value;
567 }
568
569 public function storeRawSetting( $name, $value )
570 {
571 $value = ! empty( $value ) ? $value : '';
572 $getterMethod = Helpers::snakeToCamelCase( $name );
573 if ( empty( $value ) && method_exists( $this, $getterMethod ) ) {
574 $value = $this->{$getterMethod}();
575 }
576
577 update_post_meta( $this->id, $name, $value );
578 }
579
580 /**
581 * Bulk save for compaign settings.
582 *
583 * @param $data
584 */
585 public function storeSettings( $data )
586 {
587 foreach ( $data as $prop => $value ) {
588 $method = Helpers::snakeToCamelCase( "set_{$prop}" );
589 if ( method_exists( $this, $method ) ) {
590 $this->$method( $value ?: $this->$prop );
591 } elseif ( property_exists( __CLASS__, Helpers::snakeToCamelCase( $prop ) ) ) {
592 $this->storeRawSetting( $prop, $value );
593 }
594 }
595 if ( ! isset( $data[ 'wc_conditions' ] ) ) {
596 $this->setWcConditions( [] );
597 }
598 if ( ! isset( $data[ 'sticky_bar_pages' ] ) ) {
599 $this->setStickyBarPages( [] );
600 }
601 self::buildCss();
602 }
603
604 //removeIf(pro)
605 /**
606 * @param int $mode
607 */
608 public function setMode($mode)
609 {
610 if($mode == C::MODE_RECURRING){
611 return;
612 }
613 $this->storeRawSetting('mode',$mode);
614 }
615 //endRemoveIf(pro)
616 /**
617 * Build User CSS,
618 * Then merge it with base one.
619 *
620 * @return void
621 */
622 public static function buildCss()
623 {
624
625 // Build and return CSS
626 ob_start();
627 include HURRYT_DIR . 'includes/css.php';
628 $css = ob_get_clean();
629 $base = file_get_contents( HURRYT_DIR . '/assets/css/base.css' );
630
631 // Merge built and base css.
632 $base .= $css;
633
634 // Save to public file.
635 file_put_contents( HURRYT_DIR . '/assets/css/hurrytimer.css', $base );
636 }
637
638 private function setRecurringDates( $dates )
639 {
640 foreach ( $dates as $d ) {
641 add_post_meta( $this->getId(), '_hurryt_recurring_dates', $d );
642 }
643 }
644
645 public function loadSettings()
646 {
647
648 $reflection = new \ReflectionObject( $this );
649 foreach ( $reflection->getProperties( \ReflectionProperty::IS_PUBLIC ) as $prop ) {
650 $name = $prop->getName();
651 $method = 'get' . ucfirst( $name );
652 if ( method_exists( $this, $method ) ) {
653 $this->{$name} = $this->$method();
654 } else {
655 $this->{$name} = $this->getRawSetting( Helpers::camelToSnakeCase( $name ) );
656 }
657 }
658 }
659
660 /**
661 * Returns compaign headline.
662 *
663 * @return mixed
664 */
665 public function getHeadline()
666 {
667 return $this->id ? get_the_title( $this->id ) : $this->headline;
668 }
669
670 public function isPublished()
671 {
672 return get_post_status( $this->id ) === "publish";
673 }
674
675 public function isWcEnabled()
676 {
677 return $this->getWcEnable() === C::YES;
678 }
679
680 /**
681 * Check current countdown timer mode
682 *
683 * @return bool
684 */
685 public function isEvergreen()
686 {
687 return $this->getRawSetting( 'mode' ) == C::MODE_EVERGREEN;
688 }
689
690 public function isRegular()
691 {
692 return $this->getRawSetting( 'mode' ) == C::MODE_REGULAR;
693 }
694
695 public function isRecurring()
696 {
697 return $this->getRawSetting( 'mode' ) == C::MODE_RECURRING;
698
699 }
700
701 /**
702 * Save compaign endtime for regular mode.
703 *
704 * @param $date
705 */
706 public function setEndDatetime( $date )
707 {
708 $this->storeRawSetting( 'end_datetime', $date ?: $this->defaultEndDatetime() );
709 }
710
711 /**
712 * Returns default end datetime for regular mode.
713 *
714 * @return false|string
715 */
716 private function defaultEndDatetime()
717 {
718 return date( 'Y-m-d h:i A', strtotime( '+1 week' ) );
719 }
720
721 /**
722 * Save digit color.
723 *
724 * @param $color
725 */
726 public function setDigitColor( $color )
727 {
728 $this->storeRawSetting( 'digit_color', $color );
729 }
730
731 /**
732 * Returns headline visibility.
733 *
734 * @return mixed
735 */
736
737 public function getHeadlineVisibility()
738 {
739 $meta = 'headline_visibility';
740
741 $value = $this->getRawSetting( $meta, false );
742 if ( $value === C::NO || $value === C::YES ) {
743 return $value;
744 }
745
746 $legacyMeta = 'display_headline';
747 $legacyValue = filter_var( $this->getLegacySetting( $legacyMeta ),
748 FILTER_VALIDATE_BOOLEAN );
749 $legacyValue = $legacyValue ? C::YES : C::NO;
750
751 $this->storeRawSetting( $meta, $legacyValue );
752
753 $this->deleteRawSetting( $legacyMeta );
754
755 return $this->getRawSetting( $meta );
756 }
757
758 /**
759 * Returns digit color.
760 * Backward compat with older versions.
761 *
762 * @return mixed
763 */
764 public function getDigitColor()
765 {
766 $value = $this->getRawSetting( 'digit_color', false );
767 if ( $value ) {
768 return $value;
769 }
770
771 $legacy = $this->getLegacySetting( 'text_color' );
772 if ( ! $legacy ) {
773 return $this->digitColor;
774 }
775
776 $this->setDigitColor( $legacy );
777 if ( ! $this->getRawSetting( 'label_color', false ) ) {
778 $this->setLabelColor( $legacy );
779 }
780
781 $this->deleteRawSetting( 'text_color' );
782
783 return $this->getRawSetting( 'digit_color' );
784 }
785
786 public function setLabelColor( $color )
787 {
788 $this->storeRawSetting( 'label_color', $color );
789 }
790
791 /**
792 * Get label color
793 *
794 * @return mixed
795 */
796 public function getLabelColor()
797 {
798 $value = $this->getRawSetting( 'label_color', false );
799 if ( $value ) {
800 return $value;
801 }
802
803 $legacy = $this->getLegacySetting( 'text_color' );
804 if ( ! $legacy ) {
805 return $this->labelColor;
806 }
807
808 $this->setLabelColor( $legacy );
809 if ( ! $this->getRawSetting( 'digit_color', false ) ) {
810 $this->setDigitColor( $legacy );
811 }
812
813 $this->deleteRawSetting( 'text_color' );
814
815 return $this->getRawSetting( 'label_color' );
816
817 }
818
819 /**
820 *
821 * Return timer digit size.
822 * Backward comapt. with older versions.
823 *
824 * @return int
825 * @since 1.2.4
826 */
827 public function getDigitSize()
828 {
829 $meta = 'digit_size';
830 $value = $this->getRawSetting( $meta, false );
831 if ( ! empty( $value ) ) {
832 return $value;
833 }
834 $legacy = $this->getLegacySetting( 'text_size' );
835
836 if ( empty( $legacy ) ) {
837 return $this->digitSize;
838 }
839
840 $this->setDigitSize( $legacy );
841
842 $this->deleteRawSetting( 'text_size' );
843
844 return $this->getRawSetting( 'digit_size' );
845 }
846
847 /**
848 * Save timer digit size.
849 *
850 * @param $size
851 */
852 public function setDigitSize( $size )
853 {
854 $this->storeRawSetting( 'digit_size', $size );
855 }
856
857 /**
858 * Save timer label size.
859 *
860 * @param $size
861 */
862 public function setLabelSize( $size )
863 {
864 $this->storeRawSetting( 'label_size', $size );
865 }
866
867 public function setHeadlineSize( $size )
868 {
869 $this->storeRawSetting( 'headline_size', $size );
870 }
871
872 /**
873 * Returns evergreen duration.
874 *
875 * @return array
876 */
877 public function getDuration()
878 {
879 $default = [ 0, 0, 0, 0 ];
880 $duration = $this->getRawSetting( 'duration' );
881 if ( is_array( $duration ) ) {
882 $duration = array_merge( $duration, $default );
883
884 return array_map( 'intval', $duration );
885 }
886
887 return $default;
888 }
889
890 public function setRecurringDuration( $value )
891 {
892 $this->storeRawSetting( '_hurryt_recurring_duration', $value );
893 }
894
895 public function setRecurringPauseDuration( $value )
896 {
897 $this->storeRawSetting( '_hurryt_recurring_pause_duration', $value );
898 }
899
900 /**
901 * Returns evergreen duration.
902 *
903 * @return array
904 */
905 public function getRecurringDuration()
906 {
907 $default = [ 0, 0, 0, 0 ];
908 $duration = $this->getRawSetting( '_hurryt_recurring_duration', false );
909 if ( is_array( $duration ) ) {
910 return array_map( 'intval', array_merge( $duration, $default ) );
911 }
912
913 return $default;
914 }
915
916 /**
917 * Returns actions array.
918 *
919 * @return array
920 */
921 public function getActions()
922 {
923 $legacy = $this->getLegacySetting( 'end_action' );
924 if ( $legacy ) {
925 $redirectUrl = $this->getLegacySetting( 'redirect_url' );
926 $actions = [
927 [
928 'id' => intval( $legacy ),
929 'redirectUrl' => $redirectUrl,
930 ],
931 ];
932 $this->storeRawSetting( 'actions', $actions );
933 $this->deleteRawSetting( 'end_action' );
934 $this->deleteRawSetting( 'redirect_url' );
935
936 return $this->mergeActions( $actions );
937 }
938
939 return $this->mergeActions( $this->getRawSetting( 'actions' ) );
940 }
941
942 private function mergeActions( $actions )
943 {
944 $defaults = [
945 [
946 'id' => C::ACTION_NONE,
947 'redirectUrl' => '',
948 'message' => '',
949 'wcStockStatus' => '',
950 ],
951 ];
952
953 if ( count( $actions ) === 0 ) {
954 return $defaults;
955 }
956
957 return array_map( function ( $action ) use ( $defaults ) {
958 $action[ 'id' ] = (int)$action[ 'id' ];
959
960 return array_merge( $defaults[ 0 ], $action );
961 }, $actions );
962 }
963
964 /**
965 * Returns evergreen duration in seconds.
966 *
967 * @param array $duration
968 *
969 * @return int
970 */
971 public function durationArrayToSeconds( $duration = [] )
972 {
973 list( $d, $h, $m, $s ) = empty( $duration ) ? $this->getDuration() : $duration;
974
975 return $d * DAY_IN_SECONDS +
976 $h * HOUR_IN_SECONDS +
977 $m * MINUTE_IN_SECONDS +
978 $s;
979 }
980
981 /**
982 * Returns end datetime.
983 *
984 * @return string
985 */
986 public function getEndDatetime()
987 {
988 return $this->getRawSetting( 'end_datetime' ) ?: $this->defaultEndDatetime();
989 }
990
991 /**
992 * Return true if the recurrence is expired.
993 *
994 * @return bool
995 */
996 public function isRecurringExpired()
997 {
998 $deadline = $this->getRecurringDeadline();
999 if ( ! ( $deadline instanceof Carbon ) ) {
1000 return false;
1001 }
1002
1003 $now = Carbon::now( hurryt_tz() );
1004
1005 return $now->isAfter( $deadline );
1006 }
1007
1008 function getTimeToNextRecurrence()
1009 {
1010 $this->loadSettings();
1011 $interval = absint( $this->recurringInterval );
1012
1013 if ( $this->recurringFrequency === C::RECURRING_DAILY ) {
1014 $frequencyInSeconds = DAY_IN_SECONDS;
1015 } elseif ( $this->recurringFrequency === C::RECURRING_WEEKLY ) {
1016 $frequencyInSeconds = WEEK_IN_SECONDS;
1017
1018 } elseif ( $this->recurringFrequency === C::RECURRING_HOURLY ) {
1019 $frequencyInSeconds = HOUR_IN_SECONDS;
1020
1021 } else {
1022 $frequencyInSeconds = MINUTE_IN_SECONDS;
1023 }
1024
1025 $duration = $this->durationArrayToSeconds( $this->getRecurringDuration() );
1026
1027 return max( 0, ( $frequencyInSeconds * $interval ) - $duration );
1028 }
1029
1030 /**
1031 * Return true if the current campaign can recur today.
1032 *
1033 * @return bool
1034 */
1035 public function canRecurToday()
1036 {
1037 $this->loadSettings();
1038 $day = absint( Carbon::now( hurryt_tz() )->format( 'w' ) );
1039 $recur = in_array( $day, array_map( 'absint', $this->recurringDays ) );
1040
1041 return apply_filters( 'hurryt_recur_today', $recur, $this->getId() );
1042 }
1043
1044 /**
1045 * Return current recurrence date
1046 *
1047 * @return \Carbon\CarbonInterface|null
1048 */
1049 public function getRecurringCurrentDate()
1050 {
1051 $this->loadSettings();
1052 $dtStart = Carbon::parse( $this->recurringStartTime, hurryt_tz() );
1053 $now = Carbon::now( hurryt_tz() );
1054
1055 $range = CarbonPeriod::since( $dtStart );
1056 $interval = absint( $this->recurringInterval );
1057
1058 if ( $this->recurringFrequency === C::RECURRING_DAILY ) {
1059 $range->days( $interval );
1060 } elseif ( $this->recurringFrequency === C::RECURRING_WEEKLY ) {
1061 $range->weeks( $interval );
1062 } elseif ( $this->recurringFrequency === C::RECURRING_HOURLY ) {
1063 $range->hours( $interval );
1064 } else {
1065 $range->minutes( $interval );
1066 }
1067
1068 // Recurs forever
1069 if ( absint( $this->recurringEnd ) === C::RECURRING_END_NEVER ) {
1070 $range->until( $now );
1071 // Recurs until
1072 } elseif ( absint( $this->recurringEnd ) === C::RECURRING_END_TIME ) {
1073 $range->until( Carbon::parse( $this->recurringUntil, hurryt_tz() ) );
1074
1075 $range->addFilter( function ( $date ) use ( $now ) {
1076 /**
1077 * @var Carbon $date
1078 */
1079 return $date->isBefore( $now );
1080 } );
1081
1082 // Recurs N times.
1083 } elseif ( absint( $this->recurringEnd ) === C::RECURRING_END_OCCURRENCES ) {
1084
1085 // Virtual endDate
1086 $range->until( Carbon::now( hurryt_tz() )->addCenturies( 1 ) );
1087
1088 // Limit to the number of occurences in `$this->recurringCount`
1089 $range->setRecurrences( absint( $this->recurringCount ) );
1090
1091 // Set the endDate to the last occurence date
1092 $range->setEndDate( $range->last() );
1093 $range->addFilter( function ( $date ) use ( $now ) {
1094
1095 /**
1096 * @var Carbon $date
1097 */
1098 return $date->isBefore( $now );
1099 } );
1100
1101 }
1102
1103 return $range->last();
1104 }
1105
1106 /**
1107 * Get the next/current deadline based on the current date.
1108 *
1109 * @return null|Carbon
1110 */
1111 public function getRecurringDeadline()
1112 {
1113 $date = $this->getRecurringCurrentDate();
1114 if ( ! $date ) {
1115 return null;
1116 }
1117 $date = clone Carbon::instance( $date );
1118
1119 $duration = $this->durationArrayToSeconds( $this->getRecurringDuration() );
1120
1121 $date->addSeconds( $duration );
1122
1123 return $date;
1124 }
1125
1126 /**
1127 * Returns compaign publish datetime.
1128 *
1129 * @return mixed
1130 */
1131 public function getStartTimestamp()
1132 {
1133 return get_the_date( $this->id );
1134 }
1135
1136 /**
1137 * Returns position in WooCommerce product page.
1138 *
1139 * @return mixed
1140 */
1141 public function getWcPosition()
1142 {
1143 $legacy = $this->getLegacySetting( 'position' );
1144
1145 if ( ! $legacy ) {
1146 return $this->getRawSetting( 'wc_position' );
1147 }
1148 $this->storeRawSetting( 'wc_position', $legacy );
1149 $this->deleteRawSetting( 'position' );
1150
1151 return $legacy;
1152 }
1153
1154 private function getLegacySetting( $name )
1155 {
1156 return get_post_meta( $this->id, $name, true );
1157 }
1158
1159 /**
1160 * Returns true if WooCommerce integration is enabled.
1161 *
1162 * @return mixed
1163 */
1164 public function getWcEnable()
1165 {
1166 $value = $this->getRawSetting( 'wc_enable', false );
1167
1168 if ( $value === C::YES || $value === C::NO ) {
1169 return $value;
1170 }
1171
1172 $legacy = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
1173 if ( $legacy ) {
1174 $this->storeRawSetting( 'wc_enable', C::YES );
1175 } else {
1176 $this->storeRawSetting( 'wc_enable', C::NO );
1177 }
1178
1179 return $this->getRawSetting( 'wc_enable' );
1180 }
1181
1182 /**
1183 * Returns true if label should be displayed.
1184 *
1185 * @return mixed
1186 */
1187 public function getLabelVisibility()
1188 {
1189 $meta = 'label_visibility';
1190 $value = $this->getRawSetting( $meta, false );
1191 if ( $value === C::NO || $value === C::YES ) {
1192 return $value;
1193 }
1194
1195 $legacy = filter_var( $this->getLegacySetting( 'display_labels' ),
1196 FILTER_VALIDATE_BOOLEAN );
1197 $legacy = $legacy ? C::YES : C::NO;
1198 $this->storeRawSetting( $meta, $legacy );
1199 $this->deleteRawSetting( 'display_labels' );
1200
1201 return $this->getRawSetting( $meta );
1202
1203 }
1204
1205 /**
1206 *
1207 * Returns restart type.
1208 *
1209 * @return int
1210 */
1211 public function getRestart()
1212 {
1213 return $this->getRawSetting( 'restart' ) ?: C::RESTART_NONE;
1214 }
1215
1216 /**
1217 * Returns WooCommerce products selection type.
1218 *
1219 * @return string
1220 */
1221 public function getWcProductsSelectionType()
1222 {
1223 $legacy = $this->getLegacySetting( 'products_type' );
1224 if ( ! $legacy ) {
1225 return $this->getRawSetting( 'wc_products_selection_type' );
1226 }
1227 $this->storeRawSetting( 'wc_products_selection_type', $legacy );
1228 $this->deleteRawSetting( 'products_type' );
1229
1230 return $legacy;
1231 }
1232
1233 /**
1234 * Delete setting item.
1235 *
1236 * @param $name
1237 */
1238 public function deleteRawSetting( $name )
1239 {
1240 delete_post_meta( $this->id, $name );
1241 }
1242
1243 /**
1244 * Returns products selection IDs.
1245 *
1246 * @return array
1247 */
1248 public function getWcProductsSelection()
1249 {
1250 $legacy = $this->getLegacySetting( 'products' );
1251 if ( ! $legacy ) {
1252 return $this->getRawSetting( 'wc_products_selection' );
1253 }
1254 $this->storeRawSetting( 'wc_products_selection', $legacy );
1255 $this->deleteRawSetting( 'products' );
1256
1257 return $legacy;
1258 }
1259
1260 /**
1261 * Store custom labels.
1262 *
1263 * @param $labels
1264 */
1265 public function setLabels( $labels )
1266 {
1267 $labels = array_merge( $this->labels, array_filter( $labels ) );
1268 update_post_meta( $this->id, 'labels', $labels );
1269 }
1270
1271 /**
1272 * Returns true if compaign can be published.
1273 *
1274 * @return bool
1275 */
1276 public function isActive()
1277 {
1278 return get_post_status( $this->id ) === "publish"
1279 || get_post_status( $this->id ) === "future";
1280
1281 }
1282
1283 /**
1284 * Returns trus if the compaign is scheduled.
1285 *
1286 * @return bool
1287 */
1288 public function isScheduled()
1289 {
1290 $scheduled = get_post_status( $this->getId() ) === "future";
1291 if ( $scheduled ) {
1292 return true;
1293 }
1294
1295 if ( $this->isRecurring() ) {
1296 $start_date = Carbon::parse( $this->recurringStartTime, hurryt_tz() );
1297 $now = Carbon::now( hurryt_tz() );
1298 if ( $now->isBefore( $start_date ) ) {
1299 return true;
1300 }
1301 }
1302
1303 return $scheduled;
1304 }
1305
1306 /**
1307 * Returns true if fixed campaign datetime is expired.
1308 *
1309 * @param string|null $date
1310 *
1311 * @return bool
1312 */
1313 public function isExpired( $date = null )
1314 {
1315 $endDate = $date === null ? date_create( $this->endDatetime ) : $date;
1316 $today = date_create( current_time( "mysql" ) );
1317
1318 return $endDate < $today;
1319 }
1320
1321 public function isStickyDismissed()
1322 {
1323 return isset( $_COOKIE[ CookieDetection::COOKIE_PREFIX . $this->getId() . '_dismissed' ] )
1324 && $this->stickyBarDismissible === C::YES
1325 && $this->enableSticky === C::YES;
1326 }
1327
1328 /**
1329 * Returns compaign template wrapper.
1330 *
1331 * @param string
1332 *
1333 * @return string
1334 */
1335 public function wrapTemplate( $content )
1336 {
1337 $campaignBuilder = new CampaignBuilder( $this );
1338
1339 return $campaignBuilder->build( $content );
1340 }
1341
1342 /*
1343 * Returns campaign template content.
1344 */
1345 public function buildTemplate()
1346 {
1347 $campaignBuilder = new CampaignBuilder( $this );
1348
1349 return $campaignBuilder->template();
1350 }
1351
1352 public function setWcConditions( $value )
1353 {
1354 $this->storeRawSetting( '_hurryt_wc_conditions', ! empty( $value ) ? $value : [] );
1355 }
1356
1357 public function getWcConditions()
1358 {
1359 return $this->getRawSetting( '_hurryt_wc_conditions', false );
1360 }
1361
1362 }
1363