Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<?php
/**
* Helper class that provides necessary functions for managing alignment option
*
* Class ET_Builder_Module_Helper_Alignment
*/
class ET_Builder_Module_Helper_Alignment extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'module_alignment';
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,138 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
// Include dependency for ResponsiveOptions.
if ( ! function_exists( 'et_pb_responsive_options' ) ) {
require_once 'ResponsiveOptions.php';
}
// Include dependency for HoverOptions.
if ( ! function_exists( 'et_pb_hover_options' ) ) {
require_once 'HoverOptions.php';
}
/**
* Background layout helper methods.
*
* @since 4.0.7
*
* Class ET_Builder_Module_Helper_BackgroundLayout
*/
class ET_Builder_Module_Helper_BackgroundLayout {
public static function instance() {
static $instance;
return $instance ? $instance : $instance = new self();
}
/**
* Get background layout class names.
*
* @since 4.0.7
*
* @param array $attrs
* @param boolean $is_skip_desktop Not all modules need to print desktop background layout.
* @param boolean $is_text_color Not all modules need text color layout class name.
*
* @return array
*/
public function get_background_layout_class( $attrs, $is_skip_desktop = false, $is_text_color = false ) {
// Background layout values.
$background_layouts = et_pb_responsive_options()->get_property_values( $attrs, 'background_layout' );
$background_layout = et_()->array_get( $background_layouts, 'desktop', '' );
$background_layout_tablet = et_()->array_get( $background_layouts, 'tablet', '' );
$background_layout_phone = et_()->array_get( $background_layouts, 'phone', '' );
$background_layout_hover = et_pb_hover_options()->get_value( 'background_layout', $attrs, 'light' );
// Background layout class names.
$background_layout_class_names = ! $is_skip_desktop ? array( "et_pb_bg_layout_{$background_layout}" ) : array();
if ( ! empty( $background_layout_tablet ) ) {
$background_layout_class_names[] = "et_pb_bg_layout_{$background_layout_tablet}_tablet";
}
if ( ! empty( $background_layout_phone ) ) {
$background_layout_class_names[] = "et_pb_bg_layout_{$background_layout_phone}_phone";
}
// Text color class names.
if ( $is_text_color ) {
if ( 'light' === $background_layout ) {
$background_layout_class_names[] = 'et_pb_text_color_dark';
}
if ( 'light' === $background_layout_tablet ) {
$background_layout_class_names[] = 'et_pb_text_color_dark_tablet';
}
if ( 'light' === $background_layout_phone ) {
$background_layout_class_names[] = 'et_pb_text_color_dark_phone';
}
}
return $background_layout_class_names;
}
/**
* Get background layout data attributes.
*
* @since 4.0.7
*
* @param array $attrs
*
* @return string
*/
public function get_background_layout_attrs( $attrs ) {
// Background layout data attributes is only needed by hover or sticky effect.
if ( ! et_pb_hover_options()->is_enabled( 'background_layout', $attrs ) && ! et_pb_sticky_options()->is_enabled( 'background_layout', $attrs ) ) {
return '';
}
// Background layout values.
$background_layouts = et_pb_responsive_options()->get_property_values( $attrs, 'background_layout' );
$background_layout = et_()->array_get( $background_layouts, 'desktop', '' );
$background_layout_tablet = et_()->array_get( $background_layouts, 'tablet', '' );
$background_layout_phone = et_()->array_get( $background_layouts, 'phone', '' );
$background_layout_hover = et_pb_hover_options()->get_value( 'background_layout', $attrs, '' );
$background_layout_sticky = et_pb_sticky_options()->get_value( 'background_layout', $attrs, '' );
$data_background_layout = sprintf(
' data-background-layout="%1$s"',
esc_attr( $background_layout )
);
if ( ! empty( $background_layout_hover ) ) {
$data_background_layout .= sprintf(
' data-background-layout-hover="%1$s"',
esc_attr( $background_layout_hover )
);
}
if ( ! empty( $background_layout_sticky ) ) {
$data_background_layout .= sprintf(
' data-background-layout-sticky="%1$s"',
esc_attr( $background_layout_sticky )
);
}
if ( ! empty( $background_layout_tablet ) ) {
$data_background_layout .= sprintf(
' data-background-layout-tablet="%1$s"',
esc_attr( $background_layout_tablet )
);
}
if ( ! empty( $background_layout_phone ) ) {
$data_background_layout .= sprintf(
' data-background-layout-phone="%1$s"',
esc_attr( $background_layout_phone )
);
}
return $data_background_layout;
}
}

View File

@@ -0,0 +1,158 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
// Include dependency for ResponsiveOptions.
if ( ! function_exists( 'et_pb_responsive_options' ) ) {
require_once 'ResponsiveOptions.php';
}
/**
* Font helper methods.
*
* @since 4.0
*
* Class ET_Builder_Module_Helper_Font
*/
class ET_Builder_Module_Helper_Font {
public static function instance() {
static $instance;
return $instance ? $instance : $instance = new self();
}
/**
* Check if current font is Default or not.
*
* @since 4.0
*
* @param array $attrs
* @param string $name
* @param string $device
*
* @return boolean
*/
public function is_font_default( $attrs, $name, $device = 'desktop' ) {
return 'Default' === $this->get_font_value( $attrs, $name, $device );
}
/**
* Check if current font is empty or not.
*
* @since 4.0
*
* @param array $attrs
* @param string $name
* @param string $device
*
* @return boolean
*/
public function is_font_empty( $attrs, $name, $device = 'desktop' ) {
return '' === $this->get_font_value( $attrs, $name, $device );
}
/**
* Get font value based on device.
*
* @since 4.0
*
* @param array $attrs
* @param string $name
* @param string $device
*
* @return string
*/
public function get_font_value( $attrs, $name, $device = 'desktop' ) {
$value = et_pb_responsive_options()->get_property_value( $attrs, $name, '', $device, true );
$value_pieces = ! empty( $value ) && is_string( $value ) ? explode( '|', $value ) : array();
return et_()->array_get( $value_pieces, 0, '' );
}
/**
* Get custom breakpoint by font value.
*
* There is a case where tablet and phone use Default font. Default font means the element will
* use the original or font defined on Theme Customizer. It's different with empty string which
* means the font will be inherited from the larger device. So, when current device use non
* default font, we should check smaller device uses default font or not. If the smaller device
* use default font, we have to render current font inclusidely on current device, something
* likes desktop_only, tablet_only, or desktop_tablet_only.
*
* @since 4.0
*
* @param array $attrs
* @param string $name
* @param string $device
* @param string $default_breakpoint
*
* @return string
*/
public function get_breakpoint_by_font_value( $attrs, $name, $device = 'desktop', $default_breakpoint = '' ) {
// Bail early if current $device value is default or empty.
if ( $this->is_font_default( $attrs, $name, $device ) || $this->is_font_empty( $attrs, $name, $device ) ) {
return $default_breakpoint;
}
// Phone - There is no smaller $device than phone, no need to check.
if ( 'phone' === $device ) {
return $default_breakpoint;
}
$is_phone_default = $this->is_font_default( $attrs, $name, 'phone' );
$is_tablet_default = $this->is_font_default( $attrs, $name, 'tablet' );
// Tablet.
if ( 'tablet' === $device ) {
// Return breakpoint for tablet only if phone uses default, otherwise return default.
return $is_phone_default ? et_pb_responsive_options()->get_breakpoint_by_device( 'tablet_only' ) : $default_breakpoint;
}
// Desktop.
if ( $is_tablet_default ) {
// Return breakpoint for desktop only if tablet uses default.
return et_pb_responsive_options()->get_breakpoint_by_device( 'desktop_only' );
} elseif ( $is_phone_default ) {
// Return breakpoint for desktop & only if tablet uses default.
return et_pb_responsive_options()->get_breakpoint_by_device( 'desktop_tablet_only' );
}
return $default_breakpoint;
}
/**
* Get font selector based on settings.
*
* @since 4.0
*
* @param array $option_settings
* @param string $main_css_element
*
* @return string
*/
public function get_font_selector( $option_settings, $main_css_element ) {
// Get main CSS selector.
$main_selector = et_()->array_get( $option_settings, 'css.main', $main_css_element );
$limited_main_selector = et_()->array_get( $option_settings, 'css.limited_main', '' );
$font_selector = et_()->array_get( $option_settings, 'css.font', '' );
// Use different selector for plugin if defined.
if ( et_builder_has_limitation( 'use_limited_main' ) && ! empty( $limited_main_selector ) ) {
$main_selector = $limited_main_selector;
}
// Use font selector if it's specified
if ( ! empty( $font_selector ) ) {
$main_selector = $font_selector;
}
// Join all the main selectors if it's an array.
if ( is_array( $main_selector ) ) {
$main_selector = implode( ', ', $main_selector );
}
return $main_selector;
}
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* Helper class that provides necessary functions for managing height option
*
* Class ET_Builder_Module_Helper_Height
*/
class ET_Builder_Module_Helper_Height extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'height';
}
}

View File

@@ -0,0 +1,217 @@
<?php if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Hover Options helper methods
*
* Class ET_Builder_Module_Hover_Options
*/
class ET_Builder_Module_Helper_Hover_Options {
private static $instance;
public static function get() {
if ( empty( self::$instance ) ) {
self::$instance = new ET_Builder_Module_Helper_Hover_Options();
}
return self::$instance;
}
private function util_get( $key, $list, $default = null ) {
return ET_Core_Data_Utils::instance()->array_get( $list, $key, $default );
}
/**
* Returns `__hover`
*
* @return string
*/
public function get_suffix() {
return '__hover';
}
/**
* Return `__hover_enabled`
*
* @return string
*/
public function get_enabled_suffix() {
return '__hover_enabled';
}
/**
* Returns the field original name by removing the `__hover` or `__hover_enabled` suffix if it exists.
*
* @param string $name
*
* @return string
*/
public function get_field_base_name( $name ) {
// Do not use rtim as it removes by character not by string
// So cases like `key__hoveree` will be reduced to `key`
$regex = "/(.*)({$this->get_suffix()}|{$this->get_enabled_suffix()})$/";
$replace = '${1}';
return preg_replace( $regex, $replace, $name );
}
/**
* Check if the setting has enabled hover options
*
* @param string $setting
* @param array $attrs
*
* @return bool
*/
public function is_enabled( $setting, $attrs ) {
$name = in_array( $setting, [ 'background_color', 'background_image' ], true ) ? 'background' : $setting;
$field = $this->get_hover_enabled_field( $name );
$value = ! empty( $attrs[ $field ] ) ? $attrs[ $field ] : '';
$result = ! empty( $value ) && strpos( $value, 'on' ) === 0;
return $result;
}
/**
* Check if hover settings are enabled on one of the options list.
*
* @since 4.5.1
*
* @param array $attrs All module attributes.
* @param array $list Options list.
* @return boolean Hover settings status.
*/
public function is_any_hover_enabled( $attrs, $list ) {
// Ensure list is not empty and valid array.
if ( empty( $list ) || ! is_array( $list ) ) {
return false;
}
// Check the hover status one by one.
$is_any_hover_enabled = false;
foreach ( $list as $name ) {
if ( $this->is_enabled( $name, $attrs ) ) {
$is_any_hover_enabled = true;
break;
}
}
return $is_any_hover_enabled;
}
/**
* Returns the hover setting field name
* E.g.: get_hover_enabled_field('test') => 'test__hover'
*
* @param string $setting
*
* @return string
*/
public function get_hover_field( $setting ) {
return "{$this->get_field_base_name($setting)}{$this->get_suffix()}";
}
/**
* Returns the hover enabled setting field name
* E.g.: get_hover_enabled_field('test') => 'test__hover_enabled'
*
* @param string $setting
*
* @return string
*/
public function get_hover_enabled_field( $setting ) {
return "{$this->get_field_base_name($setting)}{$this->get_enabled_suffix()}";
}
/**
* Returns setting hover value if hover is enabled;
* If it does not exist, return $default specified value
*
* @param string $setting
* @param array $attrs
* @param mixed $default
*
* @return mixed
*/
public function get_value( $setting, $attrs, $default = null ) {
return $this->is_enabled( $setting, $attrs )
? $this->get_raw_value( $setting, $attrs, $default )
: $default;
}
/**
* Returns setting hover value if hover is enabled for a compose option;
* If it does not exist, return $default specified value
*
* @param string $setting
* @param string $option
* @param array $attrs
* @param mixed $default
*
* @return mixed
*/
public function get_compose_value( $setting, $option, $attrs, $default = null ) {
return $this->is_enabled( $option, $attrs )
? $this->get_raw_value( $setting, $attrs, $default )
: $default;
}
/**
* Returns setting hover value;
* If it does not exist, return $default specified value
*
* @param string $setting
* @param array $attrs
* @param mixed $default
*
* @return mixed
*/
public function get_raw_value( $setting, $attrs, $default = null ) {
return $this->util_get( $this->get_hover_field( $setting ), $attrs, $default );
}
/**
* Adds `:hover` in selector at the end of the selector
* E.g: add_hover_to_selectors('%%order_class%%% .image') >>> '%%order_class%%% .image:hover'
*
* @since 4.6.0 moved the order of `-` in capturing group 4's character set so it captures
* `::-` prefixed pseudo selector like `::-moz-placeholder` correctly
*
* @param string $selector
*
* @return string
*/
public function add_hover_to_selectors( $selector ) {
$selectors = explode( ',', $selector );
$selectors = array_map( 'trim', $selectors );
// Add hover to the end of the selector, but prevent specific situations like this:
// .my-class:after => .my-class:after:hover, should be .my-class:hover:after
$selectors = preg_replace( '/(.+\s)*([^\::?]+)((::?[-|a-z|\(|\)|\[|\]]+)+)?$/i', '$1$2:hover$3', $selectors );
return implode( ', ', $selectors );
}
/**
* Adds `:hover` in selector after `%%order_class%%`
* E.g: add_hover_to_order_class('%%order_class%%% .image') >>> '%%order_class%%%:hover .image'
*
* @param string $selector
*
* @return string
*/
public function add_hover_to_order_class( $selector ) {
$selectors = explode( ',', $selector );
$selectors = array_map( 'trim', $selectors );
// Add hover to the end of the selector, but prevent specific situations like this:
// .my-class:after => .my-class:after:hover, should be .my-class:hover:after
$selectors = preg_replace( '/(.*%%order_class%%[^\s|^:]*)(.*)/i', '$1:hover$2', $selectors );
return implode( ', ', $selectors );
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Helper class that provides necessary functions for managing max height option
*
* Class ET_Builder_Module_Helper_Max_Height
*/
class ET_Builder_Module_Helper_Max_Height extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'max_height';
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Helper class that provides necessary functions for managing max width option
*
* Class ET_Builder_Module_Helper_Max_Width
*/
class ET_Builder_Module_Helper_Max_Width extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'max_width';
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* ET_Builder_Module_Helper_Media class file.
*
* @class ET_Builder_Module_Helper_Media
* @package Divi\Builder
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Class ET_Builder_Module_Helper_Media.
*
* Module helpers for media (image).
*
* @since 4.6.4
*/
class ET_Builder_Module_Helper_Media {
/**
* Return instance of current class.
*
* @return ET_Builder_Module_Helper_Media
*/
public static function instance() {
static $instance;
return $instance ? $instance : $instance = new self();
}
/**
* Get image attachment class.
*
* - wp-image-{$id}
* Add `wp-image-{$id}` class to let `wp_filter_content_tags()` fill in missing
* height and width attributes on the image. Those attributes are required to add
* loading "lazy" attribute on the image. WP doesn't have specific method to only
* generate this class. It's included in get_image_tag() to generate image tags.
*
* @since 4.6.4
*
* @param array $attrs All module attributes.
* @param string $source_key Key of image source.
* @param integer $attachment_id Attachment ID. Optional.
*
* @return string
*/
public function get_image_attachment_class( $attrs, $source_key, $attachment_id = 0 ) {
$attachment_class = '';
// 1.a. Find attachment ID by URL. Skip if the source key is empty.
if ( ! empty( $source_key ) ) {
$attachment_src = et_()->array_get( $attrs, $source_key, '' );
$attachment_id = et_get_attachment_id_by_url( $attachment_src );
}
// 1.b. Generate attachment ID class.
if ( $attachment_id > 0 ) {
$attachment_class = "wp-image-{$attachment_id}";
}
return $attachment_class;
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Helper class that provides necessary functions for managing max height option
*
* Class ET_Builder_Module_Helper_Min_Height
*/
class ET_Builder_Module_Helper_Min_Height extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'min_height';
}
}

View File

@@ -0,0 +1,124 @@
<?php
class ET_Builder_Module_Helper_Multi_Value {
private static $instance;
public static function instance() {
return self::$instance ? self::$instance : ( self::$instance = new self() );
}
public function get_delimiter() {
return '|';
}
/**
* Parses an array and transforms it in an valid multi value array
*
* @param array $value
* @param int $elements
*
* @return array
*/
public function parse( array $value, $elements = null ) {
$length = (int) $elements;
if ( ! $elements || count( $value ) === (int) $length ) {
return $value;
}
$new = array();
for ( $i = 0; $i < (int) $length; $i ++ ) {
$new[ $i ] = isset( $value[ $i ] ) && $value[ $i ] !== null ? $value[ $i ] : '';
}
return array_map( 'strval', $new );
}
/**
* Splits the multi value string in to an array of primitive values
* User can provide also the required number of elements that value must have
* In case the array original length will be larger then the required elements number
* the array will be cut from head to tail
* In cas the array length will be shorter, the array tail will be filled with empty strings `''`,
* till array length will match the requested elements number
*
* @param string $value
* @param int $elements
*
* @return array
*/
public function split( $value, $elements = null ) {
return $this->parse( explode( $this->get_delimiter(), $value ), $elements );
}
/**
* Takes an array and converts it to a valid multi value
* Provide the `elements` parameter to get the result string of the necessary length
*
* @param array $value
* @param int $elements
*
* @return string
*/
public function to_value( array $value, $elements = null ) {
return implode( $this->get_delimiter(), $this->parse( $value, $elements ) );
}
/**
* Check if the multi value is not empty.
* A multi value is empty when all sub values are empty strings
*
* @param string $value
*
* @return bool
*/
public function has_value( $value ) {
return trim( implode( '', $this->split( $value ) ) ) !== '';
}
/**
* Merges two multi values in to one.
* If value1 nth element is empty, value2 nth element will be used
*
* @param $value_1
* @param $value_2
* @param int $elements
*
* @return string
*/
public function merge( $value_1, $value_2, $elements = null ) {
$v1 = $this->split( $value_1, $elements );
$v2 = $this->split( $value_2, $elements );
$max = max( count( $v1 ), count( $v2 ) );
$new = array();
for ( $i = 0; $i < $max; $i ++ ) {
$new[ $i ] = ! isset( $v1[ $i ] ) ? $v2[ $i ] : et_builder_get_or( $v1[ $i ], $v2[ $i ] );
}
return $this->to_value( $new, $elements );
}
/**
* Sets a value at specific position in provided multiValue.
*
* @param int $key
* @param string $value
* @param string $motion_value
* @param int $elements
*
* @return string
*/
public function set( $key, $value, $motion_value, $elements = null ) {
$arr = $this->split( $motion_value, $elements );
if ( ! isset( $arr[ $key ] ) ) {
return $motion_value;
}
$arr[ $key ] = $value;
return implode( $this->get_delimiter(), $arr );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,731 @@
<?php
/**
* Option Templates helper methods.
*
* @since 3.28
*
* Class ET_Builder_Module_Helper_OptionTemplate
*/
class ET_Builder_Module_Helper_OptionTemplate {
private $map = array();
private $templates = array();
private $data = array();
private $cache = array();
private $tab_slug_map = array();
public $template_prefix = '%t';
protected static $_ = null;
public static function instance() {
static $instance;
return $instance ? $instance : $instance = new self();
}
private function __construct() {
self::$_ = ET_Core_Data_Utils::instance();
}
private function uniq( $prefix, $content ) {
$key = md5( $prefix . serialize( $content ) );
if ( isset( $this->map[ $key ] ) ) {
return $this->map[ $key ];
}
return ( $this->map[ $key ] = $this->template_prefix . $key );
}
/**
* Determine whether option template is enabled on current request or not
*
* @since 3.28
*
* @return bool
*/
public function is_enabled() {
// Option template tends to be enabled on most request to speed up performance
$status = true;
// Option template is disabled on:
// 1. AJAX request for fetching classic builder (BB)'s module data. BB data is shipped as
// optimized template markup which is rendered on server then sent as string. Hence
// Option Template's sent-config-rebuild-on-js won't be usable for BB
// 2. BB's editing page. BB edit page scans for field dependency and generates visibility
// setting on `window.et_pb_module_field_dependencies` variable for field depency thus
// actual field should be rendered here instead of templateId
if ( et_builder_is_loading_bb_data() || et_builder_is_bb_page() ) {
$status = false;
}
/**
* Filters option template status
*
* @since 3.28
*
* @param bool $status
*/
return apply_filters( 'et_builder_option_template_is_active', $status );
}
/**
* Determine whether given field name is option template field based on its first two characters
*
* @since 3.28
*
* @return bool
*/
public function is_option_template_field( $field_name = '' ) {
return $this->template_prefix === substr( $field_name, 0, 2 );
}
public function has( $key ) {
return isset( $this->templates[ $key ] );
}
public function add( $key, $template ) {
$fields_template = array_merge( $template, et_pb_responsive_options()->create( $template ) );
// Populate tab_slug of given template because advance fields can be rendered on any tab
foreach ( $fields_template as $field_name => $field ) {
if ( isset( $field['tab_slug'] ) ) {
$tab_slug = '' === $field['tab_slug'] ? 'advanced' : $field['tab_slug'];
if ( ! isset( $this->tab_slug_map[ $tab_slug ] ) ) {
$this->tab_slug_map[ $tab_slug ] = array( $key );
continue;
}
if ( ! in_array( $key, $this->tab_slug_map[ $tab_slug ] ) ) {
$this->tab_slug_map[ $tab_slug ][] = $key;
}
}
}
$this->templates[ $key ] = $fields_template;
}
public function create( $key, $config, $return_template_id = false ) {
$data = array( $key, $config );
$id = $this->uniq( $key, $data );
// Alternative, this will save the values directly in the Module $this->unprocessed_fields
// instead of this Calls $this->data and hence require a simpler logic.
// Theoretically it should require more memory but blackfire begs to differ.
$this->data[ $id ] = $data;
// Return as template id instead of id => key if needed
if ( $return_template_id ) {
return $id;
}
return array( $id => $key );
}
/**
* Create placeholders for template's params
*
* @return string[]
*/
public function placeholders( $config, $idx = 1, $path = array() ) {
$placeholders = array();
foreach ( $config as $key => $value ) {
if ( is_array( $value ) ) {
// Prepend current key as path so placeholder later can correctly fetch correct
// value from template data using dot notation path (both lodash get() or utils's
// array_get() support this).
$path[] = $key;
$value = $this->placeholders( $value, $idx, $path );
} else {
// Prepend dot notation path as prefix if needed
$prefix = empty( $path ) ? '' : implode( '.', $path ) . '.';
$value = "%%{$prefix}{$key}%%";
}
$placeholders[ $key ] = $value;
$idx++;
}
return $placeholders;
}
/**
* Get module's data
*
* @return array[]
*/
public function all() {
return $this->data;
}
/**
* Get templates
*
* @since 3.28
*
* @return array
*/
public function templates() {
return $this->templates;
}
/**
* Set `$this->data` property from external source (ie: static field definition cache).
*
* @since 3.28
*
* @param array $cached_data
*/
public function set_data( $cached_data = array() ) {
$this->data = wp_parse_args(
$cached_data,
$this->data
);
}
/**
* Set `$this->templates` property from external source (ie: static field definition cache).
*
* @since 3.28
*
* @param array $cached_template
*/
public function set_templates( $cached_templates = array() ) {
$this->templates = wp_parse_args(
$cached_templates,
$this->templates
);
}
/**
* Set `$this->tab_slug_map` from external source (ie: static field definition cache).
*
* @since 3.29
*
* @param array $cached_tab_slug_map
*/
public function set_tab_slug_map( $cached_tab_slug_map = array() ) {
$this->tab_slug_map = wp_parse_args(
$cached_tab_slug_map,
$this->tab_slug_map
);
}
/**
* Get template data based on given template id
*
* @since 3.28
*
* @param string $template_id
*
* @return array
*/
public function get_data( $template_id = '' ) {
return isset( $this->data[ $template_id ] ) ? $this->data[ $template_id ] : array();
}
/**
* Get template based on given template type
*
* @since 3.28
*
* @param string $type
*
* @return array
*/
public function get_template( $type = '' ) {
return isset( $this->templates[ $type ] ) ? $this->templates[ $type ] : array();
}
/**
* Get hashed cache key based on params given
*
* @since 3.28
*
* @param mixed $params
*
* @return string
*/
public function get_cache_key( $params ) {
$params = is_string( $params ) ? $params : serialize( $params );
return md5( $params );
}
/**
* Get cached value
* Return null if no cached value found
*
* @since 3.28
*
* @param string $name
* @param string $key
*
* @return mixed
*/
public function get_cache( $name, $key ) {
if (
! empty( $this->cache )
&& ! empty( $this->cache[ $name ] )
&& ! empty( $this->cache[ $name ][ $key ] )
) {
return $this->cache[ $name ][ $key ];
}
return null;
}
/**
* Set value to be cached
*
* @since 3.28
*
* @param string $name
* @param string $key
* @param mixed $value
*
* @return void
*/
public function set_cache( $name, $key, $value ) {
self::$_->array_set( $this->cache, "{$name}.{$key}", $value );
}
/**
* Get placeholder of given template
*
* @since 3.28
*
* @param string $template
*
* @return array|bool
*/
public function get_template_placeholder( $template ) {
// Check for cached result first for faster performance
$cache_name = 'template_placeholder';
$cache_key = $this->get_cache_key( $template );
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
preg_match( '/(?<=%%).*(?=%%)/', $template, $placeholder );
// Cache result
$this->set_cache( $cache_name, $cache_key, $placeholder );
return $placeholder;
}
/**
* Get tab slug maps
*
* @since 3.29
*
* @return array
*/
public function get_tab_slug_map() {
return $this->tab_slug_map;
}
public function is_template_inside_tab( $tab_name, $template_type ) {
// Template which has `%%tab_slug%%` tab_slug can exist on any tab
if ( in_array( $template_type, self::$_->array_get( $this->tab_slug_map, '%%tab_slug%%', array() ) ) ) {
return true;
}
if ( in_array( $template_type, self::$_->array_get( $this->tab_slug_map, $tab_name, array() ) ) ) {
return true;
}
return false;
}
public function rebuild_string_placeholder( $template, $data = array(), $settings = array() ) {
// Placeholder settings
$default_settings = array(
'suffix' => '',
'remove_suffix_if_empty' => false,
);
$placeholder_settings = wp_parse_args( $settings, $default_settings );
// Check for cached result first for faster performance
$cache_name = 'string_placeholder';
$cache_key = $this->get_cache_key( array( $template, $data, $placeholder_settings ) );
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
// Get placeholder
$placeholder = is_string( $template ) ? $this->get_template_placeholder( $template ) : false;
// If found, replace placeholder with correct value from data
if ( is_array( $placeholder ) && isset( $placeholder[0] ) ) {
// Get placeholder replacement
$replacement = ! empty( $data[1] ) && ! empty( $data[1][ $placeholder[0] ] ) ? $data[1][ $placeholder[0] ] : '';
// Pass null as empty string; null as attribute affect builder differently.
// Attribute with empty string will be omitted later.
if ( is_null( $replacement ) ) {
$replacement = '';
}
// If placeholder is identical to template, return replacement early. This also
// handles the case where replacement as array type
if ( "%%{$placeholder[0]}%%" === $template ) {
// Cache result
$this->set_cache( $cache_name, $cache_key, $replacement );
return $replacement;
}
// Get placeholder suffix
$has_suffix = '' === $replacement && $placeholder_settings['remove_suffix_if_empty'];
$suffix = $has_suffix ? $placeholder_settings['suffix'] : '';
// Make sure replacement is string before proceed;
if ( is_string( $replacement ) ) {
$rebuilt_string = str_replace( "%%{$placeholder[0]}%%{$suffix}", $replacement, $template );
// Cache result
$this->set_cache( $cache_name, $cache_key, $rebuilt_string );
return $rebuilt_string;
}
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $template );
return $template;
}
public function rebuild_preset_placeholder( $template, $data = array(), $settings = array() ) {
// Check for cached result first for faster performance
$cache_name = 'preset_placeholder';
$cache_key = $this->get_cache_key( array( $template, $data, $settings ) );
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
$rebuild_attr = array();
foreach ( $template as $preset_attr_key => $preset_attr_value ) {
// Object inside preset array mostly contains fields attribute which its object key
// contains placeholder while its object value contains actual value without placeholder.
if ( is_array( $preset_attr_value ) ) {
$rebuilt_preset_attr_object = array();
foreach ( $preset_attr_value as $name => $value ) {
$object_item_name = $this->rebuild_string_placeholder( $name, $data, $settings );
$rebuilt_preset_attr_object[ $object_item_name ] = $value;
}
$rebuild_attr[ $preset_attr_key ] = $rebuilt_preset_attr_object;
continue;
}
$rebuild_attr[ $preset_attr_key ] = $preset_attr_value;
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $rebuild_attr );
return $rebuild_attr;
}
public function rebuild_composite_structure_placeholder( $template_type, $template, $data = array() ) {
// Check for cached result first for faster performance
$cache_name = 'composite_structure_placeholder';
$cache_key = $this->get_cache_key( array( $template_type, $template, $data ) );
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
$rebuilt_composite_structure_field = $template;
// Replaces placeholder with actual value on border's nested composite structure fields
if ( 'border' === $template_type ) {
// Reset `controls` attribute output
$rebuilt_composite_structure_field['controls'] = array();
// Loop composite structure's original `controls` from template
foreach ( $template['controls'] as $field_name => $field ) {
$rebuilt_field_name = $this->rebuild_string_placeholder( $field_name, $data );
$rebuilt_field = $field;
// Loop field on composite structure controls
foreach ( $rebuilt_field as $attr_name => $attr_value ) {
$settings = array(
'suffix' => 'label' === $attr_name ? ' ' : '',
'remove_suffix_if_empty' => 'label' === $attr_name,
);
$rebuilt_field[ $attr_name ] = $this->rebuild_string_placeholder( $attr_value, $data, $settings );
}
$rebuilt_composite_structure_field['controls'][ $rebuilt_field_name ] = $rebuilt_field;
}
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $rebuilt_composite_structure_field );
return $rebuilt_composite_structure_field;
}
public function rebuild_field_attr_value( $attr_name, $attr_value, $template_data ) {
// Check for cached result first for faster performance
$cache_name = 'field_attr_value';
$cache_key = $this->get_cache_key( array( $attr_name, $attr_value, $template_data ) );
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
$template_type = ! empty( $template_data[0] ) ? $template_data[0] : '';
$prefix = ! empty( $template_data[1]['prefix'] ) && ! empty( $template_data[1]['prefix'] ) ? $template_data[1]['prefix'] : '';
// Certain advanced field (ie. Text Shadow) automatically adds underscore
$auto_add_prefix_underscore = isset( $template_data[0] ) && 'text_shadow' === $template_data[0] && '' === $prefix;
// 1. Field attribute value's type is string
if ( is_string( $attr_value ) ) {
$placeholder_has_space_suffix = 'label' === $attr_name && in_array( $template_type, array( 'border', 'text_shadow' ) );
$settings = array(
'suffix' => $placeholder_has_space_suffix ? ' ' : '',
'remove_suffix_if_empty' => $placeholder_has_space_suffix ? true : false,
);
$rebuilt_placeholder = $this->rebuild_string_placeholder( $attr_value, $template_data, $settings );
// Cache result
$this->set_cache( $cache_name, $cache_key, $rebuilt_placeholder );
return $rebuilt_placeholder;
}
// 2. Field attribute value's type is array (sequential)
if ( is_array( $attr_value ) && isset( $attr_value[0] ) ) {
$rebuild_attr_value = array();
foreach ( $attr_value as $array_value ) {
// Array consists of string is most likely used for defining field relationship
// such as `show_if` attribute; Replace prefix and suffix placeholder with
// placeholder replacement also consider that text_shadow advanced field
// automatically adds underscore after prefix so it needs to be adjusted as well
if ( is_string( $array_value ) ) {
$settings = array(
'suffix' => '_',
'remove_suffix_if_empty' => $auto_add_prefix_underscore,
);
$rebuild_attr_value[] = $this->rebuild_string_placeholder( $array_value, $template_data, $settings );
} elseif ( 'presets' === $attr_name ) {
// Handle preset attribute specifically due to how it is structured
$settings = array(
'suffix' => '_',
'remove_suffix_if_empty' => $auto_add_prefix_underscore,
);
$rebuild_attr_value[] = $this->rebuild_preset_placeholder( $array_value, $template_data, $settings );
} else {
// Non string and `presets` attribute less likely contains placeholder
$rebuild_attr_value[] = $array_value;
}
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $rebuild_attr_value );
return $rebuild_attr_value;
}
// 3. Field attribute value's type is array (associative)
if ( is_array( $attr_value ) && ! isset( $attr_value[0] ) ) {
$attr_object = array();
// Loop existing attrValue and populate the rebuilt result on `attrObject`.
foreach ( $attr_value as $item_key => $item_value ) {
$attr_object_key = $this->rebuild_string_placeholder( $item_key, $template_data );
// Replaces placeholder with actual value on border's nested composite structure fields
if ( 'composite_structure' === $attr_name ) {
$item_value = $this->rebuild_composite_structure_placeholder( $template_type, $item_value, $template_data );
}
$attr_object[ $attr_object_key ] = $item_value;
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $attr_object );
return $attr_object;
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $attr_value );
// 4. Unknown attribute value type; directly pass it
return $attr_value;
}
public function rebuild_field_template( $template_id, $parent_template_id = false ) {
// Check for cached result first for faster performance
$cache_name = 'field_template';
$cache_key = $parent_template_id ? "{$template_id}-inherits-{$parent_template_id}" : $template_id;
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
$fields = array();
$template_data = $this->get_data( $template_id );
// No fields will be found without template data. Return early;
if ( empty( $template_data ) ) {
return $fields;
}
$template_type = ! empty( $template_data[0] ) ? $template_data[0] : '';
$template_settings = ! empty( $template_data[1] ) ? $template_data[1] : array();
$prefix = ! empty( $template_settings['prefix'] ) ? $template_settings['prefix'] : '';
$parent_template_data = false;
// If rebuilt parent template is inside another templateId (ie. Text Shadow inside Font)
// its placeholder is passed for data; The expected structure becomes
// `[templateType, parentTemplateSettings]` instead of `[templateType, templateSettings]`;
// Thus get parent template's settings and use it
if ( $parent_template_id ) {
$parent_template_data = $this->get_data( $parent_template_id );
$parent_template_settings = ! empty( $parent_template_data[1] ) ? $parent_template_data[1] : true;
$template_settings_inherits_from_parant = array();
foreach ( $template_settings as $name => $value ) {
$placeholder = $this->get_template_placeholder( $value );
if ( is_array( $placeholder ) && isset( $placeholder[0] ) ) {
$template_settings_inherits_from_parant[ $name ] = self::$_->array_get(
$parent_template_settings,
$placeholder[0],
$value
);
}
}
$parent_template_data = array(
$template_type,
$template_settings_inherits_from_parant,
);
}
// Get fields template for given template type
$fields_template = $this->get_template( $template_type );
// Loop fields template and replace placeholder with actual value
foreach ( $fields_template as $field_name_template => $field_template ) {
// Certain advanced field (ie. Text Shadow) automatically adds underscore
// Related template type needs to be adjusted
$remove_suffix_if_empty = 'text_shadow' === $template_type && '' === $prefix;
// Replace field attribute name's placeholder
$field_template_data = $parent_template_id ? $parent_template_data : $template_data;
$field_name = $this->rebuild_string_placeholder(
$field_name_template,
$field_template_data,
array(
'remove_suffix_if_empty' => $remove_suffix_if_empty,
// placeholder's suffix, not placeholder named %%suffix%%
'suffix' => '_',
)
);
// Replace field attribute value's placeholder
$field = array();
if ( is_array( $field_template ) ) {
foreach ( $field_template as $attr_name => $attr_value ) {
$rebuilt_attr_value = $this->rebuild_field_attr_value(
$attr_name,
$attr_value,
$field_template_data
);
// Omit attribute with empty value: existance of attribute even with empty
// string value is handled differently in many field (ie, `show_if`)
if ( '' === $rebuilt_attr_value ) {
continue;
}
$field[ $attr_name ] = $rebuilt_attr_value;
}
} else {
$fields = array_merge(
$fields,
$this->rebuild_field_template( $field_name_template, $template_id )
);
}
// `name` attribute is dynamically added based on field's array key
$field['name'] = $field_name;
// Populate rebuilt field
$fields[ $field_name ] = $field;
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $fields );
return $fields;
}
public function rebuild_default_props( $template_id ) {
// Check for cached result first for faster performance
$cache_name = 'default_props';
$cache_key = $template_id;
$cache = $this->get_cache( $cache_name, $cache_key );
if ( ! is_null( $cache ) ) {
return $cache;
}
$default_props = array();
$rebuilt_fields = $this->rebuild_field_template( $template_id );
foreach ( $rebuilt_fields as $field_name => $field ) {
$value = '';
if ( isset( $field['composite_type'], $field['composite_structure'] ) ) {
require_once ET_BUILDER_DIR . 'module/field/attribute/composite/Parser.php';
$composite_atts = ET_Builder_Module_Field_Attribute_Composite_Parser::parse( $field['composite_type'], $field['composite_structure'] );
$default_props = array_merge( $default_props, $composite_atts );
} else {
if ( isset( $field['default_on_front'] ) ) {
$value = $field['default_on_front'];
} elseif ( isset( $field['default'] ) ) {
$value = $field['default'];
}
$default_props[ $field_name ] = $value;
}
}
// Cache result
$this->set_cache( $cache_name, $cache_key, $default_props );
return $default_props;
}
}

View File

@@ -0,0 +1,90 @@
<?php if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Overflow helper methods
*
* Class ET_Builder_Module_Helper_Overflow
*/
class ET_Builder_Module_Helper_Overflow {
const OVERFLOW_DEFAULT = '';
const OVERFLOW_VISIBLE = 'visible';
const OVERFLOW_HIDDEN = 'hidden';
const OVERFLOW_SCROLL = 'scroll';
const OVERFLOW_AUTO = 'auto';
private static $instance;
public static function get() {
if ( empty( self::$instance ) ) {
return self::$instance = new self();
}
return self::$instance;
}
/**
* Returns overflow settings X axis field
*
* @param string $prefix
*
* @return string
*/
public function get_field_x( $prefix = '' ) {
return $prefix . 'overflow-x';
}
/**
* Returns overflow settings Y axis field
*
* @param string $prefix
*
* @return string
*/
public function get_field_y( $prefix = '' ) {
return $prefix . 'overflow-y';
}
/**
* Return overflow X axis value
*
* @param array $props
* @param mixed $default
* @param string $prefix
*
* @return string
*/
public function get_value_x( $props, $default = null, $prefix = '' ) {
return et_()->array_get( $props, $this->get_field_x( $prefix ), $default );
}
/**
* Return overflow Y axis value
*
* @param array $props
* @param mixed $default
* @param string $prefix
*
* @return string
*/
public function get_value_y( $props, $default = null, $prefix = '' ) {
return et_()->array_get( $props, $this->get_field_y( $prefix ), $default );
}
/**
* Returns overflow valid values
*
* @return array
*/
public function get_overflow_values() {
return array(
self::OVERFLOW_DEFAULT,
self::OVERFLOW_VISIBLE,
self::OVERFLOW_HIDDEN,
self::OVERFLOW_AUTO,
self::OVERFLOW_SCROLL,
);
}
}

View File

@@ -0,0 +1,101 @@
<?php if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Overlay helper methods.
*
* Class ET_Builder_Module_Helper_Overlay
*/
class ET_Builder_Module_Helper_Overlay {
/**
* Get an overlay html tag's attributes.
*
* @since 3.29
*
* @param array $args
*
* @return array
*/
public static function get_attributes( $args ) {
$attributes = array();
if ( ! empty( $args['icon'] ) ) {
$attributes['data-icon'] = et_pb_extended_process_font_icon( $args['icon'] );
}
if ( ! empty( $args['icon_tablet'] ) ) {
$attributes['data-icon-tablet'] = et_pb_extended_process_font_icon( $args['icon_tablet'] );
}
if ( ! empty( $args['icon_phone'] ) ) {
$attributes['data-icon-phone'] = et_pb_extended_process_font_icon( $args['icon_phone'] );
}
if ( ! empty( $args['icon_sticky'] ) ) {
$attributes['data-icon-sticky'] = et_pb_extended_process_font_icon( $args['icon_sticky'] );
}
return $attributes;
}
/**
* Render an overlay html tag's attributes.
*
* @since 3.29
*
* @param array $args
*
* @return string
*/
public static function render_attributes( $args ) {
$attributes = self::get_attributes( $args );
$html = array();
foreach ( $attributes as $attribute => $value ) {
$html[] = sprintf(
'%1$s="%2$s"',
et_core_intentionally_unescaped( $attribute, 'fixed_string' ),
et_core_esc_previously( $value )
);
}
return implode( ' ', $html );
}
/**
* Render an overlay html tag.
*
* @since 3.29
*
* @param array $args
*
* @return string
*/
public static function render( $args ) {
$attributes = et_core_esc_previously( self::render_attributes( $args ) );
$classes = array( 'et_overlay' );
if ( ! empty( $args['icon'] ) ) {
$classes[] = 'et_pb_inline_icon';
}
if ( ! empty( $args['icon_tablet'] ) ) {
$classes[] = 'et_pb_inline_icon_tablet';
}
if ( ! empty( $args['icon_phone'] ) ) {
$classes[] = 'et_pb_inline_icon_phone';
}
if ( ! empty( $args['icon_sticky'] ) ) {
$classes[] = 'et_pb_inline_icon_sticky';
}
return sprintf(
'<span class="%1$s"%2$s></span>',
et_core_intentionally_unescaped( implode( ' ', $classes ), 'fixed_string' ),
( '' !== $attributes ? ' ' . $attributes : '' )
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
<?php
/**
* Helper class that provides necessary functions for managing Sizing option
*
* Class ET_Builder_Module_Helper_Sizing
*/
abstract class ET_Builder_Module_Helper_Sizing {
/**
* @var string The prefix string that may be added to field name
*/
private $prefix;
/**
* Return raw field name to create the field
*
* @return string
*/
abstract public function get_raw_field();
public function __construct( $prefix = '' ) {
$this->prefix = $prefix;
}
/**
* Returns sizing options fields prefix
*
* @return string
*/
public function get_prefix() {
return $this->prefix;
}
/**
* Returns field name of the sizing option
*
* @return string
*/
public function get_field() {
return $this->get_prefix() . $this->get_raw_field();
}
/**
* Check if the sizing feature option is enabled
*
* @return bool
*/
public function is_enabled() {
return true;
}
/**
* Returns sizing value
*
* @param array $props
* @param string $default
*
* @return string
*/
public function get_value( array $props, $default = '' ) {
return (string) et_()->array_get( $props, $this->get_field(), $default );
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* Class ET_Builder_Module_Helper_Slider
*/
class ET_Builder_Module_Helper_Slider {
/**
* Returns slider arrows CSS selector
*
* @since 3.25.3
*
* @param string $prefix
*
* @return string
*/
public function get_arrows_selector( $prefix = '%%order_class%%' ) {
return implode(
',',
array(
"$prefix .et-pb-slider-arrows .et-pb-arrow-prev",
"$prefix .et-pb-slider-arrows .et-pb-arrow-next",
)
);
}
/**
* Returns slider dots CSS selector
*
* @since 3.25.3
*
* @param string $prefix
*
* @return string
*/
public function get_dots_selector( $prefix = '%%order_class%%' ) {
return "$prefix .et-pb-controllers a, $prefix .et-pb-controllers .et-pb-active-control";
}
/**
* Reapply (fullwidth) post slider's module background on slide item which has featured image
*
* @since 4.3.3
*
* @param array $args {
* @type int $slide_post_id
* @type string|bool $post_featured_image
* @type string $render_slug
* @type array $props
* }
*/
public static function reapply_module_background_on_slide( $args = array() ) {
$defaults = array(
'slide_post_id' => 0,
'post_featured_image' => false,
'render_slug' => '',
'props' => array(),
);
// Parse argument
$args = wp_parse_args( $args, $defaults );
// Create slide class
$slide_id_class = "et_pb_post_slide-{$args['slide_post_id']}";
// Reapply background color (affecting blend mode), gradient (can be placed on top of image
// creating overlay-effect), and images (gradient is actually image) if:
// 1. Featured image exist on current slide
// 2. Featured image is shown (responsive)
// 3. Featured image placement is placed on background
// 4. Parallax (responsive) is off
// 1. Exit if featured image doesn't exist on current slide
if ( ! $args['post_featured_image'] ) {
return;
}
$props = $args['props'];
// 2. Exit if featured image is not shown
$is_show_image_responsive = et_pb_responsive_options()->is_responsive_enabled( $props, 'show_image' );
$is_featured_image_shown = $is_show_image_responsive ?
in_array( 'on', et_pb_responsive_options()->get_property_values( $props, 'show_image' ) ) :
'on' === et_()->array_get( $props, 'show_image' );
if ( ! $is_featured_image_shown ) {
return;
}
// 3. Exit if feature image is not placed in background
if ( 'background' !== et_()->array_get( $props, 'image_placement' ) ) {
return;
}
// 4. Exit if parallax is activated
$is_parallax_responsive = et_pb_responsive_options()->is_responsive_enabled( $props, 'parallax' );
$is_parallax_active = $is_parallax_responsive ?
in_array( 'on', et_pb_responsive_options()->get_property_values( $props, 'parallax' ) ) :
'on' === et_()->array_get( $props, 'parallax' );
if ( $is_parallax_active ) {
return;
}
// Process background
$props['background_image'] = $args['post_featured_image'];
$props['background_enable_image'] = 'on';
// Background responsive is generally set via background_last_edited instead of each background
// type's *_last_edited; when background's responsive active and no background image is set,
// background-image property will be set to `initial` and featured image on current image got
// removed on current breakpoint. Thus, Set background image responsive attribute on current
// background_image attribute to keep it visible
if ( et_pb_responsive_options()->is_responsive_enabled( $props, 'background' ) ) {
$props['background_image_last_edited'] = '';
$props['background_image_tablet'] = $args['post_featured_image'];
$props['background_image_phone'] = $args['post_featured_image'];
}
if ( et_builder_is_hover_enabled( 'background', $props ) ) {
$props['background_image__hover'] = $args['post_featured_image'];
}
et_pb_background_options()->get_background_style(
array(
'props' => $props,
'selector' => "%%order_class%% .{$slide_id_class}",
'selector_hover' => "%%order_class%%:hover .{$slide_id_class}",
'function_name' => $args['render_slug'],
)
);
return;
}
}

View File

@@ -0,0 +1,358 @@
<?php
/**
* Sticky Helper
*
* @package Divi
* @sub-package Builder
* @since 4.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Sticky Options helper methods
*
* @since 4.6.0
*
* Class ET_Builder_Module_Sticky_Options
*/
class ET_Builder_Module_Helper_Sticky_Options {
/**
* Class instance object
*
* @var object Class instance.
*/
private static $instance;
/**
* Get instance of ET_Builder_Module_Sticky_Options.
*
* @since 4.6.0
*
* @return object|ET_Builder_Module_Sticky_Options
*/
public static function get() {
if ( empty( self::$instance ) ) {
self::$instance = new ET_Builder_Module_Helper_Sticky_Options();
}
return self::$instance;
}
/**
* Get Sticky field suffix
*
* @since 4.6.0
*
* @return string
*/
public function get_suffix() {
return '__sticky';
}
/**
* Get Sticky field enabled suffix
*
* @since 4.6.0
*
* @return string
*/
public function get_enabled_suffix() {
return '__sticky_enabled';
}
/**
* Returns the field original name by removing the `_sticky` or `__sticky_enabled` suffix if it exists.
*
* @since 4.6.0
*
* @param string $name Field name.
*
* @return string
*/
public function get_field_base_name( $name ) {
$regex = "/(.*)({$this->get_suffix()}|{$this->get_enabled_suffix()})$/";
$replace = '${1}';
return preg_replace( $regex, $replace, $name );
}
/**
* Get valid sticky_position which implies module is sticky element
*
* @since 4.6.0
*
* @return array
*/
public function get_valid_sticky_positions() {
return array( 'top', 'bottom', 'top_bottom' );
}
/**
* Check if the setting has enabled sticky options
*
* @since 4.6.0
*
* @param string $setting Field name.
* @param array $attrs Module attributes.
*
* @return bool
*/
public function is_enabled( $setting, $attrs ) {
$name = 'background_color' === $setting ? 'background' : $setting;
$field = $this->get_sticky_enabled_field( $name );
$value = ! empty( $attrs[ $field ] ) ? $attrs[ $field ] : '';
return ! empty( $value ) && strpos( $value, 'on' ) === 0;
}
/**
* Check if current module is inside sticky module
*
* @since 4.6.2
*
* @return bool
*/
public function is_inside_sticky_module() {
global $is_inside_sticky_module;
return $is_inside_sticky_module;
}
/**
* Check if module with given attributes is a sticky module. Need to consider responsive value:
* desktop might have non sticky element value but its smaller breakpoint has sticky element value
*
* @since 4.6.0
*
* @param array $attrs Module attributes.
*
* @return bool
*/
public function is_sticky_module( $attrs ) {
// No nested sticky element.
if ( $this->is_inside_sticky_module() ) {
return false;
}
// Bail if there is fields which its selected value are incompatible to sticky mechanism.
if ( $this->has_incompatible_attrs( $attrs ) ) {
return false;
}
$sticky_position = et_pb_responsive_options()->get_checked_property_value( $attrs, 'sticky_position', 'none', true );
// Non responsive.
if ( is_string( $sticky_position ) ) {
return in_array( $sticky_position, $this->get_valid_sticky_positions(), true );
}
if ( ! is_array( $sticky_position ) ) {
return false;
}
// Responsive.
$is_sticky = false;
foreach ( $sticky_position as $device => $position ) {
if ( in_array( $position, $this->get_valid_sticky_positions(), true ) ) {
$is_sticky = true;
break;
}
}
return $is_sticky;
}
/**
* Returns the field / setting name with sticky suffix
* E.g.: get_sticky_enabled_field('test') => 'test__sticky'
*
* @since 4.6.0
*
* @param string $setting Field name.
*
* @return string
*/
public function get_sticky_field( $setting ) {
return "{$this->get_field_base_name($setting)}{$this->get_suffix()}";
}
/**
* Returns the sticky enabled setting field name
* E.g.: get_sticky_enabled_field('test') => 'test__sticky_enabled'
*
* @since 4.6.0
*
* @param string $setting Field name.
*
* @return string
*/
public function get_sticky_enabled_field( $setting ) {
return "{$this->get_field_base_name($setting)}{$this->get_enabled_suffix()}";
}
/**
* Returns setting value for sticky if enabled, otherwise return the default value
*
* @since 4.6.0
*
* @param string $setting Field name.
* @param array $attrs Module attributes.
* @param mixed $default Default value.
*
* @return mixed
*/
public function get_value( $setting, $attrs, $default = null ) {
return $this->is_enabled( $setting, $attrs )
? $this->get_raw_value( $setting, $attrs, $default )
: $default;
}
/**
* Returns setting sticky value if sticky is enabled for a compose option;
* If it does not exist, return $default specified value
*
* @since 4.6.0
*
* @param string $setting Field name.
* @param string $option Option.
* @param array $attrs Module attributes.
* @param mixed $default Default value.
*
* @return mixed
*/
public function get_compose_value( $setting, $option, $attrs, $default = null ) {
return $this->is_enabled( $option, $attrs )
? $this->get_raw_value( $setting, $attrs, $default )
: $default;
}
/**
* Returns setting sticky raw value;
* If it does not exist, return $default specified value
*
* @since 4.6.0
*
* @param string $setting Field name.
* @param array $attrs Module attributes.
* @param mixed $default Default value.
*
* @return mixed
*/
public function get_raw_value( $setting, $attrs, $default = null ) {
return et_()->array_get( $attrs, $this->get_sticky_field( $setting ), $default );
}
/**
* Adds sticky state selector prefix before given selectors
*
* @since 4.6.0
*
* @param string|array $selector CSS Selector.
* @param bool $is_sticky Whether current module is sticky or not, based on
* `sticky_position` prop value.
* @param bool $return_string Return modified selector as string or not.
*
* @return string
*/
public function add_sticky_to_selectors( $selector, $is_sticky = true, $return_string = true ) {
$selectors = is_array( $selector ) ? $selector : explode( ',', $selector );
$space = $is_sticky ? '' : ' ';
$prefix = ".et_pb_sticky{$space}";
$prefixed_selector = array();
foreach ( $selectors as $selector ) {
$prefixed_selector[] = $prefix . trim( $selector );
}
return $return_string ? implode( ', ', $prefixed_selector ) : $prefixed_selector;
}
/**
* Add sticky state selector prefix to given selector
*
* @since 4.6.0
*
* @param string $selector CSS Selector.
* @param bool $is_sticky whether current module is sticky or not, based on `sticky_position`
* prop value.
*
* @return string
*/
public function add_sticky_to_order_class( $selector, $is_sticky = true ) {
$selectors = explode( ',', $selector );
$selectors = array_map(
function( $selector ) use ( $is_sticky ) {
$selector = trim( $selector );
// If current selector is sticky module, sticky selector is directly attached; if it isn't
// it is safe to assume that the sticky selector is one of its parent DOM, hence the space.
if ( ! $is_sticky ) {
$selector = ' ' . $selector;
}
return '.et_pb_sticky' . $selector;
},
$selectors
);
return implode( ', ', $selectors );
}
/**
* Check if given attrs has incompatible attribute value which makes sticky mechanism can't
* be used on current module
*
* @since 4.6.0
*
* @param array $attrs Module attributes.
*
* @return bool
*/
public function has_incompatible_attrs( $attrs = array() ) {
$incompatible = false;
$fields = $this->get_incompatible_fields();
foreach ( $fields as $name => $options ) {
// Get attribute value of current incompatible field from attributes.
$attr = ! empty( $attrs[ $name ] ) ? $attrs[ $name ] : false;
// If the value exist on current incompatible field's options, stop loop and return true.
if ( in_array( $attr, $options, true ) ) {
$incompatible = true;
break;
}
}
return $incompatible;
}
/**
* List of fields and its value which prevent sticky mechanism to work due to how it behaves
*
* @since 4.6.0
*
* @return array
*/
public function get_incompatible_fields() {
return array(
// Position Options.
'positioning' => array( 'absolute', 'fixed' ),
// Motion Effects.
'scroll_vertical_motion_enable' => array( 'on' ),
'scroll_horizontal_motion_enable' => array( 'on' ),
'scroll_fade_enable' => array( 'on' ),
'scroll_scaling_enable' => array( 'on' ),
'scroll_rotating_enable' => array( 'on' ),
'scroll_blur_enable' => array( 'on' ),
);
}
}

View File

@@ -0,0 +1,372 @@
<?php
/**
* Style Processor
*
* @package Divi
* @sub-package Builder
* @since 4.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
// Include dependency for ResponsiveOptions.
if ( ! function_exists( 'et_pb_responsive_options' ) ) {
require_once 'ResponsiveOptions.php';
}
/**
* Icon Font helper methods.
*
* @since 4.6.0
*
* Class ET_Builder_Module_Helper_Style_Processor
*/
class ET_Builder_Module_Helper_Style_Processor {
/**
* Custom `generate_styles()` processor for responsive, hover, and sticky styles of `icon_font_size`
* attributes which sets right property value of font icon in accordion/toggle title.
*
* @since 4.6.0
*
* @used-by ET_Builder_Module_Accordion->render()
* @used-by ET_Builder_Module_Toggle->render()
*
* @param string $selector CSS Selector.
* @param string|array $option_value Option value.
* @param array $args Arguments.
* @param string $option_type Option type (responsive|sticky|hover).
*/
public static function process_toggle_title_icon_font_size( $selector, $option_value, $args, $option_type ) {
$icon_font_size_default = '16px'; // Default toggle icon size.
if ( 'responsive' === $option_type ) {
$icon_font_size_right_values = array();
foreach ( $option_value as $device => $value ) {
$icon_font_size_active = isset( $option_value[ $device ] ) ? $option_value[ $device ] : 0;
if ( ! empty( $icon_font_size_active ) && $icon_font_size_active !== $icon_font_size_default ) {
$icon_font_size_active_int = (int) $icon_font_size_active;
$icon_font_size_active_unit = str_replace( $icon_font_size_active_int, '', $icon_font_size_active );
$icon_font_size_active_diff = (int) $icon_font_size_default - $icon_font_size_active_int;
if ( 0 !== $icon_font_size_active_diff ) {
// 2 is representation of left & right sides.
$icon_font_size_right_values[ $device ] = round( $icon_font_size_active_diff / 2 ) . $icon_font_size_active_unit;
}
}
}
// Icon Font Size.
et_pb_responsive_options()->generate_responsive_css(
$option_value,
$selector,
$args['css_property'],
$args['render_slug']
);
// Right property.
et_pb_responsive_options()->generate_responsive_css(
$icon_font_size_right_values,
$selector,
'right',
$args['render_slug']
);
} elseif ( in_array( $option_type, array( 'sticky', 'hover' ), true ) ) {
$helper = 'sticky' === $option_type ? et_pb_sticky_options() : et_pb_hover_options();
$is_enabled = $helper->is_enabled( $args['base_attr_name'], $args['attrs'] );
if ( $is_enabled && $option_value !== $icon_font_size_default && '' !== $option_value ) {
$icon_font_size_mode_int = (int) $option_value;
$icon_font_size_mode_unit = str_replace( $icon_font_size_mode_int, '', $option_value );
$icon_font_size_mode_diff = (int) $icon_font_size_default - $icon_font_size_mode_int;
// Icon Font Size.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
'font-size:%1$s;',
esc_html( $option_value )
),
)
);
if ( 0 !== $icon_font_size_mode_diff ) {
// 2 is representation of left & right sides.
$icon_font_size_right_mode = round( $icon_font_size_mode_diff / 2 ) . $icon_font_size_mode_unit;
// Right property.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
'right:%1$s;',
esc_html( $icon_font_size_right_mode )
),
)
);
}
}
}
}
/**
* Prepare and set icon styles(CSS properties `font-family` and `content`)
* for the specified $selector.
*
* @since ?
*
* @param string $icon_value Extended Icon data.
* @param string $render_slug Module slug.
* @param string $selector CSS selector for icon container.
* @param string $render_type If that param equal `icon_font_family_and_content` then CSS propert `content` will be also set.
* @param string $media_query Media query name e.g max_width_767, max_width_980.
* @param bool $important Is CSS decalration should containt `!important`.
*
* @return void.
*/
private static function _set_icon_styles( $icon_value, $render_slug, $selector, $render_type, $media_query, $important ) {
$css_decalration_and_values['font-family:%1$s;'] = et_pb_get_icon_font_family( $icon_value );
$css_decalration_and_values['font-weight:%1$s;'] = et_pb_get_icon_font_weight( $icon_value );
if ( 'icon_font_family_and_content' === $render_type ) {
$css_decalration_and_values['content:%1$s;'] = et_pb_get_extended_icon_value_for_css( $icon_value );
};
foreach ( $css_decalration_and_values as $declaration => $value ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => $selector,
'declaration' => sprintf(
$declaration,
$value . ( $important ? ' !important' : '' )
),
'media_query' => $media_query,
)
);
}
}
/**
* Custom `generate_styles()` processor for extended icon's css style such as `font-family` or `content`.
*
* @since ?
*
* @param string $selector CSS Selector.
* @param string|array $option_value Option value.
* @param array $args Arguments.
* @param string $option_type Option type (responsive|sticky|hover).
*
* @return void.
*/
public static function process_extended_icon( $selector, $option_value, $args, $option_type ) {
$is_important = ! empty( $args['important'] );
if ( ! empty( $args['utility_arg'] ) && in_array( $args['utility_arg'], array( 'icon_font_family_and_content', 'icon_font_family' ), true ) ) {
$type = $args['utility_arg'];
} else {
return;
}
if ( 'responsive' === $option_type ) {
foreach ( $option_value as $breakpoint => $icon_value ) {
if ( empty( $icon_value ) ) {
continue;
}
$media_query = 'general';
if ( 'tablet' === $breakpoint ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_980' );
} elseif ( 'phone' === $breakpoint ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_767' );
}
self::_set_icon_styles( $icon_value, $args['render_slug'], $selector, $type, $media_query, $is_important );
}
} elseif ( in_array( $option_type, array( 'sticky', 'hover' ), true ) ) {
$helper = 'sticky' === $option_type ? et_pb_sticky_options() : et_pb_hover_options();
$is_enabled = $helper->is_enabled( $args['base_attr_name'], $args['attrs'] );
if ( $is_enabled && ! empty( $option_value ) ) {
self::_set_icon_styles( $option_value, $args['render_slug'], $selector, $type, 'general', $is_important );
}
}
}
/**
* Custom `generate_styles()` processor for responsive, hover, and sticky styles of
* `icon_font_size` attributes which sets css properties for social media follow's icon and
* its dimension.
*
* @since 4.6.0
*
* @used-by ET_Builder_Module_Social_Media_Follow->render()
* @used-by ET_Builder_Module_Social_Media_Follow_Item->render()
*
* @param string $selector CSS Selector.
* @param string|array $option_value Option value.
* @param array $args Arguments.
* @param string $option_type Option type (responsive|sticky|hover).
*/
public static function process_social_media_icon_font_size( $selector, $option_value, $args, $option_type ) {
if ( 'responsive' === $option_type ) {
foreach ( $option_value as $font_size_key => $font_size_value ) {
if ( '' === $font_size_value ) {
continue;
}
$media_query = 'general';
if ( 'tablet' === $font_size_key ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_980' );
} elseif ( 'phone' === $font_size_key ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_767' );
}
$font_size_value_double = et_builder_multiply_value_has_unit( $font_size_value, 2, 0 );
// Icon.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
'font-size:%1$s; line-height:%2$s; height:%2$s; width:%2$s;',
esc_html( $font_size_value ),
esc_html( $font_size_value_double )
),
'media_query' => $media_query,
)
);
// Icon Wrapper.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $args['selector_wrapper'],
'declaration' => sprintf(
'height:%1$s; width:%1$s;',
esc_html( $font_size_value_double )
),
'media_query' => $media_query,
)
);
}
} elseif ( in_array( $option_type, array( 'sticky', 'hover' ), true ) ) {
$helper = 'sticky' === $option_type ? et_pb_sticky_options() : et_pb_hover_options();
$is_enabled = $helper->is_enabled( $args['base_attr_name'], $args['attrs'] );
if ( $is_enabled && '' !== $option_value ) {
$option_value_double = et_builder_multiply_value_has_unit( $option_value, 2, 0 );
// Selector wrapper isn't default argument so it needs to be turned into sticky /
// hover selector manually here.
$selector_wrapper = 'hover' === $option_type ?
$helper->add_hover_to_selectors( $args['selector_wrapper'] ) :
$helper->add_sticky_to_selectors( $args['selector_wrapper'], $args['is_sticky_module'] );
// Icon.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
'font-size:%1$s; line-height:%2$s; height:%2$s; width:%2$s;',
esc_html( $option_value ),
esc_html( $option_value_double )
),
)
);
// Icon Wrapper.
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector_wrapper,
'declaration' => sprintf(
'height:%1$s; width:%1$s;',
esc_html( $option_value_double )
),
)
);
}
}
}
/**
* Custom `generate_styles()` processor for responsive, hover, and sticky styles of
* `icon_font_size` attributes which sets the size of overlay icon.
*
* @since 4.6.0
*
* @used-by ET_Builder_Module_Testimonial->render()
* @used-by ET_Builder_Module_Video->render()
* @used-by ET_Builder_Module_Video_Slider->render()
* @used-by ET_Builder_Module_Video_Slider_Item->render()
*
* @param string $selector CSS Selector.
* @param string|array $value Option value.
* @param array $args Arguments.
* @param string $option_type Option type (responsive|sticky|hover).
*/
public static function process_overlay_icon_font_size( $selector, $value, $args, $option_type ) {
$declaration_format = '' !== $args['processor_declaration_format'] ?
$args['processor_declaration_format'] :
'font-size:%1$s; line-height:%1$s; margin-top:-%2$s; margin-left:-%2$s;';
if ( 'responsive' === $option_type ) {
foreach ( $value as $breakpoint => $font_size_value ) {
if ( '' === $font_size_value ) {
continue;
}
$media_query = 'general';
if ( 'tablet' === $breakpoint ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_980' );
} elseif ( 'phone' === $breakpoint ) {
$media_query = ET_Builder_Element::get_media_query( 'max_width_767' );
}
$font_size_value_half = et_builder_multiply_value_has_unit( $font_size_value, 0.5, 0 );
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
$declaration_format,
esc_html( $font_size_value ),
esc_html( $font_size_value_half )
),
'media_query' => $media_query,
)
);
}
} elseif ( in_array( $option_type, array( 'sticky', 'hover' ), true ) ) {
$helper = 'sticky' === $option_type ? et_pb_sticky_options() : et_pb_hover_options();
$is_enabled = $helper->is_enabled( $args['base_attr_name'], $args['attrs'] );
if ( $is_enabled && '' !== $value ) {
$value_half = et_builder_multiply_value_has_unit( $value, 0.5, 0 );
ET_Builder_Element::set_style(
$args['render_slug'],
array(
'selector' => $selector,
'declaration' => sprintf(
$declaration_format,
esc_html( $value ),
esc_html( $value_half )
),
)
);
}
}
}
}

View File

@@ -0,0 +1,110 @@
<?php if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Transition Options helper methods
*
* Class ET_Builder_Module_Transition_Options
*/
class ET_Builder_Module_Helper_Transition_Options {
private static $instance;
public static function get() {
if ( empty( self::$instance ) ) {
self::$instance = new ET_Builder_Module_Helper_Transition_Options();
}
return self::$instance;
}
/**
* Return transition value.
*
* @since 3.23 Add $device param to support responsive settings.
*
* @param string $key
* @param array $list
* @param string $default
* @param string $device
*
* @return void
*/
private function get_value( $key, $list, $default = null, $device = 'desktop' ) {
$value = (string) ET_Core_Data_Utils::instance()->array_get( $list, $key );
if ( 'desktop' !== $device ) {
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$is_enabled = $responsive->is_responsive_enabled( $list, $key );
$value = $is_enabled ? $responsive->get_any_value( $list, "{$key}_{$device}", $value, true ) : $value;
}
return '' === $value ? $default : $value;
}
/**
* Returns the module transition duration,
* In case the setting is empty, a default value is returned
*
* @since 3.23 Add $device param to support responsive settings.
*
* @param array $props
* @param string $device
*
* @return string
*/
public function get_duration( $props, $device = 'desktop' ) {
return $this->get_value( 'hover_transition_duration', $props, '300ms', $device );
}
/**
* Returns the module transition speed curve,
* In case the setting is empty, a default value is returned
*
* @since 3.23 Add $device param to support responsive settings.
*
* @param array $props
* @param string $device
*
* @return string
*/
public function get_easing( $props, $device = 'desktop' ) {
return $this->get_value( 'hover_transition_speed_curve', $props, 'ease', $device );
}
/**
* Returns the module transition transition delay,
* In case the setting is empty, a default value is returned
*
* @since 3.23 Add $device param to support responsive settings.
*
* @param array $props
* @param string $device
*
* @return string
*/
public function get_delay( $props, $device = 'desktop' ) {
return $this->get_value( 'hover_transition_delay', $props, '0ms', $device );
}
/**
* Return transition styles.
*
* @since 3.23 Add $device param to support responsive settings.
*
* @param string $property
* @param array $props
* @param string $device
*
* @return string
*/
public function get_style( $property, $props, $device = 'desktop' ) {
$duration = $this->get_duration( $props, $device = 'desktop' );
$easing = $this->get_easing( $props, $device = 'desktop' );
$delay = $this->get_delay( $props, $device = 'desktop' );
return "{$property} {$duration} {$easing} {$delay}";
}
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* Helper class that provides necessary functions for managing width option
*
* Class ET_Builder_Module_Helper_Width
*/
class ET_Builder_Module_Helper_Width extends ET_Builder_Module_Helper_Sizing {
public function get_raw_field() {
return 'width';
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
<?php
class ET_Builder_Module_Helper_Motion_Blur extends ET_Builder_Module_Helper_Motion_Sanitizer {
/**
* @param string $value
*
* @return string
*/
protected function sanitize( $value ) {
$unit = et_pb_get_value_unit( $value );
$unit = in_array( $unit, $this->get_units() ) ? $unit : $this->get_default_unit();
return (float) $value . $unit;
}
protected function get_units() {
return array( 'cm', 'em', 'mm', 'in', 'pc', 'pt', 'px', 'rem' );
}
protected function get_default_unit() {
return 'px';
}
}

View File

@@ -0,0 +1,369 @@
<?php
/**
* Motion Helper class.
*
* @package Divi
* @subpackage Builder
*/
/**
* Motion Helpers.
*/
class ET_Builder_Module_Helper_Motion_Motions {
private $START_LIMIT = 0;
private $START_MIDDLE = 1;
private $END_MIDDLE = 2;
private $END_LIMIT = 3;
private $START_VALUE = 4;
private $MIDDLE_VALUE = 5;
private $END_VALUE = 6;
private $LENGTH = 7;
private static $instance;
public static function instance() {
return self::$instance ? self::$instance : ( self::$instance = new self() );
}
/**
* Returns the Motion Effect value. Which is the merge of Saved and Default values.
*
* @param string $value, $default_value
*
* @return string
*/
public function getValue( $saved_value, $default_value ) {
if ( $saved_value === $default_value ) {
return $saved_value;
}
$saved_array = explode( '|', $saved_value );
$default_array = explode( '|', $default_value );
if ( sizeof( $saved_array ) !== sizeof( $default_array ) ) {
return $saved_value;
}
return implode( '|', array_map( array( 'ET_Builder_Module_Helper_Motion_Motions', 'getNonEmpty' ), $saved_array, $default_array ) );
}
/**
* Returns the non-empty value or default.
*
* @param string $value, $default
*
* @return string
*/
public static function getNonEmpty( $value, $default ) {
if ( '' === $value ) {
return $default;
}
return $value;
}
/**
* Returns start limit.
*
* @param string $value
*
* @return int
*/
public function getStartLimit( $value ) {
return $this->get( $this->START_LIMIT, $value );
}
/**
* Set start limit.
*
* If limit:
* - is not a numeric value, return original motionValue
* - is lower then 0, set limit to 0
* - is higher then start middle, set limit equal to start middle
*
* @param int $value
* @param string $multi_value
*
* @return string
*/
public function setStartLimit( $value, $multi_value ) {
$value = $this->to_int( $value, $this->getStartLimit( $multi_value ) );
$ranged = $this->range( 0, $this->getStartMiddle( $multi_value ), $value );
return $this->set( $this->START_LIMIT, $ranged, $multi_value );
}
/**
* Returns start limit.
*
* @param string $value
*
* @return int
*/
public function getEndLimit( $value ) {
return $this->get( $this->END_LIMIT, $value );
}
/**
* Set end limit.
*
* If limit:
* - is not a numeric value, return original motionValue
* - is lower then end middle, set limit equal to end middle
* - is higher then 100, set limit equal to 100
*
* @param int $value
* @param string $multi_value
*
* @return string
*/
public function setEndLimit( $value, $multi_value ) {
$value = $this->to_int( $value, $this->getEndLimit( $multi_value ) );
$ranged = $this->range( $this->getEndMiddle( $multi_value ), 100, $value );
return $this->set( $this->END_LIMIT, $ranged, $multi_value );
}
/**
* Get start middle.
*
* @param $value
*
* @return int
*/
public function getStartMiddle( $value ) {
return $this->get( $this->START_MIDDLE, $value );
}
/**
* Set start middle limit.
*
* If limit:
* - is not a numeric value, return original motionValue
* - is lower then start limit, set limit equal to start limit
* - is higher then end middle, set limit equal to end middle
*
* @param int $value
* @param string $multi_value
*
* @return string
*/
public function setStartMiddle( $value, $multi_value ) {
$value = $this->to_int( $value, $this->getStartMiddle( $multi_value ) );
$ranged = $this->range( $this->getStartLimit( $value ), $this->getEndMiddle( $value ), $value );
return $this->set( $this->START_MIDDLE, $ranged, $multi_value );
}
/**
* Get end middle.
*
* @param $value
*
* @return int
*/
public function getEndMiddle( $value ) {
return $this->get( $this->END_MIDDLE, $value );
}
/**
* Set end middle limit.
*
* If limit:
* - is not a numeric value, return original motionValue
* - is lower then start middle limit, set limit equal to start middle limit
* - is higher then end limit, set limit equal to end limit
*
* @param int $value
* @param string $multi_value
*
* @return string
*/
public function setEndMiddle( $value, $multi_value ) {
$value = $this->to_int( $value, $this->getEndMiddle( $multi_value ) );
$ranged = $this->range( $this->getStartMiddle( $value ), $this->getEndLimit( $value ), $value );
return $this->set( $this->END_MIDDLE, $ranged, $multi_value );
}
/**
* Returns option value for start.
*
* @param string $value
*
* @return string
*/
public function getStartValue( $value ) {
return $this->get( $this->START_VALUE, $value );
}
/**
* Sets option value for start.
*
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setStartValue( $value, $multi_value ) {
return $this->set( $this->START_VALUE, $value, $multi_value );
}
/**
* Returns option value for middle.
*
* @param string $value
*
* @return string
*/
public function getMiddleValue( $value ) {
return $this->get( $this->MIDDLE_VALUE, $value );
}
/**
* Sets option value for middle.
*
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setMiddleValue( $value, $multi_value ) {
return $this->set( $this->MIDDLE_VALUE, $value, $multi_value );
}
/**
* Returns option value for end.
*
* @param string $value
*
* @return string
*/
public function getEndValue( $value ) {
return $this->get( $this->END_VALUE, $value );
}
/**
* Sets option value for end.
*
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setEndValue( $value, $multi_value ) {
return $this->set( $this->END_VALUE, $value, $multi_value );
}
/**
* Same as Multi.merge, but applies the elements parameter
*
* @param string $value_1
* @param string $value_2
*
* @return string
*/
public function merge( $value_1, $value_2 ) {
return $this->to_value( $this->split( $this->multi()->merge( $value_1, $value_2, $this->LENGTH ) ) );
}
/**
* Parses array value and converts it to a valid motion array
* - array length should be 7
* - first 4 values should be numeric values
* - first 4 values should respect 0-100 boundaries
* - first 4 values should be ordered in ascending order
* - last 3 values should be string values
*
* @param array $value
*
* @return array
*/
protected function parse( array $value ) {
$arr = $this->multi()->parse( $value, $this->LENGTH );
$range = array();
$range[ $this->START_LIMIT ] = $this->to_int( array_shift( $arr ), 0 );
$range[ $this->START_MIDDLE ] = $this->to_int( array_shift( $arr ), 50 );
$range[ $this->END_MIDDLE ] = $this->to_int( array_shift( $arr ), 50 );
$range[ $this->END_LIMIT ] = $this->to_int( array_shift( $arr ), 100 );
sort( $range, SORT_NUMERIC );
$range[ $this->START_LIMIT ] = max( $range[ $this->START_LIMIT ], 0 );
$range[ $this->END_LIMIT ] = min( $range[ $this->END_LIMIT ], 100 );
$range[ $this->START_MIDDLE ] = max( $range[ $this->START_MIDDLE ], $range[ $this->START_LIMIT ] );
$range[ $this->END_MIDDLE ] = min( $range[ $this->END_LIMIT ], $range[ $this->END_MIDDLE ] );
return array_merge( $range, $arr );
}
/**
* Converts a value to a valid motion array value.
*
* @param string $value
*
* @return array
*/
protected function split( $value ) {
return $this->parse( $this->multi()->split( $value, $this->LENGTH ) );
}
/**
* Converts a value to a valid motion string value.
*
* @param array $value
*
* @return string
*/
protected function to_value( array $value ) {
return $this->multi()->to_value( $this->parse( $value ), $this->LENGTH );
}
/**
* @return ET_Builder_Module_Helper_Multi_Value
*/
protected function multi() {
return ET_Builder_Module_Helper_Multi_Value::instance();
}
/**
* Returns specific key value
*
* @param int $key
* @param string $value
*
* @return mixed
*/
protected function get( $key, $value ) {
$arr = $this->parse( $this->multi()->split( $value, $this->LENGTH ) );
return $arr[ $key ];
}
/**
* @param int $key
* @param $value
* @param string $multi_value
*
* @return string
*/
protected function set( $key, $value, $multi_value ) {
return $this->multi()->set( $key, $value, $multi_value, $this->LENGTH );
}
private function to_int( $value, $default ) {
return is_numeric( $value ) ? (int) $value : $default;
}
/**
* @param int $min
* @param int $max
* @param int $value
*
* @return int
*/
private function range( $min, $max, $value ) {
return min( $max, max( $min, $value ) );
}
}

View File

@@ -0,0 +1,13 @@
<?php
class ET_Builder_Module_Helper_Motion_Opacity extends ET_Builder_Module_Helper_Motion_Sanitizer {
/**
* @param string $value
*
* @return string
*/
protected function sanitize( $value ) {
return min( 100, max( 0, (int) $value ) ) . '%';
}
}

View File

@@ -0,0 +1,13 @@
<?php
class ET_Builder_Module_Helper_Motion_Rotate extends ET_Builder_Module_Helper_Motion_Sanitizer {
/**
* @param string $value
*
* @return string
*/
protected function sanitize( $value ) {
return min( 0, (int) $value ) . 'deg';
}
}

View File

@@ -0,0 +1,62 @@
<?php
abstract class ET_Builder_Module_Helper_Motion_Sanitizer extends ET_Builder_Module_Helper_Motion {
/**
* @param string $value
*
* @return string
*/
public function getStartValue( $value ) {
return $this->sanitize( parent::getStartValue( $value ) );
}
/**
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setStartValue( $value, $multi_value ) {
return parent::setStartValue( $this->sanitize( $value ), $multi_value );
}
/**
* @param string $value
*
* @return string
*/
public function getMiddleValue( $value ) {
return $this->sanitize( parent::getMiddleValue( $value ) );
}
/**
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setMiddleValue( $value, $multi_value ) {
return parent::setMiddleValue( $this->sanitize( $value ), $multi_value );
}
/**
* @param string $value
*
* @return string
*/
public function getEndValue( $value ) {
return $this->sanitize( parent::getEndValue( $value ) );
}
/**
* @param string $value
* @param string $multi_value
*
* @return string
*/
public function setEndValue( $value, $multi_value ) {
return parent::setEndValue( $this->sanitize( $value ), $multi_value );
}
abstract protected function sanitize( $value );
}

View File

@@ -0,0 +1,13 @@
<?php
class ET_Builder_Module_Helper_Motion_Scale extends ET_Builder_Module_Helper_Motion_Sanitizer {
/**
* @param string $value
*
* @return string
*/
protected function sanitize( $value ) {
return min( 0, (int) $value );
}
}

View File

@@ -0,0 +1,13 @@
<?php
class ET_Builder_Module_Helper_Motion_Translate extends ET_Builder_Module_Helper_Motion_Sanitizer {
/**
* @param string $value
*
* @return string
*/
protected function sanitize( $value ) {
return (float) $value;
}
}