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 = '%3$s'; 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 = '%3$s'; break; case 'triangle-top': $svg_markup = '%3$s'; break; case 'triangle-bottom': $svg_markup = '%3$s'; break; default: $svg_markup = '%3$s'; 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();