dividers = apply_filters( 'et_section_dividers', array(
'arrow-bottom' => '',
'arrow-top' => '',
'arrow2-bottom' => '',
'arrow2-top' => '',
'arrow3-bottom' => '',
'arrow3-top' => '',
'asymmetric-bottom' => '',
'asymmetric-top' => '',
'asymmetric2-bottom' => '',
'asymmetric2-top' => '',
'asymmetric3-bottom' => '',
'asymmetric3-top' => '',
'asymmetric4-bottom' => '',
'asymmetric4-top' => '',
'clouds-bottom' => '',
'clouds-bottom2' => '',
'clouds-top' => '',
'clouds-top2' => '',
'clouds2-bottom' => '',
'clouds2-bottom2' => '',
'clouds2-top' => '',
'clouds2-top2' => '',
'curve-bottom' => '',
'curve-top' => '',
'curve2-bottom' => '',
'curve2-top' => '',
'graph-bottom' => '',
'graph-top' => '',
'graph2-bottom' => '',
'graph2-top' => '',
'graph3-bottom' => '',
'graph3-top' => '',
'graph4-bottom' => '',
'graph4-top' => '',
'mountains-bottom' => '',
'mountains-top' => '',
'mountains2-bottom' => '',
'mountains2-top' => '',
'ramp-bottom' => '',
'ramp-top' => '',
'ramp2-bottom' => '',
'ramp2-top' => '',
'slant-bottom' => '',
'slant-top' => '',
'slant2-bottom' => '',
'slant2-top' => '',
'triangle-bottom' => '',
'triangle-bottom2' => '',
'triangle-top' => '',
'triangle-top2' => '',
'wave-bottom' => '',
'wave-top' => '',
'wave2-bottom' => '',
'wave2-top' => '',
'waves-bottom' => '',
'waves-top' => '',
'waves2-bottom' => '',
'waves2-top' => '',
) );
if ( null === self::$data_utils ) {
self::$data_utils = ET_Core_Data_Utils::instance();
}
}
/**
* Retrieves fields for divider settings.
* @param array $args Associative array for settings.
* @return array Option settings.
*/
public function get_fields( array $args = array() ) {
// Create an array so we don't get an error.
$additional_options = array();
// Create the options by first creating the structure.
$structure = array();
foreach ( array( 'top', 'bottom' ) as $placement ) :
$structure[ "{$placement}_divider" ] = array(
'controls' => array(
"{$placement}_divider_style" => array(
'label' => esc_html__( 'Divider Style', 'et_builder' ),
'type' => 'divider',
'options' => array(
'none' => esc_html__( 'None', 'et_builder' ),
'slant' => esc_html__( 'Slant', 'et_builder' ),
'slant2' => esc_html__( 'Slant 2', 'et_builder' ),
'arrow' => esc_html__( 'Arrow', 'et_builder' ),
'arrow2' => esc_html__( 'Arrow 2', 'et_builder' ),
'arrow3' => esc_html__( 'Arrow 3', 'et_builder' ),
'ramp' => esc_html__( 'Ramp', 'et_builder' ),
'ramp2' => esc_html__( 'Ramp 2', 'et_builder' ),
'curve' => esc_html__( 'Curve', 'et_builder' ),
'curve2' => esc_html__( 'Curve 2', 'et_builder' ),
'mountains' => esc_html__( 'Mountains', 'et_builder' ),
'mountains2' => esc_html__( 'Mountains 2', 'et_builder' ),
'wave' => esc_html__( 'Wave', 'et_builder' ),
'wave2' => esc_html__( 'Wave 2', 'et_builder' ),
'waves' => esc_html__( 'Waves', 'et_builder' ),
'waves2' => esc_html__( 'Waves 2', 'et_builder' ),
'asymmetric' => esc_html__( 'Assymetric', 'et_builder' ),
'asymmetric2' => esc_html__( 'Assymetric 2', 'et_builder' ),
'asymmetric3' => esc_html__( 'Assymetric 3', 'et_builder' ),
'asymmetric4' => esc_html__( 'Assymetric 4', 'et_builder' ),
'graph' => esc_html__( 'Graph', 'et_builder' ),
'graph2' => esc_html__( 'Graph 2', 'et_builder' ),
'graph3' => esc_html__( 'Graph 3', 'et_builder' ),
'graph4' => esc_html__( 'Graph 4', 'et_builder' ),
'triangle' => esc_html__( 'Triangle', 'et_builder' ),
'clouds' => esc_html__( 'Clouds', 'et_builder' ),
'clouds2' => esc_html__( 'Clouds 2', 'et_builder' ),
),
'default' => 'none',
'flip' => '',
),
"{$placement}_divider_color" => array(
'label' => esc_html__( 'Divider Color', 'et_builder' ),
'type' => 'color-alpha',
'default' => '',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
),
"{$placement}_divider_height" => array(
'label' => esc_html__( 'Divider Height', 'et_builder' ),
'type' => 'range',
'range_settings' => array(
'min' => 0,
'max' => 500,
'step' => 1,
),
'default' => '100px',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
'mobile_options' => true,
),
"{$placement}_divider_repeat" => array(
'label' => esc_html__( 'Divider Horizontal Repeat', 'et_builder' ),
'type' => 'range',
'range_settings' => array(
'min' => 1,
'max' => 20,
'step' => 1,
),
'default' => '1x',
'fixed_unit' => 'x',
'show_if_not' => array(
"{$placement}_divider_style" => array( 'none', 'clouds', 'clouds2', 'triangle' ),
),
'mobile_options' => true,
),
"{$placement}_divider_flip" => array(
'label' => esc_html__( 'Divider Flip', 'et_builder' ),
'type' => 'multiple_buttons',
'options' => array(
'horizontal' => array(
'title' => esc_html__( 'Horizontal', 'et_builder' ),
'icon' => 'flip-horizontally',
),
'vertical' => array(
'title' => esc_html__( 'Vertical', 'et_builder' ),
'icon' => 'flip-vertically',
),
),
'toggleable' => true,
'multi_selection' => true,
'default' => '',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
),
"{$placement}_divider_arrangement" => array(
'label' => esc_html__( 'Divider Arrangement', 'et_builder' ),
'type' => 'select',
'options' => array(
'above_content' => esc_html__( 'On Top Of Section Content', 'et_builder' ),
'below_content' => esc_html__( 'Underneath Section Content', 'et_builder' ),
),
'default' => 'below_content',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
'fullwidth' => 'on',
),
),
),
);
// Automatically append responsive field
foreach ( $structure[ "{$placement}_divider" ]['controls'] as $field_name => $field ) {
if ( isset( $field['mobile_options'] ) && $field['mobile_options'] ) {
$responsive_field_default = isset( $field['default'] ) ? $field['default'] : '';
// Tablet field
$structure["{$placement}_divider"]['controls']["{$field_name}_tablet"] = array(
'type' => 'hidden',
'default' => $responsive_field_default,
);
// Phone field
$structure["{$placement}_divider"]['controls']["{$field_name}_phone"] = array(
'type' => 'hidden',
'default' => $responsive_field_default,
);
// Last edited field
$structure["{$placement}_divider"]['controls']["{$field_name}_last_edited"] = array(
'type' => 'hidden',
'default' => 'off|desktop',
);
}
}
endforeach; // End foreach().
// Set our labels.
$structure['bottom_divider']['label'] = esc_html__( 'Bottom', 'et_builder' );
$structure['top_divider']['label'] = esc_html__( 'Top', 'et_builder' );
$additional_options['divider_settings'] = array(
'label' => esc_html__( 'Dividers', 'et_builder' ),
'tab_slug' => $args['tab_slug'],
'toggle_slug' => $args['toggle_slug'],
'attr_suffix' => '',
'type' => 'composite',
'composite_type' => 'default',
'composite_structure' => $structure,
'renderer' => array(
'class' => 'ET_Builder_Module_Field_Template_Tabbed', // use default rendering.
),
);
return $additional_options;
}
/**
* Process Section Divider
*
* Adds a CSS class to the section, determines orientaion of the SVG, encodes an SVG to use as data
* for the background-image property.
* @param string $placement Whether it is the top or bottom divider.
* @param array $atts Associative array of shortcode and their
* respective values.
* @param string $breakpoint ''|tablet|phone
*/
public function process_svg( $placement, $atts, $breakpoint = '' ) {
// add a class to the section.
$this->classes[] = sprintf( 'et_pb_%s_divider', esc_attr( $placement ) );
// set some defaults.
$previous_section = ! empty( $atts['prev_background_color'] ) ? $atts['prev_background_color'] : '#ffffff';
$next_section = ! empty( $atts['next_background_color'] ) ? $atts['next_background_color'] : '#ffffff';
// set a default based on whether it is the top or bottom divider.
$default_color = ( 'top' === $placement ) ? $previous_section : $next_section;
$color = ! empty( $atts[ "{$placement}_divider_color" ] ) ? $atts[ "{$placement}_divider_color" ] : $default_color;
$height = ! empty( $atts[ "{$placement}_divider_height" ] ) ? $atts[ "{$placement}_divider_height" ] : '100px';
$repeat = ! empty( $atts[ "{$placement}_divider_repeat" ] ) ? floatval( $atts[ "{$placement}_divider_repeat" ] ) : 1;
$flip = ( '' !== $atts[ "{$placement}_divider_flip" ] ) ? explode( '|', $atts[ "{$placement}_divider_flip" ] ) : array();
$arrangement = ! empty( $atts[ "{$placement}_divider_arrangement" ] ) ? $atts[ "{$placement}_divider_arrangement" ] : 'below_content';
$style = $atts[ "{$placement}_divider_style" ] . "-{$placement}";
$fullwidth = $atts['fullwidth'];
// Apply adjustment for responsive styling
if ( '' !== $breakpoint ) {
// Check if responsive height is actually active
$is_responsive_height_active = et_pb_get_responsive_status( self::$data_utils->array_get( $atts, "{$placement}_divider_height_last_edited", '' ) );
// adjust height for responsive styling
$responsive_height = self::$data_utils->array_get( $atts, "{$placement}_divider_height_${breakpoint}", false );
if ( $is_responsive_height_active && $responsive_height && '' !== $responsive_height ) {
$height = $responsive_height;
}
// Check if responsive repeat is actually active
$is_responsive_repeat_active = et_pb_get_responsive_status( self::$data_utils->array_get( $atts, "{$placement}_divider_repeat_last_edited", '' ) );
// adjust repeat for responsive styling
$responsive_repeat = self::$data_utils->array_get( $atts, "{$placement}_divider_repeat_${breakpoint}", false );
if ( $is_responsive_repeat_active && $responsive_repeat && '' !== $responsive_repeat ) {
$repeat = $responsive_repeat;
}
}
// Make sure that we don't divide by zero.
if ( ! $repeat ) {
$repeat = 1;
}
// let's make sure we flip the fight ones, yeah?
// use the opposite SVG
if ( in_array( 'vertical', $flip ) ) {
switch ( $placement ) {
case 'top':
$style = $atts[ "{$placement}_divider_style" ] . '-bottom';
break;
case 'bottom':
$style = $atts[ "{$placement}_divider_style" ] . '-top';
break;
}
}
// The SVG markup for the background.
switch ( $style ) {
case 'clouds-top':
case 'clouds2-top':
// we can use the viewBox to move down the image since it has a height of 86px
$svg_markup = '';
break;
case 'clouds-bottom':
case 'clouds2-bottom':
// we can use the viewBox to move up the image since it has a height of 86px
$svg_markup = '';
break;
case 'triangle-top':
$svg_markup = '';
break;
case 'triangle-bottom':
$svg_markup = '';
break;
default:
$svg_markup = '';
break;
}
$svg = sprintf( $svg_markup, $height, $color, $this->dividers[ $style ] );
// encode the SVG so we can use it as data for background-image.
$this->svg = base64_encode( $svg ); // phpcs:ignore
// Build up our declaration.
// bg-image
$declaration['background-image'] = sprintf( 'url( data:image/svg+xml;base64,%s )', $this->svg );
// bg-size. the percent is how many times to repeat the image.
if ( 0 === strpos( $style, 'clouds' ) ) {
$declaration['background-size'] = 'cover';
switch ( $placement ) {
case 'top':
$declaration['background-position'] = ( 'top' === $placement || 'vertical' === $flip ) ? 'center top' : 'center bottom';
break;
case 'bottom':
$declaration['background-position'] = ( 'top' === $placement || 'vertical' !== $flip ) ? 'center top' : 'center bottom';
break;
}
} else if ( 0 === strpos( $style, 'triangle' ) ) {
$declaration['background-size'] = 'cover';
$declaration['background-position-x'] = 'center';
} else {
// Adjusts for when percentages are being used.
if ( 0 < strpos( $height, '%' ) ) {
$declaration['background-size'] = sprintf( '%1$s%% 100%%', floatval( 100 / $repeat ) );
} else {
$declaration['background-size'] = sprintf( '%1$s%% %2$s', floatval( 100 / $repeat ), $height );
}
}
// position
$declaration[ $placement ] = 0;
// height
$declaration['height'] = $height;
// z-index - determined by arrangement.
$declaration['z-index'] = ( 'on' === $fullwidth || 'above_content' === $arrangement ) ? 10 : 1;
$flip_styles = array();
// flipping the svg x|y
if ( in_array( 'horizontal', $flip ) ) {
$flip_styles[] = 'rotateY(180deg)';
}
if ( in_array( 'vertical', $flip ) ) {
$flip_styles[] = 'rotateX(180deg)';
}
if ( ! empty( $flip_styles ) ) {
$declaration['transform'] = implode( ' ', $flip_styles );
}
// finally create our CSS declaration.
$css = '';
foreach ( $declaration as $rule => $value ) {
$css .= esc_html( "{$rule}:{$value};" );
}
// prepare our selector.
$selector = sprintf( '%%order_class%%.section_has_divider.et_pb_%1$s_divider .et_pb_%1$s_inside_divider', esc_attr( $placement ) );
// The styling of our section divider.
$styling = array(
'selector' => $selector,
'declaration' => $css,
);
// Apply media query if needed
if ( in_array( $breakpoint, array( 'tablet', 'phone' ) ) ) {
$query_map = array(
'tablet' => 'max_width_980',
'phone' => 'max_width_767',
);
$styling['media_query'] = ET_Builder_Element::get_media_query( $query_map[ $breakpoint ] );
}
ET_Builder_Element::set_style( 'et_pb_section', $styling );
// if we are on the first section and is the top divider.
if ( 0 === $this->count && 'top' === $placement && '' === $breakpoint ) {
// we will use a transparent bg.
ET_Builder_Element::set_style( 'et_pb_section', array(
'selector' => $selector,
'declaration' => 'background-color: transparent;',
) );
}
}
/**
* Returns a placeholder for the section only if it is set to be inside of the section.
* @param string $placement Whether it is the top or bottom
* @return string HTML container
*/
public function get_svg( $placement ) {
// we return a div to use for the divider
return sprintf( '
', esc_attr( $placement ) );
}
}
return new ET_Builder_Module_Field_Divider();