| @@ -1,8 +1,11 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | namespace Depicter\Document\Models\Common; |
| 3 | 3 | |
| 4 | 4 | |
| 5 | +use Averta\Core\Utility\Arr; | |
| 6 | +use Averta\Core\Utility\Embed; | |
| 7 | +use Averta\WordPress\Utility\JSON; | |
| 5 | 8 | use Depicter\Document\CSS\Breakpoints; |
| 6 | 9 | use Depicter\Document\CSS\Selector; |
| 7 | 10 | use Depicter\Document\Models\Traits\HasDataSheetTrait; |
| 8 | 11 | use Depicter\Html\Html; |
| @@ -42,8 +45,13 @@ | ||
| 42 | 45 | */ |
| 43 | 46 | public $filter; |
| 44 | 47 | |
| 45 | 48 | /** |
| 49 | + * @var array | |
| 50 | + */ | |
| 51 | + public $kenBurnsData = []; | |
| 52 | + | |
| 53 | + /** | |
| 46 | 54 | * Check if section has background or not |
| 47 | 55 | * |
| 48 | 56 | * @return boolean |
| 49 | 57 | */ |
| @@ -52,17 +60,19 @@ | ||
| 52 | 60 | } |
| 53 | 61 | |
| 54 | 62 | |
| 55 | 63 | /** |
| 56 | - * @return Html|string | |
| 64 | + * Render background markup | |
| 65 | + * | |
| 66 | + * @return string | |
| 67 | + * @throws \Exception | |
| 57 | 68 | */ |
| 58 | 69 | public function render() { |
| 59 | - | |
| 60 | 70 | $html = ''; |
| 61 | 71 | |
| 62 | 72 | if ( !empty( $this->image->src ) ) { |
| 63 | 73 | $originalSrc = $this->image->src; |
| 64 | - $this->image->src = $this->maybeReplaceDataSheetTag( $this->image->src, '{{{featuredImage}}}' ); | |
| 74 | + $this->image->src = $this->maybeReplaceDataSheetTags( $this->image->src ); | |
| 65 | 75 | $html .= $this->renderImage( \Depicter::media()->getSourceUrl( $this->image->src ) ); |
| 66 | 76 | // restore original image src |
| 67 | 77 | $this->image->src = $originalSrc; |
| 68 | 78 | } |
| @@ -67,33 +77,43 @@ | ||
| 67 | 77 | $this->image->src = $originalSrc; |
| 68 | 78 | } |
| 69 | 79 | |
| 70 | 80 | if ( !empty( $this->video->src ) ) { |
| 71 | - $html .= $this->renderVideo( \Depicter::media()->getSourceUrl( $this->video->src ) ); | |
| 81 | + $videoType = $this->video->type ?? ''; | |
| 82 | + if ( $videoType == 'embedVideo') { | |
| 83 | + $html .= $this->renderEmbedVideo(); | |
| 84 | + } else { | |
| 85 | + $html .= $this->renderVideo( \Depicter::media()->getSourceUrl( $this->video->src ) ); | |
| 86 | + } | |
| 72 | 87 | } |
| 73 | 88 | |
| 74 | 89 | return $html; |
| 75 | - | |
| 76 | 90 | } |
| 77 | 91 | |
| 78 | 92 | /** |
| 79 | - * render images | |
| 80 | - * @param $image | |
| 93 | + * Render images | |
| 81 | 94 | * |
| 95 | + * @param $imageUrl | |
| 96 | + * | |
| 82 | 97 | * @return Html |
| 83 | 98 | */ |
| 84 | 99 | protected function renderImage( $imageUrl ) { |
| 85 | - $imageSrcSet = is_numeric( $this->image->src ) ? \Depicter::media()->getSrcSet( $this->image->src, 'full' ) : ''; | |
| 100 | + $imageID = \Depicter::media()->getAttachmentId( $this->image->src ); | |
| 101 | + $imageSrcSet = is_numeric( $imageID ) ? \Depicter::media()->getSrcSet( $imageID, 'full' ) : ''; | |
| 86 | 102 | |
| 87 | 103 | $args = [ |
| 88 | - 'class' => 'depicter-bg', | |
| 89 | - 'src' => \Depicter::media()::IMAGE_PLACEHOLDER_SRC, | |
| 90 | - 'data-src' => $imageUrl, | |
| 91 | - 'alt' => is_numeric( $this->image->src ) ? \Depicter::media()->getAltText( $this->image->src ) : '' | |
| 104 | + 'class' => 'depicter-bg', | |
| 105 | + 'src' => \Depicter::media()::IMAGE_PLACEHOLDER_SRC, | |
| 106 | + 'data-depicter-src' => $imageUrl, | |
| 107 | + 'alt' => is_numeric( $imageID ) ? \Depicter::media()->getAltText( $imageID ) : '' | |
| 92 | 108 | ]; |
| 93 | 109 | |
| 110 | + if ( !empty( $this->kenBurnsData ) ) { | |
| 111 | + $args = Arr::merge( $args, $this->kenBurnsData ); | |
| 112 | + } | |
| 113 | + | |
| 94 | 114 | if ( $imageSrcSet ) { |
| 95 | - $args['data-srcset'] = $imageSrcSet; | |
| 115 | + $args['data-depicter-srcset'] = $imageSrcSet; | |
| 96 | 116 | } |
| 97 | 117 | |
| 98 | 118 | $available_args = [ |
| 99 | 119 | 'responsiveArgs' => [ |
| @@ -101,13 +121,22 @@ | ||
| 101 | 121 | 'data-object-position' => 'position' |
| 102 | 122 | ] |
| 103 | 123 | ]; |
| 104 | 124 | |
| 105 | - $args = $this->get_element_attributes( 'image', $args, $available_args ); | |
| 125 | + $args = $this->getElementAttributes( 'image', $args, $available_args ); | |
| 106 | 126 | |
| 107 | - return Html::img( $imageUrl, $args); | |
| 127 | + $cropAttributes = $this->getCropAttributes( 'image' ); | |
| 128 | + | |
| 129 | + return Html::img( $imageUrl, Arr::merge( $cropAttributes, $args ) ); | |
| 108 | 130 | } |
| 109 | 131 | |
| 132 | + /** | |
| 133 | + * Renders video tag | |
| 134 | + * | |
| 135 | + * @param $videoUrl | |
| 136 | + * | |
| 137 | + * @return \TypeRocket\Html\Html | |
| 138 | + */ | |
| 110 | 139 | public function renderVideo( $videoUrl ) { |
| 111 | 140 | |
| 112 | 141 | $args = [ |
| 113 | 142 | 'class' => Selector::prefixify( 'bg-video' ), |
| @@ -126,14 +155,65 @@ | ||
| 126 | 155 | 'data-object-position' => 'position' |
| 127 | 156 | ] |
| 128 | 157 | ]; |
| 129 | 158 | |
| 130 | - $args = $this->get_element_attributes( 'video', $args, $available_args ); | |
| 159 | + $args = $this->getElementAttributes( 'video', $args, $available_args ); | |
| 131 | 160 | |
| 132 | 161 | return Html::video( $args ); |
| 133 | 162 | } |
| 134 | 163 | |
| 135 | - public function get_element_attributes( $element_type, $args, $available_args ) { | |
| 164 | + /** | |
| 165 | + * Get crop attributes | |
| 166 | + * | |
| 167 | + * @param string $type | |
| 168 | + * | |
| 169 | + * @return array | |
| 170 | + */ | |
| 171 | + protected function getCropAttributes( string $type = 'image' ){ | |
| 172 | + if ( ! $this->hasCustomFitMode( $type ) ) { | |
| 173 | + return []; | |
| 174 | + } | |
| 175 | + | |
| 176 | + $attributes = []; | |
| 177 | + $breakpointNames = Breakpoints::names(); | |
| 178 | + | |
| 179 | + foreach ( $breakpointNames as $device ) { | |
| 180 | + if( ! empty( $this->{$type}->cropData->{$device} ) ){ | |
| 181 | + $attributeDeviceValue = $this->{$type}->cropData->{$device}; | |
| 182 | + $attributeDeviceValue = is_object( $attributeDeviceValue ) || is_array( $attributeDeviceValue ) ? JSON::encode( $attributeDeviceValue ) : ''; | |
| 183 | + $attributeDeviceName = $device === 'default' ? 'data-crop' : "data-{$device}-crop"; | |
| 184 | + $attributes[ $attributeDeviceName ] = $attributeDeviceValue; | |
| 185 | + } | |
| 186 | + } | |
| 187 | + | |
| 188 | + return $attributes; | |
| 189 | + } | |
| 190 | + | |
| 191 | + /** | |
| 192 | + * Whether background types has custom fit mode or not | |
| 193 | + * | |
| 194 | + * @param string $type | |
| 195 | + * | |
| 196 | + * @return bool | |
| 197 | + */ | |
| 198 | + protected function hasCustomFitMode( string $type = 'image' ){ | |
| 199 | + if ( empty( $this->{$type}->fitMode->default ) ) { | |
| 200 | + return false; | |
| 201 | + } | |
| 202 | + | |
| 203 | + $hasCustomFitMode= false; | |
| 204 | + $breakpointNames = Breakpoints::names(); | |
| 205 | + | |
| 206 | + foreach ( $breakpointNames as $device ) { | |
| 207 | + if( !empty( $this->{$type}->fitMode->{$device} ) && $this->{$type}->fitMode->{$device} === 'custom' ){ | |
| 208 | + return true; | |
| 209 | + } | |
| 210 | + } | |
| 211 | + | |
| 212 | + return false; | |
| 213 | + } | |
| 214 | + | |
| 215 | + public function getElementAttributes( $element_type, $args, $available_args ) { | |
| 136 | 216 | foreach ( $available_args as $attribute => $property ) { |
| 137 | 217 | // for object properties that has responsive value like fitMode and position |
| 138 | 218 | if ( $attribute == 'responsiveArgs' ) { |
| 139 | 219 | foreach ( $property as $key => $value ) { |
| @@ -174,9 +254,13 @@ | ||
| 174 | 254 | |
| 175 | 255 | $css = []; |
| 176 | 256 | foreach ( $devices as $device ) { |
| 177 | 257 | if ( !empty( $this->color->{$device} ) ) { |
| 178 | - $css[ $device]['background-color'] = $this->color->{$device}; | |
| 258 | + if ( false == strpos( $this->color->{$device}, 'gradient' ) ) { | |
| 259 | + $css[ $device]['background-color'] = $this->color->{$device}; | |
| 260 | + } else { | |
| 261 | + $css[ $device]['background-image'] = $this->color->{$device}; | |
| 262 | + } | |
| 179 | 263 | } |
| 180 | 264 | } |
| 181 | 265 | |
| 182 | 266 | return $css; |
| @@ -204,9 +288,13 @@ | ||
| 204 | 288 | $css = []; |
| 205 | 289 | foreach ( $devices as $device ) { |
| 206 | 290 | if ( !empty( $this->overlay->{$device} ) && ('transparent' !== $this->overlay->{$device} ) ) { |
| 207 | 291 | $css[ $device] = $default; |
| 208 | - $css[ $device]['background-color'] = $this->overlay->{$device}; | |
| 292 | + if ( false == strpos( $this->overlay->{$device}, 'gradient' ) ) { | |
| 293 | + $css[ $device]['background-color'] = $this->overlay->{$device}; | |
| 294 | + } else { | |
| 295 | + $css[ $device]['background-image'] = $this->overlay->{$device}; | |
| 296 | + } | |
| 209 | 297 | } |
| 210 | 298 | } |
| 211 | 299 | |
| 212 | 300 | return $css; |
| @@ -214,9 +302,9 @@ | ||
| 214 | 302 | |
| 215 | 303 | /** |
| 216 | 304 | * Get filter styles of background |
| 217 | 305 | * |
| 218 | - * @return array|mixed | |
| 306 | + * @return array | |
| 219 | 307 | */ |
| 220 | 308 | public function getSectionBackgroundFilter() { |
| 221 | 309 | if( empty( $this->filter ) ){ |
| 222 | 310 | return []; |
| @@ -232,7 +320,64 @@ | ||
| 232 | 320 | public function getContainerClassName() { |
| 233 | 321 | if ( !empty( $this->video->src ) ) { |
| 234 | 322 | return Selector::prefixify('bg-video-container'); |
| 235 | 323 | } |
| 236 | - return Selector::prefixify('bg-container'); | |
| 324 | + return Selector::prefixify('section-background'); | |
| 325 | + } | |
| 326 | + | |
| 327 | + /** | |
| 328 | + * Set ken burns data | |
| 329 | + * | |
| 330 | + * @param array $kenBurnsData | |
| 331 | + * | |
| 332 | + * @return void | |
| 333 | + */ | |
| 334 | + public function setKenBurnsData( array $kenBurnsData = [] ) { | |
| 335 | + $this->kenBurnsData = $kenBurnsData; | |
| 336 | + } | |
| 337 | + | |
| 338 | + /** | |
| 339 | + * Renders embed video tag | |
| 340 | + * | |
| 341 | + * @return \TypeRocket\Html\Html | |
| 342 | + */ | |
| 343 | + public function renderEmbedVideo() { | |
| 344 | + $embedUrl = $this->video->src; | |
| 345 | + | |
| 346 | + if ( $this->video->embedType == 'youtube' ) { | |
| 347 | + if( $embedUrl = Embed::getYouTubeVimeoEmbedUrl( $embedUrl ) ){ | |
| 348 | + $embedUrl = add_query_arg([ | |
| 349 | + 'controls' => '0', | |
| 350 | + 'mute' => '1', | |
| 351 | + 'rel' => '0' | |
| 352 | + ], $embedUrl ); | |
| 353 | + } | |
| 354 | + } else if ( $this->video->embedType == 'vimeo' ) { | |
| 355 | + if( $embedUrl = Embed::getYouTubeVimeoEmbedUrl( $embedUrl ) ){ | |
| 356 | + $embedUrl = add_query_arg([ | |
| 357 | + 'controls' => '0', | |
| 358 | + 'background' => '1' | |
| 359 | + ], $embedUrl ); | |
| 360 | + } | |
| 361 | + } | |
| 362 | + | |
| 363 | + $iframe = Html::iframe([ | |
| 364 | + 'src' => $embedUrl, | |
| 365 | + "frameborder" => "0", | |
| 366 | + "allowfullscreen" => "", | |
| 367 | + 'data-type' => $this->video->embedType, | |
| 368 | + 'data-width' => $this->video->size->width, | |
| 369 | + 'data-height' => $this->video->size->height, | |
| 370 | + 'data-goto-next' => $this->video->goNextSlide ?? false, | |
| 371 | + 'data-auto-pause' => $this->video->pause ?? false, | |
| 372 | + 'data-loop' => $this->video->loop ?? true | |
| 373 | + ]); | |
| 374 | + | |
| 375 | + if ( $this->video->embedType == 'youtube' ) { | |
| 376 | + $iframe .= Html::img( Embed::getYouTubePosterUrl( $this->video->src ), [ | |
| 377 | + 'class' => Selector::prefixify( 'bg-embed-poster' ) | |
| 378 | + ]); | |
| 379 | + } | |
| 380 | + | |
| 381 | + return Html::div(['class' => 'depicter-bg-embed'], $iframe ); | |
| 237 | 382 | } |
| 238 | 383 | } |