| @@ -1,8 +1,11 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Hurrytimer; |
| 4 | 4 | |
| 5 | +use Carbon\Carbon; | |
| 6 | +use Exception; | |
| 7 | + | |
| 5 | 8 | class CampaignBuilder |
| 6 | 9 | { |
| 7 | 10 | use CampaignBuilderLegacy; |
| 8 | 11 | |
| @@ -16,13 +19,12 @@ | ||
| 16 | 19 | * @var \Hurrytimer\Campaign |
| 17 | 20 | */ |
| 18 | 21 | protected $campaign; |
| 19 | 22 | |
| 20 | - public function __construct($campaign) | |
| 23 | + public function __construct( $campaign ) | |
| 21 | 24 | { |
| 22 | 25 | $this->campaign = $campaign; |
| 23 | 26 | $this->campaign->loadSettings(); |
| 24 | - | |
| 25 | 27 | } |
| 26 | 28 | |
| 27 | 29 | /** |
| 28 | 30 | * Returns built template. |
| @@ -31,33 +33,39 @@ | ||
| 31 | 33 | * @param boolean |
| 32 | 34 | * |
| 33 | 35 | * @return string |
| 34 | 36 | */ |
| 35 | - public function build($content = '', $withConfig = true) | |
| 37 | + public function build( $content = '', $withConfig = true ) | |
| 36 | 38 | { |
| 37 | - $config = $this->getClientConfig(); | |
| 38 | - $json = json_encode($config); | |
| 39 | - $legacyClass = $this->legacyCampaignClass($this->campaign->getId()); | |
| 40 | - if ($this->campaign->enableSticky === C::YES) { | |
| 39 | + $config = $this->getClientConfig(); | |
| 40 | + $json = json_encode( $config ); | |
| 41 | + $legacyClass = $this->legacyCampaignClass( $this->campaign->getId() ); | |
| 42 | + if ( $this->campaign->enableSticky === C::YES ) { | |
| 41 | 43 | |
| 42 | 44 | return "<div class='hurrytimer-sticky hurryt-loading hurrytimer-sticky-{$this->campaign->getId()}'><div class='hurrytimer-sticky-inner'>" |
| 43 | - . "<div class='{$legacyClass} hurrytimer-campaign hurrytimer-campaign-{$this->campaign->getId()}'" | |
| 44 | - . "data-config='{$json}' >{$content}</div></div>" . $this->stickyBarCloseButton() ."</div>"; | |
| 45 | + . "<div class='{$legacyClass} hurrytimer-campaign hurrytimer-campaign-{$this->campaign->getId()}'" | |
| 46 | + . "data-config='{$json}' >{$content}</div></div>" . $this->stickyBarCloseButton() | |
| 47 | + . "</div>"; | |
| 45 | 48 | } |
| 49 | + | |
| 46 | 50 | return "<div class='{$legacyClass} hurrytimer-campaign hurryt-loading hurrytimer-campaign-{$this->campaign->getId()}'" |
| 47 | - . "data-config='{$json}' >{$content}</div>"; | |
| 51 | + . "data-config='{$json}' >{$content}</div>"; | |
| 48 | 52 | } |
| 49 | 53 | |
| 50 | 54 | public function template() |
| 51 | 55 | { |
| 52 | - return | |
| 53 | - ($this->campaign->headlinePosition == C::HEADLINE_POSITION_ABOVE_TIMER | |
| 54 | - ? $this->headline() | |
| 55 | - : '') | |
| 56 | - . '<div class="' . $this->legacyTimerClass() . ' hurrytimer-timer"></div>' | |
| 57 | - . ($this->campaign->headlinePosition == C::HEADLINE_POSITION_BELOW_TIMER | |
| 58 | - ? $this->headline() : '') | |
| 59 | - . $this->callToActionButton(); | |
| 56 | + | |
| 57 | + $template = ( $this->campaign->headlinePosition == C::HEADLINE_POSITION_ABOVE_TIMER | |
| 58 | + ? $this->headline() | |
| 59 | + : '' ) | |
| 60 | + . '<div class="' . $this->legacyTimerClass() . ' hurrytimer-timer"></div>' | |
| 61 | + . ( $this->campaign->headlinePosition == C::HEADLINE_POSITION_BELOW_TIMER | |
| 62 | + ? $this->headline() : '' ) | |
| 63 | + . $this->callToActionButton(); | |
| 64 | + | |
| 65 | + | |
| 66 | + return $template; | |
| 67 | + | |
| 60 | 68 | } |
| 61 | 69 | |
| 62 | 70 | /** |
| 63 | 71 | * Returns common client config. |
| @@ -66,10 +74,10 @@ | ||
| 66 | 74 | */ |
| 67 | 75 | private function commonClientConfig() |
| 68 | 76 | { |
| 69 | 77 | return [ |
| 70 | - 'id' => $this->campaign->getId(), | |
| 71 | - 'actions' => $this->campaign->actions, | |
| 78 | + 'id' => $this->campaign->getId(), | |
| 79 | + 'actions' => $this->campaign->actions, | |
| 72 | 80 | 'template' => $this->timer(), |
| 73 | 81 | ]; |
| 74 | 82 | } |
| 75 | 83 | |
| @@ -81,13 +89,14 @@ | ||
| 81 | 89 | new IPDetection() |
| 82 | 90 | ); |
| 83 | 91 | |
| 84 | 92 | return [ |
| 85 | - 'isRegular' => false, | |
| 86 | - 'duration' => $this->campaign->getDurationInSeconds(), | |
| 87 | - 'reset' => $evergreenCompaign->reseting(), | |
| 88 | - 'restart' => $this->campaign->getRestart(), | |
| 89 | - 'endDate' => intval($evergreenCompaign->getEndDate()), | |
| 93 | + 'isRegular' => false, | |
| 94 | + 'duration' => $this->campaign->durationArrayToSeconds(), | |
| 95 | + 'reset' => $evergreenCompaign->reseting(), | |
| 96 | + 'restart' => apply_filters( 'hurryt_evergreen_restart', | |
| 97 | + $this->campaign->getRestart() ), | |
| 98 | + 'endDate' => intval( $evergreenCompaign->getEndDate() ), | |
| 90 | 99 | 'cookieName' => $evergreenCompaign->cookieName(), |
| 91 | 100 | ]; |
| 92 | 101 | |
| 93 | 102 | } |
| @@ -98,15 +107,35 @@ | ||
| 98 | 107 | * @return array |
| 99 | 108 | */ |
| 100 | 109 | private function regularClientConfig() |
| 101 | 110 | { |
| 111 | + try { | |
| 112 | + $endDate = Carbon::parse( $this->campaign->getEndDatetime(), hurryt_tz() ) | |
| 113 | + ->getBrowserTimestamp(); | |
| 114 | + if ( $this->campaign->isRecurring() ) { | |
| 115 | + $endDate = $this->campaign->getRecurringDeadline(); | |
| 116 | + if ( $endDate ) { | |
| 117 | + $endDate = $endDate->getBrowserTimestamp(); | |
| 118 | + } else { | |
| 119 | + $endDate = null; | |
| 120 | + } | |
| 121 | + } | |
| 102 | 122 | |
| 103 | - return [ | |
| 104 | - 'isRegular' => true, | |
| 105 | - 'endDate' => date( | |
| 106 | - 'Y/m/d H:i:s', | |
| 107 | - strtotime($this->campaign->getEndDatetime())), | |
| 108 | - ]; | |
| 123 | + $timeToNextRecurrence = $this->campaign->isRecurring() | |
| 124 | + ? $this->campaign->getTimeToNextRecurrence() | |
| 125 | + : 0; | |
| 126 | + | |
| 127 | + return [ | |
| 128 | + 'recurr' => $this->campaign->isRecurring(), | |
| 129 | + 'timeToNextRecurrence' => $timeToNextRecurrence, | |
| 130 | + 'isRegular' => true, | |
| 131 | + 'endDate' => $endDate, | |
| 132 | + ]; | |
| 133 | + | |
| 134 | + } catch ( Exception $e ) { | |
| 135 | + echo __( sprintf( 'HurryTimer Error: Invalid campaign (ID: %d). Please double check your settings.', | |
| 136 | + $this->campaign->getId() ), 'hurrytimer' ); | |
| 137 | + } | |
| 109 | 138 | } |
| 110 | 139 | |
| 111 | 140 | /** |
| 112 | 141 | * Returns client config for the compaign. |
| @@ -114,13 +143,13 @@ | ||
| 114 | 143 | * @return array|null |
| 115 | 144 | */ |
| 116 | 145 | public function getClientConfig() |
| 117 | 146 | { |
| 118 | - if ($this->campaign->isEvergreen()) { | |
| 119 | - return array_merge($this->commonClientConfig(), $this->evergreenClientConfig()); | |
| 147 | + if ( $this->campaign->isEvergreen() ) { | |
| 148 | + return array_merge( $this->commonClientConfig(), $this->evergreenClientConfig() ); | |
| 120 | 149 | |
| 121 | 150 | } else { |
| 122 | - return array_merge($this->commonClientConfig(), $this->regularClientConfig()); | |
| 151 | + return array_merge( $this->commonClientConfig(), $this->regularClientConfig() ); | |
| 123 | 152 | |
| 124 | 153 | } |
| 125 | 154 | } |
| 126 | 155 | |
| @@ -130,17 +159,20 @@ | ||
| 130 | 159 | * @return string |
| 131 | 160 | */ |
| 132 | 161 | public function timer() |
| 133 | 162 | { |
| 134 | - $blocks = array_filter([ | |
| 163 | + $blocks = array_filter( [ | |
| 135 | 164 | $this->daysBlock(), |
| 136 | 165 | $this->hoursBlock(), |
| 137 | 166 | $this->minutesBlock(), |
| 138 | 167 | $this->secondsBlock(), |
| 139 | - ]); | |
| 168 | + ] ); | |
| 140 | 169 | |
| 141 | - return implode($this->separator(), $blocks); | |
| 170 | + $template = implode( $this->separator(), $blocks ); | |
| 142 | 171 | |
| 172 | + | |
| 173 | + return $template; | |
| 174 | + | |
| 143 | 175 | } |
| 144 | 176 | |
| 145 | 177 | /** |
| 146 | 178 | * Returns separator. |
| @@ -149,10 +181,10 @@ | ||
| 149 | 181 | */ |
| 150 | 182 | public function separator() |
| 151 | 183 | { |
| 152 | 184 | return $this->campaign->blockSeparatorVisibility === C::YES |
| 153 | - ? '<div class="' . $this->legacySeparatorClass() . ' hurrytimer-timer-sep">:</div>' | |
| 154 | - : ''; | |
| 185 | + ? '<div class="' . $this->legacySeparatorClass() . ' hurrytimer-timer-sep">:</div>' | |
| 186 | + : ''; | |
| 155 | 187 | } |
| 156 | 188 | |
| 157 | 189 | /** |
| 158 | 190 | * Returns days block. |
| @@ -160,11 +192,13 @@ | ||
| 160 | 192 | * @return string |
| 161 | 193 | */ |
| 162 | 194 | public function daysBlock() |
| 163 | 195 | { |
| 196 | + $label = $this->campaign->labels[ 'days' ]; | |
| 197 | + | |
| 164 | 198 | return $this->campaign->daysVisibility === C::YES |
| 165 | - ? $this->block("%D", $this->campaign->labels['days']) | |
| 166 | - : ''; | |
| 199 | + ? $this->block( "%D", $label ) | |
| 200 | + : ''; | |
| 167 | 201 | } |
| 168 | 202 | |
| 169 | 203 | /** |
| 170 | 204 | * Returns hours block. |
| @@ -172,11 +206,13 @@ | ||
| 172 | 206 | * @return string |
| 173 | 207 | */ |
| 174 | 208 | public function hoursBlock() |
| 175 | 209 | { |
| 210 | + $label = $this->campaign->labels[ 'hours' ]; | |
| 211 | + | |
| 176 | 212 | return $this->campaign->hoursVisibility === C::YES |
| 177 | - ? $this->block("%H", $this->campaign->labels['hours']) | |
| 178 | - : ''; | |
| 213 | + ? $this->block( "%H", $label ) | |
| 214 | + : ''; | |
| 179 | 215 | } |
| 180 | 216 | |
| 181 | 217 | /** |
| 182 | 218 | * Returns minutes block. |
| @@ -184,11 +220,13 @@ | ||
| 184 | 220 | * @return string |
| 185 | 221 | */ |
| 186 | 222 | public function minutesBlock() |
| 187 | 223 | { |
| 224 | + $label = $this->campaign->labels[ 'minutes' ]; | |
| 225 | + | |
| 188 | 226 | return $this->campaign->minutesVisibility === C::YES |
| 189 | - ? $this->block("%M", $this->campaign->labels['minutes']) | |
| 190 | - : ''; | |
| 227 | + ? $this->block( "%M", $label ) | |
| 228 | + : ''; | |
| 191 | 229 | |
| 192 | 230 | } |
| 193 | 231 | |
| 194 | 232 | /** |
| @@ -197,11 +235,14 @@ | ||
| 197 | 235 | * @return string |
| 198 | 236 | */ |
| 199 | 237 | public function secondsBlock() |
| 200 | 238 | { |
| 239 | + | |
| 240 | + $label = $this->campaign->labels[ 'seconds' ]; | |
| 241 | + | |
| 201 | 242 | return $this->campaign->secondsVisibility === C::YES |
| 202 | - ? $this->block("%S", $this->campaign->labels['seconds']) | |
| 203 | - : ''; | |
| 243 | + ? $this->block( "%S", $label ) | |
| 244 | + : ''; | |
| 204 | 245 | |
| 205 | 246 | } |
| 206 | 247 | |
| 207 | 248 | /** |
| @@ -211,60 +252,72 @@ | ||
| 211 | 252 | * @param $label |
| 212 | 253 | * |
| 213 | 254 | * @return string |
| 214 | 255 | */ |
| 215 | - public function block($digitFormat, $label) | |
| 256 | + public function block( $digitFormat, $label ) | |
| 216 | 257 | { |
| 217 | 258 | return '<div class="hurrytimer-timer-block ' . $this->legacyBlockClass() . '">' |
| 218 | - . $this->digit($digitFormat) | |
| 219 | - . $this->label($label) | |
| 220 | - . '</div>'; | |
| 259 | + . $this->digit( $digitFormat ) | |
| 260 | + . $this->label( $label ) | |
| 261 | + . '</div>'; | |
| 221 | 262 | } |
| 222 | 263 | |
| 223 | - public function digit($format) | |
| 264 | + public function digit( $format ) | |
| 224 | 265 | { |
| 225 | 266 | return '<div class="hurrytimer-timer-digit ' . $this->legacyDigitClass() . '">' . $format |
| 226 | - . '</div>'; | |
| 267 | + . '</div>'; | |
| 227 | 268 | } |
| 228 | 269 | |
| 229 | - public function label($text) | |
| 270 | + public function label( $text ) | |
| 230 | 271 | { |
| 231 | - if ($this->campaign->labelVisibility === "no") { | |
| 272 | + if ( $this->campaign->labelVisibility === "no" ) { | |
| 232 | 273 | return ''; |
| 233 | 274 | } |
| 234 | 275 | |
| 235 | 276 | return '<div class="hurrytimer-timer-label ' . $this->legacyLabelClass() . '" >' |
| 236 | - . __($text, 'hurrytimer') . '</div>'; | |
| 277 | + . __( $text, 'hurrytimer' ) . '</div>'; | |
| 237 | 278 | |
| 238 | 279 | } |
| 239 | 280 | |
| 240 | 281 | public function headline() |
| 241 | 282 | { |
| 283 | + | |
| 284 | + $headline = __( $this->campaign->headline, 'hurrytimer' ); | |
| 285 | + | |
| 242 | 286 | return $this->campaign->headlineVisibility === C::YES |
| 243 | - ? '<div class="' . $this->legacyHeadlineClass() . ' hurrytimer-headline">' | |
| 244 | - . __($this->campaign->headline, 'hurrytimer') . '</div>' | |
| 245 | - : ''; | |
| 287 | + ? '<div class="' . $this->legacyHeadlineClass() . ' hurrytimer-headline">' | |
| 288 | + . $headline . '</div>' | |
| 289 | + : ''; | |
| 290 | + | |
| 246 | 291 | } |
| 247 | 292 | |
| 248 | 293 | public function callToActionButton() |
| 249 | 294 | { |
| 250 | - if ($this->campaign->callToAction['enabled'] === C::NO) { | |
| 295 | + if ( $this->campaign->callToAction[ 'enabled' ] === C::NO ) { | |
| 251 | 296 | return ''; |
| 252 | 297 | } |
| 253 | 298 | |
| 254 | - $target = $this->campaign->callToAction['new_tab'] === C::YES ? '_blank' : '_self'; | |
| 255 | - return "<div class='hurrytimer-button-wrap'><a class='hurrytimer-button' target='" . $target . "' href='" . $this->campaign->callToAction['url'] . "' >" . $this->campaign->callToAction['text'] . "</a></div>"; | |
| 299 | + $cta_text = $this->campaign->callToAction[ 'text' ]; | |
| 300 | + | |
| 301 | + $cta_url = $this->campaign->callToAction[ 'url' ]; | |
| 302 | + | |
| 303 | + $target = $this->campaign->callToAction[ 'new_tab' ] === C::YES ? '_blank' : '_self'; | |
| 304 | + $template = "<a class='hurrytimer-button' target='" . $target . "' href='" . $cta_url | |
| 305 | + . "' >" . $cta_text . "</a>"; | |
| 306 | + | |
| 307 | + return "<div class='hurrytimer-button-wrap'>" . $template . "</div>"; | |
| 308 | + | |
| 256 | 309 | } |
| 257 | 310 | |
| 258 | 311 | public function stickyBarCloseButton() |
| 259 | 312 | { |
| 260 | - if ($this->campaign->stickyBarDismissible === C::NO || | |
| 261 | - isset($_COOKIE['_dismissed_sticky_' . $this->campaign->getId()]) | |
| 313 | + if ( $this->campaign->stickyBarDismissible === C::NO | |
| 314 | + || isset( $_COOKIE[ '_dismissed_sticky_' . $this->campaign->getId() ] ) | |
| 262 | 315 | ) { |
| 263 | 316 | return ''; |
| 264 | 317 | } |
| 265 | 318 | |
| 266 | - if ($this->campaign->stickyBarDismissible === C::YES) { | |
| 319 | + if ( $this->campaign->stickyBarDismissible === C::YES ) { | |
| 267 | 320 | return '<button type="button" class="hurrytimer-sticky-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 357 357"> |
| 268 | 321 | <polygon points="357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 357,321.3 |
| 269 | 322 | 214.2,178.5"/></svg></button>'; |
| 270 | 323 | |