| 1 |
<?php |
| 2 |
defined('ABSPATH') || exit; |
| 3 |
|
| 4 |
class Themify_Builder_Component_Row{ |
| 5 |
|
| 6 |
public static $isFirstRow = false; |
| 7 |
|
| 8 |
|
| 9 |
/** |
| 10 |
* Computes and returns data for Builder row or column video background. |
| 11 |
* |
| 12 |
* @since 2.3.3 |
| 13 |
* |
| 14 |
* @param array $styling The row's or column's styling array. |
| 15 |
* |
| 16 |
* @return string Return video data if row/col has a background video, else return false. |
| 17 |
*/ |
| 18 |
public static function get_video_background(array $styling):string { |
| 19 |
if (!( isset($styling['background_type']) && 'video' === $styling['background_type'] && !empty($styling['background_video']) )) { |
| 20 |
return ''; |
| 21 |
} |
| 22 |
$video_data = 'data-tbfullwidthvideo="' . esc_url(themify_https_esc($styling['background_video'])) . '"'; |
| 23 |
|
| 24 |
// Will only be written if they exist, for backwards compatibility with global JS variable tbLocalScript.backgroundVideoLoop |
| 25 |
|
| 26 |
|
| 27 |
if (!empty($styling['background_video_options'])) { |
| 28 |
if (is_array($styling['background_video_options'])) { |
| 29 |
$video_data .= in_array('mute', $styling['background_video_options'], true) ? '' : ' data-mutevideo="unmute"'; |
| 30 |
$video_data .= in_array('unloop', $styling['background_video_options'], true) ? ' data-unloopvideo="unloop"' : ''; |
| 31 |
$video_data .= in_array('playonmobile', $styling['background_video_options'], true) ? ' data-playonmobile="play"' : ''; |
| 32 |
} else { |
| 33 |
$video_data .= ( false !== stripos($styling['background_video_options'], 'mute') ) ? '' : ' data-mutevideo="unmute"'; |
| 34 |
$video_data .= ( false !== stripos($styling['background_video_options'], 'unloop') ) ? ' data-unloopvideo="unloop"' : ''; |
| 35 |
$video_data .= ( false !== stripos($styling['background_video_options'], 'playonmobile') ) ? ' data-playonmobile="play"' : ''; |
| 36 |
} |
| 37 |
} |
| 38 |
return apply_filters('themify_builder_row_video_background', $video_data, $styling); |
| 39 |
} |
| 40 |
|
| 41 |
/** |
| 42 |
* Computes and returns the HTML a color overlay. |
| 43 |
* |
| 44 |
* @since 2.3.3 |
| 45 |
* |
| 46 |
* @param array $styling The row's or column's styling array. |
| 47 |
* |
| 48 |
* @return bool Returns false if $styling doesn't have a color overlay. Otherwise outputs the HTML; |
| 49 |
*/ |
| 50 |
private static function do_color_overlay(array $styling, $selector = ''):bool { |
| 51 |
|
| 52 |
$type = !isset($styling['cover_color-type']) || $styling['cover_color-type'] === 'color' ? 'color' : 'gradient'; |
| 53 |
$is_empty = $type === 'color' ? ( empty($styling['cover_color']) && empty( $styling['cover_bg'] ) ) : empty($styling['cover_gradient-gradient']); |
| 54 |
if ( $is_empty === true && ! empty( $styling['cover_backdrop'] ) ) { |
| 55 |
$is_empty = false; |
| 56 |
} |
| 57 |
|
| 58 |
if ($is_empty === true) { |
| 59 |
$hover_type = !isset($styling['cover_color_hover-type']) || $styling['cover_color_hover-type'] === 'hover_color' ? 'color' : 'gradient'; |
| 60 |
$is_empty_hover = $hover_type === 'color' ? ( empty($styling['cover_color_hover']) && empty($styling['cover_bg_h']) ) : empty($styling['cover_gradient_hover-gradient']); |
| 61 |
if ( $is_empty_hover === true && ! empty( $styling['cover_backdrop_h'] ) ) { |
| 62 |
$is_empty_hover = false; |
| 63 |
} |
| 64 |
} |
| 65 |
if ($is_empty === false || $is_empty_hover === false) { |
| 66 |
$attr = [ |
| 67 |
'class' => 'builder_row_cover tf_abs', |
| 68 |
'data-lazy' => 1 |
| 69 |
]; |
| 70 |
$attr = self::get_reveal_effect( $styling, $attr, 'cover_reveal' ); |
| 71 |
|
| 72 |
Themify_Builder_Component_Module::sticky_element_props( $attr, $styling, 'cover_' ); |
| 73 |
echo '<span ', themify_get_element_attributes($attr), '></span>'; |
| 74 |
return true; |
| 75 |
} |
| 76 |
return false; |
| 77 |
} |
| 78 |
|
| 79 |
private static function get_reveal_effect( array $styling, array $attr, string $option_prefix ) : array { |
| 80 |
if ( ! empty( $styling[$option_prefix] ) ) { |
| 81 |
$effect = $styling[$option_prefix]; |
| 82 |
$reveal_viewport = empty( $styling[$option_prefix . '_vp'] ) ? '0,100' : $styling[$option_prefix . '_vp']; |
| 83 |
$minMaxSize = empty( $styling[$option_prefix . '_minmax'] ) ? '0,100' : $styling[$option_prefix . '_minmax']; |
| 84 |
$attr['data-tb_clip'] = $effect . ',' . $reveal_viewport . ',' . $minMaxSize; |
| 85 |
if ( $effect === 'sp' || $effect === 'r' || $effect === 'sw' ) { |
| 86 |
$corner_radius_unit = empty( $styling[$option_prefix . '_br_unit'] ) ? 'px' : $styling[$option_prefix . '_br_unit']; |
| 87 |
$attr['data-tb_clip_br'] = empty( $styling[$option_prefix . '_br'] ) ? '0' : $styling[$option_prefix . '_br'] . $corner_radius_unit; |
| 88 |
} |
| 89 |
if ( $effect === 'sp' ) { |
| 90 |
if ( ! empty( $styling[$option_prefix . '_sp_dir'] ) && $styling[$option_prefix . '_sp_dir'] !== 'ho' ) { |
| 91 |
$attr['data-tb_dir'] = $styling[$option_prefix . '_sp_dir']; |
| 92 |
} |
| 93 |
} else if ( $effect === 'c' || $effect === 'r' ) { |
| 94 |
if ( ! empty( $styling[$option_prefix . '_zoomdir'] ) && $styling[$option_prefix . '_zoomdir'] !== 'i' ) { |
| 95 |
$attr['data-tb_dir'] = $styling[$option_prefix . '_zoomdir']; |
| 96 |
} |
| 97 |
if ( ! empty( $styling[$option_prefix . '_pos'] ) ) { |
| 98 |
$attr['data-tb_clip_pos'] = $styling[$option_prefix . '_pos']; |
| 99 |
} |
| 100 |
} else if ( $effect === 'sw' ) { |
| 101 |
if ( ! empty( $styling[$option_prefix . '_sw_dir'] ) && $styling[$option_prefix . '_sw_dir'] !== 'l' ) { |
| 102 |
$attr['data-tb_dir'] = $styling[$option_prefix . '_sw_dir']; |
| 103 |
} |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
return $attr; |
| 108 |
} |
| 109 |
|
| 110 |
/** |
| 111 |
* Get the frame type |
| 112 |
*/ |
| 113 |
private static function get_frame(array $settings, string $side):string { |
| 114 |
if ((!isset($settings["{$side}-frame_type"]) || $settings["{$side}-frame_type"] === $side . '-presets') && !empty($settings["{$side}-frame_layout"])) { |
| 115 |
return $settings["{$side}-frame_layout"] !== 'none' ? 'presets' : ''; |
| 116 |
} |
| 117 |
if (isset($settings["{$side}-frame_type"]) && $settings["{$side}-frame_type"] === $side . '-custom' && !empty($settings["{$side}-frame_custom"])) { |
| 118 |
return 'custom'; |
| 119 |
} |
| 120 |
return ''; |
| 121 |
} |
| 122 |
|
| 123 |
private static function show_frame(array $styles, $printed = array()) { |
| 124 |
$breakpoints = array('desktop' => '') + themify_get_breakpoints(); |
| 125 |
$sides = array('top', 'bottom', 'left', 'right'); |
| 126 |
$output = ''; |
| 127 |
foreach ($sides as $side) { |
| 128 |
if (!isset($printed[$side])) { |
| 129 |
foreach ($breakpoints as $bp => $v) { |
| 130 |
$settings = 'desktop' === $bp ? $styles : (!empty($styles['breakpoint_' . $bp]) ? $styles['breakpoint_' . $bp] : array() ); |
| 131 |
if (!empty($settings) && self::get_frame($settings, $side)) { |
| 132 |
$printed[$side] = true; |
| 133 |
$frame_location = ( isset($settings["{$side}-frame_location"]) && $settings["{$side}-frame_location"] === 'in_front' ) ? $settings["{$side}-frame_location"] : ''; |
| 134 |
$cl = $side === 'left' || $side === 'right' ? 'tf_h' : 'tf_w'; |
| 135 |
$output .= '<span class="tb_row_frame tb_row_frame_' . $side . ' ' . $frame_location . ' tf_abs tf_hide tf_overflow ' . $cl . '"></span>'; |
| 136 |
break; |
| 137 |
} |
| 138 |
} |
| 139 |
} |
| 140 |
} |
| 141 |
if (!empty($output)) { |
| 142 |
Themify_Builder_Model::loadCssModules('fr', THEMIFY_BUILDER_CSS_MODULES . 'frames.css', THEMIFY_VERSION); |
| 143 |
echo '<span class="tb_row_frame_wrap tf_overflow tf_abs" data-lazy="1">', $output, '</span>'; |
| 144 |
} |
| 145 |
return $printed; |
| 146 |
} |
| 147 |
|
| 148 |
public static function background_styling(array $row, string $type, $builder_id) { |
| 149 |
// Background cover color |
| 150 |
if (!empty($row['styling'])) { |
| 151 |
$hasOverlay = false; |
| 152 |
$selector = '.themify_builder_content-' . $builder_id . ' .tb_' . $row['element_id'] . ' > .builder_row_cover::before'; |
| 153 |
if ( ! self::do_color_overlay( $row['styling'], $selector ) ) { |
| 154 |
$breakpoints = themify_get_breakpoints(); |
| 155 |
foreach ($breakpoints as $bp => $v) { |
| 156 |
if (!empty($row['styling']['breakpoint_' . $bp]) && self::do_color_overlay($row['styling']['breakpoint_' . $bp])) { |
| 157 |
$hasOverlay = true; |
| 158 |
break; |
| 159 |
} |
| 160 |
} |
| 161 |
} else { |
| 162 |
$hasOverlay = true; |
| 163 |
} |
| 164 |
// Background Slider |
| 165 |
self::do_slider_background($row, $type); |
| 166 |
$frames = array(); |
| 167 |
$framesCount = 0; |
| 168 |
if (!empty($row['styling']['global_styles'])) { |
| 169 |
$used_gs = Themify_Global_Styles::get_used_gs($builder_id); |
| 170 |
if (!empty($used_gs)) { |
| 171 |
$global_styles = explode(' ', $row['styling']['global_styles']); |
| 172 |
if ($hasOverlay === false) { |
| 173 |
$breakpoints = array('desktop' => '') + themify_get_breakpoints(); |
| 174 |
} |
| 175 |
foreach ($global_styles as $cl) { |
| 176 |
if (isset($used_gs[$cl])) { |
| 177 |
if ($hasOverlay === false) { |
| 178 |
foreach ($breakpoints as $bp => $v) { |
| 179 |
|
| 180 |
if (($bp === 'desktop' && self::do_color_overlay($used_gs[$cl])) || ($bp !== 'desktop' && !empty($used_gs[$cl]['breakpoint_' . $bp]) && self::do_color_overlay($used_gs[$cl]['breakpoint_' . $bp]))) { |
| 181 |
$hasOverlay = true; |
| 182 |
break; |
| 183 |
} |
| 184 |
} |
| 185 |
} |
| 186 |
if ($framesCount !== 4) { |
| 187 |
$frames = self::show_frame($used_gs[$cl], $frames); |
| 188 |
$framesCount = count($frames); |
| 189 |
} |
| 190 |
} |
| 191 |
if ($hasOverlay === true && $framesCount === 4) { |
| 192 |
break; |
| 193 |
} |
| 194 |
} |
| 195 |
} |
| 196 |
} |
| 197 |
if ($framesCount !== 4) { |
| 198 |
self::show_frame($row['styling'], $frames); |
| 199 |
} |
| 200 |
if ($hasOverlay === true) { |
| 201 |
Themify_Builder_Model::loadCssModules('cover', THEMIFY_BUILDER_CSS_MODULES . 'cover.css', THEMIFY_VERSION); |
| 202 |
} |
| 203 |
} |
| 204 |
} |
| 205 |
|
| 206 |
public static function clickable_component(array &$attr, array $settings) { |
| 207 |
if (!empty($settings['_link'])) { |
| 208 |
$classes = []; |
| 209 |
$attr['data-tb_link'] = esc_url($settings['_link']); |
| 210 |
if ( isset( $settings['_link_n'] ) ) { |
| 211 |
if ( $settings['_link_n'] === 'yes' ) { |
| 212 |
$attr['data-tb_link_new'] = '1'; |
| 213 |
} else if ( $settings['_link_n'] === 'lb' ) { |
| 214 |
$attr['data-tb_link'] = add_query_arg( 'post_in_lightbox', 1, $attr['data-tb_link'] ); |
| 215 |
$attr['data-tb_lb'] = 1; |
| 216 |
$settings = $settings + [ |
| 217 |
'_link_lw' => '', |
| 218 |
'_link_lh' => '', |
| 219 |
'_link_lw_unit' => 'px', |
| 220 |
'_link_lh_unit' => 'px' |
| 221 |
]; |
| 222 |
if ( $settings['_link_lw'] !== '' || $settings['_link_lh'] !== '' ) { |
| 223 |
$attr['data-zoom-config'] = esc_attr( |
| 224 |
themify_sanitize_css_size( $settings['_link_lw'], $settings['_link_lw_unit'] ) |
| 225 |
. '|' |
| 226 |
. themify_sanitize_css_size( $settings['_link_lh'], $settings['_link_lh_unit'] ) |
| 227 |
); |
| 228 |
} |
| 229 |
} |
| 230 |
} |
| 231 |
if ( ! isset( $settings['_link_o'] ) || $settings['_link_o'] === 'no' ) { |
| 232 |
$classes[] = 'tb_link_outline'; |
| 233 |
} |
| 234 |
if ( ! empty( $classes ) ) { |
| 235 |
if ( ! isset( $attr['class'] ) ) { |
| 236 |
$attr['class'] = ''; |
| 237 |
} |
| 238 |
$attr['class'] .= ' ' . implode( ' ', $classes ); |
| 239 |
} |
| 240 |
themify_enque_style('tf_clickablecomponent', THEMIFY_BUILDER_CSS_MODULES . 'clickable-component.css', null, THEMIFY_VERSION); |
| 241 |
} |
| 242 |
} |
| 243 |
|
| 244 |
public static function set_bg_mode(array &$attr, array $styling) { |
| 245 |
$breakpoints = array('desktop' => '') + themify_get_breakpoints(); |
| 246 |
foreach ($breakpoints as $bp => $v) { |
| 247 |
$bg = ''; |
| 248 |
if ($bp === 'desktop') { |
| 249 |
if (isset($styling['background_repeat'])) { |
| 250 |
$bg = $styling['background_repeat']; |
| 251 |
} |
| 252 |
} elseif (isset($styling['breakpoint_' . $bp]['background_repeat'])) { |
| 253 |
$bg = $styling['breakpoint_' . $bp]['background_repeat']; |
| 254 |
} |
| 255 |
if ($bg === 'builder-parallax-scrolling' || $bg === 'builder-zoom-scrolling' || $bg === 'builder-zooming') { |
| 256 |
$bg = explode('-', $bg); |
| 257 |
$attr['data-' . $bg[1] . '-bg'] = $bp; |
| 258 |
} |
| 259 |
} |
| 260 |
return $attr; |
| 261 |
} |
| 262 |
|
| 263 |
public static function get_responsive_cols(array $row) { |
| 264 |
$cl = array(); |
| 265 |
$isFullpage = function_exists('themify_theme_is_fullpage_scroll') && themify_theme_is_fullpage_scroll(); |
| 266 |
if (!empty($row['sizes'])) { |
| 267 |
$_arr = array('align', 'gutter', 'auto_h', 'dir'); |
| 268 |
foreach ($_arr as $k) { |
| 269 |
if (!empty($row['sizes']['desktop_' . $k])) { |
| 270 |
$v = $row['sizes']['desktop_' . $k]; |
| 271 |
if ($k === 'align') { |
| 272 |
if ($v === 'center') { |
| 273 |
$v = 'col_align_middle'; |
| 274 |
} elseif ($v === 'end') { |
| 275 |
$v = 'col_align_bottom'; |
| 276 |
} else { |
| 277 |
$v = 'col_align_top'; |
| 278 |
} |
| 279 |
} elseif ($k === 'gutter') { |
| 280 |
$v = $v === 'narrow' || $v === 'none' ? 'gutter-' . $v : ''; |
| 281 |
} elseif ($k === 'auto_h') { |
| 282 |
$v = $v == '1' ? 'col_auto_height' : ''; |
| 283 |
} elseif ($k === 'dir') { |
| 284 |
$v = $v === 'rtl' ? 'direction_rtl' : ''; |
| 285 |
} |
| 286 |
if ($v !== '') { |
| 287 |
$cl[] = $v; |
| 288 |
} |
| 289 |
} elseif ($k === 'align') { |
| 290 |
$cl[] = $isFullpage === true ? 'col_align_middle' : 'col_align_top'; |
| 291 |
} |
| 292 |
} |
| 293 |
} else { |
| 294 |
if (!empty($row['column_h'])) { |
| 295 |
$cl[] = 'col_auto_height'; |
| 296 |
} |
| 297 |
if (!empty($row['gutter']) && $row['gutter'] !== 'gutter-default') { |
| 298 |
$cl[] = $row['gutter']; |
| 299 |
} |
| 300 |
if (isset($row['desktop_dir']) && $row['desktop_dir'] === 'rtl') { |
| 301 |
$cl[] = 'direction_rtl'; |
| 302 |
} |
| 303 |
$cl[] = !empty($row['column_alignment']) ? $row['column_alignment'] : ($isFullpage === true ? 'col_align_middle' : 'col_align_top'); |
| 304 |
} |
| 305 |
|
| 306 |
$cl[] = 'tb_col_count_' . count($row['cols']); |
| 307 |
|
| 308 |
return $cl; |
| 309 |
} |
| 310 |
|
| 311 |
/** |
| 312 |
* Computes and returns the HTML for a background slider. |
| 313 |
* |
| 314 |
* @since 2.3.3 |
| 315 |
* |
| 316 |
* @param array $row_or_col Row or column definition. |
| 317 |
* @param string $order Order of row/column (e.g. 0 or 0-1-0-1 for sub columns) |
| 318 |
* @param string $type Accepts 'row', 'col', 'sub-col' |
| 319 |
* |
| 320 |
* @return bool Returns false if $row_or_col doesn't have a bg slider. Otherwise outputs the HTML for the slider. |
| 321 |
*/ |
| 322 |
public static function do_slider_background(array $row_or_col, $type = 'row'):bool { |
| 323 |
if (!isset($row_or_col['styling']['background_type']) || 'slider' !== $row_or_col['styling']['background_type'] || empty($row_or_col['styling']['background_slider'])) { |
| 324 |
return false; |
| 325 |
} |
| 326 |
$images = themify_get_gallery_shortcode($row_or_col['styling']['background_slider']); |
| 327 |
if (!empty($images)) : |
| 328 |
|
| 329 |
$size = isset($row_or_col['styling']['background_slider_size']) ? $row_or_col['styling']['background_slider_size'] : false; |
| 330 |
if (!$size) { |
| 331 |
$size = themify_get_gallery_shortcode_params($row_or_col['styling']['background_slider'], 'size'); |
| 332 |
if (!$size) { |
| 333 |
$size = 'large'; |
| 334 |
} |
| 335 |
} |
| 336 |
$bgmode = !empty($row_or_col['styling']['background_slider_mode']) ? $row_or_col['styling']['background_slider_mode'] : 'fullcover'; |
| 337 |
$slider_speed = !empty($row_or_col['styling']['background_slider_speed']) ? $row_or_col['styling']['background_slider_speed'] : '2000'; |
| 338 |
?> |
| 339 |
<span class="tf_hide <?php echo $type; ?>-slider tb_slider tf_abs" data-bgmode="<?php echo $bgmode; ?>" data-sliderspeed="<?php echo $slider_speed ?>"> |
| 340 |
<span class="tf_abs row-slider-slides tf_w tf_hidden tf_clearfix"> |
| 341 |
<?php |
| 342 |
foreach ($images as $i => $img) { |
| 343 |
$img_data = wp_get_attachment_image_src($img->ID, $size); |
| 344 |
if (empty($img_data)) { |
| 345 |
continue; |
| 346 |
} |
| 347 |
$alt = get_post_meta($img->ID, '_wp_attachment_image_alt', TRUE); |
| 348 |
?> |
| 349 |
<span data-bg="<?php echo esc_url(themify_https_esc($img_data[0])); ?>"<?php if (!empty($alt)): ?> data-bg-alt="<?php esc_attr_e($alt); ?>"<?php endif; ?>> |
| 350 |
<a href="javascript:;" rel="nofollow" class="row-slider-dot" data-index="<?php echo $i; ?>"><span class="screen-reader-text">•</span></a> |
| 351 |
</span> |
| 352 |
<?php |
| 353 |
} |
| 354 |
?> |
| 355 |
</span> |
| 356 |
<span class="row-slider-nav tf_abs_t tf_w"> |
| 357 |
<a href="javascript:;" rel="nofollow" class="row-slider-arrow row-slider-prev tf_hidden tf_abs_t"><span class="screen-reader-text">←</span></a> |
| 358 |
<a href="javascript:;" rel="nofollow" class="row-slider-arrow row-slider-next tf_hidden tf_abs_t"><span class="screen-reader-text">→</span></a> |
| 359 |
</span> |
| 360 |
</span> |
| 361 |
<?php |
| 362 |
return true; |
| 363 |
endif; // images |
| 364 |
return false; |
| 365 |
} |
| 366 |
|
| 367 |
/** |
| 368 |
* Get template row |
| 369 |
* |
| 370 |
* @param array $row |
| 371 |
* @param string $builder_id |
| 372 |
* @param bool $echo |
| 373 |
* |
| 374 |
* @return string |
| 375 |
*/ |
| 376 |
public static function template(&$row, $builder_id, $echo = true, $tmp = -1) {//4 argument isn't used need for backward to avoid fatal error |
| 377 |
if ($tmp === true || $tmp === false) {//map old data arguments |
| 378 |
$row = $builder_id; |
| 379 |
$builder_id = $echo; |
| 380 |
$echo = $tmp; |
| 381 |
} |
| 382 |
$row = apply_filters('tf_builder_row', $row, $builder_id); |
| 383 |
// prevent empty rows from being rendered |
| 384 |
if (Themify_Builder::$frontedit_active === false || Themify_Builder::$is_loop === true) { |
| 385 |
$count = isset($row['cols']) ? count($row['cols']) : 0; |
| 386 |
if (($count === 0 && !isset($row['styling']) ) || ($count === 1 && empty($row['cols'][0]['modules']) && empty($row['cols'][0]['styling']) && empty($row['styling']) ) // there's only one column and it's empty |
| 387 |
) { |
| 388 |
return ''; |
| 389 |
} |
| 390 |
/* allow addons to control the display of the rows */ |
| 391 |
$display = apply_filters('themify_builder_row_display', true, $row, $builder_id); |
| 392 |
if (false === $display || (isset($row['styling']['visibility_all']) && $row['styling']['visibility_all'] === 'hide_all' )) { |
| 393 |
return ''; |
| 394 |
} |
| 395 |
} else { |
| 396 |
$count = 0; |
| 397 |
} |
| 398 |
$row_classes = array('module_row themify_builder_row'); |
| 399 |
$row_attributes = array(); |
| 400 |
$is_styling = !empty($row['styling']); |
| 401 |
$video_data = ''; |
| 402 |
if ($is_styling === true) { |
| 403 |
if (!isset($row['styling']['background_type']) && !empty($row['styling']['background_video'])) { |
| 404 |
$row['styling']['background_type'] = 'video'; |
| 405 |
} elseif ((!isset($row['styling']['background_type']) || $row['styling']['background_type'] === 'image' ) && isset($row['styling']['background_zoom']) && $row['styling']['background_zoom'] === 'zoom' && $row['styling']['background_repeat'] === 'repeat-none') { |
| 406 |
$row_classes[] = 'themify-bg-zoom'; |
| 407 |
} |
| 408 |
$class_fields = array('custom_css_row', 'row_height'); |
| 409 |
foreach ($class_fields as $field) { |
| 410 |
if (!empty($row['styling'][$field])) { |
| 411 |
$row_classes[] = themify_sanitize_css_classes( $row['styling'][$field] ); |
| 412 |
} |
| 413 |
} |
| 414 |
unset($class_fields); |
| 415 |
/** |
| 416 |
* Row Width class |
| 417 |
* To provide backward compatibility, the CSS classname and the option label do not match. See #5284 |
| 418 |
*/ |
| 419 |
if (isset($row['styling']['row_width'])) { |
| 420 |
if ('fullwidth' === $row['styling']['row_width']) { |
| 421 |
$row_classes[] = 'fullwidth_row_container'; |
| 422 |
} elseif ('fullwidth-content' === $row['styling']['row_width']) { |
| 423 |
$row_classes[] = 'fullwidth'; |
| 424 |
} |
| 425 |
$breakpoints = themify_get_breakpoints('', true); |
| 426 |
$breakpoints['desktop'] = 1; |
| 427 |
$prop = 'fullwidth' === $row['styling']['row_width'] ? 'padding' : 'margin'; |
| 428 |
foreach ($breakpoints as $k => $v) { |
| 429 |
$styles = $k === 'desktop' ? $row['styling'] : (!empty($row['styling']['breakpoint_' . $k]) ? $row['styling']['breakpoint_' . $k] : false); |
| 430 |
if ($styles) { |
| 431 |
$val = self::getDataValue($styles, $prop); |
| 432 |
if ($val) { |
| 433 |
$row_attributes['data-' . $k . '-' . $prop] = $val; |
| 434 |
} |
| 435 |
} |
| 436 |
} |
| 437 |
$breakpoints = null; |
| 438 |
} |
| 439 |
// background video |
| 440 |
$video_data = self::get_video_background($row['styling']); |
| 441 |
if ($video_data) { |
| 442 |
$video_data = ' ' . $video_data; |
| 443 |
} else { |
| 444 |
self::set_bg_mode($row_attributes, $row['styling']); |
| 445 |
} |
| 446 |
// Class for Scroll Highlight |
| 447 |
if (!empty($row['styling']['row_anchor']) && $row['styling']['row_anchor'] !== '#') { |
| 448 |
$anchor = preg_replace( '/[^a-zA-Z0-9_-]/', '', $row['styling']['row_anchor'] ); |
| 449 |
if ( $anchor !== '' ) { |
| 450 |
$row_classes[] = 'tb_has_section'; |
| 451 |
$row_classes[] = 'tb_section-' . $anchor; |
| 452 |
$row_attributes['data-anchor'] = $anchor; |
| 453 |
} |
| 454 |
} |
| 455 |
// Disable change hashtag in URL |
| 456 |
if (!empty($row['styling']['hide_anchor'])) { |
| 457 |
$row_attributes['data-hide-anchor'] = $row['styling']['hide_anchor']; |
| 458 |
} |
| 459 |
if (!empty($row['styling']['global_styles'])) { |
| 460 |
Themify_Global_Styles::add_class_to_components($row_classes, $row['styling'], $builder_id); |
| 461 |
} |
| 462 |
} else { |
| 463 |
$row['styling'] = array(); |
| 464 |
} |
| 465 |
if ($echo === false) { |
| 466 |
$output = PHP_EOL; // add line break |
| 467 |
ob_start(); |
| 468 |
} |
| 469 |
if (Themify_Builder::$frontedit_active === false) { |
| 470 |
$row_content_classes = $count > 0 ? self::get_responsive_cols($row) : array(); |
| 471 |
$row_content_classes = implode(' ', $row_content_classes); |
| 472 |
if (isset($row['styling']['row_width']) && ('fullwidth' === $row['styling']['row_width'] || 'fullwidth-content' === $row['styling']['row_width'])) { |
| 473 |
$row_attributes['data-css_id'] = $row['element_id']; |
| 474 |
} |
| 475 |
$row_classes[] = 'tb_' . $row['element_id']; |
| 476 |
if ($is_styling === true) { |
| 477 |
Themify_Builder_Component_Module::sticky_element_props($row_attributes, $row['styling']); |
| 478 |
} |
| 479 |
$row_attributes['data-lazy'] = 1; |
| 480 |
if (self::$isFirstRow === false) { |
| 481 |
self::$isFirstRow = true; |
| 482 |
$row_classes[] = 'tb_first'; //need for lazy loadd, load first row bg image |
| 483 |
} else { |
| 484 |
self::$isFirstRow = null; |
| 485 |
} |
| 486 |
} |
| 487 |
do_action('themify_builder_row_start', $builder_id, $row, ''); |
| 488 |
$row_classes[] = 'tf_w'; |
| 489 |
$row_attributes['class'] = implode(' ', apply_filters('themify_builder_row_classes', $row_classes, $row, $builder_id)); |
| 490 |
$row_classes = null; |
| 491 |
self::clickable_component($row_attributes, $row['styling']); |
| 492 |
$row_attributes = self::get_reveal_effect( $row['styling'], $row_attributes, 'row_reveal' ); |
| 493 |
$row_attributes = apply_filters('themify_builder_row_attributes', Themify_Builder_Component_Module::parse_animation_effect($row['styling'], $row_attributes), $row['styling'], $builder_id); |
| 494 |
?> |
| 495 |
<?php if (strpos($row_attributes['class'], 'tb-page-break') !== false): ?> |
| 496 |
<!-- tb_page_break --> |
| 497 |
<?php endif; ?> |
| 498 |
<div <?php echo themify_get_element_attributes($row_attributes), $video_data; ?>> |
| 499 |
<?php |
| 500 |
$row_attributes = $video_data = null; |
| 501 |
if ($is_styling === true) { |
| 502 |
do_action('themify_builder_background_styling', $builder_id, $row, 'row', ''); |
| 503 |
self::background_styling($row, 'row', $builder_id); |
| 504 |
} |
| 505 |
?> |
| 506 |
<div class="row_inner<?php if (Themify_Builder::$frontedit_active === false): ?> <?php echo $row_content_classes ?><?php endif; ?> tf_box tf_rel"> |
| 507 |
<?php |
| 508 |
unset($row_content_classes); |
| 509 |
if ($count > 0) { |
| 510 |
if (isset($row['desktop_dir']) && $row['desktop_dir'] === 'rtl') {//backward compatibility |
| 511 |
$row['cols'] = array_reverse($row['cols']); |
| 512 |
} |
| 513 |
foreach ($row['cols'] as $i => &$col) { |
| 514 |
$cl = $i === 0 ? 'first' : ($i === ($count - 1) ? 'last' : null); //backward compatibility |
| 515 |
Themify_Builder_Component_Column::template($col, $builder_id, true, false, $cl); |
| 516 |
} |
| 517 |
unset($col); |
| 518 |
} |
| 519 |
?> |
| 520 |
</div> |
| 521 |
</div> |
| 522 |
<?php |
| 523 |
do_action('themify_builder_row_end', $builder_id, $row, ''); |
| 524 |
if ($echo === false) { |
| 525 |
return PHP_EOL . ob_get_clean() . PHP_EOL; |
| 526 |
} |
| 527 |
} |
| 528 |
|
| 529 |
private static function getDataValue(array $styles,string $type = 'padding'):string { |
| 530 |
$value = ''; |
| 531 |
if (!empty($styles['checkbox_' . $type . '_apply_all']) && !empty($styles[$type . '_top'])) { |
| 532 |
$value = $styles[$type . '_top']; |
| 533 |
$value .= isset($styles[$type . '_top_unit']) ? $styles[$type . '_top_unit'] : 'px'; |
| 534 |
$value = $value . ',' . $value; |
| 535 |
} elseif (!empty($styles[$type . '_left']) || !empty($styles[$type . '_right'])) { |
| 536 |
if (!empty($styles[$type . '_left'])) { |
| 537 |
$value = $styles[$type . '_left']; |
| 538 |
$value .= isset($styles[$type . '_left_unit']) ? $styles[$type . '_left_unit'] : 'px'; |
| 539 |
} |
| 540 |
if (!empty($styles[$type . '_right'])) { |
| 541 |
$value .= ',' . $styles[$type . '_right']; |
| 542 |
$value .= isset($styles[$type . '_right_unit']) ? $styles[$type . '_right_unit'] : 'px'; |
| 543 |
} |
| 544 |
} |
| 545 |
return $value; |
| 546 |
} |
| 547 |
} |
| 548 |
|