Commit realizado el 12:13:52 08-04-2024
This commit is contained in:
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
158
wp-content/themes/Divi/includes/builder/module/helpers/Font.php
Normal file
158
wp-content/themes/Divi/includes/builder/module/helpers/Font.php
Normal 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;
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
@@ -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';
|
||||
}
|
||||
}
|
||||
|
@@ -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';
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
||||
|
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
@@ -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
@@ -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 );
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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' ),
|
||||
);
|
||||
}
|
||||
}
|
@@ -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 )
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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}";
|
||||
}
|
||||
}
|
||||
|
@@ -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
@@ -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';
|
||||
}
|
||||
}
|
@@ -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 ) );
|
||||
}
|
||||
}
|
@@ -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 ) ) . '%';
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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 );
|
||||
}
|
@@ -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 );
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user