PluginProbe
Depicter — Popup & Slider Builder / 1.9.2
Depicter — Popup & Slider Builder v1.9.2
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / app / src / Document / Models / Common / Background.php

Background.php in Depicter — Popup & Slider Builder 1.9.2, at app/src/Document/Models/Common/Background.php

384 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Depicter\Document\Models\Common;
3
4
5 use Averta\Core\Utility\Arr;
6 use Averta\Core\Utility\Embed;
7 use Averta\WordPress\Utility\JSON;
8 use Depicter\Document\CSS\Breakpoints;
9 use Depicter\Document\CSS\Selector;
10 use Depicter\Document\Models\Traits\HasDataSheetTrait;
11 use Depicter\Html\Html;
12 use Depicter\Services\MediaBridge;
13
14 class Background
15 {
16 use HasDataSheetTrait;
17
18 /**
19 * @var Color
20 */
21 public $color;
22
23 /**
24 * @var string
25 */
26 public $fitMode;
27
28 /**
29 * @var object
30 */
31 public $video;
32
33 /**
34 * @var object
35 */
36 public $image;
37
38 /**
39 * @var Color
40 */
41 public $overlay;
42
43 /**
44 * @var Styles\Filter
45 */
46 public $filter;
47
48 /**
49 * @var array
50 */
51 public $kenBurnsData = [];
52
53 /**
54 * Check if section has background or not
55 *
56 * @return boolean
57 */
58 public function hasBackground() {
59 return !empty( $this->image->src ) || !empty( $this->video->src );
60 }
61
62
63 /**
64 * Render background markup
65 *
66 * @return string
67 * @throws \Exception
68 */
69 public function render() {
70 $html = '';
71
72 if ( !empty( $this->image->src ) ) {
73 $originalSrc = $this->image->src;
74 $this->image->src = $this->maybeReplaceDataSheetTags( $this->image->src );
75 $html .= $this->renderImage( \Depicter::media()->getSourceUrl( $this->image->src ) );
76 // restore original image src
77 $this->image->src = $originalSrc;
78 }
79
80 if ( !empty( $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 }
87 }
88
89 return $html;
90 }
91
92 /**
93 * Render images
94 *
95 * @param $imageUrl
96 *
97 * @return Html
98 */
99 protected function renderImage( $imageUrl ) {
100 $imageID = \Depicter::media()->getAttachmentId( $this->image->src );
101 $imageSrcSet = is_numeric( $imageID ) ? \Depicter::media()->getSrcSet( $imageID, 'full' ) : '';
102
103 $args = [
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 ) : ''
108 ];
109
110 if ( !empty( $this->kenBurnsData ) ) {
111 $args = Arr::merge( $args, $this->kenBurnsData );
112 }
113
114 if ( $imageSrcSet ) {
115 $args['data-depicter-srcset'] = $imageSrcSet;
116 }
117
118 $available_args = [
119 'responsiveArgs' => [
120 'data-object-fit' => 'fitMode',
121 'data-object-position' => 'position'
122 ]
123 ];
124
125 $args = $this->getElementAttributes( 'image', $args, $available_args );
126
127 $cropAttributes = $this->getCropAttributes( 'image' );
128
129 return Html::img( $imageUrl, Arr::merge( $cropAttributes, $args ) );
130 }
131
132 /**
133 * Renders video tag
134 *
135 * @param $videoUrl
136 *
137 * @return \TypeRocket\Html\Html
138 */
139 public function renderVideo( $videoUrl ) {
140
141 $args = [
142 'class' => Selector::prefixify( 'bg-video' ),
143 'src' => $videoUrl,
144 'preload' => 'metadata',
145 'playsinline' => "true"
146 ];
147
148 $available_args = [
149 'muted' => 'muted',
150 'loop' => 'loop',
151 'data-goto-next' => 'goNextSlide',
152 'data-auto-pause' => 'pause',
153 'responsiveArgs' => [
154 'data-object-fit' => 'fitMode',
155 'data-object-position' => 'position'
156 ]
157 ];
158
159 $args = $this->getElementAttributes( 'video', $args, $available_args );
160
161 return Html::video( $args );
162 }
163
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 ) {
216 foreach ( $available_args as $attribute => $property ) {
217 // for object properties that has responsive value like fitMode and position
218 if ( $attribute == 'responsiveArgs' ) {
219 foreach ( $property as $key => $value ) {
220 $breakpointNames = Breakpoints::names();
221 if ( !empty( $this->{$element_type}->{$value} ) ) {
222 foreach ( $breakpointNames as $device ) {
223 $args[ $key ][] = !empty( $this->{$element_type}->{$value}->{$device} ) ? $this->{$element_type}->{$value}->{$device} : '';
224 }
225 $args[ $key ] = implode(',', $args[ $key ] );
226 }
227 }
228
229 // for simple object properties
230 } elseif ( !empty( $this->{$element_type}->{$property} ) ) {
231 $value = $this->{$element_type}->{$property} == "1" ? "true" : $this->{$element_type}->{$property};
232 $args[ $attribute ] = $value;
233 }
234
235 // In video background, if each of `muted` or `loop` are not set, consider it as `true` by default
236 if( $element_type === 'video' ){
237 if( in_array( $property, ['muted', 'loop'] ) ){
238 if( ! isset( $this->{$element_type}->{$property} ) ){
239 $args[ $attribute ] = 'true';
240 }
241 }
242 }
243 }
244 return $args;
245 }
246
247 /**
248 * Get css background color
249 *
250 * @return array
251 */
252 public function getColor() {
253 $devices = Breakpoints::names();
254
255 $css = [];
256 foreach ( $devices as $device ) {
257 if ( !empty( $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 }
263 }
264 }
265
266 return $css;
267 }
268
269 /**
270 * Get background overlay styles
271 *
272 * @return array
273 */
274 public function getOverlayStyles() {
275 $default = [
276 "content" => '""',
277 "display" => "block",
278 "position"=> "absolute",
279 "top" => "0",
280 "bottom" => "0",
281 "right" => "0",
282 "left" => "0",
283 "z-index" => "1",
284 ];
285
286 $devices = Breakpoints::names();
287
288 $css = [];
289 foreach ( $devices as $device ) {
290 if ( !empty( $this->overlay->{$device} ) && ('transparent' !== $this->overlay->{$device} ) ) {
291 $css[ $device] = $default;
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 }
297 }
298 }
299
300 return $css;
301 }
302
303 /**
304 * Get filter styles of background
305 *
306 * @return array
307 */
308 public function getSectionBackgroundFilter() {
309 if( empty( $this->filter ) ){
310 return [];
311 }
312 return $this->filter->set([]);
313 }
314
315 /**
316 * Get class name of background container
317 *
318 * @return string
319 */
320 public function getContainerClassName() {
321 if ( !empty( $this->video->src ) ) {
322 return Selector::prefixify('bg-video-container');
323 }
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 );
382 }
383 }
384