version 4.13.0

This commit is contained in:
2021-12-07 11:08:05 +00:00
commit cb26d2c0c4
1285 changed files with 254735 additions and 0 deletions

View File

@ -0,0 +1,433 @@
<?php
class ET_Builder_Module_Accordion extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Accordion', 'et_builder' );
$this->plural = esc_html__( 'Accordions', 'et_builder' );
$this->slug = 'et_pb_accordion';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_accordion_item';
$this->main_css_element = '%%order_class%%.et_pb_accordion';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'extended_icon' => esc_html__( 'Toggle Icon', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
'toggle_layout' => esc_html__( 'Toggle', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_accordion_item",
'border_styles' => "{$this->main_css_element} .et_pb_accordion_item",
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#d9d9d9',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_toggle',
),
),
),
'fonts' => array(
'toggle' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h5.et_pb_toggle_title, {$this->main_css_element} h1.et_pb_toggle_title, {$this->main_css_element} h2.et_pb_toggle_title, {$this->main_css_element} h3.et_pb_toggle_title, {$this->main_css_element} h4.et_pb_toggle_title, {$this->main_css_element} h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h5',
),
'options_priority' => array(
'toggle_text_color' => 9,
),
),
'closed_toggle' => array(
'label' => esc_html__( 'Closed Title', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_toggle_close h5.et_pb_toggle_title, {$this->main_css_element} .et_pb_toggle_close h1.et_pb_toggle_title, {$this->main_css_element} .et_pb_toggle_close h2.et_pb_toggle_title, {$this->main_css_element} .et_pb_toggle_close h3.et_pb_toggle_title, {$this->main_css_element} .et_pb_toggle_close h4.et_pb_toggle_title, {$this->main_css_element} .et_pb_toggle_close h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'hide_text_color' => true,
'line_height' => array(
'default' => '1.7em',
),
'font_size' => array(
'default' => '16px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_toggle_content",
'limited_main' => "{$this->main_css_element} .et_pb_toggle_content, {$this->main_css_element} .et_pb_toggle_content p",
'line_height' => "{$this->main_css_element} .et_pb_toggle_content p",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
),
'margin_padding' => array(
'draggable_padding' => false,
'css' => array(
'padding' => "{$this->main_css_element} .et_pb_toggle_content",
'margin' => $this->main_css_element,
'important' => array( 'custom_margin' ),
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
);
$this->custom_css_fields = array(
'toggle' => array(
'label' => esc_html__( 'Toggle', 'et_builder' ),
'selector' => '.et_pb_toggle',
),
'open_toggle' => array(
'label' => esc_html__( 'Open Toggle', 'et_builder' ),
'selector' => '.et_pb_toggle_open',
),
'toggle_title' => array(
'label' => esc_html__( 'Toggle Title', 'et_builder' ),
'selector' => '.et_pb_toggle_title',
),
'toggle_icon' => array(
'label' => esc_html__( 'Toggle Icon', 'et_builder' ),
'selector' => '.et_pb_toggle_title:before',
),
'toggle_content' => array(
'label' => esc_html__( 'Toggle Content', 'et_builder' ),
'selector' => '.et_pb_toggle_content',
),
);
$this->help_videos = array(
array(
'id' => 'OBbuKXTJyj8',
'name' => esc_html__( 'An introduction to the Accordion module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'open_toggle_text_color' => array(
'label' => esc_html__( 'Open Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the open state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'open_toggle_background_color' => array(
'label' => esc_html__( 'Open Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the open state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle_layout',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_text_color' => array(
'label' => esc_html__( 'Closed Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the closed state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'closed_toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_background_color' => array(
'label' => esc_html__( 'Closed Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the closed state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle_layout',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'toggle_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'toggle_slug' => 'extended_icon',
'type' => 'select_icon',
'option_category' => 'basic_option',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
),
'icon_color' => array(
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the toggle icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'sticky' => true,
'depends_show_if' => 'on',
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$title = '%%order_class%% .et_pb_toggle .et_pb_toggle_title';
$fields['icon_color'] = array( 'color' => '%%order_class%% .et_pb_toggle .et_pb_toggle_title:before' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%% .et_pb_toggle .et_pb_toggle_title:before',
'margin-top' => '%%order_class%% .et_pb_toggle .et_pb_toggle_title:before',
'right' => '%%order_class%% .et_pb_toggle .et_pb_toggle_title:before',
);
$fields['toggle_text_color'] = array( 'color' => $title );
$fields['toggle_font_size'] = array( 'font-size' => $title );
$fields['toggle_letter_spacing'] = array( 'letter-spacing' => $title );
$fields['toggle_line_height'] = array( 'line-height' => $title );
$fields['toggle_text_shadow_style'] = array( 'text-shadow' => $title );
$fields['closed_toggle_text_color'] = array( 'color' => '%%order_class%%.et_pb_accordion .et_pb_toggle_close .et_pb_toggle_title' );
$fields['closed_toggle_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_toggle_close' );
$fields['open_toggle_text_color'] = array( 'color' => '%%order_class%%.et_pb_accordion .et_pb_toggle_open .et_pb_toggle_title' );
$fields['open_toggle_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_toggle_open' );
return $fields;
}
function before_render() {
global $et_pb_accordion_item_number, $et_pb_accordion_header_level;
$et_pb_accordion_item_number = 1;
$et_pb_accordion_header_level = $this->props['toggle_level'];
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_accordion_item_number;
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Open Toggle Background Color.
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'open_toggle_background_color',
'css_property' => 'background-color',
'selector' => '%%order_class%% .et_pb_toggle_open',
)
);
// Closed Toggle Background Color.
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'closed_toggle_background_color',
'css_property' => 'background-color',
'selector' => '%%order_class%% .et_pb_toggle_close',
)
);
// Open Toggle Text Color.
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'open_toggle_text_color',
'css_property' => 'color',
'important' => true,
'selector' => '%%order_class%%.et_pb_accordion .et_pb_toggle_open h5.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_open h1.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_open h2.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_open h3.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_open h4.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_open h6.et_pb_toggle_title',
'hover_selector' => '%%order_class%%:hover .et_pb_toggle_open h5.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_open h1.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_open h2.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_open h3.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_open h4.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_open h6.et_pb_toggle_title',
)
);
// Closed Toggle Text Color.
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'closed_toggle_text_color',
'css_property' => 'color',
'important' => true,
'selector' => '%%order_class%%.et_pb_accordion .et_pb_toggle_close h5.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_close h1.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_close h2.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_close h3.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_close h4.et_pb_toggle_title, %%order_class%%.et_pb_accordion .et_pb_toggle_close h6.et_pb_toggle_title',
'hover_selector' => '%%order_class%%:hover .et_pb_toggle_close h5.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_close h1.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_close h2.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_close h3.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_close h4.et_pb_toggle_title, %%order_class%%:hover .et_pb_toggle_close h6.et_pb_toggle_title',
)
);
// Icon Size.
$use_icon_font_size = $this->props['use_icon_font_size'];
if ( 'off' !== $use_icon_font_size ) {
// Calculate icon font size and its right position.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%% .et_pb_toggle_title:before',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'css_property' => 'font-size',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_toggle_title_icon_font_size',
),
)
);
}
// Icon Color.
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'icon_color',
'css_property' => 'color',
'selector' => '%%order_class%% .et_pb_toggle_title:before',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'priority' => ET_Builder_Element::DEFAULT_PRIORITY,
)
);
// Module classnames.
$this->add_classname( $this->get_text_orientation_classname() );
// Toggle Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'toggle_icon',
'important' => true,
'selector' => '%%order_class%% .et_pb_toggle_title:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
$output = sprintf(
'<div%3$s class="%2$s">
%5$s
%4$s
%1$s
</div>',
$this->content,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background
);
return $output;
}
public function add_new_child_text() {
return esc_html__( 'Add New Accordion Item', 'et_builder' );
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Accordion();
}

View File

@ -0,0 +1,298 @@
<?php
class ET_Builder_Module_Accordion_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Accordion', 'et_builder' );
$this->plural = esc_html__( 'Accordions', 'et_builder' );
$this->slug = 'et_pb_accordion_item';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'title';
$this->no_render = true;
$this->main_css_element = '%%order_class%%.et_pb_toggle';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
'toggle_layout' => esc_html__( 'Toggle', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'toggle' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h5.et_pb_toggle_title, {$this->main_css_element} h1.et_pb_toggle_title, {$this->main_css_element} h2.et_pb_toggle_title, {$this->main_css_element} h3.et_pb_toggle_title, {$this->main_css_element} h4.et_pb_toggle_title, {$this->main_css_element} h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h5',
),
'options_priority' => array(
'toggle_text_color' => 9,
),
),
'closed_toggle' => array(
'label' => esc_html__( 'Closed Toggle', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_toggle_close h5.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h1.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h2.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h3.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h4.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'hide_text_color' => true,
'line_height' => array(
'default' => '1.7em',
),
'font_size' => array(
'default' => '16px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_toggle_content",
'limited_main' => "{$this->main_css_element} .et_pb_toggle_content, {$this->main_css_element} .et_pb_toggle_content p",
'line_height' => "{$this->main_css_element} .et_pb_toggle_content p",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
// Accordion Item can use %%parent_class%% because its slug is parent_slug + `_item` suffix
'border_radii' => "%%parent_class%% .et_pb_module{$this->main_css_element}",
'border_styles' => "%%parent_class%% .et_pb_module{$this->main_css_element}",
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#d9d9d9',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'important' => true,
),
),
),
'margin_padding' => array(
'draggable_margin' => false,
'draggable_padding' => false,
'css' => array(
'important' => 'all',
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_toggle',
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%%',
),
),
'button' => false,
'sticky' => false,
'height' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_toggle_content',
),
),
'position_fields' => array(
'default' => 'relative',
),
'z_index' => array(
'default' => '1',
),
);
$this->custom_css_fields = array(
'toggle' => array(
'label' => esc_html__( 'Toggle', 'et_builder' ),
),
'open_toggle' => array(
'label' => esc_html__( 'Open Toggle', 'et_builder' ),
'selector' => '.et_pb_toggle_open',
'no_space_before_selector' => true,
),
'toggle_title' => array(
'label' => esc_html__( 'Toggle Title', 'et_builder' ),
'selector' => '.et_pb_toggle_title',
),
'toggle_icon' => array(
'label' => esc_html__( 'Toggle Icon', 'et_builder' ),
'selector' => '.et_pb_toggle_title:before',
),
'toggle_content' => array(
'label' => esc_html__( 'Toggle Content', 'et_builder' ),
'selector' => '.et_pb_toggle_content',
),
);
$this->help_videos = array(
array(
'id' => 'OBbuKXTJyj8',
'name' => esc_html__( 'An introduction to the Accordion module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'The title will appear above the content and when the toggle is closed.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'hover' => 'tabs',
'mobile_options' => true,
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Here you can define the content that will be placed within the current tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'hover' => 'tabs',
'mobile_options' => true,
),
'open_toggle_text_color' => array(
'label' => esc_html__( 'Open Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the open state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'open_toggle_background_color' => array(
'label' => esc_html__( 'Open Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the open state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle_layout',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_text_color' => array(
'label' => esc_html__( 'Closed Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the closed state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'closed_toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_background_color' => array(
'label' => esc_html__( 'Closed Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the closed state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle_layout',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'toggle_icon' => array(
'label' => esc_html__( 'Closed Icon', 'et_builder' ),
'toggle_slug' => 'icon',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'icon_color' => array(
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the toggle icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'sticky' => true,
'depends_show_if' => 'on',
'hover' => 'tabs',
),
);
return $fields;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Accordion_Item();
}

View File

@ -0,0 +1,530 @@
<?php
class ET_Builder_Module_Audio extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Audio', 'et_builder' );
$this->plural = esc_html__( 'Audios', 'et_builder' );
$this->slug = 'et_pb_audio';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_audio_module';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'audio' => esc_html__( 'Audio', 'et_builder' ),
'image' => et_builder_i18n( 'Image' ),
),
),
'advanced' => array(
'toggles' => array(
'image' => array(
'title' => et_builder_i18n( 'Image' ),
),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h2, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h2',
),
),
'caption' => array(
'label' => esc_html__( 'Caption', 'et_builder' ),
'css' => array(
'line_height' => "{$this->main_css_element} p",
'main' => "{$this->main_css_element} p",
'limited_main' => "{$this->main_css_element} p, {$this->main_css_element} p strong",
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
'css' => array(
'important' => true,
),
'options' => array(
'background_color' => array(
'default' => et_builder_accent_color(),
),
),
),
'borders' => array(
'default' => array(),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_audio_cover_art',
'border_styles' => '%%order_class%% .et_pb_audio_cover_art',
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_audio_cover_art',
'overlay' => 'inset',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
'padding' => '.et_pb_column %%order_class%% .et_pb_audio_module_content',
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_audio_module.et_pb_module',
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'text_orientation' => '%%order_class%% .et_pb_audio_module_content',
'text_shadow' => '%%order_class%% .et_pb_audio_module_content',
),
'options' => array(
'text_orientation' => array(
'default_on_front' => 'center',
),
'background_layout' => array(
'default_on_front' => 'dark',
'hover' => 'tabs',
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_audio_cover_art',
),
),
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->custom_css_fields = array(
'audio_cover_art' => array(
'label' => esc_html__( 'Audio Cover Art', 'et_builder' ),
'selector' => '.et_pb_audio_cover_art',
),
'audio_content' => array(
'label' => esc_html__( 'Audio Content', 'et_builder' ),
'selector' => '.et_pb_audio_module_content',
),
'audio_title' => array(
'label' => esc_html__( 'Audio Title', 'et_builder' ),
'selector' => '.et_pb_audio_module_content h2',
),
'audio_meta' => array(
'label' => esc_html__( 'Audio Meta', 'et_builder' ),
'selector' => '.et_audio_module_meta',
),
'audio_buttons' => array(
'label' => esc_html__( 'Player Buttons', 'et_builder' ),
'selector' => "{$this->main_css_element} .mejs-button.mejs-playpause-button button:before,{$this->main_css_element} .mejs-button.mejs-volume-button.mejs-mute button:before",
),
'audio_timer' => array(
'label' => esc_html__( 'Player Timer', 'et_builder' ),
'selector' => '.mejs-time.mejs-duration-container .mejs-duration',
),
'audio_sliders' => array(
'label' => esc_html__( 'Player Sliders', 'et_builder' ),
'selector' => "{$this->main_css_element} .et_audio_container .mejs-controls .mejs-time-rail .mejs-time-total,{$this->main_css_element} .et_audio_container .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total",
),
'audio_sliders_current' => array(
'label' => esc_html__( 'Player Sliders Current', 'et_builder' ),
'selector' => "{$this->main_css_element} .et_audio_container .mejs-controls .mejs-time-rail .mejs-time-current,{$this->main_css_element} .et_audio_container .mejs-controls .mejs-time-rail .mejs-time-handle,{$this->main_css_element} .et_audio_container .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current,{$this->main_css_element} .et_audio_container .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-handle",
),
);
$this->help_videos = array(
array(
'id' => '3bg1qUaSZ5I',
'name' => esc_html__( 'An introduction to the Audio Player module', 'et_builder' ),
),
);
}
public function get_transition_fields_css_props() {
$title = "{$this->main_css_element} .et_pb_module_header";
$meta = "{$this->main_css_element} .et_audio_module_meta";
$container = "{$this->main_css_element} .et_audio_container";
$fields = parent::get_transition_fields_css_props();
$fields['background_layout'] = array(
'color' => implode(
', ',
array(
$title,
$meta,
"{$container} .mejs-playpause-button button:before",
"{$container} .mejs-volume-button button:before",
"{$container} .mejs-container .mejs-controls .mejs-time span",
)
),
'background-color' => implode(
', ',
array(
$title,
"{$container} .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-total",
"{$container} .mejs-controls .mejs-time-rail .mejs-time-total",
"{$container} .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-current",
"{$container} .mejs-controls .mejs-time-rail .mejs-time-current",
"{$container} .mejs-controls .mejs-horizontal-volume-slider .mejs-horizontal-volume-handle",
)
),
);
$fields['text_shadow_style'] = array(
'text-shadow' => implode(
', ',
array(
$title,
$meta,
"{$this->main_css_element} .et_audio_container .mejs-container .mejs-controls .mejs-time span",
)
),
);
return $fields;
}
function get_fields() {
$fields = array(
'audio' => array(
'label' => esc_html__( 'Audio File', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'data_type' => 'audio',
'upload_button_text' => esc_attr__( 'Upload an audio file', 'et_builder' ),
'choose_text' => esc_attr__( 'Choose an Audio file', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Audio for the module', 'et_builder' ),
'description' => esc_html__( 'Define the audio file for use in the module. To remove an audio file from the module, simply delete the URL from the settings field.', 'et_builder' ),
'toggle_slug' => 'audio',
'computed_affects' => array(
'__audio',
),
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define a title.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'artist_name' => array(
'label' => esc_html__( 'Artist', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define an artist name.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'album_name' => array(
'label' => esc_html__( 'Album', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define an album name.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'image_url' => array(
'label' => et_builder_i18n( 'Image' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display.', 'et_builder' ),
'toggle_slug' => 'image',
'computed_affects' => array(
'__audio',
),
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'__audio' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Audio', 'get_audio' ),
'computed_depends_on' => array(
'audio',
),
'computed_minimum' => array(
'audio',
),
),
);
return $fields;
}
static function get_audio( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'audio' => '',
);
$args = wp_parse_args( $args, $defaults );
// remove all filters from WP audio shortcode to make sure current theme doesn't add any elements into audio module
remove_all_filters( 'wp_audio_shortcode_library' );
remove_all_filters( 'wp_audio_shortcode' );
remove_all_filters( 'wp_audio_shortcode_class' );
return do_shortcode( sprintf( '[audio src="%s" /]', $args['audio'] ) );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $wp_version;
$multi_view = et_pb_multi_view_options( $this );
$audio = $this->props['audio'];
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['title_level'], 'h2' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_module_header',
),
)
);
$artist_name = $this->_esc_attr( 'artist_name' );
$album_name = $this->_esc_attr( 'album_name' );
$image_url = $multi_view->render_element(
array(
'tag' => 'div',
'styles' => array(
'background-image' => 'url({{image_url}})',
),
'classes' => array(
'et_pb_audio_cover_art' => array(
'image_url' => '__not_empty',
),
),
'required' => 'image_url',
)
);
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$meta = '';
$metas = array();
$artist_name = $multi_view->render_element(
array(
'tag' => 'strong',
'content' => '{{artist_name}}',
)
);
if ( $artist_name ) {
$metas[] = sprintf(
et_get_safe_localization( _x( 'by %1$s', 'Audio Module meta information', 'et_builder' ) ),
et_core_esc_previously( $artist_name )
);
}
$album_name = $multi_view->render_element(
array(
'content' => '{{album_name}}',
)
);
if ( $album_name ) {
$metas[] = $album_name;
}
if ( $metas ) {
$meta = sprintf( '<p class="et_audio_module_meta">%1$s</p>', implode( ' | ', $metas ) );
}
$parallax_image_background = $this->get_parallax_image_background();
// some themes do not include these styles/scripts so we need to enqueue them in this module
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'et-builder-mediaelement' );
// remove all filters from WP audio shortcode to make sure current theme doesn't add any elements into audio module
remove_all_filters( 'wp_audio_shortcode_library' );
remove_all_filters( 'wp_audio_shortcode' );
remove_all_filters( 'wp_audio_shortcode_class' );
$video_background = $this->video_background();
// Module classnames
$this->add_classname(
array(
'et_pb_audio_module',
'clearfix',
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props, false, true );
$this->add_classname( $background_layout_class_names );
if ( '' === $image_url ) {
$this->add_classname( 'et_pb_audio_no_image' );
}
// Remove automatically added module (backward compat)
$this->remove_classname( $render_slug );
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
// WP 4.8 or lower compatibility
if ( version_compare( $wp_version, '4.9' ) === -1 ) {
$this->add_classname( 'et_pb_audio_legacy' );
}
$muti_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_audio_no_image' => array(
'image_url' => '__empty',
),
),
)
);
$output = sprintf(
'<div%6$s class="%4$s"%9$s%10$s>
%8$s
%7$s
%5$s
<div class="et_pb_audio_module_content et_audio_container">
%1$s
%2$s
%3$s
</div>
</div>',
$title, // #1
et_core_esc_previously( $meta ), // #2
self::get_audio(
array(
'audio' => $audio,
)
), // #3
$this->module_classname( $render_slug ), // #4
et_core_esc_previously( $image_url ), // #5
$this->module_id(), // #6
$video_background, // #7
$parallax_image_background, // #8
et_core_esc_previously( $data_background_layout ), // #9
et_core_esc_previously( $muti_view_data_attr ) // #10
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$fields_need_escape = array(
'title',
'artist_name',
'album_name',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Audio();
}

View File

@ -0,0 +1,292 @@
<?php
class ET_Builder_Module_Bar_Counters extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Bar Counters', 'et_builder' );
$this->plural = esc_html__( 'Bar Counters', 'et_builder' );
$this->slug = 'et_pb_counters';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_counter';
$this->child_item_text = esc_html__( 'Bar Counter', 'et_builder' );
$this->main_css_element = '%%order_class%%.et_pb_counters';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'bar' => esc_html__( 'Bar', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_counter_container, %%order_class%% .et_pb_counter_amount',
'border_styles' => '%%order_class%% .et_pb_counter_container',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_counter_container',
'overlay' => 'inset',
),
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_counter_title",
),
),
'percent' => array(
'label' => esc_html__( 'Percentage', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_counter_amount_number",
'text_align' => "{$this->main_css_element} .et_pb_counter_amount",
),
),
),
'background' => array(
'use_background_color' => 'fields_only',
'css' => array(
'main' => "{$this->main_css_element} .et_pb_counter_container",
),
'options' => array(
'background_color' => array(
'default' => '',
),
),
),
'margin_padding' => array(
'draggable_padding' => false,
'css' => array(
'margin' => "{$this->main_css_element}",
'padding' => "{$this->main_css_element} .et_pb_counter_amount",
'important' => array( 'custom_margin' ),
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default_on_front' => 'light',
'hover' => 'tabs',
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
);
$this->custom_css_fields = array(
'counter_title' => array(
'label' => esc_html__( 'Counter Title', 'et_builder' ),
'selector' => '.et_pb_counter_title',
),
'counter_container' => array(
'label' => esc_html__( 'Counter Container', 'et_builder' ),
'selector' => '.et_pb_counter_container',
),
'counter_amount' => array(
'label' => esc_html__( 'Counter Amount', 'et_builder' ),
'selector' => '.et_pb_counter_amount',
),
);
$this->help_videos = array(
array(
'id' => '2QLX8Lwr3cs',
'name' => esc_html__( 'An introduction to the Bar Counter module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'bar_bg_color' => array(
'label' => esc_html__( 'Bar Background Color', 'et_builder' ),
'type' => 'color-alpha',
'tab_slug' => 'advanced',
'toggle_slug' => 'bar',
'hover' => 'tabs',
'description' => esc_html__( 'This will change the fill color for the bar.', 'et_builder' ),
'default' => et_builder_accent_color(),
'mobile_options' => true,
'sticky' => true,
),
'use_percentages' => array(
'label' => esc_html__( 'Show Percentage', 'et_builder' ),
'description' => esc_html__( 'Turning off percentages will remove the percentage text from within the filled portion of the bar.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'toggle_slug' => 'elements',
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['background_layout'] = array( 'color' => '%%order_class%% .et_pb_counter_title' );
$fields['bar_bg_color'] = array( 'background-color' => '%%order_class%% .et_pb_counter_amount' );
return $fields;
}
function before_render() {
global $et_pb_counters_settings;
$multi_view = et_pb_multi_view_options( $this );
$background_image = $this->props['background_image'];
$parallax = $this->props['parallax'];
$parallax_method = $this->props['parallax_method'];
$background_video_mp4 = $this->props['background_video_mp4'];
$background_video_webm = $this->props['background_video_webm'];
$background_video_width = $this->props['background_video_width'];
$background_video_height = $this->props['background_video_height'];
$allow_player_pause = $this->props['allow_player_pause'];
$bar_bg_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'bar_bg_color' );
$background_video_pause_outside_viewport = $this->props['background_video_pause_outside_viewport'];
$use_background_color_gradient = $this->props['use_background_color_gradient'];
// Background Color.
$background_last_edited = self::$_->array_get( $this->props, 'background_last_edited', '' );
$background_hover_enabled = self::$_->array_get( $this->props, 'background__hover_enabled', '' );
$background_colors = et_pb_responsive_options()->get_composite_property_values( $this->props, 'background', 'background_color' );
$background_enable_colors = et_pb_responsive_options()->get_composite_property_values( $this->props, 'background', 'background_enable_color' );
$background_color_hover = et_pb_hover_options()->get_compose_value( 'background_color', 'background', $this->props, '' );
$background_enable_color_hover = et_pb_hover_options()->get_compose_value( 'background_enable_color', 'background', $this->props, '' );
// Sticky Element.
$is_sticky_module = et_pb_sticky_options()->is_sticky_module( $this->props );
$et_pb_counters_settings = array(
// Background Color.
'background_last_edited' => $background_last_edited,
'background__hover_enabled' => $background_hover_enabled,
'background_color' => $background_colors['desktop'],
'background_color_tablet' => $background_colors['tablet'],
'background_color_phone' => $background_colors['phone'],
'background_enable_color' => $background_enable_colors['desktop'],
'background_enable_color_tablet' => $background_enable_colors['tablet'],
'background_enable_color_phone' => $background_enable_colors['phone'],
'background_color_hover' => $background_color_hover,
'background_color__hover' => $background_color_hover,
'background_enable_color__hover' => $background_enable_color_hover,
'background_image' => $background_image,
'parallax' => $parallax,
'parallax_method' => $parallax_method,
'background_video_mp4' => $background_video_mp4,
'background_video_webm' => $background_video_webm,
'background_video_width' => $background_video_width,
'background_video_height' => $background_video_height,
'allow_player_pause' => $allow_player_pause,
'bar_bg_color' => isset( $bar_bg_color_values['desktop'] ) ? $bar_bg_color_values['desktop'] : '',
'bar_bg_color_tablet' => isset( $bar_bg_color_values['tablet'] ) ? $bar_bg_color_values['tablet'] : '',
'bar_bg_color_phone' => isset( $bar_bg_color_values['phone'] ) ? $bar_bg_color_values['phone'] : '',
'use_percentages' => $multi_view->get_values( 'use_percentages' ),
'background_video_pause_outside_viewport' => $background_video_pause_outside_viewport,
'use_background_color_gradient' => $use_background_color_gradient,
'is_sticky_module' => $is_sticky_module,
);
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$video_background = $this->video_background();
// Module classname
$this->add_classname(
array(
'et-waypoint',
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
$this->add_classname( $this->get_text_orientation_classname() );
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Sticky & Hover style rendering.
$this->generate_styles(
array(
'responsive' => false,
'render_slug' => $render_slug,
'base_attr_name' => 'background_color',
'css_property' => 'background-color',
'selector' => '%%order_class%% .et_pb_counter_container',
)
);
$this->generate_styles(
array(
'responsive' => false,
'render_slug' => $render_slug,
'base_attr_name' => 'bar_bg_color',
'css_property' => 'background-color',
'selector' => '%%order_class%% .et_pb_counter_amount',
)
);
$output = sprintf(
'<ul%3$s class="%2$s"%4$s>
%1$s
</ul>',
$this->content,
$this->module_classname( $render_slug ),
$this->module_id(),
et_core_esc_previously( $data_background_layout )
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Bar_Counters();
}

View File

@ -0,0 +1,512 @@
<?php
class ET_Builder_Module_Bar_Counters_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Bar Counter', 'et_builder' );
$this->plural = esc_html__( 'Bar Counters', 'et_builder' );
$this->slug = 'et_pb_counter';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'content';
$this->advanced_setting_title_text = esc_html__( 'New Bar Counter', 'et_builder' );
$this->settings_text = esc_html__( 'Bar Counter Settings', 'et_builder' );
$this->main_css_element = '%%order_class%%';
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} span.et_pb_counter_container, {$this->main_css_element} span.et_pb_counter_amount",
'border_styles' => "{$this->main_css_element} span.et_pb_counter_container",
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% span.et_pb_counter_container',
'overlay' => 'inset',
),
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => ".et_pb_counters {$this->main_css_element} .et_pb_counter_title",
),
),
'percent' => array(
'label' => esc_html__( 'Percentage', 'et_builder' ),
'css' => array(
'main' => ".et_pb_counters {$this->main_css_element} .et_pb_counter_amount_number",
'text_align' => ".et_pb_counters {$this->main_css_element} .et_pb_counter_amount",
),
),
),
'background' => array(
'use_background_color' => 'fields_only',
'css' => array(
'main' => ".et_pb_counters li{$this->main_css_element} .et_pb_counter_container",
),
),
'margin_padding' => array(
'draggable_margin' => false,
'draggable_padding' => false,
'css' => array(
'margin' => ".et_pb_counters {$this->main_css_element}",
'padding' => ".et_pb_counters {$this->main_css_element} .et_pb_counter_amount",
),
),
'max_width' => array(
'css' => array(
'module_alignment' => ".et_pb_counters {$this->main_css_element}",
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% .et_pb_counter_title, %%order_class%% .et_pb_counter_amount',
),
),
'button' => false,
'sticky' => false,
'height' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_counter_container, %%order_class%% .et_pb_counter_container .et_pb_counter_amount',
),
),
);
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'bar' => esc_html__( 'Bar Counter', 'et_builder' ),
),
),
);
$this->custom_css_fields = array(
'counter_title' => array(
'label' => esc_html__( 'Counter Title', 'et_builder' ),
'selector' => '.et_pb_counter_title',
),
'counter_container' => array(
'label' => esc_html__( 'Counter Container', 'et_builder' ),
'selector' => '.et_pb_counter_container',
),
'counter_amount' => array(
'label' => esc_html__( 'Counter Amount', 'et_builder' ),
'selector' => '.et_pb_counter_amount',
),
);
}
function get_fields() {
$fields = array(
'content' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input a title for your bar.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'percent' => array(
'label' => esc_html__( 'Percent', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define a percentage for this bar.', 'et_builder' ),
'toggle_slug' => 'main_content',
'default_on_front' => '0',
'mobile_options' => true,
'hover' => 'tabs',
),
'bar_background_color' => array(
'label' => esc_html__( 'Bar Background Color', 'et_builder' ),
'description' => esc_html__( 'This will change the fill color for the bar.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'hover' => 'tabs',
'tab_slug' => 'advanced',
'toggle_slug' => 'bar',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['background_layout'] = array( 'color' => '%%order_class%% .et_pb_counter_title' );
$fields['bar_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_counter_amount' );
return $fields;
}
function get_parallax_image_background( $base_name = 'background' ) {
global $et_pb_counters_settings;
// Parallax setting is only derived from parent if bar counter item has no background
$use_counter_value = '' !== $this->props['background_color'] || 'on' === $this->props['use_background_color_gradient'] || '' !== $this->props['background_image'] || '' !== $this->props['background_video_mp4'] || '' !== $this->props['background_video_webm'];
$background_image = $use_counter_value ? $this->props['background_image'] : $et_pb_counters_settings['background_image'];
$parallax = $use_counter_value ? $this->props['parallax'] : $et_pb_counters_settings['parallax'];
$parallax_method = $use_counter_value ? $this->props['parallax_method'] : $et_pb_counters_settings['parallax_method'];
$parallax_background = '';
if ( '' !== $background_image && 'on' == $parallax ) {
$parallax_classname = array(
'et_parallax_bg',
);
if ( 'off' === $parallax_method ) {
$parallax_classname[] = 'et_pb_parallax_css';
}
$parallax_background = sprintf(
'<div class="et_parallax_bg_wrap"><div
class="%1$s"
style="background-image: url(%2$s);"
></div></div>',
esc_attr( implode( ' ', $parallax_classname ) ),
esc_attr( $background_image )
);
}
return $parallax_background;
}
function video_background( $args = array(), $base_name = 'background' ) {
global $et_pb_counters_settings;
$use_counter_value = '' !== $this->props['background_color'] || 'on' === $this->props['use_background_color_gradient'] || '' !== $this->props['background_image'] || '' !== $this->props['background_video_mp4'] || '' !== $this->props['background_video_webm'];
$background_video_mp4 = $use_counter_value && isset( $this->props['background_video_mp4'] ) ? $this->props['background_video_mp4'] : $et_pb_counters_settings['background_video_mp4'];
$background_video_webm = $use_counter_value && isset( $this->props['background_video_webm'] ) ? $this->props['background_video_webm'] : $et_pb_counters_settings['background_video_webm'];
$background_video_width = $use_counter_value && isset( $this->props['background_video_width'] ) ? $this->props['background_video_width'] : $et_pb_counters_settings['background_video_width'];
$background_video_height = $use_counter_value && isset( $this->props['background_video_height'] ) ? $this->props['background_video_height'] : $et_pb_counters_settings['background_video_height'];
if ( ! empty( $args ) ) {
$background_video = self::get_video_background( $args );
$allow_player_pause = isset( $args['allow_player_pause'] ) ? $args['allow_player_pause'] : 'off';
$pause_outside_viewport = isset( $args['background_video_pause_outside_viewport'] ) ? $args['background_video_pause_outside_viewport'] : 'on';
} else {
$background_video = self::get_video_background(
array(
'background_video_mp4' => $background_video_mp4,
'background_video_webm' => $background_video_webm,
'background_video_width' => $background_video_width,
'background_video_height' => $background_video_height,
)
);
$allow_player_pause = $use_counter_value ? $this->props['allow_player_pause'] : $et_pb_counters_settings['allow_player_pause'];
$pause_outside_viewport = $use_counter_value ? $this->props['background_video_pause_outside_viewport'] : $et_pb_counters_settings['background_video_pause_outside_viewport'];
}
$video_background = '';
if ( $background_video ) {
$video_background = sprintf(
'<div class="et_pb_section_video_bg%2$s">
%1$s
</div>',
$background_video,
( 'on' === $allow_player_pause ? ' et_pb_allow_player_pause' : '' ),
( 'off' === $pause_outside_viewport ? ' et_pb_video_play_outside_viewport' : '' )
);
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'wp-mediaelement' );
}
// Added classname for module wrapper
if ( '' !== $video_background ) {
$this->add_classname( array( 'et_pb_section_video', 'et_pb_preload' ) );
}
return $video_background;
}
/**
* Set inheritance value for bar counters item.
*
* This method is introduced to inherit background colors values. There are some situations where not
* all inheritance process done here.
*
* @since 3.27.4
*/
function maybe_inherit_values() {
global $et_pb_counters_settings;
// To avoid unnecessary inheritance process, ensure to run this action on FE only.
if ( ! empty( $et_pb_counters_settings ) && ! is_admin() && ! et_fb_is_enabled() ) {
// Get parent and item background hover & responsive status.
$is_background_hover = et_pb_hover_options()->is_enabled( 'background', $this->props );
$is_background_parent_hover = et_pb_hover_options()->is_enabled( 'background', $et_pb_counters_settings );
$is_background_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, 'background' );
$is_background_parent_responsive = et_pb_responsive_options()->is_responsive_enabled( $et_pb_counters_settings, 'background' );
$is_inherit_parent_hover = ! $is_background_hover && $is_background_parent_hover;
$is_inherit_parent_responsive = ! $is_background_responsive && $is_background_parent_responsive;
// Background hover status.
if ( $is_inherit_parent_hover ) {
$this->props['background__hover_enabled'] = self::$_->array_get( $et_pb_counters_settings, 'background__hover_enabled', '' );
}
// Background responsive status.
if ( $is_inherit_parent_responsive ) {
$this->props['background_last_edited'] = self::$_->array_get( $et_pb_counters_settings, 'background_last_edited', '' );
}
// Background color and background color enable status.
foreach ( array( 'background_color', 'background_enable_color' ) as $field ) {
// Desktop. Simple inherit parent value if current item value is empty.
$value = self::$_->array_get( $this->props, $field, '' );
$parent_value = self::$_->array_get( $et_pb_counters_settings, $field, '' );
$this->props[ $field ] = empty( $value ) ? $parent_value : $value;
// Hover. Inherit parent value only if current item hover is disabled.
if ( $is_inherit_parent_hover ) {
$this->props[ "{$field}__hover" ] = self::$_->array_get( $et_pb_counters_settings, "{$field}__hover", '' );
}
// Responsive. Inherit parent value only if current item responsive is disabled.
if ( $is_inherit_parent_responsive ) {
$this->props[ "{$field}_tablet" ] = self::$_->array_get( $et_pb_counters_settings, "{$field}_tablet", '' );
$this->props[ "{$field}_phone" ] = self::$_->array_get( $et_pb_counters_settings, "{$field}_phone", '' );
}
}
}
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_counters_settings;
$multi_view = et_pb_multi_view_options( $this );
$multi_view->set_custom_prop( 'use_percentages', $et_pb_counters_settings['use_percentages'] );
$percent = $multi_view->get_value( 'percent' );
$bar_background_color = self::$_->array_get( $this->props, 'bar_background_color' );
$bar_background_color = empty( $bar_background_color ) ? $et_pb_counters_settings['bar_bg_color'] : $bar_background_color;
$background_image = $this->props['background_image'];
$use_background_color_gradient = $this->props['use_background_color_gradient'];
// Background Color.
$background_color = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_color', 'desktop' );
$background_color_tablet = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_color', 'tablet' );
$background_color_phone = et_pb_responsive_options()->get_inheritance_background_value( $this->props, 'background_color', 'phone' );
// Bar background color responsive. First of all, check if value from bar counters item is
// exist and responsive setting is enabled. If it doesn't exist, get it from bar counters
// and also ensure responsive setting is enabled.
$is_bar_background_color_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, 'bar_background_color' );
$bar_background_color_tablet = $is_bar_background_color_responsive ? et_pb_responsive_options()->get_any_value( $this->props, 'bar_background_color_tablet' ) : '';
$bar_background_color_tablet = '' === $bar_background_color_tablet ? $et_pb_counters_settings['bar_bg_color_tablet'] : $bar_background_color_tablet;
$bar_background_color_phone = $is_bar_background_color_responsive ? et_pb_responsive_options()->get_any_value( $this->props, 'bar_background_color_phone' ) : '';
$bar_background_color_phone = '' === $bar_background_color_phone ? $et_pb_counters_settings['bar_bg_color_phone'] : $bar_background_color_phone;
// Add % only if it hasn't been added to the attribute
if ( '%' !== substr( trim( $percent ), -1 ) ) {
$percent .= '%';
}
$background_color_style = $bar_bg_color_style = '';
$parent_bg_image = isset( $et_pb_counters_settings['background_image'] ) ? $et_pb_counters_settings['background_image'] : '';
$parent_use_bg_gradient = isset( $et_pb_counters_settings['use_background_color_gradient'] ) ? $et_pb_counters_settings['use_background_color_gradient'] : 'off';
$parent_enable_bg_image = ! empty( $parent_bg_image ) || 'on' === $parent_use_bg_gradient;
if ( '' !== $background_color && $parent_enable_bg_image ) {
if ( empty( $background_image ) && 'on' !== $use_background_color_gradient ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '.et_pb_counters %%order_class%% .et_pb_counter_container',
'declaration' => 'background-image: none!important;',
)
);
}
}
// Background color.
$background_color_values = array(
'desktop' => esc_html( $background_color ),
'tablet' => esc_html( $background_color_tablet ),
'phone' => esc_html( $background_color_phone ),
);
et_pb_responsive_options()->generate_responsive_css( $background_color_values, '%%order_class%% .et_pb_counter_container', 'background-color', $render_slug, '', 'color' );
// Bar background color.
$bar_background_color_values = array(
'desktop' => esc_html( $bar_background_color ),
'tablet' => esc_html( $bar_background_color_tablet ),
'phone' => esc_html( $bar_background_color_phone ),
);
et_pb_responsive_options()->generate_responsive_css( $bar_background_color_values, '%%order_class%% .et_pb_counter_amount', 'background-color', $render_slug, '', 'color' );
et_pb_responsive_options()->generate_responsive_css( $bar_background_color_values, '%%order_class%% .et_pb_counter_amount.overlay', 'color', $render_slug, '', 'color' );
// Extended (hover & sticky) style of bar and its background color
// Background Color.
$this->generate_styles(
array(
'responsive' => false,
'render_slug' => $render_slug,
'base_attr_name' => 'background_color',
'css_property' => 'background-color',
'selector' => '.et_pb_counters %%order_class%% .et_pb_counter_container',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'is_sticky_module' => $et_pb_counters_settings['is_sticky_module'],
)
);
// Bar Background Color.
$this->generate_styles(
array(
'responsive' => false,
'render_slug' => $render_slug,
'base_attr_name' => 'bar_background_color',
'css_property' => 'background-color',
'selector' => '.et_pb_counters %%order_class%% .et_pb_counter_amount',
'hover_pseudo_selector_location' => 'order_class',
'sticky_pseudo_selector_location' => 'prefix',
'is_sticky_module' => $et_pb_counters_settings['is_sticky_module'],
)
);
$this->generate_styles(
array(
'responsive' => false,
'render_slug' => $render_slug,
'attrs' => $this->props,
'base_attr_name' => 'bar_background_color',
'css_property' => 'color',
'selector' => '.et_pb_counters %%order_class%% .et_pb_counter_amount.overlay',
'hover_pseudo_selector_location' => 'order_class',
'sticky_pseudo_selector_location' => 'prefix',
'is_sticky_module' => $et_pb_counters_settings['is_sticky_module'],
)
);
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Module classname
$this->add_classname( $this->get_text_orientation_classname() );
// Remove automatically added classnames
$this->remove_classname(
array(
'et_pb_module',
$render_slug,
)
);
$multi_view_data_title = $multi_view->render_attrs(
array(
'content' => '{{content}}',
)
);
$multi_view_data_percent_attrs = $multi_view->render_attrs(
array(
'attrs' => array(
'data-width' => '{{percent}}',
),
'target' => '%%order_class%% .et_pb_counter_amount',
)
);
$multi_view_data_percent_content = $multi_view->render_attrs(
array(
'content' => '{{percent}}',
'visibility' => array(
'use_percentages' => 'on',
),
)
);
$output = sprintf(
'<li class="et_pb_counter %6$s">
<span class="et_pb_counter_title"%9$s>%1$s</span>
<span class="et_pb_counter_container"%4$s%10$s>
%8$s
%7$s
<span class="et_pb_counter_amount" style="%5$s" data-width="%3$s"><span class="et_pb_counter_amount_number"><span class="et_pb_counter_amount_number_inner"%11$s>%2$s</span></span></span>
<span class="et_pb_counter_amount overlay" style="%5$s" data-width="%3$s"><span class="et_pb_counter_amount_number"><span class="et_pb_counter_amount_number_inner"%11$s>%2$s</span></span></span>
</span>
</li>',
sanitize_text_field( $content ), // #1
$multi_view->has_value( 'use_percentages', 'on' ) ? esc_html( $percent ) : '',
esc_attr( $percent ),
$background_color_style,
$bar_bg_color_style, // #5
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background,
$multi_view_data_title,
$multi_view_data_percent_attrs, // #10
$multi_view_data_percent_content
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
if ( $raw_value && 'percent' === $name ) {
if ( '%' !== substr( trim( $raw_value ), -1 ) ) {
$raw_value .= '%';
}
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Bar_Counters_Item();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
<?php
class ET_Builder_Module_Button extends ET_Builder_Module {
function init() {
$this->name = et_builder_i18n( 'Button' );
$this->plural = esc_html__( 'Buttons', 'et_builder' );
$this->slug = 'et_pb_button';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%';
$this->wrapper_settings = array(
// Flag that indicates that this module's wrapper where order class is declared
// has another wrapper (mostly for button alignment purpose).
'order_class_wrapper' => true,
);
$this->custom_css_fields = array(
'main_element' => array(
'label' => et_builder_i18n( 'Main Element' ),
'no_space_before_selector' => true,
),
);
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'link' => et_builder_i18n( 'Link' ),
),
),
'advanced' => array(
'toggles' => array(
'alignment' => esc_html__( 'Alignment', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => false,
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => $this->main_css_element,
'limited_main' => "{$this->main_css_element}.et_pb_button",
),
'box_shadow' => false,
'margin_padding' => false,
),
),
'margin_padding' => array(
'css' => array(
'padding' => "{$this->main_css_element}_wrapper {$this->main_css_element}, {$this->main_css_element}_wrapper {$this->main_css_element}:hover",
'margin' => "{$this->main_css_element}_wrapper",
'important' => 'all',
),
),
'text' => array(
'use_text_orientation' => false,
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default_on_front' => 'light',
'hover' => 'tabs',
),
),
),
'text_shadow' => array(
// Text Shadow settings are already included on button's advanced style
'default' => false,
),
'background' => false,
'fonts' => false,
'max_width' => false,
'height' => false,
'link_options' => false,
'position_fields' => array(
'css' => array(
'main' => "{$this->main_css_element}_wrapper",
),
),
'transform' => array(
'css' => array(
'main' => "{$this->main_css_element}_wrapper",
),
),
);
$this->help_videos = array(
array(
'id' => 'XpM2G7tQQIE',
'name' => esc_html__( 'An introduction to the Button module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'button_url' => array(
'label' => esc_html__( 'Button Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the destination URL for your button.', 'et_builder' ),
'toggle_slug' => 'link',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Button Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
'default_on_front' => 'off',
),
'button_text' => array(
'label' => et_builder_i18n( 'Button' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your desired button text.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'button_alignment' => array(
'label' => esc_html__( 'Button Alignment', 'et_builder' ),
'description' => esc_html__( 'Align your button to the left, right or center of the module.', 'et_builder' ),
'type' => 'text_align',
'option_category' => 'configuration',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'tab_slug' => 'advanced',
'toggle_slug' => 'alignment',
'description' => esc_html__( 'Here you can define the alignment of Button', 'et_builder' ),
'mobile_options' => true,
),
);
return $fields;
}
/**
* Get button alignment.
*
* @since 3.23 Add responsive support by adding device parameter.
*
* @param string $device Current device name.
* @return string Alignment value, rtl or not.
*/
public function get_button_alignment( $device = 'desktop' ) {
$suffix = 'desktop' !== $device ? "_{$device}" : '';
$text_orientation = isset( $this->props[ "button_alignment{$suffix}" ] ) ? $this->props[ "button_alignment{$suffix}" ] : '';
return et_pb_get_alignment( $text_orientation );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$button_url = $this->props['button_url'];
$button_rel = $this->props['button_rel'];
$button_text = $this->_esc_attr( 'button_text', 'limited' );
$url_new_window = $this->props['url_new_window'];
$button_custom = $this->props['custom_button'];
$button_alignment = $this->get_button_alignment();
$is_button_aligment_responsive = et_pb_responsive_options()->is_responsive_enabled( $this->props, 'button_alignment' );
$button_alignment_tablet = $is_button_aligment_responsive ? $this->get_button_alignment( 'tablet' ) : '';
$button_alignment_phone = $is_button_aligment_responsive ? $this->get_button_alignment( 'phone' ) : '';
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
// Button Alignment.
$button_alignments = array();
if ( ! empty( $button_alignment ) ) {
array_push( $button_alignments, sprintf( 'et_pb_button_alignment_%1$s', esc_attr( $button_alignment ) ) );
}
if ( ! empty( $button_alignment_tablet ) ) {
array_push( $button_alignments, sprintf( 'et_pb_button_alignment_tablet_%1$s', esc_attr( $button_alignment_tablet ) ) );
}
if ( ! empty( $button_alignment_phone ) ) {
array_push( $button_alignments, sprintf( 'et_pb_button_alignment_phone_%1$s', esc_attr( $button_alignment_phone ) ) );
}
$button_alignment_classes = join( ' ', $button_alignments );
// Nothing to output if neither Button Text nor Button URL defined
$button_url = trim( $button_url );
if ( '' === $button_text && '' === $button_url ) {
return '';
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
// Module classnames
$this->remove_classname( 'et_pb_module' );
// Render Button
$button = $this->render_button(
array(
'button_id' => $this->module_id( false ),
'button_classname' => explode( ' ', $this->module_classname( $render_slug ) ),
'button_custom' => $button_custom,
'button_rel' => $button_rel,
'button_text' => $button_text,
'button_text_escaped' => true,
'button_url' => $button_url,
'custom_icon' => $custom_icon,
'custom_icon_tablet' => $custom_icon_tablet,
'custom_icon_phone' => $custom_icon_phone,
'has_wrapper' => false,
'url_new_window' => $url_new_window,
'multi_view_data' => $multi_view->render_attrs(
array(
'content' => '{{button_text}}',
'hover_selector' => '%%order_class%%.et_pb_button',
'visibility' => array(
'button_text' => '__not_empty',
),
)
),
)
);
// Render module output
$output = sprintf(
'<div class="et_pb_button_module_wrapper %3$s_wrapper %2$s et_pb_module "%4$s>
%1$s
</div>',
et_core_esc_previously( $button ),
esc_attr( $button_alignment_classes ),
esc_attr( ET_Builder_Element::get_module_order_class( $this->slug ) ),
et_core_esc_previously( $data_background_layout )
);
$transition_style = $this->get_transition_style( array( 'all' ) );
self::set_style(
$render_slug,
array(
'selector' => '%%order_class%%, %%order_class%%:after',
'declaration' => esc_html( $transition_style ),
)
);
// Tablet.
$transition_style_tablet = $this->get_transition_style( array( 'all' ), 'tablet' );
if ( $transition_style_tablet !== $transition_style ) {
self::set_style(
$render_slug,
array(
'selector' => '%%order_class%%, %%order_class%%:after',
'declaration' => esc_html( $transition_style_tablet ),
'media_query' => ET_Builder_Element::get_media_query( 'max_width_980' ),
)
);
}
// Phone.
$transition_style_phone = $this->get_transition_style( array( 'all' ), 'phone' );
if ( $transition_style_phone !== $transition_style || $transition_style_phone !== $transition_style_tablet ) {
$el_style = array(
'selector' => '%%order_class%%, %%order_class%%:after',
'declaration' => esc_html( $transition_style_phone ),
'media_query' => ET_Builder_Element::get_media_query( 'max_width_767' ),
);
self::set_style( $render_slug, $el_style );
}
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$context = isset( $args['context'] ) ? $args['context'] : '';
$fields_need_escape = array(
'title',
);
if ( $raw_value && 'content' === $context && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Button();
}

View File

@ -0,0 +1,434 @@
<?php
class ET_Builder_Module_Circle_Counter extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Circle Counter', 'et_builder' );
$this->plural = esc_html__( 'Circle Counters', 'et_builder' );
$this->slug = 'et_pb_circle_counter';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_circle_counter';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'circle' => et_builder_i18n( 'Circle' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h3, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h2.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header, {$this->main_css_element} h3 a, {$this->main_css_element} h1.et_pb_module_header a, {$this->main_css_element} h2.et_pb_module_header a, {$this->main_css_element} h4.et_pb_module_header a, {$this->main_css_element} h5.et_pb_module_header a, {$this->main_css_element} h6.et_pb_module_header a",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h3',
),
),
'number' => array(
'label' => esc_html__( 'Number', 'et_builder' ),
'hide_line_height' => true,
'css' => array(
'main' => "{$this->main_css_element} .percent p",
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ),
),
'custom_margin' => array(
'default' => '0px|auto|30px|auto|false|false',
),
),
'max_width' => array(
'options' => array(
'max_width' => array(
'default' => '225px',
'range_settings' => array(
'min' => '0',
'max' => '450',
'step' => '1',
),
),
'module_alignment' => array(
'depends_show_if_not' => array(
'',
'225px',
),
),
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => '%%order_class%% .percent p, %%order_class%% .et_pb_module_header',
),
'options' => array(
'text_orientation' => array(
'default_on_front' => 'center',
),
'background_layout' => array(
'default_on_front' => 'light',
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
),
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->custom_css_fields = array(
'percent' => array(
'label' => esc_html__( 'Percent Container', 'et_builder' ),
'selector' => '.percent',
),
'circle_counter_title' => array(
'label' => esc_html__( 'Circle Counter Title', 'et_builder' ),
'selector' => 'h3',
),
'percent_text' => array(
'label' => esc_html__( 'Percent Text', 'et_builder' ),
'selector' => '.percent p',
),
);
$this->help_videos = array(
array(
'id' => 'GTslkWWbda0',
'name' => esc_html__( 'An introduction to the Circle Counter module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input a title for the circle counter.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'number' => array(
'label' => esc_html__( 'Number', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'number_validation' => true,
'value_type' => 'float',
'value_min' => 0,
'value_max' => 100,
'description' => et_get_safe_localization( __( "Define a number for the circle counter. (Don't include the percentage sign, use the option below.). <strong>Note: You can use only natural numbers from 0 to 100</strong>", 'et_builder' ) ),
'toggle_slug' => 'main_content',
'default_on_front' => '0',
'mobile_options' => true,
'hover' => 'tabs',
),
'percent_sign' => array(
'label' => esc_html__( 'Percent Sign', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether the percent sign should be added after the number set above.', 'et_builder' ),
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'bar_bg_color' => array(
'default' => et_builder_accent_color(),
'label' => esc_html__( 'Circle Color', 'et_builder' ),
'type' => 'color-alpha',
'tab_slug' => 'advanced',
'toggle_slug' => 'circle',
'description' => esc_html__( 'This will change the fill color for the bar.', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'circle_color' => array(
'label' => esc_html__( 'Circle Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to be used in the unfilled space of the circle.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'circle',
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'circle_color_alpha' => array(
'label' => esc_html__( 'Circle Background Opacity', 'et_builder' ),
'description' => esc_html__( 'Decrease the opacity of the unfilled space of the circle to make the color fade into the background.', 'et_builder' ),
'type' => 'range',
'option_category' => 'configuration',
'range_settings' => array(
'min' => '0.1',
'max' => '1.0',
'step' => '0.05',
'min_limit' => '0.0',
'max_limit' => '1.0',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'circle',
'unitless' => true,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$number = $multi_view->get_value( 'number' );
$percent_sign = $this->props['percent_sign'];
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['title_level'], 'h3' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_module_header',
),
)
);
$custom_padding = $this->props['custom_padding'];
$custom_padding_tablet = $this->props['custom_padding_tablet'];
$custom_padding_phone = $this->props['custom_padding_phone'];
$header_level = $this->props['title_level'];
$bar_bg_color = $this->props['bar_bg_color'];
$bar_bg_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'bar_bg_color' );
$bar_bg_color_tablet = isset( $bar_bg_color_values['tablet'] ) ? $bar_bg_color_values['tablet'] : '';
$bar_bg_color_phone = isset( $bar_bg_color_values['phone'] ) ? $bar_bg_color_values['phone'] : '';
$bar_bg_color_hover = et_pb_hover_options()->get_value( 'bar_bg_color', $this->props, '' );
$bar_bg_color_hover_enabled = et_builder_is_hover_enabled( 'bar_bg_color', $this->props );
$bar_bg_color_sticky = $sticky->get_value( 'bar_bg_color', $this->props, '' );
$circle_color = $this->props['circle_color'];
$circle_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'circle_color' );
$circle_color_tablet = isset( $circle_color_values['tablet'] ) ? $circle_color_values['tablet'] : '';
$circle_color_phone = isset( $circle_color_values['phone'] ) ? $circle_color_values['phone'] : '';
$circle_color_hover = et_pb_hover_options()->get_value( 'circle_color', $this->props, '' );
$circle_color_hover_enabled = et_builder_is_hover_enabled( 'circle_color', $this->props );
$circle_color_sticky = $sticky->get_value( 'circle_color', $this->props, '' );
$circle_color_alpha = $this->props['circle_color_alpha'];
$circle_color_alpha_values = et_pb_responsive_options()->get_property_values( $this->props, 'circle_color_alpha' );
$circle_color_alpha_tablet = isset( $circle_color_alpha_values['tablet'] ) ? $circle_color_alpha_values['tablet'] : '';
$circle_color_alpha_phone = isset( $circle_color_alpha_values['phone'] ) ? $circle_color_alpha_values['phone'] : '';
$circle_color_alpha_hover = et_pb_hover_options()->get_value( 'circle_color_alpha', $this->props, '' );
$circle_color_alpha_hover_enable = et_builder_is_hover_enabled( 'circle_color_alpha', $this->props );
$circle_color_alpha_sticky = $sticky->get_value( 'circle_color_alpha', $this->props, '' );
$number = str_ireplace( '%', '', $number );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$bar_bg_color_data_tablet = '' !== $bar_bg_color_tablet ?
sprintf( ' data-bar-bg-color-tablet="%1$s"', esc_attr( $bar_bg_color_tablet ) )
: '';
$bar_bg_color_data_phone = '' !== $bar_bg_color_phone ?
sprintf( ' data-bar-bg-color-phone="%1$s"', esc_attr( $bar_bg_color_phone ) )
: '';
$bar_bg_color_data_hover = '' !== $bar_bg_color_hover && $bar_bg_color_hover_enabled ?
sprintf( ' data-bar-bg-color-hover="%1$s"', esc_attr( $bar_bg_color_hover ) )
: '';
$bar_bg_color_data_sticky = '' !== $bar_bg_color_sticky ?
sprintf( ' data-bar-bg-color-sticky="%1$s"', esc_attr( $bar_bg_color_sticky ) )
: '';
$circle_color_data = '' !== $circle_color ?
sprintf( ' data-color="%1$s"', esc_attr( $circle_color ) )
: '';
$circle_color_data_tablet = '' !== $circle_color_tablet ?
sprintf( ' data-color-tablet="%1$s"', esc_attr( $circle_color_tablet ) )
: '';
$circle_color_data_phone = '' !== $circle_color_phone ?
sprintf( ' data-color-phone="%1$s"', esc_attr( $circle_color_phone ) )
: '';
$circle_color_data_hover = '' !== $circle_color_hover && $circle_color_hover_enabled ?
sprintf( ' data-color-hover="%1$s"', esc_attr( $circle_color_hover ) )
: '';
$circle_color_data_sticky = '' !== $circle_color_sticky ?
sprintf( ' data-color-sticky="%1$s"', esc_attr( $circle_color_sticky ) )
: '';
$circle_color_alpha_data = '' !== $circle_color_alpha ?
sprintf( ' data-alpha="%1$s"', esc_attr( $circle_color_alpha ) )
: '';
$circle_color_alpha_data_tablet = '' !== $circle_color_alpha_tablet ?
sprintf( ' data-alpha-tablet="%1$s"', esc_attr( $circle_color_alpha_tablet ) )
: '';
$circle_color_alpha_data_phone = '' !== $circle_color_alpha_phone ?
sprintf( ' data-alpha-phone="%1$s"', esc_attr( $circle_color_alpha_phone ) )
: '';
$circle_color_alpha_data_hover = '' !== $circle_color_alpha_hover && $circle_color_alpha_hover_enable ?
sprintf( ' data-alpha-hover="%1$s"', esc_attr( $circle_color_alpha_hover ) )
: '';
$circle_color_alpha_data_sticky = '' !== $circle_color_alpha_sticky ?
sprintf( ' data-alpha-sticky="%1$s"', esc_attr( $circle_color_alpha_sticky ) )
: '';
// Sticky id.
$data_sticky_id = $sticky->is_sticky_module( $this->props ) ?
sprintf( ' data-sticky-id="%1$s"', esc_attr( $this->get_sticky_id( $render_slug ) ) )
: '';
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$multi_view_data_attr = $multi_view->render_attrs(
array(
'attrs' => array(
'data-number-value' => '{{number}}',
'data-percent-sign' => '{{percent_sign}}',
),
'classes' => array(
'et_pb_with_title' => array(
'title' => '__not_empty',
),
),
)
);
// Module classnames
$this->add_classname(
array(
'container-width-change-notify',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( '' !== $title ) {
$this->add_classname( 'et_pb_with_title' );
}
$output = sprintf(
'<div%1$s class="%2$s"%11$s>
<div class="et_pb_circle_counter_inner" data-number-value="%3$s" data-bar-bg-color="%4$s"%7$s%8$s%12$s%13$s%14$s%15$s%16$s%17$s%18$s%19$s%20$s%21$s%22$s%23$s%24$s%25$s>
%10$s
%9$s
<div class="percent"%19$s><p><span class="percent-value"></span><span class="percent-sign">%5$s</span></p></div>
%6$s
</div>
</div>',
$this->module_id(),
$this->module_classname( $render_slug ),
esc_attr( $number ),
esc_attr( $bar_bg_color ),
( 'on' == $multi_view->get_value( 'percent_sign' ) ? '%' : '' ), // #5
et_core_esc_previously( $title ),
$circle_color_data,
$circle_color_alpha_data,
$video_background,
$parallax_image_background, // #10
et_core_esc_previously( $data_background_layout ),
$bar_bg_color_data_tablet,
$bar_bg_color_data_phone,
$circle_color_data_tablet,
$circle_color_data_phone, // #15
$circle_color_alpha_data_tablet,
$circle_color_alpha_data_phone,
$bar_bg_color_data_hover,
$circle_color_data_hover,
$circle_color_alpha_data_hover, // #20
$multi_view_data_attr,
$bar_bg_color_data_sticky,
$circle_color_data_sticky,
$circle_color_alpha_data_sticky,
$data_sticky_id // #25
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
if ( 'number' === $name ) {
$raw_value = str_replace( array( '%' ), '', $raw_value );
} elseif ( 'percent_sign' === $name ) {
$raw_value = 'on' === $raw_value ? '%' : '&nbsp;';
}
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Circle_Counter();
}

View File

@ -0,0 +1,148 @@
<?php
class ET_Builder_Module_Code extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Code', 'et_builder' );
$this->plural = esc_html__( 'Codes', 'et_builder' );
$this->slug = 'et_pb_code';
$this->vb_support = 'on';
$this->use_raw_content = true;
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'width' => array(
'title' => et_builder_i18n( 'Sizing' ),
'priority' => 65,
),
),
),
);
$this->advanced_fields = array(
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text_shadow' => array(
// Don't add text-shadow fields since they already are via font-options
'default' => false,
),
'fonts' => false,
'button' => false,
);
$this->help_videos = array(
array(
'id' => 'dTY6-Cbr00A',
'name' => esc_html__( 'An introduction to the Code module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'raw_content' => array(
'label' => esc_html__( 'Code', 'et_builder' ),
'type' => 'codemirror',
'mode' => 'html',
'option_category' => 'basic_option',
'description' => esc_html__( 'Here you can create the content that will be used within the module.', 'et_builder' ),
'is_fb_content' => true,
'toggle_slug' => 'main_content',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Module classnames
$this->add_classname( $this->get_text_orientation_classname() );
$raw_content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{raw_content}}',
'attrs' => array(
'class' => 'et_pb_code_inner',
),
)
);
$output = sprintf(
'<div%2$s class="%3$s">
%5$s
%4$s
%1$s
</div>',
$raw_content,
$this->module_id(),
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : 'desktop';
if ( $raw_value && 'raw_content' === $name ) {
if ( 'desktop' !== $mode ) {
$raw_value = et_builder_convert_line_breaks( et_builder_replace_code_content_entities( $raw_value ) );
}
$raw_value = $this->fix_wptexturized_scripts( $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Code();
}

View File

@ -0,0 +1,579 @@
<?php
class ET_Builder_Module_Comments extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Comments', 'et_builder' );
$this->plural = esc_html__( 'Comments', 'et_builder' );
$this->slug = 'et_pb_comments';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'image' => array(
'title' => et_builder_i18n( 'Image' ),
'priority' => 30,
),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'box_shadow' => array(
'default' => array(),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => "{$this->main_css_element} .commentlist img.avatar",
),
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element}",
'border_styles' => "{$this->main_css_element}",
),
'important' => 'all',
),
),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%%.et_pb_comments_module .commentlist li img.avatar',
'border_styles' => '%%order_class%%.et_pb_comments_module .commentlist li img.avatar',
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'fonts' => array(
'header' => array(
'label' => esc_html__( 'Comment Count', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h1.page_title, {$this->main_css_element} h2.page_title, {$this->main_css_element} h3.page_title, {$this->main_css_element} h4.page_title, {$this->main_css_element} h5.page_title, {$this->main_css_element} h6.page_title",
),
'header_level' => array(
'default' => 'h1',
),
),
'title' => array(
'label' => esc_html__( 'Form Title', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .comment-reply-title",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '22px',
),
'letter_spacing' => array(
'default' => '0px',
),
'header_level' => array(
'default' => 'h3',
),
),
'meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .comment_postinfo span",
'important' => 'all',
'text_align' => "{$this->main_css_element} .comment_postinfo",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'body' => array(
'label' => esc_html__( 'Comment', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .comment-content p",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_comments_module .et_pb_button",
'limited_main' => "{$this->main_css_element}.et_pb_comments_module .et_pb_button",
'alignment' => "{$this->main_css_element} .form-submit",
),
'no_rel_attr' => true,
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => "{$this->main_css_element} .et_pb_button",
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => '%%order_class%% p, %%order_class%% .comment_postinfo *, %%order_class%% .page_title, %%order_class%% .comment-reply-title',
'text_shadow' => '%%order_class%% p, %%order_class%% .comment_postinfo, %%order_class%% .page_title, %%order_class%% .comment-reply-title',
),
'options' => array(
'background_layout' => array(
'default_on_front' => 'light',
'hover' => 'tabs',
),
),
),
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Fields', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url']",
'hover' => "{$this->main_css_element} #commentform textarea:hover, {$this->main_css_element} #commentform input[type='text']:hover, {$this->main_css_element} #commentform input[type='email']:hover, {$this->main_css_element} #commentform input[type='url']:hover",
'focus' => "{$this->main_css_element} #commentform textarea:focus, {$this->main_css_element} #commentform input[type='text']:focus, {$this->main_css_element} #commentform input[type='email']:focus, {$this->main_css_element} #commentform input[type='url']:focus",
'focus_hover' => "{$this->main_css_element} #commentform textarea:focus:hover, {$this->main_css_element} #commentform input[type='text']:focus:hover, {$this->main_css_element} #commentform input[type='email']:focus:hover, {$this->main_css_element} #commentform input[type='url']:focus:hover",
'placeholder' => "{$this->main_css_element} #commentform textarea::-webkit-input-placeholder, {$this->main_css_element} #commentform textarea::-moz-placeholder, {$this->main_css_element} #commentform textarea:-ms-input-placeholder, {$this->main_css_element} #commentform input::-webkit-input-placeholder, {$this->main_css_element} #commentform input::-moz-placeholder, {$this->main_css_element} #commentform input:-ms-input-placeholder",
'placeholder_focus' => "{$this->main_css_element} #commentform textarea:focus::-webkit-input-placeholder, {$this->main_css_element} #commentform textarea:focus::-moz-placeholder, {$this->main_css_element} #commentform textarea:focus:-ms-input-placeholder, {$this->main_css_element} #commentform input:focus::-webkit-input-placeholder, {$this->main_css_element} #commentform input:focus::-moz-placeholder, {$this->main_css_element} #commentform input:focus:-ms-input-placeholder",
'margin' => "{$this->main_css_element} #commentform .comment-form-comment, {$this->main_css_element} #commentform .comment-form-author, {$this->main_css_element} #commentform .comment-form-email, {$this->main_css_element} #commentform .comment-form-url",
),
'box_shadow' => array(
'name' => 'fields',
'css' => array(
'main' => "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url']",
),
),
'border_styles' => array(
'form_field' => array(
'name' => 'fields',
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url']",
'border_styles' => "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url']",
),
'important' => 'all',
),
'label_prefix' => esc_html__( 'Fields', 'et_builder' ),
),
'form_field_focus' => array(
'name' => 'fields_focus',
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} #commentform textarea:focus, {$this->main_css_element} #commentform input[type='text']:focus, {$this->main_css_element} #commentform input[type='email']:focus, {$this->main_css_element} #commentform input[type='url']:focus",
'border_styles' => "{$this->main_css_element} #commentform textarea:focus, {$this->main_css_element} #commentform input[type='text']:focus, {$this->main_css_element} #commentform input[type='email']:focus, {$this->main_css_element} #commentform input[type='url']:focus",
),
),
'label_prefix' => esc_html__( 'Fields Focus', 'et_builder' ),
),
),
'font_field' => array(
'css' => array(
'main' => "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url'], {$this->main_css_element} #commentform label",
'important' => 'all',
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '18px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
),
),
'filters' => array(
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => "{$this->main_css_element} .commentlist img.avatar",
),
),
);
$this->custom_css_fields = array(
'main_header' => array(
'label' => esc_html__( 'Comments Count', 'et_builder' ),
'selector' => 'h1#comments',
),
'comment_body' => array(
'label' => esc_html__( 'Comment Body', 'et_builder' ),
'selector' => '.comment-body',
),
'comment_meta' => array(
'label' => esc_html__( 'Comment Meta', 'et_builder' ),
'selector' => '.comment_postinfo',
),
'comment_content' => array(
'label' => esc_html__( 'Comment Content', 'et_builder' ),
'selector' => '.comment_area .comment-content',
),
'comment_avatar' => array(
'label' => esc_html__( 'Comment Avatar', 'et_builder' ),
'selector' => '.comment_avatar',
),
'reply_button' => array(
'label' => esc_html__( 'Reply Button', 'et_builder' ),
'selector' => '.comment-reply-link.et_pb_button',
),
'new_title' => array(
'label' => esc_html__( 'New Comment Title', 'et_builder' ),
'selector' => 'h3#reply-title',
),
'message_field' => array(
'label' => esc_html__( 'Message Field', 'et_builder' ),
'selector' => '.comment-form-comment textarea#comment',
),
'name_field' => array(
'label' => esc_html__( 'Name Field', 'et_builder' ),
'selector' => '.comment-form-author input',
),
'email_field' => array(
'label' => esc_html__( 'Email Field', 'et_builder' ),
'selector' => '.comment-form-email input',
),
'website_field' => array(
'label' => esc_html__( 'Website Field', 'et_builder' ),
'selector' => '.comment-form-url input',
),
'submit_button' => array(
'label' => esc_html__( 'Submit Button', 'et_builder' ),
'selector' => '.form-submit .et_pb_button#et_pb_submit',
),
);
$this->help_videos = array(
array(
'id' => 'k6vskmOxM4U',
'name' => esc_html__( 'An introduction to the Comments module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'show_avatar' => array(
'label' => esc_html__( 'Show Author Avatar', 'et_builder' ),
'description' => esc_html__( 'Disabling the author avatar will remove the profile picture from the module.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'show_reply' => array(
'label' => esc_html__( 'Show Reply Button', 'et_builder' ),
'description' => esc_html__( 'Disabling the reply button will prevent visitors from creating threaded comments.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'show_count' => array(
'label' => esc_html__( 'Show Comment Count', 'et_builder' ),
'description' => esc_html__( 'Disabling the comment count will remove the number of comments from the top of the module.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Get comments markup for comments module
*
* @since 4.0.9 Add custom form title heading level.
*
* @param {string} $header_level
* @param {string} $form_title_level
*
* @return string of comment section markup
*/
static function get_comments( $header_level, $form_title_level ) {
global $et_pb_comments_print, $et_comments_header_level, $et_comments_form_title_level;
// Globally flag that comment module is being printed
$et_pb_comments_print = true;
// set custom header level for comments form
$et_comments_header_level = $header_level;
$et_comments_form_title_level = $form_title_level;
// remove filters to make sure comments module rendered correctly if the below filters were applied earlier.
remove_filter( 'get_comments_number', '__return_zero' );
remove_filter( 'comments_open', '__return_false' );
remove_filter( 'comments_array', '__return_empty_array' );
// Custom action before calling comments_template.
do_action( 'et_fb_before_comments_template' );
ob_start();
comments_template( '', true );
$comments_content = ob_get_contents();
ob_end_clean();
// Custom action after calling comments_template.
do_action( 'et_fb_after_comments_template' );
// Globally flag that comment module has been printed
$et_pb_comments_print = false;
$et_comments_header_level = '';
return $comments_content;
}
/**
* Action and filter hooks that are called before comment content rendering. These are
* abstracted into method so module which extends comment module can modify these
*
* @since 3.29
*/
function before_comments_content() {
// Modify the comments request to make sure it's unique.
// Otherwise WP generates SQL error and doesn't allow multiple comments sections on single page
add_action( 'pre_get_comments', array( $this, 'et_pb_modify_comments_request' ), 1 );
// include custom comments_template to display the comment section with Divi style
add_filter( 'comments_template', array( $this, 'et_pb_comments_template' ) );
// Modify submit button to be advanced button style ready
add_filter( 'comment_form_submit_button', array( $this, 'et_pb_comments_submit_button' ) );
}
/**
* Comment content rendering. These are abstracted into method so module which extends comment
* module can modify these
*
* @since 3.29
* @since 4.0.9 Add form title heading level.
*/
function get_comments_content() {
$header_level = et_()->array_get( $this->props, 'header_level' );
$form_title_level = et_()->array_get( $this->props, 'title_level' );
$header_level_processed = et_pb_process_header_level( $header_level, 'h1' );
$form_title_level_processed = et_pb_process_header_level( $form_title_level, 'h3' );
return self::get_comments( $header_level_processed, $form_title_level_processed );
}
/**
* Action and filter hooks that are called after comment content rendering. These are
* abstracted into method so module which extends comment module can modify these
*/
function after_comments_content() {
// remove all the actions and filters to not break the default comments section from theme
remove_filter( 'comments_template', array( $this, 'et_pb_comments_template' ) );
remove_action( 'pre_get_comments', array( $this, 'et_pb_modify_comments_request' ), 1 );
}
function et_pb_comments_template() {
return realpath( dirname( __FILE__ ) . '/..' ) . '/comments_template.php';
}
function et_pb_comments_submit_button( $submit_button ) {
return sprintf(
'<button name="%1$s" type="submit" id="%2$s" class="%3$s">%4$s</button>',
esc_attr( 'submit' ),
esc_attr( 'et_pb_submit' ),
esc_attr( 'submit' ),
esc_html__( 'Submit Comment', 'et_builder' )
);
}
function et_pb_modify_comments_request( $params ) {
// modify the request parameters the way it doesn't change the result just to make request with unique parameters
$params->query_vars['type__not_in'] = 'et_pb_comments_random_type_' . $this->et_pb_unique_comments_module_class;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$button_custom = $this->props['custom_button'];
$show_avatar = $this->props['show_avatar'];
$show_reply = $this->props['show_reply'];
$show_count = $this->props['show_count'];
$header_level = $this->props['header_level'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$this->et_pb_unique_comments_module_class = ET_Builder_Element::get_module_order_class( $render_slug ); // use this variable to make the comments request unique for each module instance
// Action & filter hooks before comment content rendering
$this->before_comments_content();
// Comment content rendering
$comments_content = $this->get_comments_content();
// Action & filter hooks after comment content rendering
$this->after_comments_content();
// Image - CSS Filters.
if ( et_()->array_get( $this->advanced_fields, 'image.css', false ) ) {
$this->add_classname(
$this->generate_css_filters(
$this->slug,
'child_',
et_()->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
$comments_custom_icon = 'on' === $button_custom ? $custom_icon : '';
$comments_custom_icon_tablet = 'on' === $button_custom ? $custom_icon_tablet : '';
$comments_custom_icon_phone = 'on' === $button_custom ? $custom_icon_phone : '';
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Module classname
$this->add_classname(
array(
'et_pb_comments_module',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( 'off' === $show_avatar ) {
$this->add_classname( 'et_pb_no_avatar' );
}
if ( 'off' === $show_reply ) {
$this->add_classname( 'et_pb_no_reply_button' );
}
if ( 'off' === $show_count ) {
$this->add_classname( 'et_pb_no_comments_count' );
}
// Removed automatically added classname
$this->remove_classname( $render_slug );
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_no_avatar' => array(
'show_avatar' => 'off',
),
'et_pb_no_reply_button' => array(
'show_reply' => 'off',
),
'et_pb_no_comments_count' => array(
'show_count' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%2$s"%4$s%7$s%8$s%9$s%10$s>
%5$s
%6$s
%1$s
</div>',
$comments_content,
$this->module_classname( $render_slug ),
$this->module_id(),
'' !== $comments_custom_icon ? sprintf( ' data-icon="%1$s"', esc_attr( et_pb_process_font_icon( $comments_custom_icon ) ) ) : '',
$video_background, // #5
$parallax_image_background,
et_core_esc_previously( $data_background_layout ),
'' !== $comments_custom_icon_tablet ? sprintf( ' data-icon-tablet="%1$s"', esc_attr( et_pb_process_font_icon( $comments_custom_icon_tablet ) ) ) : '',
'' !== $comments_custom_icon_phone ? sprintf( ' data-icon-phone="%1$s"', esc_attr( et_pb_process_font_icon( $comments_custom_icon_phone ) ) ) : '',
$multi_view_data_attr // #10
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Comments();
}
if ( et_is_woocommerce_plugin_active() && defined( 'ET_BUILDER_DIR' ) ) {
// Use separate files for better organization.
require_once ET_BUILDER_DIR . 'module/woocommerce/Reviews.php';
}

View File

@ -0,0 +1,803 @@
<?php
class ET_Builder_Module_Contact_Form extends ET_Builder_Module_Type_WithSpamProtection {
function init() {
parent::init();
$this->name = esc_html__( 'Contact Form', 'et_builder' );
$this->plural = esc_html__( 'Contact Forms', 'et_builder' );
$this->slug = 'et_pb_contact_form';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_contact_field';
$this->child_item_text = esc_html__( 'Field', 'et_builder' );
$this->main_css_element = '%%order_class%%.et_pb_contact_form_container';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'email' => esc_html__( 'Email', 'et_builder' ),
'elements' => et_builder_i18n( 'Elements' ),
'redirect' => esc_html__( 'Redirect', 'et_builder' ),
'spam' => esc_html__( 'Spam Protection', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', $this->main_css_element ),
'border_styles' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', $this->main_css_element ),
),
'important' => 'plugin_only',
),
'label_prefix' => esc_html__( 'Inputs', 'et_builder' ),
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h1, {$this->main_css_element} h2.et_pb_contact_main_title, {$this->main_css_element} h3.et_pb_contact_main_title, {$this->main_css_element} h4.et_pb_contact_main_title, {$this->main_css_element} h5.et_pb_contact_main_title, {$this->main_css_element} h6.et_pb_contact_main_title",
),
'header_level' => array(
'default' => 'h1',
),
),
'captcha' => array(
'label' => esc_html__( 'Captcha', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_contact_right p",
),
'hide_text_align' => true,
'line_height' => array(
'default' => '1.7em',
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .et_pb_contact_field input',
'%%order_class%% .et_pb_contact_field select',
'%%order_class%% .et_pb_contact_field textarea',
'%%order_class%% .et_pb_contact_field .et_pb_contact_field_options_list label > i',
'%%order_class%% input.et_pb_contact_captcha',
)
),
),
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_module .et_pb_button",
'limited_main' => "{$this->main_css_element}.et_pb_module .et_pb_button",
'important' => 'plugin_only',
),
'no_rel_attr' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_contact_submit',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_contact_form_container.et_pb_module',
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% input, %%order_class%% textarea, %%order_class%% label',
'text_shadow' => '%%order_class%%, %%order_class%% input, %%order_class%% textarea, %%order_class%% label, %%order_class%% select',
),
),
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Fields', 'et_builder' ),
'css' => array(
'main' => '%%order_class%% .input',
'background_color' => '%%order_class%% .input, %%order_class%% .input[type="checkbox"] + label i, %%order_class%% .input[type="radio"] + label i',
'background_color_hover' => '%%order_class%% .input:hover, %%order_class%% .input[type="checkbox"]:hover + label i, %%order_class%% .input[type="radio"]:hover + label i',
'focus_background_color' => '%%order_class%% .input:focus, %%order_class%% .input[type="checkbox"]:active + label i, %%order_class%% .input[type="radio"]:active + label i',
'focus_background_color_hover' => '%%order_class%% .input:focus:hover, %%order_class%% .input[type="checkbox"]:active:hover + label i, %%order_class%% .input[type="radio"]:active:hover + label i',
'placeholder_focus' => '%%order_class%% p .input:focus::-webkit-input-placeholder, %%order_class%% p .input:focus::-moz-placeholder, %%order_class%% p .input:focus:-ms-input-placeholder, %%order_class%% p textarea:focus::-webkit-input-placeholder, %%order_class%% p textarea:focus::-moz-placeholder, %%order_class%% p textarea:focus:-ms-input-placeholder',
'padding' => '%%order_class%% .et_pb_contact_field .input',
'margin' => '%%order_class%% .et_pb_contact_field',
'form_text_color' => '%%order_class%% .input, %%order_class%% .input[type="checkbox"] + label, %%order_class%% .input[type="radio"] + label, %%order_class%% .input[type="checkbox"]:checked + label i:before',
'form_text_color_hover' => '%%order_class%% .input:hover, %%order_class%% .input[type="checkbox"]:hover + label, %%order_class%% .input[type="radio"]:hover + label, %%order_class%% .input[type="checkbox"]:checked:hover + label i:before',
'focus_text_color' => '%%order_class%% .input:focus, %%order_class%% .input[type="checkbox"]:active + label, %%order_class%% .input[type="radio"]:active + label, %%order_class%% .input[type="checkbox"]:checked:active + label i:before',
'focus_text_color_hover' => '%%order_class%% .input:focus:hover, %%order_class%% .input[type="checkbox"]:active:hover + label, %%order_class%% .input[type="radio"]:active:hover + label, %%order_class%% .input[type="checkbox"]:checked:active:hover + label i:before',
),
'box_shadow' => false,
'border_styles' => false,
'font_field' => array(
'css' => array(
'main' => implode(
', ',
array(
"{$this->main_css_element} .input",
"{$this->main_css_element} .input::placeholder",
"{$this->main_css_element} .input::-webkit-input-placeholder",
"{$this->main_css_element} .input::-moz-placeholder",
"{$this->main_css_element} .input:-ms-input-placeholder",
"{$this->main_css_element} .input[type=checkbox] + label",
"{$this->main_css_element} .input[type=radio] + label",
)
),
'hover' => array(
"{$this->main_css_element} .input:hover",
"{$this->main_css_element} .input:hover::placeholder",
"{$this->main_css_element} .input:hover::-webkit-input-placeholder",
"{$this->main_css_element} .input:hover::-moz-placeholder",
"{$this->main_css_element} .input:hover:-ms-input-placeholder",
"{$this->main_css_element} .input[type=checkbox]:hover + label",
"{$this->main_css_element} .input[type=radio]:hover + label",
),
),
),
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%% .input',
'padding' => '%%order_class%% .et_pb_contact_field .input',
'margin' => '%%order_class%% .et_pb_contact_field',
),
),
),
),
);
$this->custom_css_fields = array(
'contact_title' => array(
'label' => esc_html__( 'Contact Title', 'et_builder' ),
'selector' => '.et_pb_contact_main_title',
),
'contact_button' => array(
'label' => esc_html__( 'Contact Button', 'et_builder' ),
'selector' => '.et_pb_contact_form_container .et_contact_bottom_container .et_pb_contact_submit.et_pb_button',
'no_space_before_selector' => true,
),
'contact_fields' => array(
'label' => esc_html__( 'Form Fields', 'et_builder' ),
'selector' => 'input',
),
'text_field' => array(
'label' => esc_html__( 'Message Field', 'et_builder' ),
'selector' => 'textarea.et_pb_contact_message',
),
'captcha_field' => array(
'label' => esc_html__( 'Captcha Field', 'et_builder' ),
'selector' => 'input.et_pb_contact_captcha',
),
'captcha_label' => array(
'label' => esc_html__( 'Captcha Text', 'et_builder' ),
'selector' => '.et_pb_contact_right p',
),
);
$this->help_videos = array(
array(
'id' => 'y3NSTE6BSfo',
'name' => esc_html__( 'An introduction to the Contact Form module', 'et_builder' ),
),
);
}
/**
* Get form map containing essential info (form number, field id/type/required) based on
* et_pb_contact_field's shortcode layout
*
* @since 3.26.5
*
* @param string $content_shortcode
* @param int $contact_form_number
* @param array $hidden_form_fields
*
* @return mixed[] {
* Form Map
*
* @type int $form_number Contact form number.
* @type string[] $fields {
* Form Field
*
* @type string $field_type Field type
* @type string $field_id Field id
* @type string $required_mark Required field status. Accepts 'on', 'off'.
* }
* }
*/
function get_form_map( $content_shortcode = '', $contact_form_number = 0, $hidden_form_fields = array() ) {
$pattern = get_shortcode_regex( array( 'et_pb_contact_field' ) );
$map = array(
'form_number' => (int) $contact_form_number,
'fields' => array(),
);
preg_match_all( "/$pattern/", $content_shortcode, $contact_fields, PREG_SET_ORDER );
foreach ( $contact_fields as $contact_field ) {
$contact_field_attrs = shortcode_parse_atts( $contact_field[3] );
$field_id = strtolower( self::$_->array_get( $contact_field_attrs, 'field_id' ) );
$conditional_logic = self::$_->array_get( $contact_field_attrs, 'conditional_logic', 'off' );
// Only allow to disable fields for which conditional logic has been enabled
if ( 'on' === $conditional_logic && in_array( $field_id, $hidden_form_fields ) ) {
continue;
}
$map['fields'][] = array(
'field_type' => self::$_->array_get( $contact_field_attrs, 'field_type', 'input' ),
'field_id' => $field_id,
'required_mark' => self::$_->array_get( $contact_field_attrs, 'required_mark', 'on' ),
);
}
return $map;
}
function get_fields() {
return array_merge(
self::_get_spam_provider_fields(),
array(
'captcha' => array(
'label' => esc_html__( 'Use Basic Captcha', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'spam',
'description' => esc_html__( 'Turn the captcha on or off using this option.', 'et_builder' ),
'default_on_front' => 'on',
'show_if' => array(
'use_spam_service' => 'off',
),
),
'email' => array(
'label' => esc_html__( 'Email Address', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => et_get_safe_localization(
sprintf(
__( 'Input the email address where messages should be sent.<br /><br /> Note: email delivery and spam prevention are complex processes. We recommend using a delivery service such as <a href="%1$s">Mandrill</a>, <a href="%2$s">SendGrid</a>, or other similar service to ensure the deliverability of messages that are submitted through this form', 'et_builder' ),
'http://mandrill.com/',
'https://sendgrid.com/'
)
),
'toggle_slug' => 'email',
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define a title for your contact form.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'custom_message' => array(
'label' => esc_html__( 'Message Pattern', 'et_builder' ),
'type' => 'textarea',
'option_category' => 'configuration',
'description' => et_get_safe_localization( __( 'Here you can define the custom pattern for the email Message. Fields should be included in following format - <strong>%%field_id%%</strong>. For example if you want to include the field with id = <strong>phone</strong> and field with id = <strong>message</strong>, then you can use the following pattern: <strong>My message is %%message%% and phone number is %%phone%%</strong>. Leave blank for default.', 'et_builder' ) ),
'toggle_slug' => 'email',
),
'use_redirect' => array(
'label' => esc_html__( 'Enable Redirect URL', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'affects' => array(
'redirect_url',
),
'toggle_slug' => 'redirect',
'description' => esc_html__( 'Redirect users after successful form submission.', 'et_builder' ),
'default_on_front' => 'off',
),
'redirect_url' => array(
'label' => esc_html__( 'Redirect URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'depends_show_if' => 'on',
'toggle_slug' => 'redirect',
'description' => esc_html__( 'Type the Redirect URL', 'et_builder' ),
),
'success_message' => array(
'label' => esc_html__( 'Success Message', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'description' => esc_html__( 'Type the message you want to display after successful form submission. Leave blank for default', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
),
'submit_button_text' => array(
'label' => esc_html__( 'Submit Button', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define the text of the form submit button.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
)
);
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['form_field_background_color'] = array(
'background-color' => implode(
', ',
array(
'%%order_class%% .input',
'%%order_class%% .input[type="checkbox"]+label i',
'%%order_class%% .input[type="radio"]+label i',
)
),
);
return $fields;
}
function predefined_child_modules() {
$output = sprintf(
'[et_pb_contact_field field_title="%1$s" field_type="input" field_id="Name" required_mark="on" fullwidth_field="off" /][et_pb_contact_field field_title="%2$s" field_type="email" field_id="Email" required_mark="on" fullwidth_field="off" /][et_pb_contact_field field_title="%3$s" field_type="text" field_id="Message" required_mark="on" fullwidth_field="on" /]',
esc_attr__( 'Name', 'et_builder' ),
esc_attr__( 'Email Address', 'et_builder' ),
esc_attr__( 'Message', 'et_builder' )
);
return $output;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
parent::render( $attrs, $content, $render_slug );
global $et_pb_half_width_counter, $et_pb_contact_form_num;
$et_pb_half_width_counter = 0;
$multi_view = et_pb_multi_view_options( $this );
$multi_view->set_default_value( 'submit_button_text', __( 'Submit', 'et_builder' ) );
$captcha = $this->props['captcha'];
$email = $this->props['email'];
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['title_level'], 'h1' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_contact_main_title',
),
)
);
$form_field_text_color = $this->props['form_field_text_color'];
$button_custom = $this->props['custom_button'];
$custom_message = $this->props['custom_message'];
$use_redirect = $this->props['use_redirect'];
$redirect_url = $this->props['redirect_url'];
$success_message = $this->_esc_attr( 'success_message' );
$header_level = $this->props['title_level'];
$use_spam_service = $this->prop( 'use_spam_service', 'off' );
$field_text_color_hover = $this->get_hover_value( 'form_field_text_color' );
$field_text_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'form_field_text_color' );
$field_focus_text_color_hover = $this->get_hover_value( 'form_field_focus_text_color' );
$field_focus_text_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'form_field_focus_text_color' );
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Form Field Text Color - Radio Checked.
$field_text_color_important = et_builder_has_limitation( 'force_use_global_important' ) ? ' !important' : '';
et_pb_responsive_options()->generate_responsive_css( $field_text_color_values, '%%order_class%% .input[type="radio"]:checked + label i:before', 'background-color', $render_slug, $field_text_color_important, 'color' );
if ( et_builder_is_hover_enabled( 'form_field_text_color', $this->props ) ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%% .input[type="radio"]:checked:hover + label i:before',
'declaration' => sprintf(
'background-color: %1$s%2$s;',
esc_html( $field_text_color_hover ),
$field_text_color_important
),
)
);
}
// Form Field Text Color on Focus - Radio Checked.
et_pb_responsive_options()->generate_responsive_css( $field_focus_text_color_values, '%%order_class%% .input[type="radio"]:checked:active + label i:before', 'background-color', $render_slug, $field_text_color_important, 'color' );
if ( et_builder_is_hover_enabled( 'form_field_focus_text_color', $this->props ) ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%% .input[type="radio"]:checked:active:hover + label i:before',
'declaration' => sprintf(
'background-color: %1$s%2$s;',
esc_html( $field_focus_text_color_hover ),
$field_text_color_important
),
)
);
}
$success_message = '' !== $success_message ? $success_message : esc_html__( 'Thanks for contacting us', 'et_builder' );
$et_pb_contact_form_num = $this->render_count();
$hidden_form_fields_key = "et_pb_contact_email_hidden_fields_{$et_pb_contact_form_num}";
$hidden_form_fields = self::$_->array_get( $_POST, $hidden_form_fields_key, array() );
$shortcode_content = $content;
if ( ! empty( $hidden_form_fields ) ) {
$hidden_form_fields = str_replace( '\\', '', $hidden_form_fields );
$hidden_form_fields = json_decode( $hidden_form_fields );
}
$content = $this->content;
$et_error_message = '';
$et_contact_error = false;
$current_form_fields = isset( $_POST[ 'et_pb_contact_email_fields_' . $et_pb_contact_form_num ] ) ? $_POST[ 'et_pb_contact_email_fields_' . $et_pb_contact_form_num ] : '';
$contact_email = '';
$processed_fields_values = array();
$nonce_result = isset( $_POST[ '_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num ] ) && wp_verify_nonce( $_POST[ '_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num ], 'et-pb-contact-form-submit' ) ? true : false;
// check that the form was submitted and et_pb_contact_et_number field is empty to protect from spam
if ( $nonce_result && isset( $_POST[ 'et_pb_contactform_submit_' . $et_pb_contact_form_num ] ) && empty( $_POST[ 'et_pb_contact_et_number_' . $et_pb_contact_form_num ] ) ) {
if ( '' !== $current_form_fields ) {
$fields_data_json = str_replace( '\\', '', $current_form_fields );
$fields_data_array = json_decode( $fields_data_json, true );
$fields_data_array = null === $fields_data_array ? [] : $fields_data_array;
// check whether captcha field is not empty.
if ( 'on' === $captcha && 'off' === $use_spam_service && ( ! isset( $_POST[ 'et_pb_contact_captcha_' . $et_pb_contact_form_num ] ) || empty( $_POST[ 'et_pb_contact_captcha_' . $et_pb_contact_form_num ] ) ) ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Make sure you entered the captcha.', 'et_builder' ) );
$et_contact_error = true;
} elseif ( 'on' === $use_spam_service && $this->is_spam_submission() ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'You must be a human to submit this form.', 'et_builder' ) );
$et_contact_error = true;
}
// check all fields on current form and generate error message if needed
// Generate form map of submitted form.
$submitted_form_map = array(
'form_number' => $et_pb_contact_form_num,
'fields' => array(),
);
foreach ( $fields_data_array as $index => $value ) {
if ( ! isset( $value['field_id'], $value['field_label'], $value['field_type'], $value['original_id'], $value['required_mark'] ) ) {
continue;
}
if ( 'et_pb_contact_et_number_' . $et_pb_contact_form_num === $value['field_id'] ) {
continue;
}
// Populate form map's fields.
$submitted_form_map['fields'][] = array(
'field_type' => self::$_->array_get( $value, 'field_type', 'input' ),
'field_id' => self::$_->array_get( $value, 'original_id' ),
'required_mark' => 'required' === self::$_->array_get( $value, 'required_mark', 'required' ) ? 'on' : 'off',
);
// Check all the required fields, generate error message if required field is empty.
// Use `sanitize_textarea_field` for message field content to preserve newlines.
$sanitize_callback = isset( $value['original_id'] ) && 'text' === $value['field_type'] ? 'sanitize_textarea_field' : 'sanitize_text_field';
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput.InputNotSanitized -- The $sanitize_callback will sanitize the field value.
$field_value = isset( $_POST[ $value['field_id'] ] ) ? trim( call_user_func( $sanitize_callback, $_POST[ $value['field_id'] ] ) ) : '';
if ( 'required' === $value['required_mark'] && empty( $field_value ) && ! is_numeric( $field_value ) ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Make sure you fill in all required fields.', 'et_builder' ) );
$et_contact_error = true;
continue;
}
// additional check for email field.
if ( 'email' === $value['field_type'] && ! empty( $field_value ) ) {
$contact_email = isset( $_POST[ $value['field_id'] ] ) ? sanitize_email( $_POST[ $value['field_id'] ] ) : '';
if ( 'required' === $value['required_mark'] && ( empty( $contact_email ) || ! is_email( $contact_email ) ) ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Invalid Email.', 'et_builder' ) );
$et_contact_error = true;
}
}
// prepare the array of processed field values in convenient format.
if ( false === $et_contact_error ) {
$processed_fields_values[ $value['original_id'] ]['value'] = $field_value;
$processed_fields_values[ $value['original_id'] ]['label'] = $value['field_label'];
}
}
// Check form's integrity by comparing fields structure (used for required fields check, etc)
// stored in the shortcode against submitted value generated using JS on the front end
// to prevent data being altered by modifying form markup.
$form_map = $this->get_form_map( $shortcode_content, $et_pb_contact_form_num, $hidden_form_fields );
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- doing equality check between two serialized arrays
if ( serialize( $submitted_form_map ) !== serialize( $form_map ) ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Invalid submission. Please refresh the page and try again.', 'et_builder' ) );
$et_contact_error = true;
}
} else {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Make sure you fill in all required fields.', 'et_builder' ) );
$et_contact_error = true;
}
} else {
if ( false === $nonce_result && isset( $_POST[ 'et_pb_contactform_submit_' . $et_pb_contact_form_num ] ) && empty( $_POST[ 'et_pb_contact_et_number_' . $et_pb_contact_form_num ] ) ) {
$et_error_message .= sprintf( '<p class="et_pb_contact_error_text">%1$s</p>', esc_html__( 'Please refresh the page and try again.', 'et_builder' ) );
}
$et_contact_error = true;
}
// generate digits for captcha
$et_pb_first_digit = rand( 1, 15 );
$et_pb_second_digit = rand( 1, 15 );
if ( ! $et_contact_error && $nonce_result ) {
$et_email_to = '' !== $email
? $email
: get_site_option( 'admin_email' );
$et_site_name = get_option( 'blogname' );
$contact_name = isset( $processed_fields_values['name'] ) ? stripslashes( sanitize_text_field( $processed_fields_values['name']['value'] ) ) : '';
if ( '' !== $custom_message ) {
// decode html entites to make sure HTML from the message pattern is rendered properly
$message_pattern = et_builder_convert_line_breaks( html_entity_decode( $custom_message ), "\r\n" );
// insert the data from contact form into the message pattern
foreach ( $processed_fields_values as $key => $value ) {
// strip all tags from each field. Don't strip tags from the entire message to allow using HTML in the pattern.
$message_pattern = str_ireplace( "%%{$key}%%", wp_strip_all_tags( $value['value'] ), $message_pattern );
}
if ( is_array( $hidden_form_fields ) ) {
foreach ( $hidden_form_fields as $hidden_field_label ) {
$message_pattern = str_ireplace( "%%{$hidden_field_label}%%", '', $message_pattern );
}
}
} else {
// use default message pattern if custom pattern is not defined
$message_pattern = isset( $processed_fields_values['message']['value'] ) ? $processed_fields_values['message']['value'] : '';
// Add all custom fields into the message body by default
foreach ( $processed_fields_values as $key => $value ) {
if ( ! in_array( $key, array( 'message', 'name', 'email' ) ) ) {
$message_pattern .= "\r\n";
$message_pattern .= sprintf(
'%1$s: %2$s',
'' !== $value['label'] ? $value['label'] : $key,
$value['value']
);
}
}
// strip all tags from the message content
$message_pattern = wp_strip_all_tags( $message_pattern );
}
$http_host = str_replace( 'www.', '', $_SERVER['HTTP_HOST'] );
$headers[] = "From: \"{$contact_name}\" <mail@{$http_host}>";
// Set `Reply-To` email header based on contact_name and contact_email values
if ( ! empty( $contact_email ) ) {
$contact_name = ! empty( $contact_name ) ? $contact_name : $contact_email;
$headers[] = "Reply-To: \"{$contact_name}\" <{$contact_email}>";
}
add_filter( 'et_get_safe_localization', 'et_allow_ampersand' );
// don't strip tags at this point to properly send the HTML from pattern. All the unwanted HTML stripped at this point.
$email_message = trim( stripslashes( $message_pattern ) );
wp_mail(
apply_filters( 'et_contact_page_email_to', $et_email_to ),
et_get_safe_localization(
sprintf(
__( 'New Message From %1$s%2$s', 'et_builder' ),
sanitize_text_field( html_entity_decode( $et_site_name, ENT_QUOTES, 'UTF-8' ) ),
( '' !== $title ? sprintf( _x( ' - %s', 'contact form title separator', 'et_builder' ), $title ) : '' )
)
),
! empty( $email_message ) ? $email_message : ' ',
apply_filters( 'et_contact_page_headers', $headers, $contact_name, $contact_email )
);
remove_filter( 'et_get_safe_localization', 'et_allow_ampersand' );
$et_error_message = sprintf( '<p>%1$s</p>', et_core_esc_previously( $success_message ) );
}
$form = '';
$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$et_pb_captcha = sprintf(
'
<div class="et_pb_contact_right">
<p class="clearfix">
<span class="et_pb_contact_captcha_question">%1$s</span> = <input type="text" size="2" class="input et_pb_contact_captcha" data-first_digit="%3$s" data-second_digit="%4$s" value="" name="et_pb_contact_captcha_%2$s" data-required_mark="required" autocomplete="off">
</p>
</div>',
sprintf( '%1$s + %2$s', esc_html( $et_pb_first_digit ), esc_html( $et_pb_second_digit ) ),
esc_attr( $et_pb_contact_form_num ),
esc_attr( $et_pb_first_digit ),
esc_attr( $et_pb_second_digit )
);
if ( '' === trim( $content ) ) {
$content = do_shortcode( $this->predefined_child_modules() );
}
if ( $et_contact_error ) {
$multi_view_data_attr = $multi_view->render_attrs(
array(
'content' => '{{submit_button_text}}',
)
);
$form = sprintf(
'
<div class="et_pb_contact">
<form class="et_pb_contact_form clearfix" method="post" action="%1$s">
%7$s
<input type="hidden" value="et_contact_proccess" name="et_pb_contactform_submit_%6$s"/>
<div class="et_contact_bottom_container">
%2$s
<button type="submit" name="et_builder_submit_button" class="et_pb_contact_submit et_pb_button"%5$s%8$s%9$s%10$s>%3$s</button>
</div>
%4$s
</form>
</div>',
esc_url( $current_url ),
( 'on' === $captcha && 'off' === $use_spam_service ? $et_pb_captcha : '' ),
esc_html( $multi_view->get_value( 'submit_button_text' ) ),
wp_nonce_field( 'et-pb-contact-form-submit', '_wpnonce-et-pb-contact-form-submitted-' . $et_pb_contact_form_num, true, false ),
'' !== $custom_icon && 'on' === $button_custom ? sprintf(
' data-icon="%1$s"',
esc_attr( et_pb_process_font_icon( $custom_icon ) )
) : '', // #5
esc_attr( $et_pb_contact_form_num ),
$content,
'' !== $custom_icon_tablet && 'on' === $button_custom ? sprintf( ' data-icon-tablet="%1$s"', esc_attr( et_pb_process_font_icon( $custom_icon_tablet ) ) ) : '',
'' !== $custom_icon_phone && 'on' === $button_custom ? sprintf( ' data-icon-phone="%1$s"', esc_attr( et_pb_process_font_icon( $custom_icon_phone ) ) ) : '',
$multi_view_data_attr // #10
);
}
// Module classnames
$this->add_classname(
array(
'et_pb_contact_form_container',
'clearfix',
$this->get_text_orientation_classname(),
)
);
// Remove automatically added classname
$this->remove_classname( $render_slug );
// Contact form should always have the ID. Use saved ID or generate automatically
$module_id = '' !== $this->module_id( false ) ? $this->module_id( false ) : 'et_pb_contact_form_' . $et_pb_contact_form_num;
$output = sprintf(
'
<div id="%4$s" class="%5$s" data-form_unique_num="%6$s"%7$s>
%9$s
%8$s
%1$s
<div class="et-pb-contact-message">%2$s</div>
%3$s
</div>
',
$title,
$et_error_message,
$form,
esc_attr( $module_id ),
$this->module_classname( $render_slug ),
esc_attr( $et_pb_contact_form_num ),
'on' === $use_redirect && '' !== $redirect_url ? sprintf( ' data-redirect_url="%1$s"', esc_attr( $redirect_url ) ) : '',
$video_background,
$parallax_image_background
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
} elseif ( 'submit_button_text' === $name ) {
if ( '' === trim( $raw_value ) ) {
$raw_value = __( 'Submit', 'et_builder' );
}
return esc_html( $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Contact_Form();
}

View File

@ -0,0 +1,943 @@
<?php
class ET_Builder_Module_Contact_Form_Item extends ET_Builder_Module {
public $additional_shortcode_slugs = array( 'et_pb_signup_custom_field' );
function init() {
$this->name = esc_html__( 'Field', 'et_builder' );
$this->plural = esc_html__( 'Fields', 'et_builder' );
$this->slug = 'et_pb_contact_field';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'field_id';
$this->advanced_setting_title_text = esc_html__( 'New Field', 'et_builder' );
$this->settings_text = esc_html__( 'Field Settings', 'et_builder' );
$this->main_css_element = '.et_pb_contact_form_container %%order_class%%.et_pb_contact_field';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'field_options' => esc_html__( 'Field Options', 'et_builder' ),
'conditional_logic' => esc_html__( 'Conditional Logic', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', $this->main_css_element ),
'border_styles' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', $this->main_css_element ),
),
'important' => 'plugin_only',
),
'label_prefix' => esc_html__( 'Input', 'et_builder' ),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% input',
'%%order_class%% select',
'%%order_class%% textarea',
'%%order_class%% .et_pb_contact_field_options_list label > i',
)
),
'important' => true,
),
),
),
'background' => array(
'css' => array(
'main' => '%%order_class%%',
),
),
'margin_padding' => array(
'css' => array(
'padding' => 'p%%order_class%%',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% input, %%order_class%% textarea, %%order_class%% label',
),
),
'text_shadow' => array(
// Don't add text-shadow fields since they already are via font-options
'default' => false,
),
'filters' => array(
'css' => array(
'main' => array(
'%%order_class%% input',
'%%order_class%% textarea',
'%%order_class%% label',
),
),
),
'button' => false,
'sticky' => false,
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Field', 'et_builder' ),
'css' => array(
'background_color' => '%%order_class%% .input, %%order_class%% .input[type="checkbox"] + label i, %%order_class%% .input[type="radio"] + label i',
'main' => '%%order_class%%.et_pb_contact_field .input',
'background_color' => '%%order_class%%.et_pb_contact_field .input, %%order_class%%.et_pb_contact_field .input[type="checkbox"] + label i, %%order_class%%.et_pb_contact_field .input[type="radio"] + label i',
'background_color_hover' => '%%order_class%%.et_pb_contact_field .input:hover, %%order_class%%.et_pb_contact_field .input[type="checkbox"] + label:hover i, %%order_class%%.et_pb_contact_field .input[type="radio"] + label:hover i',
'focus_background_color' => '%%order_class%%.et_pb_contact_field .input:focus, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:active + label i, %%order_class%%.et_pb_contact_field .input[type="radio"]:active + label i',
'focus_background_color_hover' => '%%order_class%%.et_pb_contact_field .input:focus:hover, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:active:hover + label i, %%order_class%%.et_pb_contact_field .input[type="radio"]:active:hover + label i',
'form_text_color' => '%%order_class%%.et_pb_contact_field .input, %%order_class%%.et_pb_contact_field .input[type="checkbox"] + label, %%order_class%%.et_pb_contact_field .input[type="radio"] + label, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:checked + label i:before',
'form_text_color_hover' => '%%order_class%%.et_pb_contact_field .input:hover, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:hover + label,
%%order_class%%.et_pb_contact_field .input[type="radio"]:hover + label, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:checked:hover + label i:before',
'focus_text_color' => '%%order_class%%.et_pb_contact_field .input:focus, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:active + label,
%%order_class%%.et_pb_contact_field .input[type="radio"]:active + label, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:checked:active + label i:before',
'focus_text_color_hover' => '%%order_class%%.et_pb_contact_field .input:focus:hover, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:active:hover + label,
%%order_class%%.et_pb_contact_field .input[type="radio"]:active:hover + label, %%order_class%%.et_pb_contact_field .input[type="checkbox"]:checked:active:hover + label i:before',
),
'margin_padding' => false,
'box_shadow' => false,
'border_styles' => false,
'font_field' => array(
'css' => array(
'main' => implode(
',',
array(
'%%order_class%%.et_pb_contact_field .et_pb_contact_field_options_title',
"{$this->main_css_element} .input",
"{$this->main_css_element} .input::placeholder",
"{$this->main_css_element} .input::-webkit-input-placeholder",
"{$this->main_css_element} .input::-moz-placeholder",
"{$this->main_css_element} .input:-ms-input-placeholder",
"{$this->main_css_element} .input[type=checkbox] + label",
"{$this->main_css_element} .input[type=radio] + label",
)
),
'important' => 'plugin_only',
),
),
),
),
'height' => array(
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% input[type=text]',
'%%order_class%% input[type=email]',
'%%order_class%% textarea',
'%%order_class%%[data-type=checkbox]',
'%%order_class%%[data-type=radio]',
'%%order_class%%[data-type=select]',
'%%order_class%%[data-type=select] select',
)
),
),
),
);
}
function get_fields() {
$labels = array(
'link_url' => esc_html__( 'Link URL', 'et_builder' ),
'link_text' => esc_html__( 'Link Text', 'et_builder' ),
'link_cancel' => esc_html__( 'Discard Changes', 'et_builder' ),
'link_save' => esc_html__( 'Save Changes', 'et_builder' ),
'link_settings' => esc_html__( 'Option Link', 'et_builder' ),
);
$fields = array(
'field_id' => array(
'label' => esc_html__( 'Field ID', 'et_builder' ),
'type' => 'text',
'description' => esc_html__( 'Define the unique ID of this field. You should use only English characters without special characters and spaces.', 'et_builder' ),
'toggle_slug' => 'main_content',
'default_on_front' => '',
'option_category' => 'basic_option',
),
'field_title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'description' => esc_html__( 'Here you can define the content that will be placed within the current tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'default_on_front' => esc_html__( 'New Field', 'et_builder' ),
'option_category' => 'basic_option',
'mobile_options' => true,
'hover' => 'tabs',
),
'field_type' => array(
'label' => esc_html__( 'Type', 'et_builder' ),
'type' => 'select',
'default' => 'input',
'option_category' => 'basic_option',
'options' => array(
'input' => esc_html__( 'Input Field', 'et_builder' ),
'email' => esc_html__( 'Email Field', 'et_builder' ),
'text' => esc_html__( 'Textarea', 'et_builder' ),
'checkbox' => esc_html__( 'Checkboxes', 'et_builder' ),
'radio' => esc_html__( 'Radio Buttons', 'et_builder' ),
'select' => esc_html__( 'Select Dropdown', 'et_builder' ),
),
'description' => esc_html__( 'Choose the type of field', 'et_builder' ),
'affects' => array(
'checkbox_options',
'booleancheckbox_options',
'radio_options',
'select_options',
'min_length',
'max_length',
'allowed_symbols',
),
'toggle_slug' => 'field_options',
),
'checkbox_checked' => array(
'label' => esc_html__( 'Checked By Default', 'et_builder' ),
'description' => esc_html__( 'If enabled, the check mark will be automatically selected for the visitor. They can still deselected it.', 'et_builder' ),
'type' => 'hidden',
'option_category' => 'layout',
'default' => 'off',
'depends_show_if' => 'checkbox',
'toggle_slug' => 'field_options',
),
'checkbox_options' => array(
'label' => esc_html__( 'Options', 'et_builder' ),
'type' => 'sortable_list',
'checkbox' => true,
'option_category' => 'basic_option',
'depends_show_if' => 'checkbox',
'toggle_slug' => 'field_options',
'right_actions' => 'move|link|copy|delete',
'labels' => $labels,
),
'booleancheckbox_options' => array(
'label' => esc_html__( 'Options', 'et_builder' ),
'type' => 'sortable_list',
'checkbox' => true,
'option_category' => 'basic_option',
'depends_show_if' => 'booleancheckbox',
'toggle_slug' => 'field_options',
'right_actions' => 'move|link|copy|delete',
'labels' => $labels,
),
'radio_options' => array(
'label' => esc_html__( 'Options', 'et_builder' ),
'type' => 'sortable_list',
'radio' => true,
'option_category' => 'basic_option',
'depends_show_if' => 'radio',
'toggle_slug' => 'field_options',
'right_actions' => 'move|link|copy|delete',
'labels' => $labels,
),
'select_options' => array(
'label' => esc_html__( 'Options', 'et_builder' ),
'type' => 'sortable_list',
'option_category' => 'basic_option',
'depends_show_if' => 'select',
'toggle_slug' => 'field_options',
),
'min_length' => array(
'label' => esc_html__( 'Minimum Length', 'et_builder' ),
'description' => esc_html__( 'Leave at 0 to remove restriction', 'et_builder' ),
'type' => 'range',
'default' => '0',
'unitless' => true,
'range_settings' => array(
'min' => '0',
'max' => '255',
'step' => '1',
),
'option_category' => 'basic_option',
'depends_show_if' => 'input',
'toggle_slug' => 'field_options',
),
'max_length' => array(
'label' => esc_html__( 'Maximum Length', 'et_builder' ),
'description' => esc_html__( 'Leave at 0 to remove restriction', 'et_builder' ),
'type' => 'range',
'default' => '0',
'unitless' => true,
'range_settings' => array(
'min' => '0',
'max' => '255',
'step' => '1',
),
'option_category' => 'basic_option',
'depends_show_if' => 'input',
'toggle_slug' => 'field_options',
),
'allowed_symbols' => array(
'label' => esc_html__( 'Allowed Symbols', 'et_builder' ),
'type' => 'select',
'default' => 'all',
'options' => array(
'all' => esc_html__( 'All', 'et_builder' ),
'letters' => esc_html__( 'Letters Only (A-Z)', 'et_builder' ),
'numbers' => esc_html__( 'Numbers Only (0-9)', 'et_builder' ),
'alphanumeric' => esc_html__( 'Alphanumeric Only (A-Z, 0-9)', 'et_builder' ),
),
'option_category' => 'basic_option',
'depends_show_if' => 'input',
'toggle_slug' => 'field_options',
),
'required_mark' => array(
'label' => esc_html__( 'Required Field', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'default' => 'on',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'description' => esc_html__( 'Define whether the field should be required or optional', 'et_builder' ),
'toggle_slug' => 'field_options',
),
'fullwidth_field' => array(
'label' => esc_html__( 'Make Fullwidth', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'description' => esc_html__( 'If enabled, the field will take 100% of the width of the content area, otherwise it will take 50%', 'et_builder' ),
'default_on_front' => 'off',
),
'conditional_logic' => array(
'label' => esc_html__( 'Enable', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'default' => 'off',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'affects' => array(
'conditional_logic_rules',
'conditional_logic_relation',
),
'description' => et_get_safe_localization( __( 'Enabling conditional logic makes this field only visible when any or all of the rules below are fulfilled<br><strong>Note:</strong> Only fields with an unique and non-empty field ID can be used', 'et_builder' ) ),
'toggle_slug' => 'conditional_logic',
),
'conditional_logic_relation' => array(
'label' => esc_html__( 'Relation', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => esc_html__( 'All', 'et_builder' ),
'off' => esc_html__( 'Any', 'et_builder' ),
),
'default' => 'off',
'button_options' => array(
'button_type' => 'equal',
),
'depends_show_if' => 'on',
'description' => esc_html__( 'Choose whether any or all of the rules should be fulfilled', 'et_builder' ),
'toggle_slug' => 'conditional_logic',
),
'conditional_logic_rules' => array(
'label' => esc_html__( 'Rules', 'et_builder' ),
'type' => 'conditional_logic',
'option_category' => 'layout',
'depends_show_if' => 'on',
'toggle_slug' => 'conditional_logic',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['form_field_background_color'] = array(
'background' => implode(
', ',
array(
'%%order_class%%.et_pb_contact_field .input',
'%%order_class%%.et_pb_contact_field .input + label:hover i',
)
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_half_width_counter, $et_pb_contact_form_num;
et_core_nonce_verified_previously();
$multi_view = et_pb_multi_view_options( $this );
$field_title = $this->props['field_title'];
$field_type = $this->props['field_type'];
$field_id = $this->props['field_id'];
$required_mark = $this->props['required_mark'];
$fullwidth_field = $this->props['fullwidth_field'];
$form_field_text_color = $this->props['form_field_text_color'];
$checkbox_checked = $this->props['checkbox_checked'];
$checkbox_options = $this->props['checkbox_options'];
$booleancheckbox_options = isset( $this->props['booleancheckbox_options'] ) ? $this->props['booleancheckbox_options'] : false;
$radio_options = $this->props['radio_options'];
$select_options = $this->props['select_options'];
$min_length = $this->props['min_length'];
$max_length = $this->props['max_length'];
$conditional_logic = $this->props['conditional_logic'];
$conditional_logic_relation = $this->props['conditional_logic_relation'];
$conditional_logic_rules = $this->props['conditional_logic_rules'];
$allowed_symbols = $this->props['allowed_symbols'];
$render_count = $this->render_count();
$current_module_num = null === $et_pb_contact_form_num ? 0 : intval( $et_pb_contact_form_num ) + 1;
$field_text_color_hover = $this->get_hover_value( 'form_field_text_color' );
$field_text_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'form_field_text_color' );
$field_focus_text_color_hover = $this->get_hover_value( 'form_field_focus_text_color' );
$field_focus_text_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'form_field_focus_text_color' );
if ( ! empty( $attrs['form_field_text_color'] ) ) {
$this->generate_styles(
array(
'type' => 'color',
'render_slug' => $render_slug,
'base_attr_name' => 'form_field_text_color',
'css_property' => 'color',
'selector' => '%%order_class%% .input + label, %%order_class%% .input + label i:before',
'important' => true,
)
);
}
// set a field ID.
if ( '' === $field_id ) {
$field_id = sprintf( 'field_%d_%d', $et_pb_contact_form_num, $render_count );
}
if ( 'et_pb_signup_custom_field' === $render_slug ) {
$this->add_classname( 'et_pb_newsletter_field' );
} else {
$field_id = strtolower( $field_id );
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$et_pb_half_width_counter = ! isset( $et_pb_half_width_counter ) ? 0 : $et_pb_half_width_counter;
// count fields to add the et_pb_contact_field_last properly
if ( 'off' === $fullwidth_field ) {
$et_pb_half_width_counter++;
} else {
$et_pb_half_width_counter = 0;
}
$input_field = '';
// Form Field Text Color - Radio Checked.
$field_text_color_important = et_builder_has_limitation( 'force_use_global_important' ) ? ' !important' : '';
et_pb_responsive_options()->generate_responsive_css( $field_text_color_values, '%%order_class%%.et_pb_contact_field .input[type="radio"]:checked + label i:before', 'background-color', $render_slug, $field_text_color_important, 'color' );
if ( et_builder_is_hover_enabled( 'form_field_text_color', $this->props ) ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%%.et_pb_contact_field .input[type="radio"]:checked:hover + label i:before',
'declaration' => sprintf(
'background-color: %1$s%2$s;',
esc_html( $field_text_color_hover ),
$field_text_color_important
),
)
);
}
// Form Field Text Color on Focus - Radio Checked.
et_pb_responsive_options()->generate_responsive_css( $field_focus_text_color_values, '%%order_class%%.et_pb_contact_field .input[type="radio"]:checked:active + label i:before', 'background-color', $render_slug, $field_text_color_important, 'color' );
if ( et_builder_is_hover_enabled( 'form_field_focus_text_color', $this->props ) ) {
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%%.et_pb_contact_field .input[type="radio"]:checked:active:hover + label i:before',
'declaration' => sprintf(
'background-color: %1$s%2$s;',
esc_html( $field_focus_text_color_hover ),
$field_text_color_important
),
)
);
}
$pattern = '';
$title = '';
$min_length = intval( $min_length );
$max_length = intval( $max_length );
$max_length_attr = '';
$symbols_pattern = '.';
$length_pattern = '*';
if ( in_array( $allowed_symbols, array( 'letters', 'numbers', 'alphanumeric' ) ) ) {
switch ( $allowed_symbols ) {
case 'letters':
$symbols_pattern = '[A-Z|a-z|\s-]';
$title = __( 'Only letters allowed.', 'et_builder' );
break;
case 'numbers':
$symbols_pattern = '[0-9\s-]';
$title = __( 'Only numbers allowed.', 'et_builder' );
break;
case 'alphanumeric':
$symbols_pattern = '[\w\s-]';
$title = __( 'Only letters and numbers allowed.', 'et_builder' );
break;
}
}
if ( 0 !== $min_length && 0 !== $max_length ) {
$max_length = max( $min_length, $max_length );
$min_length = min( $min_length, $max_length );
if ( $max_length > 0 ) {
$max_length_attr = sprintf(
' maxlength="%1$d"',
$max_length
);
}
}
if ( 0 !== $min_length || 0 !== $max_length ) {
$length_pattern = '{';
if ( 0 !== $min_length ) {
$length_pattern .= $min_length;
$title .= sprintf( __( 'Minimum length: %1$d characters. ', 'et_builder' ), $min_length );
}
if ( 0 === $max_length ) {
$length_pattern .= ',';
}
if ( 0 === $min_length ) {
$length_pattern .= '0';
}
if ( 0 !== $max_length ) {
$length_pattern .= ",{$max_length}";
$title .= sprintf( __( 'Maximum length: %1$d characters.', 'et_builder' ), $max_length );
}
$length_pattern .= '}';
}
if ( '.' !== $symbols_pattern || '*' !== $length_pattern ) {
$pattern = sprintf(
' pattern="%1$s%2$s"',
esc_attr( $symbols_pattern ),
esc_attr( $length_pattern )
);
}
if ( '' !== $title ) {
$title = sprintf(
' title="%1$s"',
esc_attr( $title )
);
}
$conditional_logic_attr = '';
if ( 'on' === $conditional_logic && ! empty( $conditional_logic_rules ) ) {
$option_search = array( '&#91;', '&#93;' );
$option_replace = array( '[', ']' );
$conditional_logic_rules = str_replace( $option_search, $option_replace, $conditional_logic_rules );
$condition_rows = json_decode( $conditional_logic_rules );
$ruleset = array();
// Ensure the JSON has been decoded successfully without any errors.
if ( JSON_ERROR_NONE === json_last_error() ) {
foreach ( $condition_rows as $condition_row ) {
$condition_value = isset( $condition_row->value ) ? $condition_row->value : '';
$condition_value = trim( $condition_value );
$ruleset[] = array(
$condition_row->field,
$condition_row->condition,
$condition_value,
);
}
if ( ! empty( $ruleset ) ) {
$json = wp_json_encode( $ruleset );
$relation = 'off' === $conditional_logic_relation ? 'any' : 'all';
$conditional_logic_attr = sprintf(
' data-conditional-logic="%1$s" data-conditional-relation="%2$s"',
esc_attr( $json ),
$relation
);
}
}
}
switch ( $field_type ) {
case 'text':
case 'textarea':
$input_field = sprintf(
'<textarea name="et_pb_contact_%3$s_%2$s" id="et_pb_contact_%3$s_%2$s" class="et_pb_contact_message input" data-required_mark="%6$s" data-field_type="%4$s" data-original_id="%3$s" placeholder="%5$s"%7$s>%1$s</textarea>',
( isset( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ? esc_html( sanitize_text_field( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ) : '' ),
esc_attr( $current_module_num ),
esc_attr( $field_id ),
esc_attr( $field_type ),
esc_attr( $field_title ),
'off' === $required_mark ? 'not_required' : 'required',
$multi_view->render_attrs(
array(
'attrs' => array(
'placeholder' => '{{field_title}}',
),
)
)
);
break;
case 'input':
case 'email':
if ( 'email' === $field_type ) {
$pattern = '';
}
$input_field = sprintf(
'<input type="text" id="et_pb_contact_%3$s_%2$s" class="input" value="%1$s" name="et_pb_contact_%3$s_%2$s" data-required_mark="%6$s" data-field_type="%4$s" data-original_id="%3$s" placeholder="%5$s"%7$s%8$s%9$s%10$s>',
( isset( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ? esc_attr( sanitize_text_field( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ) : '' ),
esc_attr( $current_module_num ),
esc_attr( $field_id ),
esc_attr( $field_type ),
esc_attr( $field_title ),
'off' === $required_mark ? 'not_required' : 'required',
$pattern,
$title,
$max_length_attr,
$multi_view->render_attrs(
array(
'attrs' => array(
'placeholder' => '{{field_title}}',
),
)
)
);
break;
case 'checkbox':
$input_field = '';
if ( ! $checkbox_options ) {
$is_checked = ! empty( $checkbox_checked ) && 'on' === $checkbox_checked;
$checkbox_options = sprintf(
'[{"value":"%1$s","checked":%2$s}]',
esc_attr( $field_title ),
$is_checked ? 1 : 0
);
$field_title = '';
}
$option_search = array( '&#91;', '&#93;' );
$option_replace = array( '[', ']' );
$checkbox_options = str_replace( $option_search, $option_replace, $checkbox_options );
$checkbox_options = json_decode( $checkbox_options );
foreach ( $checkbox_options as $index => $option ) {
$is_checked = 1 === $option->checked ? true : false;
$option_value = wp_strip_all_tags( $option->value );
$drag_id = isset( $option->dragID ) ? $option->dragID : '';
$option_id = isset( $option->id ) ? $option->id : $drag_id;
$option_id = sprintf( ' data-id="%1$s"', esc_attr( $option_id ) );
$option_label = wp_strip_all_tags( $option->value );
$option_link = '';
if ( ! empty( $option->link_url ) ) {
$link_text = isset( $option->link_text ) ? $option->link_text : '';
$option_link = sprintf( ' <a href="%1$s" target="_blank">%2$s</a>', esc_url( $option->link_url ), esc_html( $link_text ) );
}
// The required field needs a value, use link information if the option value is empty
if ( 'off' !== $required_mark && empty( $option_value ) && ! empty( $option_link ) ) {
$option_value = isset( $option->link_text ) && ! empty( $option->link_text ) ? esc_html( $option->link_text ) : esc_url( $option->link_url );
}
$input_field .= sprintf(
'<span class="et_pb_contact_field_checkbox">
<input type="checkbox" id="et_pb_contact_%1$s_%5$s_%3$s" class="input" value="%2$s"%4$s%6$s>
<label for="et_pb_contact_%1$s_%5$s_%3$s"><i></i>%7$s%8$s</label>
</span>',
esc_attr( $field_id ),
esc_attr( $option_value ),
esc_attr( $index ),
$is_checked ? ' checked="checked"' : '',
esc_attr( $render_count ), // #5
$option_id,
$option_label,
$option_link // #8
);
}
$input_field = sprintf(
'<input class="et_pb_checkbox_handle" type="hidden" name="et_pb_contact_%1$s_%4$s" data-required_mark="%3$s" data-field_type="%2$s" data-original_id="%1$s">
<span class="et_pb_contact_field_options_wrapper">
<span class="et_pb_contact_field_options_title"%7$s>%5$s</span>
<span class="et_pb_contact_field_options_list">%6$s</span>
</span>',
esc_attr( $field_id ),
esc_attr( $field_type ),
'off' === $required_mark ? 'not_required' : 'required',
esc_attr( $current_module_num ),
esc_html( $field_title ),
$input_field,
$multi_view->render_attrs(
array(
'content' => '{{field_title}}',
)
)
);
break;
case 'booleancheckbox':
$input_field = '';
$option_search = array( '&#91;', '&#93;' );
$option_replace = array( '[', ']' );
$checkbox_options = str_replace( $option_search, $option_replace, $booleancheckbox_options );
$checkbox_options = json_decode( $checkbox_options );
$option = self::$_->array_get( $checkbox_options, 0 );
$is_checked = 1 === $option->checked;
$option_value = wp_strip_all_tags( $option->value );
$drag_id = isset( $option->dragID ) ? $option->dragID : ''; // phpcs:ignore ET.Sniffs.ValidVariableName.UsedPropertyNotSnakeCase -- The $option is the sortable list item object set from the sortable-list.jsx
$option_id = isset( $option->id ) ? $option->id : $drag_id;
$option_id = sprintf( ' data-id="%1$s"', esc_attr( $option_id ) );
$input_field .= sprintf(
'<input type="checkbox" id="et_pb_contact_%1$s_%5$s_%3$s" class="input" value="%2$s"%4$s%6$s>
<label for="et_pb_contact_%1$s_%5$s_%3$s"><i></i><span class="et_pb_contact_field_options_title">%7$s</span></label>',
esc_attr( $field_id ),
esc_attr( $option_value ),
esc_attr( 0 ),
$is_checked ? ' checked="checked"' : '',
esc_attr( $render_count ), // #5
$option_id,
esc_html( $field_title )
);
$input_field = sprintf(
'<input class="et_pb_checkbox_handle" type="hidden" name="et_pb_contact_%1$s_%4$s" data-required_mark="%3$s" data-field_type="%2$s" data-original_id="%1$s">
<span class="et_pb_contact_field_options_wrapper">
%5$s
%6$s
</span>',
esc_attr( $field_id ),
esc_attr( $field_type ),
'off' === $required_mark ? 'not_required' : 'required',
esc_attr( $current_module_num ),
$input_field,
$multi_view->render_attrs(
array(
'content' => '{{field_title}}',
)
)
);
break;
case 'radio':
$input_field = '';
if ( $radio_options ) {
$option_search = array( '&#91;', '&#93;' );
$option_replace = array( '[', ']' );
$radio_options = str_replace( $option_search, $option_replace, $radio_options );
$radio_options = json_decode( $radio_options );
foreach ( $radio_options as $index => $option ) {
$is_checked = ( isset( $option->checked ) && 1 === $option->checked ) ? true : false;
$drag_id = isset( $option->dragID ) ? $option->dragID : '';
$option_id = isset( $option->id ) ? $option->id : $drag_id;
$option_id = sprintf( ' data-id="%1$s"', esc_attr( $option_id ) );
$option_link = '';
if ( ! empty( $option->link_url ) ) {
$link_text = isset( $option->link_text ) ? $option->link_text : '';
$option_link = sprintf( ' <a href="%1$s" target="_blank">%2$s</a>', esc_url( $option->link_url ), esc_html( $link_text ) );
}
$input_field .= sprintf(
'<span class="et_pb_contact_field_radio">
<input type="radio" id="et_pb_contact_%3$s_%2$s_%10$s_%7$s" class="input" value="%8$s" name="et_pb_contact_%3$s_%2$s" data-required_mark="%6$s" data-field_type="%4$s" data-original_id="%3$s" %9$s%11$s>
<label for="et_pb_contact_%3$s_%2$s_%10$s_%7$s"><i></i>%8$s%12$s</label>
</span>',
( isset( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ? esc_attr( sanitize_text_field( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ) : '' ),
esc_attr( $current_module_num ),
esc_attr( $field_id ),
esc_attr( $field_type ),
esc_attr( $field_title ), // #5
'off' === $required_mark ? 'not_required' : 'required',
esc_attr( $index ),
esc_attr( wp_strip_all_tags( isset( $option->value ) ? $option->value : '' ) ),
checked( $is_checked, true, false ),
esc_attr( $render_count ), // #10
$option_id,
$option_link // #12
);
}
} else {
$input_field .= esc_html__( 'No options added.', 'et_builder' );
}
$input_field = sprintf(
'<span class="et_pb_contact_field_options_wrapper">
<span class="et_pb_contact_field_options_title"%3$s>%1$s</span>
<span class="et_pb_contact_field_options_list">%2$s</span>
</span>',
esc_html( $field_title ),
$input_field,
$multi_view->render_attrs(
array(
'content' => '{{field_title}}',
)
)
);
break;
case 'select':
$options = sprintf(
'<option value=""%2$s>%1$s</option>',
esc_html( $field_title ),
$multi_view->render_attrs(
array(
'content' => '{{field_title}}',
)
)
);
if ( $select_options ) {
$option_search = array( '&#91;', '&#93;' );
$option_replace = array( '[', ']' );
$select_options = str_replace( $option_search, $option_replace, $select_options );
$select_options = json_decode( $select_options );
foreach ( $select_options as $option ) {
$option_id = isset( $option->id ) ? sprintf( ' data-id="%1$s"', esc_attr( $option->id ) ) : '';
$options .= sprintf(
'<option value="%1$s"%3$s>%2$s</option>',
esc_attr( wp_strip_all_tags( $option->value ) ),
wp_strip_all_tags( $option->value ),
$option_id
);
}
}
$input_field = sprintf(
'<select id="et_pb_contact_%3$s_%2$s" class="et_pb_contact_select input" name="et_pb_contact_%3$s_%2$s" data-required_mark="%6$s" data-field_type="%4$s" data-original_id="%3$s">
%7$s
</select>',
( isset( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ? esc_attr( sanitize_text_field( $_POST[ 'et_pb_contact_' . $field_id . '_' . $current_module_num ] ) ) : '' ),
esc_attr( $current_module_num ),
esc_attr( $field_id ),
esc_attr( $field_type ),
esc_attr( $field_title ),
'off' === $required_mark ? 'not_required' : 'required',
$options
);
break;
}
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
if ( 'off' === $fullwidth_field ) {
$this->add_classname( 'et_pb_contact_field_half' );
}
if ( 0 === $et_pb_half_width_counter % 2 ) {
$this->add_classname( 'et_pb_contact_field_last' );
}
if ( 'on' === self::$_->array_get( $this->props, 'hidden' ) ) {
$this->add_classname( 'et_pb_contact_field--hidden' );
}
if ( $this->_has_background() ) {
$this->add_classname( 'has-background' );
}
// Remove automatically added classname
$this->remove_classname( 'et_pb_module' );
$output = sprintf(
'<p class="%5$s"%6$s data-id="%3$s" data-type="%7$s">
%9$s
%8$s
<label for="et_pb_contact_%3$s_%2$s" class="et_pb_contact_form_label"%10$s>%1$s</label>
%4$s
</p>',
esc_html( $field_title ),
esc_attr( $current_module_num ),
esc_attr( $field_id ),
$input_field,
$this->module_classname( $render_slug ),
$conditional_logic_attr,
$field_type,
$video_background,
$parallax_image_background,
$multi_view->render_attrs(
array(
'content' => '{{field_title}}',
)
)
);
return $output;
}
/**
* Checks if module has background.
*
* @since 4.9.3
*
* @return bool
*/
protected function _has_background() {
return 'on' === self::$_->array_get( $this->props, 'background_enable_color' )
|| 'on' === self::$_->array_get( $this->props, 'background_enable_image' )
|| 'on' === self::$_->array_get( $this->props, 'background_enable_video_mp4' )
|| 'on' === self::$_->array_get( $this->props, 'background_enable_video_webm' );
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Contact_Form_Item();
}

View File

@ -0,0 +1,299 @@
<?php
class ET_Builder_Module_Countdown_Timer extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Countdown Timer', 'et_builder' );
$this->plural = esc_html__( 'Countdown Timers', 'et_builder' );
$this->slug = 'et_pb_countdown_timer';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_countdown_timer';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => et_builder_i18n( 'Text' ),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h4, {$this->main_css_element} h1.title, {$this->main_css_element} h2.title, {$this->main_css_element} h3.title, {$this->main_css_element} h5.title, {$this->main_css_element} h6.title",
'important' => array( 'size', 'plugin_all' ),
),
'header_level' => array(
'default' => 'h4',
),
),
'numbers' => array(
'label' => esc_html__( 'Numbers', 'et_builder' ),
'css' => array(
'main' => ".et_pb_column {$this->main_css_element} .section p.value, .et_pb_column {$this->main_css_element} .section.sep p",
'important' => 'all',
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
),
'separator' => array(
'label' => esc_html__( 'Separator', 'et_builder' ),
'css' => array(
'main' => ".et_pb_column {$this->main_css_element} .et_pb_countdown_timer_container .section.sep p",
'important' => 'all',
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'hide_text_align' => true,
),
'label' => array(
'label' => esc_html__( 'Label', 'et_builder' ),
'css' => array(
'main' => ".et_pb_column {$this->main_css_element} .section p.label",
'important' => array(
'size',
'line-height',
),
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
),
),
'background' => array(
'has_background_color_toggle' => true,
'use_background_color' => true,
'options' => array(
'background_color' => array(
'depends_show_if' => 'on',
'default' => et_builder_accent_color(),
),
'use_background_color' => array(
'default' => 'on',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => '%%order_class%% .et_pb_countdown_timer_container, %%order_class%% .title',
'text_orientation' => '%%order_class%% .et_pb_countdown_timer_container, %%order_class%% .title',
),
'options' => array(
'text_orientation' => array(
'default' => 'center',
),
'background_layout' => array(
'default' => 'dark',
'hover' => 'tabs',
),
),
),
'button' => false,
);
$this->custom_css_fields = array(
'container' => array(
'label' => esc_html__( 'Container', 'et_builder' ),
'selector' => '.et_pb_countdown_timer_container',
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'selector' => '.title',
),
'timer_section' => array(
'label' => esc_html__( 'Timer Section', 'et_builder' ),
'selector' => '.section',
),
);
$this->help_videos = array(
array(
'id' => 'irIXKlOw6JA',
'name' => esc_html__( 'An introduction to the Countdown Timer module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'This is the title displayed for the countdown timer.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'date_time' => array(
'label' => esc_html__( 'Date', 'et_builder' ),
'type' => 'date_picker',
'option_category' => 'basic_option',
'description' => et_get_safe_localization( sprintf( __( 'This is the date the countdown timer is counting down to. Your countdown timer is based on your timezone settings in your <a href="%1$s" target="_blank" title="WordPress General Settings">WordPress General Settings</a>', 'et_builder' ), esc_url( admin_url( 'options-general.php' ) ) ) ),
'toggle_slug' => 'main_content',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['header_level'], 'h4' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'title',
),
)
);
$date_time = $this->props['date_time'];
$use_background_color = $this->props['use_background_color'];
$end_date = gmdate( 'M d, Y H:i:s', strtotime( $date_time ) );
$gmt_offset = get_option( 'gmt_offset' );
$gmt_divider = '-' === substr( $gmt_offset, 0, 1 ) ? '-' : '+';
$gmt_offset_hour = str_pad( abs( intval( $gmt_offset ) ), 2, '0', STR_PAD_LEFT );
$gmt_offset_minute = str_pad( ( ( abs( $gmt_offset ) * 100 ) % 100 ) * ( 60 / 100 ), 2, '0', STR_PAD_LEFT );
$gmt = "GMT{$gmt_divider}{$gmt_offset_hour}{$gmt_offset_minute}";
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Module classnames
if ( 'on' !== $use_background_color ) {
$this->add_classname( 'et_pb_no_bg' );
}
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
$output = sprintf(
'<div%1$s class="%2$s"%3$s data-end-timestamp="%4$s"%16$s>
%15$s
%14$s
<div class="et_pb_countdown_timer_container clearfix">
%5$s
<div class="days section values" data-short="%13$s" data-full="%6$s">
<p class="value"></p>
<p class="label">%6$s</p>
</div><div class="sep section">
<p>:</p>
</div><div class="hours section values" data-short="%8$s" data-full="%7$s">
<p class="value"></p>
<p class="label">%7$s</p>
</div><div class="sep section">
<p>:</p>
</div><div class="minutes section values" data-short="%10$s" data-full="%9$s">
<p class="value"></p>
<p class="label">%9$s</p>
</div><div class="sep section">
<p>:</p>
</div><div class="seconds section values" data-short="%12$s" data-full="%11$s">
<p class="value"></p>
<p class="label">%11$s</p>
</div>
</div>
</div>',
$this->module_id(),
$this->module_classname( $render_slug ),
'',
esc_attr( strtotime( "{$end_date} {$gmt}" ) ),
et_core_esc_previously( $title ), // #5
esc_html__( 'Day(s)', 'et_builder' ),
esc_html__( 'Hour(s)', 'et_builder' ),
esc_attr__( 'Hrs', 'et_builder' ),
esc_html__( 'Minute(s)', 'et_builder' ),
esc_attr__( 'Min', 'et_builder' ), // #10
esc_html__( 'Second(s)', 'et_builder' ),
esc_attr__( 'Sec', 'et_builder' ),
esc_attr__( 'Day', 'et_builder' ),
$video_background,
$parallax_image_background, // #15
et_core_esc_previously( $data_background_layout )
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Countdown_Timer();
}

View File

@ -0,0 +1,362 @@
<?php
class ET_Builder_Module_Cta extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Call To Action', 'et_builder' );
$this->plural = esc_html__( 'Call To Actions', 'et_builder' );
$this->slug = 'et_pb_cta';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_promo';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'width' => array(
'title' => et_builder_i18n( 'Sizing' ),
'priority' => 80,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h2, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
'important' => 'all',
),
'header_level' => array(
'default' => 'h2',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_promo_description div",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
'css' => array(
'main' => "{$this->main_css_element}",
),
),
),
),
'background' => array(
'has_background_color_toggle' => true,
'use_background_color' => true,
'options' => array(
'background_color' => array(
'depends_show_if' => 'on',
'default' => et_builder_accent_color(),
),
'use_background_color' => array(
'default' => 'on',
),
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_promo.et_pb_module',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_promo_button.et_pb_button",
'limited_main' => "{$this->main_css_element} .et_pb_promo_button.et_pb_button",
'alignment' => "{$this->main_css_element} .et_pb_button_wrapper",
),
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button',
),
),
'margin_padding' => array(
'css' => array(
'main' => "{$this->main_css_element} .et_pb_button_wrapper .et_pb_promo_button.et_pb_button",
'important' => 'all',
),
),
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => '%%order_class%% .et_pb_promo_description, %%order_class%% .et_pb_module_header',
'text_shadow' => '%%order_class%% .et_pb_promo_description',
),
'options' => array(
'text_orientation' => array(
'default' => 'center',
),
'background_layout' => array(
'default' => 'dark',
),
),
),
);
$this->custom_css_fields = array(
'promo_description' => array(
'label' => esc_html__( 'Promo Description', 'et_builder' ),
'selector' => '.et_pb_promo_description',
),
'promo_button' => array(
'label' => esc_html__( 'Promo Button', 'et_builder' ),
'selector' => '.et_pb_promo .et_pb_button.et_pb_promo_button',
'no_space_before_selector' => true,
),
'promo_title' => array(
'label' => esc_html__( 'Promo Title', 'et_builder' ),
'selector' => '.et_pb_promo_description h2',
),
);
$this->help_videos = array(
array(
'id' => 'E3AEllqnCus',
'name' => esc_html__( 'An introduction to the Call To Action module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your value to action title here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'button_url' => array(
'label' => esc_html__( 'Button Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the destination URL for your CTA button.', 'et_builder' ),
'toggle_slug' => 'link_options',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Button Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'toggle_slug' => 'link_options',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
'default_on_front' => 'off',
),
'button_text' => array(
'label' => et_builder_i18n( 'Button' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your desired button text, or leave blank for no button.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the main text content for your module here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
function get_max_width_additional_css() {
$additional_css = 'center' === $this->get_text_orientation() ? '; margin: 0 auto;' : '';
return $additional_css;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['header_level'], 'h2' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_module_header',
),
)
);
$button_url = $this->props['button_url'];
$button_rel = $this->props['button_rel'];
$button_text = $this->_esc_attr( 'button_text', 'limited' );
$background_color = $this->props['background_color'];
$use_background_colors = et_pb_responsive_options()->get_composite_property_values( $this->props, 'background', 'use_background_color' );
$use_background_color_hover = et_pb_hover_options()->get_compose_value( 'use_background_color', 'background', $this->props, '' );
$url_new_window = $this->props['url_new_window'];
$button_custom = $this->props['custom_button'];
$header_level = $this->props['header_level'];
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$button_url = trim( $button_url );
// Module classnames
$this->add_classname(
array(
'et_pb_promo',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
// Background color class.
foreach ( $use_background_colors as $mode => $value ) {
// Ensure value is not empty.
if ( empty( $value ) ) {
continue;
}
$is_value_on = 'on' === $value;
$infix_class = $is_value_on ? 'has' : 'no';
// Desktop doesn't need has background class.
if ( 'desktop' === $mode && $is_value_on ) {
continue;
}
$this->add_classname( et_pb_responsive_options()->get_field_name( "et_pb_{$infix_class}_bg", $mode ) );
}
if ( ! empty( $use_background_color_hover ) ) {
$is_value_hover_on = 'on' === $use_background_color_hover;
$infix_class_hover = $is_value_hover_on ? 'has' : 'on';
$this->add_classname( "et_pb_{$infix_class_hover}_bg_hover" );
}
// Remove automatically added classname
$this->remove_classname( 'et_pb_cta' );
// Render button
$button = $this->render_button(
array(
'button_classname' => array( 'et_pb_promo_button' ),
'button_custom' => $button_custom,
'button_rel' => $button_rel,
'button_text' => $button_text,
'button_text_escaped' => true,
'button_url' => $button_url,
'custom_icon' => $custom_icon,
'custom_icon_tablet' => $custom_icon_tablet,
'custom_icon_phone' => $custom_icon_phone,
'url_new_window' => $url_new_window,
'display_button' => ( '' !== $button_url && $multi_view->has_value( 'button_text' ) ),
'multi_view_data' => $multi_view->render_attrs(
array(
'content' => '{{button_text}}',
'visibility' => array(
'button_text' => '__not_empty',
'button_url' => '__not_empty',
),
)
),
)
);
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
)
);
$content_wrapper = $multi_view->render_element(
array(
'tag' => 'div',
'content' => "{$title}{$content}",
'attrs' => array(
'class' => 'et_pb_promo_description',
),
'classes' => array(
'et_multi_view_hidden' => array(
'title' => '__empty',
'content' => '__empty',
),
),
)
);
// Render module output
$output = sprintf(
'<div%5$s class="%4$s"%8$s>
%7$s
%6$s
%9$s
%3$s
</div>',
et_core_esc_previously( $title ),
et_core_esc_previously( $content ),
$button,
$this->module_classname( $render_slug ),
$this->module_id(), // #5
$video_background,
$parallax_image_background,
et_core_esc_previously( $data_background_layout ),
et_core_esc_previously( $content_wrapper )
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Cta();
}

View File

@ -0,0 +1,403 @@
<?php
class ET_Builder_Module_Divider extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Divider', 'et_builder' );
$this->plural = esc_html__( 'Dividers', 'et_builder' );
$this->slug = 'et_pb_divider';
$this->vb_support = 'on';
$style_option_name = sprintf( '%1$s-divider_style', $this->slug );
$global_divider_style = ET_Global_Settings::get_value( $style_option_name );
$position_option_name = sprintf( '%1$s-divider_position', $this->slug );
$global_divider_position = ET_Global_Settings::get_value( $position_option_name );
$weight_option_name = sprintf( '%1$s-divider_weight', $this->slug );
$global_divider_weight = ET_Global_Settings::get_value( $weight_option_name );
$this->defaults = array(
'divider_style' => $global_divider_style && '' !== $global_divider_style ? $global_divider_style : 'solid',
'divider_position' => $global_divider_position && '' !== $global_divider_position ? $global_divider_position : 'top',
'divider_weight' => $global_divider_weight && '' !== $global_divider_weight ? $global_divider_weight : '1px',
);
// Show divider options is modifieable via customizer
$this->show_divider_options = array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
);
// Handle different default values for Builder Plugin
if ( ! et_is_builder_plugin_active() && true === et_get_option( 'et_pb_divider-show_divider', false ) ) {
$this->show_divider_options = array_reverse( $this->show_divider_options );
}
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Visibility' ),
),
),
'advanced' => array(
'toggles' => array(
'line' => esc_html__( 'Line', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%%',
'border_styles' => '%%order_class%%',
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'fonts' => false,
'text' => false,
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => 'BL4CEVbDZfw',
'name' => esc_html__( 'An introduction to the Divider module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'color' => array(
'default' => et_builder_accent_color(),
'label' => esc_html__( 'Line Color', 'et_builder' ),
'type' => 'color-alpha',
'tab_slug' => 'advanced',
'description' => esc_html__( 'This will adjust the color of the 1px divider line.', 'et_builder' ),
'depends_show_if' => 'on',
'toggle_slug' => 'line',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'show_divider' => array(
'default' => 'on',
'label' => esc_html__( 'Show Divider', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => $this->show_divider_options,
'affects' => array(
'divider_style',
'divider_position',
'divider_weight',
'color',
),
'toggle_slug' => 'main_content',
'description' => esc_html__( 'This settings turns on and off the 1px divider line, but does not affect the divider height.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'divider_style' => array(
'label' => esc_html__( 'Line Style', 'et_builder' ),
'description' => esc_html__( 'Select the shape of the dividing line used for the divider.', 'et_builder' ),
'type' => 'select',
'option_category' => 'layout',
'options' => et_builder_get_border_styles(),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'line',
'default' => $this->defaults['divider_style'],
'mobile_options' => true,
),
'divider_position' => array(
'label' => esc_html__( 'Line Position', 'et_builder' ),
'description' => esc_html__( 'The dividing line can be placed either above, below or in the center of the module.', 'et_builder' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'top' => et_builder_i18n( 'Top' ),
'center' => esc_html__( 'Vertically Centered', 'et_builder' ),
'bottom' => et_builder_i18n( 'Bottom' ),
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'line',
'default' => $this->defaults['divider_position'],
'mobile_options' => true,
),
'divider_weight' => array(
'label' => esc_html__( 'Divider Weight', 'et_builder' ),
'description' => esc_html__( 'Increasing the divider weight will increase the thickness of the dividing line.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'px',
'default' => $this->defaults['divider_weight'],
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_height_fields() {
$defaults = array(
'default' => '23px',
'min' => '1',
'max' => '100',
);
return ET_Builder_Module_Fields_Factory::get( 'Height' )->get_fields( $defaults );
}
public function get_max_height_fields() {
$defaults = array(
'min' => '1',
'max' => '100',
);
return ET_Builder_Module_Fields_Factory::get( 'MaxHeight' )->get_fields( $defaults );
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['color'] = array( 'border' => '%%order_class%%:before' );
$fields['divider_weight'] = array( 'border' => '%%order_class%%:before' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$show_divider = $this->props['show_divider'];
$divider_position_customizer = ! et_is_builder_plugin_active() ? et_get_option( 'et_pb_divider-divider_position', 'top' ) : 'top';
$custom_padding = $this->props['custom_padding'];
$custom_padding_tablet = $this->props['custom_padding_tablet'];
$custom_padding_phone = $this->props['custom_padding_phone'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$color = $this->props['color'];
$color_values = et_pb_responsive_options()->get_property_values( $this->props, 'color' );
$color_tablet = isset( $color_values['tablet'] ) ? $color_values['tablet'] : '';
$color_phone = isset( $color_values['phone'] ) ? $color_values['phone'] : '';
$divider_style = $this->props['divider_style'];
$divider_style_hover = $this->get_hover_value( 'divider_style' );
$divider_style_values = et_pb_responsive_options()->get_property_values( $this->props, 'divider_style' );
$divider_style_tablet = isset( $divider_style_values['tablet'] ) ? $divider_style_values['tablet'] : '';
$divider_style_phone = isset( $divider_style_values['phone'] ) ? $divider_style_values['phone'] : '';
$divider_weight = $this->props['divider_weight'];
$divider_weight_values = et_pb_responsive_options()->get_property_values( $this->props, 'divider_weight' );
$divider_weight_tablet = isset( $divider_weight_values['tablet'] ) ? $divider_weight_values['tablet'] : '';
$divider_weight_phone = isset( $divider_weight_values['phone'] ) ? $divider_weight_values['phone'] : '';
$divider_position = $this->props['divider_position'];
$divider_position_values = et_pb_responsive_options()->get_property_values( $this->props, 'divider_position' );
$divider_position_tablet = isset( $divider_position_values['tablet'] ) ? $divider_position_values['tablet'] : '';
$divider_position_phone = isset( $divider_position_values['phone'] ) ? $divider_position_values['phone'] : '';
// In Divider module, divider color is really important. Basically, the divider won't be
// displayed, unless we set divider color for Desktop. Divider color on desktop mode is
// the key to display divider style and weight and set the position class.
// Desktop Color is not empty, means:
// - Render divider style and weight for all devices.
// - Render divider position class for all devices.
if ( 'on' === $show_divider ) {
// Responsive Color, Divider Style, and Divider Weight.
$divider_styles_values = array();
foreach ( et_pb_responsive_options()->get_modes() as $device ) {
$is_desktop = 'desktop' === $device;
$suffix = ! $is_desktop ? "_{$device}" : '';
// Get divider color and set general color variables.
$divider_color_value = '';
if ( $is_desktop ) {
$divider_color_value = $color;
} else {
$divider_color_value = 'tablet' === $device ? $color_tablet : $color_phone;
}
// Ensure color value is not empty. At least desktop color.
if ( empty( $color ) && empty( $divider_color_value ) ) {
continue;
}
$divider_style_value = '';
$divider_weight_value = '';
if ( $is_desktop ) {
$divider_style_value = $divider_style;
$divider_weight_value = $divider_weight;
} else {
$divider_style_value = 'tablet' === $device ? $divider_style_tablet : $divider_style_phone;
$divider_weight_value = 'tablet' === $device ? $divider_weight_tablet : $divider_weight_phone;
}
$divider_styles_values[ $device ] = array(
'border-top-color' => esc_attr( $divider_color_value ),
'border-top-style' => esc_attr( $divider_style_value ),
'border-top-width' => ! empty( $divider_weight_value ) ? esc_attr( et_sanitize_input_unit( $divider_weight_value ) ) : '',
);
}
et_pb_responsive_options()->generate_responsive_css( $divider_styles_values, '%%order_class%%:before', '', $render_slug, '', 'border' );
// Divider Position Class.
if ( ! empty( $color ) ) {
if ( $this->defaults['divider_position'] !== $divider_position ) {
$this->add_classname( "et_pb_divider_position_{$divider_position}" );
} elseif ( $this->defaults['divider_position'] !== $divider_position_customizer ) {
$this->add_classname(
array(
"et_pb_divider_position_{$divider_position_customizer}",
'customized_et_pb_divider_position',
)
);
}
}
if ( ! empty( $divider_position_tablet ) && ( ! empty( $color ) || ! empty( $color_tablet ) ) ) {
$this->add_classname( "et_pb_divider_position_{$divider_position_tablet}_tablet" );
}
if ( ! empty( $divider_position_phone ) && ( ! empty( $color ) || ! empty( $color_phone ) ) ) {
$this->add_classname( "et_pb_divider_position_{$divider_position_phone}_phone" );
}
}
// Hover & sticky styles.
$this->generate_styles(
array(
'responsive' => false,
'base_attr_name' => 'color',
'selector' => '%%order_class%%:before',
'css_property' => 'border-top-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
$this->generate_styles(
array(
'responsive' => false,
'base_attr_name' => 'divider_weight',
'selector' => '%%order_class%%:before',
'css_property' => 'border-top-width',
'render_slug' => $render_slug,
'type' => 'range',
)
);
if ( '' !== $custom_padding && '|||' !== $custom_padding ) {
$el_style = array(
'selector' => '%%order_class%%:before',
'declaration' => sprintf(
'width: auto; top: %1$s; right: %2$s; left: %3$s;',
esc_attr( et_pb_get_spacing( $custom_padding, 'top', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding, 'right', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding, 'left', '0px' ) )
),
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
if ( '' !== $custom_padding_tablet && '|||' !== $custom_padding_tablet ) {
$el_style = array(
'selector' => '%%order_class%%:before',
'declaration' => sprintf(
'width: auto; top: %1$s; right: %2$s; left: %3$s;',
esc_attr( et_pb_get_spacing( $custom_padding_tablet, 'top', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding_tablet, 'right', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding_tablet, 'left', '0px' ) )
),
'media_query' => ET_Builder_Element::get_media_query( 'max_width_980' ),
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
if ( '' !== $custom_padding_phone && '|||' !== $custom_padding_phone ) {
$el_style = array(
'selector' => '%%order_class%%:before',
'declaration' => sprintf(
'width: auto; top: %1$s; right: %2$s; left: %3$s;',
esc_attr( et_pb_get_spacing( $custom_padding_phone, 'top', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding_phone, 'right', '0px' ) ),
esc_attr( et_pb_get_spacing( $custom_padding_phone, 'left', '0px' ) )
),
'media_query' => ET_Builder_Element::get_media_query( 'max_width_767' ),
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
// Module classnames
$this->add_classname( 'et_pb_space' );
if ( 'on' !== $show_divider ) {
$this->remove_classname( 'et_pb_divider' );
$this->add_classname( 'et_pb_divider_hidden' );
}
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_divider' => array(
'show_divider' => 'on',
),
'et_pb_divider_hidden' => array(
'show_divider' => 'off',
),
),
)
);
$output = sprintf(
'<div%2$s class="%1$s"%5$s>%4$s%3$s<div class="et_pb_divider_internal"></div></div>',
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background,
$multi_view_data_attr
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Divider();
}

View File

@ -0,0 +1,791 @@
<?php
class ET_Builder_Module_Filterable_Portfolio extends ET_Builder_Module_Type_PostBased {
function init() {
$this->name = esc_html__( 'Filterable Portfolio', 'et_builder' );
$this->plural = esc_html__( 'Filterable Portfolios', 'et_builder' );
$this->slug = 'et_pb_filterable_portfolio';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_filterable_portfolio';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Content' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'overlay' => et_builder_i18n( 'Overlay' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'image' => et_builder_i18n( 'Image' ),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h2, {$this->main_css_element} .et_pb_module_header",
'limited_main' => "{$this->main_css_element} h2, {$this->main_css_element} h2 a, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h1.et_pb_module_header a, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header a, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header a, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header a, {$this->main_css_element} h6.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header a",
'hover' => "{$this->main_css_element} h2:hover, {$this->main_css_element} h2:hover a, {$this->main_css_element} h1.et_pb_module_header:hover, {$this->main_css_element} h1.et_pb_module_header:hover a, {$this->main_css_element} h3.et_pb_module_header:hover, {$this->main_css_element} h3.et_pb_module_header:hover a, {$this->main_css_element} h4.et_pb_module_header:hover, {$this->main_css_element} h4.et_pb_module_header:hover a, {$this->main_css_element} h5.et_pb_module_header:hover, {$this->main_css_element} h5.et_pb_module_header:hover a, {$this->main_css_element} h6.et_pb_module_header:hover, {$this->main_css_element} h6.et_pb_module_header:hover a",
'important' => 'all',
),
'header_level' => array(
'default' => 'h2',
),
),
'filter' => array(
'label' => esc_html__( 'Filter Criteria', 'et_builder' ),
'hide_text_align' => true,
'css' => array(
'main' => "{$this->main_css_element} .et_pb_portfolio_filter",
'limited_main' => "{$this->main_css_element} .et_pb_portfolio_filter, {$this->main_css_element} .et_pb_portfolio_filter a",
'hover' => "{$this->main_css_element} .et_pb_portfolio_filter:hover, {$this->main_css_element} .et_pb_portfolio_filter:hover a",
'color_hover' => "{$this->main_css_element} .et_pb_portfolio_filter:hover a",
'color' => "{$this->main_css_element} .et_pb_portfolio_filter a",
),
),
'caption' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .post-meta, {$this->main_css_element} .post-meta a",
'hover' => "{$this->main_css_element} .post-meta a:hover",
),
),
'pagination' => array(
'label' => esc_html__( 'Pagination', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_portofolio_pagination a",
'text_align' => "{$this->main_css_element} .et_pb_portofolio_pagination ul",
'hover' => "{$this->main_css_element} .et_pb_portofolio_pagination a:hover",
),
'text_align' => array(
'options' => et_builder_get_text_orientation_options( array( 'justified' ), array() ),
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_portfolio_item",
'border_styles' => "{$this->main_css_element} .et_pb_portfolio_item",
),
),
),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_portfolio_image",
'border_styles' => "{$this->main_css_element} .et_portfolio_image",
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'box_shadow' => array(
'default' => array(),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_portfolio_item .et_portfolio_image',
'overlay' => 'inset',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_filterable_portfolio.et_pb_module',
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => '%%order_class%% .et_pb_module_header, %%order_class%% .post-meta',
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_portfolio_image',
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
);
$this->custom_css_fields = array(
'portfolio_filters' => array(
'label' => esc_html__( 'Portfolio Filters', 'et_builder' ),
'selector' => '.et_pb_filterable_portfolio .et_pb_portfolio_filters',
'no_space_before_selector' => true,
),
'active_portfolio_filter' => array(
'label' => esc_html__( 'Active Portfolio Filter', 'et_builder' ),
'selector' => '.et_pb_filterable_portfolio .et_pb_portfolio_filters li a.active',
'no_space_before_selector' => true,
),
'portfolio_image' => array(
'label' => esc_html__( 'Portfolio Image', 'et_builder' ),
'selector' => '.et_portfolio_image',
),
'overlay' => array(
'label' => et_builder_i18n( 'Overlay' ),
'selector' => '.et_overlay',
),
'overlay_icon' => array(
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
'selector' => '.et_overlay:before',
),
'portfolio_title' => array(
'label' => esc_html__( 'Portfolio Title', 'et_builder' ),
'selector' => '.et_pb_portfolio_item h2',
),
'portfolio_post_meta' => array(
'label' => esc_html__( 'Portfolio Post Meta', 'et_builder' ),
'selector' => '.et_pb_portfolio_item .post-meta',
),
'portfolio_pagination' => array(
'label' => esc_html__( 'Portfolio Pagination', 'et_builder' ),
'selector' => '.et_pb_portofolio_pagination',
),
'portfolio_pagination_active' => array(
'label' => esc_html__( 'Pagination Active Page', 'et_builder' ),
'selector' => '.et_pb_portofolio_pagination a.active',
),
);
$this->help_videos = array(
array(
'id' => 'AZheY1hVcJc',
'name' => esc_html__( 'An introduction to the Filterable Portfolio module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'fullwidth' => array(
'label' => et_builder_i18n( 'Layout' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'on' => esc_html__( 'Fullwidth', 'et_builder' ),
'off' => esc_html__( 'Grid', 'et_builder' ),
),
'affects' => array(
'hover_icon',
'zoom_icon_color',
'hover_overlay_color',
),
'description' => esc_html__( 'Choose your desired portfolio layout style.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'default_on_front' => 'on',
),
'posts_number' => array(
'default' => 10,
'label' => esc_html__( 'Post Count', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'description' => esc_html__( 'Define the number of projects that should be displayed per page.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'toggle_slug' => 'main_content',
),
'include_categories' => array(
'label' => esc_html__( 'Included Categories', 'et_builder' ),
'type' => 'categories',
'option_category' => 'basic_option',
'description' => esc_html__( 'Select the categories that you would like to include in the feed.', 'et_builder' ),
'computed_affects' => array(
'__project_terms',
'__projects',
),
'taxonomy_name' => 'project_category',
'toggle_slug' => 'main_content',
),
'show_title' => array(
'label' => esc_html__( 'Show Title', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn project titles on or off.', 'et_builder' ),
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'show_categories' => array(
'label' => esc_html__( 'Show Categories', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn the category links on or off.', 'et_builder' ),
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'show_pagination' => array(
'label' => esc_html__( 'Show Pagination', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Enable or disable pagination for this feed.', 'et_builder' ),
'default_on_front' => 'on',
'mobile_options' => true,
'hover' => 'tabs',
),
'zoom_icon_color' => array(
'label' => esc_html__( 'Zoom Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the zoom icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Hover Overlay Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Hover Icon Picker', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'sticky' => true,
),
'__project_terms' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Filterable_Portfolio', 'get_portfolio_terms' ),
'computed_depends_on' => array(
'include_categories',
),
),
'__projects' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Filterable_Portfolio', 'get_portfolio_item' ),
'computed_depends_on' => array(
'show_pagination',
'posts_number',
'include_categories',
'fullwidth',
),
),
);
return $fields;
}
static function get_portfolio_item( $args = array(), $conditional_tags = array(), $current_page = array() ) {
global $et_fb_processing_shortcode_object, $post;
$global_processing_original_value = $et_fb_processing_shortcode_object;
$defaults = array(
'show_pagination' => 'on',
'include_categories' => '',
'fullwidth' => 'on',
'nopaging' => true,
);
$query_args = array();
$args = wp_parse_args( $args, $defaults );
$include_categories = self::filter_invalid_term_ids( explode( ',', $args['include_categories'] ), 'project_category' );
if ( ! empty( $include_categories ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'project_category',
'field' => 'id',
'terms' => $include_categories,
'operator' => 'IN',
),
);
}
$default_query_args = array(
'post_type' => 'project',
'post_status' => array( 'publish', 'private' ),
'perm' => 'readable',
'posts_per_page' => - 1,
);
$query_args = wp_parse_args( $query_args, $default_query_args );
// Get portfolio query
$query = new WP_Query( $query_args );
// Format portfolio output, and add supplementary data
$width = 'on' === $args['fullwidth'] ? 1080 : 400;
$width = (int) apply_filters( 'et_pb_portfolio_image_width', $width );
$height = 'on' === $args['fullwidth'] ? 9999 : 284;
$height = (int) apply_filters( 'et_pb_portfolio_image_height', $height );
$classtext = 'on' === $args['fullwidth'] ? 'et_pb_post_main_image' : '';
$titletext = get_the_title();
// Loop portfolio item and add supplementary data
if ( $query->have_posts() ) {
$post_index = 0;
while ( $query->have_posts() ) {
$query->the_post();
ET_Post_Stack::replace( $post );
$categories = array();
$category_classes = array( 'et_pb_portfolio_item' );
if ( 'on' !== $args['fullwidth'] ) {
$category_classes[] = 'et_pb_grid_item';
}
$categories_object = get_the_terms( get_the_ID(), 'project_category' );
if ( ! empty( $categories_object ) ) {
foreach ( $categories_object as $category ) {
// Update category classes which will be used for post_class
$category_classes[] = 'project_category_' . urldecode( $category->slug );
// Push category data
$categories[] = array(
'id' => $category->term_id,
'slug' => $category->slug,
'label' => $category->name,
'permalink' => get_term_link( $category ),
);
}
}
// need to disable processing to make sure get_thumbnail() doesn't generate errors
$et_fb_processing_shortcode_object = false;
// Capture the ALT text defined in WP Media Library
$alttext = get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true );
// Get thumbnail
$thumbnail = get_thumbnail( $width, $height, $classtext, $alttext, $titletext, false, 'Blogimage' );
$et_fb_processing_shortcode_object = $global_processing_original_value;
// Append value to query post
$query->posts[ $post_index ]->post_permalink = get_permalink();
$query->posts[ $post_index ]->post_thumbnail = print_thumbnail( $thumbnail['thumb'], $thumbnail['use_timthumb'], $titletext, $width, $height, '', false, true );
$query->posts[ $post_index ]->post_categories = $categories;
$query->posts[ $post_index ]->post_class_name = array_merge( get_post_class( '', get_the_ID() ), $category_classes );
// Append category classes
$category_classes = implode( ' ', $category_classes );
$post_index++;
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
} elseif ( self::is_processing_computed_prop() ) {
// This is for the VB
$query = array( 'posts' => self::get_no_results_template() );
}
return $query;
}
static function get_portfolio_terms( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$portfolio = self::get_portfolio_item( $args, $conditional_tags, $current_page );
$terms = array();
if ( ! empty( $portfolio->posts ) ) {
foreach ( $portfolio->posts as $post ) {
if ( ! empty( $post->post_categories ) ) {
foreach ( $post->post_categories as $category ) {
$terms[ $category['slug'] ] = $category;
}
}
}
}
return $terms;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $post;
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$fullwidth = $this->props['fullwidth'];
$posts_number = $this->props['posts_number'];
$include_categories = $this->props['include_categories'];
$show_title = $this->props['show_title'];
$show_categories = $this->props['show_categories'];
$show_pagination = $this->props['show_pagination'];
$hover_icon = $this->props['hover_icon'];
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
$header_level = $this->props['title_level'];
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'zoom_icon_color',
'selector' => '%%order_class%% .et_overlay:before',
'css_property' => 'color',
'render_slug' => $render_slug,
'important' => true,
'type' => 'color',
)
);
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => '%%order_class%% .et_overlay',
'css_property' => array( 'background-color', 'border-color' ),
'render_slug' => $render_slug,
'type' => 'color',
)
);
$projects = self::get_portfolio_item(
array(
'show_pagination' => $show_pagination,
'posts_number' => $posts_number,
'include_categories' => $include_categories,
'fullwidth' => $fullwidth,
)
);
$categories_included = array();
$portfolio_order = self::_get_index( array( self::INDEX_MODULE_ORDER, $render_slug ) );
$items_count = 0;
$overlay_output = 'on' === $fullwidth ? '' : ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_sticky' => $hover_icon_sticky,
)
);
if ( 'on' !== $fullwidth ) {
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => '%%order_class%% .et_overlay:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
}
ob_start();
if ( $projects->post_count > 0 ) {
while ( $projects->have_posts() ) {
$projects->the_post();
ET_Post_Stack::replace( $post );
$category_classes = array();
$categories = get_the_terms( get_the_ID(), 'project_category' );
if ( $categories ) {
foreach ( $categories as $category ) {
$category_classes[] = 'project_category_' . urldecode( $category->slug );
$categories_included[] = $category->term_id;
}
}
$category_classes = implode( ' ', $category_classes );
$item_class = sprintf( 'et_pb_filterable_portfolio_item_%1$s_%2$s', $portfolio_order, $items_count );
$items_count++;
$main_post_class = sprintf(
'et_pb_portfolio_item%1$s %2$s %3$s',
( 'on' !== $fullwidth ? ' et_pb_grid_item' : '' ),
$category_classes,
$item_class
);
?>
<div id="post-<?php the_ID(); ?>" <?php post_class( $main_post_class ); ?>>
<?php
$thumb = '';
$width = 'on' === $fullwidth ? 1080 : 400;
$width = (int) apply_filters( 'et_pb_portfolio_image_width', $width );
$height = 'on' === $fullwidth ? 9999 : 284;
$height = (int) apply_filters( 'et_pb_portfolio_image_height', $height );
$classtext = 'on' === $fullwidth ? 'et_pb_post_main_image' : '';
$titletext = get_the_title();
$permalink = get_permalink();
$post_meta = get_the_term_list( get_the_ID(), 'project_category', '', ', ' );
$alttext = get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true );
$thumbnail = get_thumbnail( $width, $height, $classtext, $alttext, $titletext, false, 'Blogimage' );
$thumb = $thumbnail['thumb'];
if ( '' !== $thumb ) :
?>
<a href="<?php echo esc_url( $permalink ); ?>">
<span class="et_portfolio_image">
<?php print_thumbnail( $thumb, $thumbnail['use_timthumb'], $titletext, $width, $height ); ?>
<?php
if ( 'on' !== $fullwidth ) {
echo et_core_esc_previously( $overlay_output ); }
?>
</span>
</a>
<?php
endif;
$multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h2' ),
'content' => sprintf( '<a href="%1$s">%2$s</a>', esc_url( $permalink ), et_core_intentionally_unescaped( $titletext, 'html' ) ),
'attrs' => array(
'class' => 'et_pb_module_header',
),
'visibility' => array(
'show_title' => 'on',
),
'required' => array(
'show_title' => 'on',
),
),
true
);
$multi_view->render_element(
array(
'tag' => 'p',
'content' => et_core_esc_wp( $post_meta ),
'attrs' => array(
'class' => 'post-meta',
),
'visibility' => array(
'show_categories' => 'on',
),
'required' => array(
'show_categories' => 'on',
),
),
true
);
?>
</div>
<?php
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
}
if ( ! $posts = ob_get_clean() ) {
$posts = self::get_no_results_template();
$category_filters = '';
} else {
$categories_included = explode( ',', $include_categories );
$terms_args = array(
'include' => $categories_included,
'orderby' => 'name',
'order' => 'ASC',
);
$terms = get_terms( 'project_category', $terms_args );
$category_filters = '<ul class="clearfix">';
$category_filters .= sprintf(
'<li class="et_pb_portfolio_filter et_pb_portfolio_filter_all"><a href="#" class="active" data-category-slug="all">%1$s</a></li>',
esc_html__( 'All', 'et_builder' )
);
foreach ( $terms as $term ) {
$category_filters .= sprintf(
'<li class="et_pb_portfolio_filter"><a href="#" data-category-slug="%1$s">%2$s</a></li>',
esc_attr( urldecode( $term->slug ) ),
esc_html( $term->name )
);
}
$category_filters .= '</ul>';
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( isset( $this->advanced_fields['image']['css'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
// Module classnames
$this->add_classname(
array(
'et_pb_portfolio',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( 'on' === $fullwidth ) {
$this->add_classname( 'et_pb_filterable_portfolio_fullwidth' );
} else {
$this->add_classname(
array(
'et_pb_filterable_portfolio_grid',
'clearfix',
)
);
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$pagination_classes_multi_view_attr = $multi_view->render_attrs(
array(
'classes' => array(
'clearfix' => array(
'show_pagination' => 'on',
),
'no_pagination' => array(
'show_pagination' => 'off',
),
),
)
);
$pagination_multi_view = $multi_view->render_element(
array(
'tag' => 'div',
'attrs' => array(
'class' => 'et_pb_portofolio_pagination',
),
'visibility' => array(
'show_pagination' => 'on',
),
'required' => array(
'show_pagination' => 'on',
),
)
);
$output = sprintf(
'<div%4$s class="%1$s" data-posts-number="%5$d"%8$s%11$s>
%10$s
%9$s
<div class="et_pb_portfolio_filters clearfix">%2$s</div>
<div class="et_pb_portfolio_items_wrapper %6$s"%12$s>
<div class="et_pb_portfolio_items">%3$s</div>
</div>
%7$s
</div>',
$this->module_classname( $render_slug ),
$category_filters,
$posts,
$this->module_id(),
esc_attr( $posts_number ), // #5
( 'on' === $multi_view->get_value( 'show_pagination' ) ? 'clearfix' : 'no_pagination' ),
$pagination_multi_view,
is_rtl() ? ' data-rtl="true"' : '',
$video_background,
$parallax_image_background, // #10
et_core_esc_previously( $data_background_layout ),
$pagination_classes_multi_view_attr
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Filterable_Portfolio();
}

View File

@ -0,0 +1,141 @@
<?php
class ET_Builder_Module_Fullwidth_Code extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Fullwidth Code', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Codes', 'et_builder' );
$this->slug = 'et_pb_fullwidth_code';
$this->vb_support = 'on';
$this->fullwidth = true;
$this->use_raw_content = true;
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
);
$this->advanced_fields = array(
'text_shadow' => array(
// Don't add text-shadow fields since they already are via font-options
'default' => false,
),
'fonts' => false,
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
'z_index' => array(
'default' => '9',
),
);
$this->help_videos = array(
array(
'id' => 'dTY6-Cbr00A',
'name' => esc_html__( 'An introduction to the Fullwidth Code module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'raw_content' => array(
'label' => esc_html__( 'Code', 'et_builder' ),
'type' => 'codemirror',
'mode' => 'html',
'option_category' => 'basic_option',
'description' => esc_html__( 'Here you can create the content that will be used within the module.', 'et_builder' ),
'is_fb_content' => true,
'toggle_slug' => 'main_content',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$this->add_classname( $this->get_text_orientation_classname() );
$raw_content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{raw_content}}',
'attrs' => array(
'class' => 'et_pb_code_inner',
),
)
);
$output = sprintf(
'<div%2$s class="%3$s">
%5$s
%4$s
%1$s
</div>',
$raw_content,
$this->module_id(),
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : 'desktop';
if ( $raw_value && 'raw_content' === $name ) {
if ( 'desktop' !== $mode ) {
$raw_value = et_builder_convert_line_breaks( et_builder_replace_code_content_entities( $raw_value ) );
}
$raw_value = $this->fix_wptexturized_scripts( $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Code();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,401 @@
<?php
class ET_Builder_Module_Fullwidth_Image extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Fullwidth Image', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Images', 'et_builder' );
$this->slug = 'et_pb_fullwidth_image';
$this->vb_support = 'on';
$this->fullwidth = true;
$this->defaults = array(
'align' => 'left',
);
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Image' ),
'link' => et_builder_i18n( 'Link' ),
),
),
'advanced' => array(
'toggles' => array(
'overlay' => et_builder_i18n( 'Overlay' ),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
'attributes' => array(
'title' => esc_html__( 'Attributes', 'et_builder' ),
'priority' => 95,
),
),
),
);
$this->advanced_fields = array(
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
),
'fonts' => false,
'text' => false,
'button' => false,
'link_options' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => 'cYwqxoHnjNA',
'name' => esc_html__( 'An introduction to the Fullwidth Image module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'src' => array(
'label' => et_builder_i18n( 'Image' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'affects' => array(
'alt',
'title_text',
),
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'alt' => array(
'label' => esc_html__( 'Image Alternative Text', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'on',
'depends_on' => array(
'src',
),
'description' => esc_html__( 'This defines the HTML ALT text. A short description of your image can be placed here.', 'et_builder' ),
'tab_slug' => 'custom_css',
'toggle_slug' => 'attributes',
'dynamic_content' => 'text',
),
'title_text' => array(
'label' => esc_html__( 'Image Title Text', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'on',
'depends_on' => array(
'src',
),
'description' => esc_html__( 'This defines the HTML Title text.', 'et_builder' ),
'tab_slug' => 'custom_css',
'toggle_slug' => 'attributes',
'dynamic_content' => 'text',
),
'show_in_lightbox' => array(
'label' => esc_html__( 'Open In Lightbox', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'url',
'url_new_window',
'use_overlay',
),
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not the image should open in Lightbox. Note: if you select to open the image in Lightbox, url options below will be ignored.', 'et_builder' ),
),
'url' => array(
'label' => esc_html__( 'Image Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'off',
'affects' => array(
'use_overlay',
),
'description' => esc_html__( 'If you would like your image to be a link, input your destination URL here. No link will be created if this field is left blank.', 'et_builder' ),
'toggle_slug' => 'link',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Image Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'default_on_front' => 'off',
'depends_show_if' => 'off',
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
),
'use_overlay' => array(
'label' => esc_html__( 'Image Overlay', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'Off' ),
'on' => et_builder_i18n( 'On' ),
),
'default_on_front' => 'off',
'affects' => array(
'overlay_icon_color',
'hover_overlay_color',
'hover_icon',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'If enabled, an overlay color and icon will be displayed when a visitors hovers over the image', 'et_builder' ),
),
'overlay_icon_color' => array(
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom color for the overlay icon', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Hover Overlay Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Hover Icon Picker', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$filters = $this->get_transition_filters_fields_css_props( 'child_filters' );
// Note: overlay_icon_color and hover_overlay color requires transition but `.et_overlay`'s
// static class already set transition to all so no dynamic transition needs to be added.
return array_merge( $fields, $filters );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$sticky = et_pb_sticky_options();
$src = $this->props['src'];
$alt = $this->props['alt'];
$title_text = $this->props['title_text'];
$url = $this->props['url'];
$url_new_window = $this->props['url_new_window'];
$show_in_lightbox = $this->props['show_in_lightbox'];
$hover_icon = $this->props['hover_icon'];
$hover_icon_tablet = $this->props['hover_icon_tablet'];
$hover_icon_phone = $this->props['hover_icon_phone'];
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
$use_overlay = $this->props['use_overlay'];
$animation_style = $this->props['animation_style'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Load up Dynamic Content (if needed) to capture Featured Image objects.
// In this way we can process `alt` and `title` attributes defined in
// the WP Media Library when they haven't been specified by the user in
// Module Settings.
if ( empty( $alt ) || empty( $title_text ) ) {
$raw_src = et_()->array_get( $this->attrs_unprocessed, 'src' );
$src_value = et_builder_parse_dynamic_content( $raw_src );
if ( $src_value->is_dynamic() && $src_value->get_content() === 'post_featured_image' ) {
// If there is no user-specified ALT attribute text, check the WP
// Media Library entry for text that may have been added there.
if ( empty( $alt ) ) {
$alt = et_builder_resolve_dynamic_content( 'post_featured_image_alt_text', array(), get_the_ID(), 'display' );
}
// If there is no user-specified TITLE attribute text, check the WP
// Media Library entry for text that may have been added there.
if ( empty( $title_text ) ) {
$title_text = et_builder_resolve_dynamic_content( 'post_featured_image_title_text', array(), get_the_ID(), 'display' );
}
}
}
// overlay can be applied only if image has link or if lightbox enabled
$is_overlay_applied = 'on' === $use_overlay && ( 'on' === $show_in_lightbox || ( 'off' === $show_in_lightbox && '' !== $url ) ) ? 'on' : 'off';
$is_sticky_module = $sticky->is_sticky_module( $this->props );
if ( 'on' === $is_overlay_applied ) {
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'overlay_icon_color',
'selector' => '%%order_class%% .et_overlay:before',
'css_property' => 'color',
'render_slug' => $render_slug,
'important' => true,
'type' => 'color',
)
);
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => '%%order_class%% .et_overlay',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
$overlay_output = ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_tablet' => $hover_icon_tablet,
'icon_phone' => $hover_icon_phone,
'icon_sticky' => $hover_icon_sticky,
)
);
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => '%%order_class%% .et_overlay:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
}
$image_attrs = array(
'src' => '{{src}}',
'alt' => esc_attr( $alt ),
'title' => esc_attr( $title_text ),
);
$image_attachment_class = et_pb_media_options()->get_image_attachment_class( $this->props, 'src' );
if ( ! empty( $image_attachment_class ) ) {
$image_attrs['class'] = esc_attr( $image_attachment_class );
}
$image_html = $multi_view->render_element(
array(
'tag' => 'img',
'attrs' => $image_attrs,
'required' => 'src',
)
);
$output = sprintf(
'%1$s
%2$s',
$image_html,
'on' === $is_overlay_applied ? $overlay_output : ''
);
if ( 'on' === $show_in_lightbox ) {
$output = sprintf(
'<a href="%1$s" class="et_pb_lightbox_image" title="%3$s">%2$s</a>',
esc_attr( $src ),
$output,
esc_attr( $title_text )
);
} elseif ( '' !== $url ) {
$output = sprintf(
'<a href="%1$s"%3$s>%2$s</a>',
esc_url( $url ),
$output,
( 'on' === $url_new_window ? ' target="_blank"' : '' )
);
}
// Module classnames
if ( ! in_array( $animation_style, array( '', 'none' ) ) ) {
$this->add_classname( 'et-waypoint' );
}
if ( 'on' === $is_overlay_applied ) {
$this->add_classname( 'et_pb_has_overlay' );
}
$output = sprintf(
'<div%3$s class="%2$s">
%5$s
%4$s
%1$s
</div>',
$output,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Image();
}

View File

@ -0,0 +1,280 @@
<?php
class ET_Builder_Module_Fullwidth_Map extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Fullwidth Map', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Maps', 'et_builder' );
$this->slug = 'et_pb_fullwidth_map';
$this->vb_support = 'on';
$this->fullwidth = true;
$this->child_slug = 'et_pb_map_pin';
$this->child_item_text = esc_html__( 'Pin', 'et_builder' );
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'map' => esc_html__( 'Map', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'controls' => esc_html__( 'Controls', 'et_builder' ),
'child_filters' => array(
'title' => esc_html__( 'Map', 'et_builder' ),
'priority' => 51,
),
),
),
);
$this->advanced_fields = array(
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'label' => esc_html__( 'Map', 'et_builder' ),
),
),
'child_filters' => array(
'css' => array(
'main' => '%%order_class%% .gm-style>div>div>div>div>div>img',
),
),
'height' => array(
'css' => array(
'main' => '%%order_class%% > .et_pb_map',
),
'options' => array(
'height' => array(
'default' => '440px',
'default_tablet' => '350px',
'default_phone' => '200px',
),
),
),
'fonts' => false,
'text' => false,
'button' => false,
);
$this->help_videos = array(
array(
'id' => 'JtTSSI6wlU0',
'name' => esc_html__( 'An introduction to the Fullwidth Map module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'google_maps_script_notice' => array(
'type' => 'warning',
'value' => et_pb_enqueue_google_maps_script(),
'display_if' => false,
'message' => esc_html__(
sprintf(
'The Google Maps API Script is currently disabled in the <a href="%s" target="_blank">Theme Options</a>. This module will not function properly without the Google Maps API.',
admin_url( 'admin.php?page=et_divi_options' )
),
'et_builder'
),
'toggle_slug' => 'map',
),
'google_api_key' => array(
'label' => esc_html__( 'Google API Key', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'attributes' => 'readonly',
'additional_button' => sprintf(
' <a href="%2$s" target="_blank" class="et_pb_update_google_key button" data-empty_text="%3$s">%1$s</a>',
esc_html__( 'Change API Key', 'et_builder' ),
esc_url( et_pb_get_options_page_link() ),
esc_attr__( 'Add Your API Key', 'et_builder' )
),
'additional_button_type' => 'change_google_api_key',
'class' => array( 'et_pb_google_api_key', 'et-pb-helper-field' ),
'description' => et_get_safe_localization( sprintf( __( 'The Maps module uses the Google Maps API and requires a valid Google API Key to function. Before using the map module, please make sure you have added your API key inside the Divi Theme Options panel. Learn more about how to create your Google API Key <a href="%1$s" target="_blank">here</a>.', 'et_builder' ), esc_url( 'http://www.elegantthemes.com/gallery/divi/documentation/map/#gmaps-api-key' ) ) ),
'toggle_slug' => 'map',
),
'address' => array(
'label' => esc_html__( 'Map Center Address', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'additional_button' => sprintf(
' <a href="#" class="et_pb_find_address button">%1$s</a>',
esc_html__( 'Find', 'et_builder' )
),
'class' => array( 'et_pb_address' ),
'description' => esc_html__( 'Enter an address for the map center point, and the address will be geocoded and displayed on the map below.', 'et_builder' ),
'toggle_slug' => 'map',
),
'zoom_level' => array(
'type' => 'hidden',
'class' => array( 'et_pb_zoom_level' ),
'default' => '18',
),
'address_lat' => array(
'type' => 'hidden',
'class' => array( 'et_pb_address_lat' ),
),
'address_lng' => array(
'type' => 'hidden',
'class' => array( 'et_pb_address_lng' ),
),
'map_center_map' => array(
'type' => 'center_map',
'use_container_wrapper' => false,
'option_category' => 'basic_option',
'toggle_slug' => 'map',
),
'mouse_wheel' => array(
'label' => esc_html__( 'Mouse Wheel Zoom', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'controls',
'description' => esc_html__( 'Here you can choose whether the zoom level will be controlled by mouse wheel or not.', 'et_builder' ),
'default_on_front' => 'on',
),
'mobile_dragging' => array(
'label' => esc_html__( 'Draggable On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'controls',
'description' => esc_html__( 'Here you can choose whether or not the map will be draggable on mobile devices.', 'et_builder' ),
'default_on_front' => 'on',
),
'use_grayscale_filter' => array(
'label' => esc_html__( 'Use Grayscale Filter', 'et_builder' ),
'description' => esc_html__( 'Adjusting the grayscale filter will allow you to change the color saturation of the map.', 'et_builder' ),
'type' => 'hidden',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'affects' => array(
'grayscale_filter_amount',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'default_on_front' => 'off',
),
'grayscale_filter_amount' => array(
'label' => esc_html__( 'Grayscale Filter Amount (%)', 'et_builder' ),
'description' => esc_html__( 'Adjusting the grayscale filter will allow you to change the color saturation of the map.', 'et_builder' ),
'type' => 'hidden',
'default_on_front' => '0',
'option_category' => 'configuration',
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'depends_show_if' => 'on',
'validate_unit' => false,
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$address_lat = $this->props['address_lat'];
$address_lng = $this->props['address_lng'];
$zoom_level = $this->props['zoom_level'];
$mouse_wheel = $this->props['mouse_wheel'];
$mobile_dragging = $this->props['mobile_dragging'];
$use_grayscale_filter = $this->props['use_grayscale_filter'];
$grayscale_filter_amount = $this->props['grayscale_filter_amount'];
if ( et_pb_enqueue_google_maps_script() ) {
wp_enqueue_script( 'google-maps-api' );
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$all_pins_content = $this->content;
$grayscale_filter_data = '';
if ( 'on' === $use_grayscale_filter && '' !== $grayscale_filter_amount ) {
$grayscale_filter_data = sprintf( ' data-grayscale="%1$s"', esc_attr( $grayscale_filter_amount ) );
}
// Map Tiles: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'child_filters', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['child_filters'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['child_filters']['css'], 'main', '%%order_class%%' )
)
);
}
// Module classnames
$this->add_classname(
array(
'et_pb_map_container',
)
);
// Remove automatically added classname
$this->remove_classname( $render_slug );
$output = sprintf(
'<div%5$s class="%6$s"%11$s>
%10$s
%9$s
<div class="et_pb_map" data-center-lat="%1$s" data-center-lng="%2$s" data-zoom="%3$d" data-mouse-wheel="%7$s" data-mobile-dragging="%8$s"></div>
%4$s
</div>',
esc_attr( et_()->to_css_decimal( $address_lat ) ),
esc_attr( et_()->to_css_decimal( $address_lng ) ),
esc_attr( $zoom_level ),
$all_pins_content,
$this->module_id(),
$this->module_classname( $render_slug ),
esc_attr( $mouse_wheel ),
esc_attr( $mobile_dragging ),
$video_background,
$parallax_image_background,
$grayscale_filter_data
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Map();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,702 @@
<?php
class ET_Builder_Module_Fullwidth_Portfolio extends ET_Builder_Module_Type_PostBased {
function init() {
$this->name = esc_html__( 'Fullwidth Portfolio', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Portfolios', 'et_builder' );
$this->slug = 'et_pb_fullwidth_portfolio';
$this->vb_support = 'on';
$this->fullwidth = true;
// need to use global settings from the slider module
$this->global_settings_slug = 'et_pb_portfolio';
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Content' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'overlay' => et_builder_i18n( 'Overlay' ),
'rotation' => esc_html__( 'Rotation', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'image' => et_builder_i18n( 'Image' ),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'portfolio_header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_portfolio_title",
'important' => 'all',
),
'header_level' => array(
'default' => 'h2',
),
'font_size' => array(
'default' => '26px',
),
'line_height' => array(
'default' => '1em',
),
),
'title' => array(
'label' => esc_html__( 'Portfolio Item Title', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h3, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h2.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
'important' => 'all',
),
'header_level' => array(
'default' => 'h3',
),
),
'caption' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .post-meta, {$this->main_css_element} .post-meta a",
'text_align' => "{$this->main_css_element} .et_pb_portfolio_image p.post-meta",
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element}",
'border_styles' => "{$this->main_css_element}",
),
),
),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_portfolio_image",
'border_styles' => "{$this->main_css_element} .et_pb_portfolio_image",
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'box_shadow' => array(
'default' => array(),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_portfolio_image',
'overlay' => 'inset',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'text_orientation' => '%%order_class%% h2, %%order_class%% .et_pb_portfolio_image h3, %%order_class%% .et_pb_portfolio_image p, %%order_class%% .et_pb_portfolio_title, %%order_class%% .et_pb_portfolio_image .et_pb_module_header',
),
'options' => array(
'text_orientation' => array(
'default_on_front' => 'center',
),
'background_layout' => array(
'default_on_front' => 'light',
'hover' => 'tabs',
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_portfolio_image',
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->custom_css_fields = array(
'portfolio_title' => array(
'label' => esc_html__( 'Portfolio Title', 'et_builder' ),
'selector' => '> h2',
),
'portfolio_item' => array(
'label' => esc_html__( 'Portfolio Item', 'et_builder' ),
'selector' => '.et_pb_portfolio_item',
),
'portfolio_overlay' => array(
'label' => esc_html__( 'Item Overlay', 'et_builder' ),
'selector' => 'span.et_overlay',
),
'portfolio_item_title' => array(
'label' => esc_html__( 'Item Title', 'et_builder' ),
'selector' => '.meta h3',
),
'portfolio_meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'selector' => '.meta p',
),
'portfolio_arrows' => array(
'label' => esc_html__( 'Navigation Arrows', 'et_builder' ),
'selector' => '.et-pb-slider-arrows a',
),
);
$this->help_videos = array(
array(
'id' => 'Mug6LhcJQ5M',
'name' => esc_html__( 'An introduction to the Fullwidth Portfolio module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => esc_html__( 'Portfolio Title', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Title displayed above the portfolio.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'fullwidth' => array(
'label' => et_builder_i18n( 'Layout' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'on' => esc_html__( 'Carousel', 'et_builder' ),
'off' => esc_html__( 'Grid', 'et_builder' ),
),
'default_on_front' => 'on',
'affects' => array(
'auto',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'description' => esc_html__( 'Choose your desired portfolio layout style.', 'et_builder' ),
),
'include_categories' => array(
'label' => esc_html__( 'Included Categories', 'et_builder' ),
'type' => 'categories',
'meta_categories' => array(
'all' => esc_html__( 'All Categories', 'et_builder' ),
'current' => esc_html__( 'Current Category', 'et_builder' ),
),
'option_category' => 'basic_option',
'description' => esc_html__( 'Select the categories that you would like to include in the feed.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'taxonomy_name' => 'project_category',
'toggle_slug' => 'main_content',
),
'posts_number' => array(
'label' => esc_html__( 'Post Count', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'description' => esc_html__( 'Control how many projects are displayed. Leave blank or use 0 to not limit the amount.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'toggle_slug' => 'main_content',
),
'show_title' => array(
'label' => esc_html__( 'Show Title', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn project titles on or off.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_date' => array(
'label' => esc_html__( 'Show Date', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn the date display on or off.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'zoom_icon_color' => array(
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the zoom icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Overlay Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the icon that appears when hovering over a portfolio item.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
'description' => esc_html__( 'Select an icon to appear when hovering over a portfolio item.', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'__projects' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Fullwidth_Portfolio', 'get_portfolio_item' ),
'computed_depends_on' => array(
'posts_number',
'include_categories',
),
),
);
return $fields;
}
/**
* Get portfolio objects for portfolio module
*
* @param array arguments that affect et_pb_portfolio query
* @param array passed conditional tag for update process
* @param array passed current page params
* @return array portfolio item data
*/
static function get_portfolio_item( $args = array(), $conditional_tags = array(), $current_page = array() ) {
global $post;
$defaults = array(
'posts_number' => '',
'include_categories' => '',
);
$args = wp_parse_args( $args, $defaults );
$query_args = array(
'post_type' => 'project',
'post_status' => array( 'publish', 'private' ),
'perm' => 'readable',
);
if ( is_numeric( $args['posts_number'] ) && $args['posts_number'] > 0 ) {
$query_args['posts_per_page'] = $args['posts_number'];
} else {
$query_args['nopaging'] = true;
}
$include_categories = self::filter_include_categories( $args['include_categories'], 0, 'project_category' );
if ( ! empty( $include_categories ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'project_category',
'field' => 'id',
'terms' => $include_categories,
'operator' => 'IN',
),
);
}
// Get portfolio query
$query = new WP_Query( $query_args );
// Format portfolio output, add supplementary data
$width = (int) apply_filters( 'et_pb_portfolio_image_width', 510 );
$height = (int) apply_filters( 'et_pb_portfolio_image_height', 382 );
if ( $query->post_count > 0 ) {
$post_index = 0;
while ( $query->have_posts() ) {
$query->the_post();
ET_Post_Stack::replace( $post );
// Get thumbnail
$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), array( $width, $height ) );
if ( isset( $thumbnail[2] ) && isset( $thumbnail[1] ) ) {
$orientation = ( $thumbnail[2] > $thumbnail[1] ) ? 'portrait' : 'landscape';
} else {
$orientation = false;
}
// Append value to query post
$query->posts[ $post_index ]->post_permalink = get_permalink();
$query->posts[ $post_index ]->post_thumbnail = isset( $thumbnail[0] ) ? $thumbnail[0] : false;
$query->posts[ $post_index ]->post_thumbnail_orientation = $orientation;
$query->posts[ $post_index ]->post_date_readable = get_the_date();
$query->posts[ $post_index ]->post_class_name = get_post_class( 'et_pb_portfolio_item et_pb_grid_item ' );
$post_index++;
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
} elseif ( self::is_processing_computed_prop() ) {
// This is for the VB
$posts = '<div class="et_pb_row et_pb_no_results">';
$posts .= self::get_no_results_template();
$posts .= '</div>';
$query = array( 'posts' => $posts );
}
return $query;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $post;
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['portfolio_header_level'], 'h2' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_portfolio_title',
),
)
);
$fullwidth = $this->props['fullwidth'];
$include_categories = $this->props['include_categories'];
$posts_number = $this->props['posts_number'];
$show_title = $this->props['show_title'];
$show_date = $this->props['show_date'];
$auto = $this->props['auto'];
$auto_speed = $this->props['auto_speed'];
$hover_icon = $this->props['hover_icon'];
$header_level = $this->props['title_level'];
$zoom_and_hover_selector = '.et_pb_fullwidth_portfolio%%order_class%% .et_pb_portfolio_image';
// Zoom Icon color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'zoom_icon_color',
'selector' => "{$zoom_and_hover_selector} .et_overlay:before",
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Hover Overlay color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => "{$zoom_and_hover_selector} .et_overlay",
'css_property' => array( 'background-color', 'border-color' ),
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Overlay.
$hover_icon = $this->props['hover_icon'];
$hover_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'hover_icon' );
$hover_icon_tablet = isset( $hover_icon_values['tablet'] ) ? $hover_icon_values['tablet'] : '';
$hover_icon_phone = isset( $hover_icon_values['phone'] ) ? $hover_icon_values['phone'] : '';
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
$overlay = ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_tablet' => $hover_icon_tablet,
'icon_phone' => $hover_icon_phone,
'icon_sticky' => $hover_icon_sticky,
)
);
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => "{$zoom_and_hover_selector} .et_overlay:before",
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
$projects = self::get_portfolio_item(
array(
'posts_number' => $posts_number,
'include_categories' => $include_categories,
)
);
$portfolio_order = self::_get_index( array( self::INDEX_MODULE_ORDER, $render_slug ) );
$items_count = 0;
ob_start();
if ( $projects->post_count > 0 ) {
while ( $projects->have_posts() ) {
$projects->the_post();
ET_Post_Stack::replace( $post );
$item_class = sprintf( 'et_pb_fullwidth_portfolio_item_%1$s_%2$s', $portfolio_order, $items_count );
$items_count++;
?>
<div id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_portfolio_item et_pb_grid_item ' . $item_class ); ?>>
<?php
$thumb = '';
$width = 510;
$width = (int) apply_filters( 'et_pb_portfolio_image_width', $width );
$height = 382;
$height = (int) apply_filters( 'et_pb_portfolio_image_height', $height );
list($thumb_src, $thumb_width, $thumb_height) = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), array( $width, $height ) );
$orientation = ( $thumb_height > $thumb_width ) ? 'portrait' : 'landscape';
if ( '' !== $thumb_src ) :
?>
<div class="et_pb_portfolio_image <?php echo esc_attr( $orientation ); ?>">
<?php
$image_attrs = array(
'alt' => get_the_title(),
);
$full_src = get_the_post_thumbnail_url();
if ( $full_src ) {
$image_attrs['srcset'] = $full_src . ' 479w, ' . $thumb_src . ' 480w';
$image_attrs['sizes'] = '(max-width:479px) 479px, 100vw';
}
$image_attachment_class = et_pb_media_options()->get_image_attachment_class( $this->props, '', get_post_thumbnail_id() );
if ( ! empty( $image_attachment_class ) ) {
$image_attrs['class'] = esc_attr( $image_attachment_class );
}
$this->render_image( $thumb_src, $image_attrs );
?>
<div class="meta">
<a href="<?php esc_url( the_permalink() ); ?>">
<?php
echo et_core_esc_previously( $overlay );
$multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h3' ),
'content' => get_the_title(),
'attrs' => array(
'class' => 'et_pb_module_header',
),
'visibility' => array(
'show_title' => 'on',
),
),
true
);
$multi_view->render_element(
array(
'tag' => 'p',
'content' => get_the_date(),
'attrs' => array(
'class' => 'post-meta',
),
'visibility' => array(
'show_date' => 'on',
),
),
true
);
?>
</a>
</div>
</div>
<?php endif; ?>
</div>
<?php
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
}
if ( ! $posts = ob_get_clean() ) {
$posts = '<div class="et_pb_row et_pb_no_results">';
$posts .= self::get_no_results_template();
$posts .= '</div>';
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( isset( $this->advanced_fields['image']['css'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
// Module classnames
if ( 'on' === $fullwidth ) {
$this->add_classname( 'et_pb_fullwidth_portfolio_carousel' );
} else {
$this->add_classname(
array(
'et_pb_fullwidth_portfolio_grid',
'clearfix',
)
);
}
$output = sprintf(
'<div%3$s class="%1$s" data-auto-rotate="%4$s" data-auto-rotate-speed="%5$s"%9$s>
%8$s
%7$s
%6$s
<div class="et_pb_portfolio_items clearfix" data-portfolio-columns="">
%2$s
</div>
</div>',
$this->module_classname( $render_slug ),
$posts,
$this->module_id(),
( '' !== $auto && in_array( $auto, array( 'on', 'off' ) ) ? esc_attr( $auto ) : 'off' ),
( '' !== $auto_speed && is_numeric( $auto_speed ) ? esc_attr( $auto_speed ) : '7000' ), // #5
$title,
$video_background,
$parallax_image_background,
et_core_esc_previously( $data_background_layout )
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Portfolio();
}

View File

@ -0,0 +1,21 @@
<?php
class ET_Builder_Module_Fullwidth_PostContent extends ET_Builder_Module_Type_PostContent {
public $slug = 'et_pb_fullwidth_post_content';
public function init() {
$this->name = esc_html__( 'Fullwidth Post Content', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Post Content', 'et_builder' );
$this->fullwidth = true;
$this->vb_support = 'on';
$this->help_videos = array();
// Use specific selector to target only content inside the app when in VB
$this->main_css_element = '%%order_class%%';
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_PostContent();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,772 @@
<?php
class ET_Builder_Module_Fullwidth_Post_Title extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Fullwidth Post Title', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Post Titles', 'et_builder' );
$this->slug = 'et_pb_fullwidth_post_title';
$this->vb_support = 'on';
$this->fullwidth = true;
$this->defaults = array();
$this->featured_image_background = true;
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'image_settings' => et_builder_i18n( 'Image' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element}.et_pb_featured_bg, {$this->main_css_element}",
'border_styles' => "{$this->main_css_element}.et_pb_featured_bg, {$this->main_css_element}",
),
),
),
),
'margin_padding' => array(
'css' => array(
'main' => ".et_pb_fullwidth_section {$this->main_css_element}.et_pb_post_title",
'important' => 'all',
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'use_all_caps' => true,
'css' => array(
'main' => "{$this->main_css_element} .et_pb_title_container h1.entry-title, {$this->main_css_element} .et_pb_title_container h2.entry-title, {$this->main_css_element} .et_pb_title_container h3.entry-title, {$this->main_css_element} .et_pb_title_container h4.entry-title, {$this->main_css_element} .et_pb_title_container h5.entry-title, {$this->main_css_element} .et_pb_title_container h6.entry-title",
),
'header_level' => array(
'default' => 'h1',
),
),
'meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container a",
'limited_main' => "{$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container a, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container span",
),
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element}, {$this->main_css_element}.et_pb_featured_bg",
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '.et_pb_fullwidth_section %%order_class%%.et_pb_post_title.et_pb_module',
),
),
'text' => array(
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
),
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .entry-title',
'%%order_class%% .et_pb_title_meta_container',
)
),
),
),
'button' => false,
);
$this->custom_css_fields = array(
'post_title' => array(
'label' => et_builder_i18n( 'Title' ),
'selector' => 'h1',
),
'post_meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'selector' => '.et_pb_title_meta_container',
),
'post_image' => array(
'label' => esc_html__( 'Featured Image', 'et_builder' ),
'selector' => '.et_pb_title_featured_container',
),
);
$this->help_videos = array(
array(
'id' => 'wb8c06U0uCU',
'name' => esc_html__( 'An introduction to the Fullwidth Post Title module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => esc_html__( 'Show Title', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Post Title', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'meta' => array(
'label' => esc_html__( 'Show Meta', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'author',
'date',
'comments',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'author' => array(
'label' => esc_html__( 'Show Author', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Author Name in Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'date' => array(
'label' => esc_html__( 'Show Date', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'affects' => array(
'date_format',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Date in Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'date_format' => array(
'label' => esc_html__( 'Date Format', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'default_on_front' => 'M j, Y',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can define the Date Format in Post Meta. Default is \'M j, Y\'', 'et_builder' ),
),
'categories' => array(
'label' => esc_html__( 'Show Post Categories', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'show_if' => array(
'meta' => 'on',
'function.isPostOrTBLayout' => 'on',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Categories in Post Meta. Note: This option doesn\'t work with custom post types.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'comments' => array(
'label' => esc_html__( 'Show Comments Count', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Comments Count in Post Meta.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'featured_image' => array(
'label' => esc_html__( 'Show Featured Image', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'featured_placement',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Featured Image', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'featured_placement' => array(
'label' => esc_html__( 'Featured Image Placement', 'et_builder' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'below' => esc_html__( 'Below Title', 'et_builder' ),
'above' => esc_html__( 'Above Title', 'et_builder' ),
'background' => esc_html__( 'Title/Meta Background Image', 'et_builder' ),
),
'default_on_front' => 'below',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose where to place the Featured Image', 'et_builder' ),
),
'force_fullwidth' => array(
'label' => esc_html__( 'Force Fullwidth', 'et_builder' ),
'description' => esc_html__( "When enabled, this will force your image to extend 100% of the width of the column it's in.", 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
),
'image_width' => array(
'label' => esc_html__( 'Featured Image Width', 'et_builder' ),
'description' => esc_html__( 'Adjust the width of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'width' ),
'default' => '100%',
'default_unit' => '%',
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
'sticky' => true,
),
'image_max_width' => array(
'label' => esc_html__( 'Featured Image Max Width', 'et_builder' ),
'description' => esc_html__( 'Adjust the max width of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-width' ),
'default' => 'none',
'default_unit' => '%',
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
'sticky' => true,
),
'image_height' => array(
'label' => esc_html__( 'Featured Image Height', 'et_builder' ),
'description' => esc_html__( 'Adjust the height of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'height' ),
'default' => 'auto',
'default_unit' => 'px',
'range_settings' => array(
'min' => '0',
'max' => '1000',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
'sticky' => true,
),
'image_max_height' => array(
'label' => esc_html__( 'Featured Image Max Height', 'et_builder' ),
'description' => esc_html__( 'Adjust the max height of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-height' ),
'default' => 'none',
'default_unit' => 'px',
'range_settings' => array(
'min' => '0',
'max' => '1000',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
'sticky' => true,
),
'image_alignment' => array(
'label' => esc_html__( 'Image Alignment', 'et_builder' ),
'description' => esc_html__( 'Align image to the left, right or center.', 'et_builder' ),
'type' => 'align',
'option_category' => 'layout',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image_settings',
'default' => 'center',
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
),
'text_color' => array(
'label' => esc_html__( 'Text Color', 'et_builder' ),
'type' => 'select',
'option_category' => 'color_option',
'options' => array(
'dark' => et_builder_i18n( 'Dark' ),
'light' => et_builder_i18n( 'Light' ),
),
'default_on_front' => 'dark',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'hover' => 'tabs',
'description' => esc_html__( 'Here you can choose the color for the Title/Meta text', 'et_builder' ),
),
'text_background' => array(
'label' => esc_html__( 'Use Text Background Color', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'color_option',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'text_bg_color',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'description' => esc_html__( 'Here you can choose whether or not use the background color for the Title/Meta text', 'et_builder' ),
),
'text_bg_color' => array(
'default' => 'rgba(255,255,255,0.9)',
'label' => esc_html__( 'Text Background Color', 'et_builder' ),
'description' => esc_html__( "Pick a color to use behind the post title text. Reducing the color's opacity will allow the background image to show through while still increasing text readability.", 'et_builder' ),
'type' => 'color-alpha',
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['text_color'] = array(
'color' => implode(
', ',
array(
'%%order_class%% .entry-title',
'%%order_class%% .et_pb_title_meta_container',
)
),
);
$fields['text_bg_color'] = array( 'background-color' => '%%order_class%% .et_pb_title_container' );
$fields['image_height'] = array( 'height' => '%%order_class%% .et_pb_title_featured_container img' );
$fields['image_max_height'] = array( 'max-height' => '%%order_class%% .et_pb_title_featured_container img' );
$fields['image_width'] = array( 'width' => '%%order_class%% .et_pb_title_featured_image' );
$fields['image_max_width'] = array( 'max-width' => '%%order_class%% .et_pb_title_featured_image' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$date_format = $this->props['date_format'];
$featured_image = $this->props['featured_image'];
$featured_placement = $this->props['featured_placement'];
$text_color = $this->props['text_color'];
$text_color_hover = et_pb_hover_options()->get_value( 'text_color', $this->props );
$text_background = $this->props['text_background'];
$header_level = $this->props['title_level'];
$post_id = get_the_ID();
// display the shortcode only on singlular pages
if ( ! is_singular() ) {
$post_id = 0;
}
$output = '';
$featured_image_output = '';
$parallax_image_background = $this->get_parallax_image_background();
if ( $post_id && $multi_view->has_value( 'featured_image', 'on' ) && ( 'above' === $featured_placement || 'below' === $featured_placement ) ) {
// Largest featured image size is needed when featured image is used in "post" post type and full width layout
$featured_image_size = 'post' === get_post_type() && 'et_full_width_page' === get_post_meta( get_the_ID(), '_et_pb_page_layout', true ) ? 'et-pb-post-main-image-fullwidth-large' : 'large';
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
$featured_image_src = et_()->array_get( wp_get_attachment_image_src( $post_thumbnail_id, $featured_image_size ), 0 );
$featured_image_alt = get_post_meta( $post_thumbnail_id, '_wp_attachment_image_alt', true );
$featured_image_title = get_the_title( $post_thumbnail_id );
$featured_image_class = et_pb_media_options()->get_image_attachment_class( $this->props, '', $post_thumbnail_id );
$featured_image_attrs = array(
'src' => $featured_image_src,
'alt' => $featured_image_alt,
'title' => $featured_image_title,
);
if ( ! empty( $featured_image_class ) ) {
$featured_image_attrs['class'] = esc_attr( $featured_image_class );
}
$featured_image_content = $multi_view->render_element(
array(
'tag' => 'img',
'attrs' => $featured_image_attrs,
)
);
$featured_image_output = $multi_view->render_element(
array(
'tag' => 'div',
'content' => sprintf( '<div class="et_pb_title_featured_image"><span class="et_pb_image_wrap">%1$s</span></div>', $featured_image_content ),
'attrs' => array(
'class' => 'et_pb_title_featured_container',
),
'visibility' => array(
'featured_image' => 'on',
),
'required' => array(
'featured_image' => 'on',
),
)
);
// Image height.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_height',
'selector' => '%%order_class%% .et_pb_title_featured_container img',
'css_property' => 'height',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image max height.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_max_height',
'selector' => '%%order_class%% .et_pb_title_featured_container img',
'css_property' => 'max-height',
'render_slug' => $render_slug,
'type' => 'range',
)
);
if ( 'off' === $this->props['force_fullwidth'] ) {
// Image width.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_width',
'selector' => '%%order_class%% .et_pb_title_featured_image',
'css_property' => 'width',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image max width.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_max_width',
'selector' => '%%order_class%% .et_pb_title_featured_image',
'css_property' => 'max-width',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image alignment style
$image_alignment_values = et_pb_responsive_options()->get_property_values( $this->props, 'image_alignment', 'none' );
et_pb_responsive_options()->generate_responsive_css(
$image_alignment_values,
'%%order_class%% .et_pb_title_featured_image',
'text-align',
$render_slug,
'',
'align'
);
$image_alignments = array(
'left' => 'auto auto auto 0',
'center' => 'auto',
'right' => 'auto 0 auto auto',
);
foreach ( $image_alignment_values as $breakpoint => $alignment ) {
$image_alignment_values[ $breakpoint ] = et_()->array_get(
$image_alignments,
$alignment,
''
);
}
et_pb_responsive_options()->generate_responsive_css(
$image_alignment_values,
'%%order_class%% .et_pb_title_featured_image',
'margin',
$render_slug,
'',
'align'
);
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%% .et_pb_image_wrap',
'declaration' => 'width: auto;',
)
);
}
}
if ( $multi_view->has_value( 'title', 'on' ) ) {
if ( is_et_pb_preview() && isset( $_POST['post_title'] ) && wp_verify_nonce( $_POST['et_pb_preview_nonce'], 'et_pb_preview_nonce' ) ) {
$post_title = esc_html( sanitize_text_field( wp_unslash( $_POST['post_title'] ) ) );
} else {
// Unescaped for backwards compat reasons.
$post_title = et_core_intentionally_unescaped( et_builder_get_current_title(), 'html' );
}
$output .= $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h1' ),
'content' => $post_title,
'attrs' => array(
'class' => 'entry-title',
),
'visibility' => array(
'title' => 'on',
),
)
);
}
if ( $post_id && $multi_view->has_value( 'meta', 'on' ) ) {
$meta_array = array();
foreach ( array( 'author', 'date', 'categories', 'comments' ) as $single_meta ) {
if ( 'categories' === $single_meta && ! is_singular( 'post' ) ) {
continue;
}
$meta_array[] = $multi_view->render_element(
array(
'content' => et_pb_postinfo_meta( array( $single_meta ), $date_format, esc_html__( '0 comments', 'et_builder' ), esc_html__( '1 comment', 'et_builder' ), '% ' . esc_html__( 'comments', 'et_builder' ) ),
'classes' => array(
'et_pb_title_meta_item--visible' => array(
$single_meta => 'on',
'meta' => 'on',
),
),
'visibility' => array(
$single_meta => 'on',
'meta' => 'on',
),
'required' => array(
$single_meta => 'on',
'meta' => 'on',
),
)
);
}
$output .= $multi_view->render_element(
array(
'tag' => 'p',
'content' => implode( '', $meta_array ),
'attrs' => array(
'class' => 'et_pb_title_meta_container',
),
'visibility' => array(
'meta' => 'on',
),
)
);
}
if ( 'on' === $text_background ) {
// Text Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'text_bg_color',
'selector' => '%%order_class%% .et_pb_title_container',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
'additional_css' => 'padding: 1em 1.5em;',
)
);
}
$video_background = $this->video_background();
$background_layout = 'dark' === $text_color ? 'light' : 'dark';
$data_background_layout = '';
$data_background_layout_hover = '';
if ( et_pb_hover_options()->is_enabled( 'text_color', $this->props ) && ! empty( $text_color_hover ) && $text_color !== $text_color_hover ) {
$data_background_layout = sprintf( ' data-background-layout="%1$s"', esc_attr( $text_color_hover ) );
$data_background_layout_hover = sprintf( ' data-background-layout-hover="%1$s"', esc_attr( $text_color ) );
}
// Module classnames
$this->add_classname(
array(
'et_pb_post_title',
$this->get_text_orientation_classname(),
"et_pb_bg_layout_{$background_layout}",
)
);
if ( 'on' === $multi_view->get_value( 'featured_image' ) && 'background' === $featured_placement ) {
$this->add_classname( 'et_pb_featured_bg' );
}
if ( 'above' === $featured_placement ) {
$this->add_classname( 'et_pb_image_above' );
}
if ( 'below' === $featured_placement ) {
$this->add_classname( 'et_pb_image_below' );
}
// Remove automatically added classnames
$this->remove_classname(
array(
'et_pb_fullwidth_post_title',
)
);
$muti_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_featured_bg' => array(
'featured_image' => 'on',
'featured_placement' => 'background',
),
),
)
);
$output = sprintf(
'<div%3$s class="%2$s" %8$s %9$s %10$s>
%4$s
%7$s
%5$s
<div class="et_pb_title_container">
%1$s
</div>
%6$s
</div>',
$output,
$this->module_classname( $render_slug ),
$this->module_id(),
$parallax_image_background,
'on' === $featured_image && 'above' === $featured_placement ? $featured_image_output : '', // #5
'on' === $featured_image && 'below' === $featured_placement ? $featured_image_output : '',
$video_background,
$data_background_layout,
$data_background_layout_hover,
et_core_esc_previously( $muti_view_data_attr ) // #10
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Post_Title();
}

View File

@ -0,0 +1,817 @@
<?php
require_once 'helpers/Slider.php';
class ET_Builder_Module_Fullwidth_Slider extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Fullwidth Slider', 'et_builder' );
$this->plural = esc_html__( 'Fullwidth Sliders', 'et_builder' );
$this->slug = 'et_pb_fullwidth_slider';
$this->vb_support = 'on';
$this->fullwidth = true;
$this->child_slug = 'et_pb_slide';
$this->child_item_text = et_builder_i18n( 'Slide' );
$this->main_css_element = '%%order_class%%.et_pb_slider';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'overlay' => et_builder_i18n( 'Overlay' ),
'navigation' => esc_html__( 'Navigation', 'et_builder' ),
'image' => et_builder_i18n( 'Image' ),
'layout' => et_builder_i18n( 'Layout' ),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_slide_description .et_pb_slide_title",
'limited_main' => "{$this->main_css_element} .et_pb_slide_description .et_pb_slide_title, {$this->main_css_element} .et_pb_slide_description .et_pb_slide_title a",
'important' => array(
'color',
'size',
'font-size',
'plugin_all',
),
),
'header_level' => array(
'default' => 'h2',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_module .et_pb_slides .et_pb_slide_content",
'line_height' => "{$this->main_css_element} p",
'important' => array( 'size', 'font-size' ),
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
),
'borders' => array(
'default' => array(),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_slide_image img',
'border_styles' => '%%order_class%% .et_pb_slide_image img',
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'depends_show_if' => 'off',
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_slide_image img',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_more_button.et_pb_button",
'linited_main' => "{$this->main_css_element} .et_pb_more_button.et_pb_button",
'alignment' => "{$this->main_css_element} .et_pb_button_wrapper",
),
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'background' => array(
'use_background_color' => 'fields_only',
'use_background_color_gradient' => 'fields_only',
'use_background_image' => 'fields_only',
'options' => array(
'parallax_method' => array(
'default' => 'off',
),
'background_position' => array(),
'background_size' => array(),
),
),
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%%',
'padding' => '%%order_class%% .et_pb_slide_description, .et_pb_slider_fullwidth_off%%order_class%% .et_pb_slide_description',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% .et_pb_slide .et_pb_slide_description',
'text_shadow' => '%%order_class%% .et_pb_slide .et_pb_slide_description',
),
'options' => array(
'text_orientation' => array(
'default' => 'center',
),
),
),
'height' => array(
'css' => array(
'main' => '%%order_class%%, %%order_class%% .et_pb_slide',
),
),
'image' => array(
'css' => array(
'main' => array(
'%%order_class%% .et_pb_slide_image',
'%%order_class%% .et_pb_section_video_bg',
),
),
),
'max_width' => array(
'extra' => array(
'content' => array(
'use_module_alignment' => false,
'css' => array(
'main' => '%%order_class%% .et_pb_slide > .et_pb_container',
),
'options' => array(
'width' => array(
'label' => esc_html__( 'Content Width', 'et_builder' ),
'default' => '80%',
),
'max_width' => array(
'label' => esc_html__( 'Content Max Width', 'et_builder' ),
'default' => '1080px',
),
),
),
),
),
);
$this->custom_css_fields = array(
'slide_description' => array(
'label' => esc_html__( 'Slide Description', 'et_builder' ),
'selector' => '.et_pb_slide_description',
),
'slide_title' => array(
'label' => esc_html__( 'Slide Title', 'et_builder' ),
'selector' => '.et_pb_slide_description .et_pb_slide_title',
),
'slide_button' => array(
'label' => esc_html__( 'Slide Button', 'et_builder' ),
'selector' => '.et_pb_slider .et_pb_slide .et_pb_slide_description a.et_pb_more_button.et_pb_button',
'no_space_before_selector' => true,
),
'slide_controllers' => array(
'label' => esc_html__( 'Slide Controllers', 'et_builder' ),
'selector' => '.et-pb-controllers',
),
'slide_active_controller' => array(
'label' => esc_html__( 'Slide Active Controller', 'et_builder' ),
'selector' => '.et-pb-controllers .et-pb-active-control',
),
'slide_image' => array(
'label' => esc_html__( 'Slide Image', 'et_builder' ),
'selector' => '.et_pb_slide_image',
),
'slide_arrows' => array(
'label' => esc_html__( 'Slide Arrows', 'et_builder' ),
'selector' => '.et-pb-slider-arrows a',
),
);
$this->help_videos = array(
array(
'id' => 'zfMBE_zX744',
'name' => esc_html__( 'An introduction to the Fullwidth Slider module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'show_arrows' => array(
'label' => esc_html__( 'Show Arrows', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'This setting allows you to turn the navigation arrows on or off.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_pagination' => array(
'label' => esc_html__( 'Show Controls', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Disabling this option will remove the circle button at the bottom of the slider.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_content_on_mobile' => array(
'label' => esc_html__( 'Show Content On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'show_cta_on_mobile' => array(
'label' => esc_html__( 'Show CTA On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'show_image_video_mobile' => array(
'label' => esc_html__( 'Show Image / Video On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'use_bg_overlay' => array(
'label' => esc_html__( 'Use Background Overlay', 'et_builder' ),
'description' => esc_html__( 'When enabled, a custom overlay color will be added above your background image and behind your slider content.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
// Uses cached uppercase translation but keeps the lowercase not change definition content.
'on' => strtolower( et_builder_i18n( 'Yes' ) ),
),
'default_on_front' => '',
'affects' => array(
'bg_overlay_color',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
),
'bg_overlay_color' => array(
'label' => esc_html__( 'Background Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Use the color picker to choose a color for the background overlay.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
'mobile_options' => true,
'sticky' => true,
),
'use_text_overlay' => array(
'label' => esc_html__( 'Use Text Overlay', 'et_builder' ),
'description' => esc_html__( 'When enabled, a background color is added behind the slider text to make it more readable atop background images.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
// Uses cached uppercase translation but keeps the lowercase not change definition content.
'on' => strtolower( et_builder_i18n( 'Yes' ) ),
),
'default_on_front' => '',
'affects' => array(
'text_overlay_color',
'text_border_radius',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
),
'text_overlay_color' => array(
'label' => esc_html__( 'Text Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Use the color picker to choose a color for the text overlay.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
'mobile_options' => true,
'sticky' => true,
),
'text_border_radius' => array(
'label' => esc_html__( 'Text Overlay Border Radius', 'et_builder' ),
'description' => esc_html__( 'Increasing the border radius will increase the roundness of the overlay corners. Setting this value to 0 will result in squared corners.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'default' => '3',
'default_unit' => 'px',
'default_on_front' => '',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'arrows_custom_color' => array(
'label' => esc_html__( 'Arrow Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the slider arrows that are used to navigate through each slide.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'navigation',
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'dot_nav_custom_color' => array(
'label' => esc_html__( 'Dot Navigation Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the dot navigation that appears at the bottom of the slider to designate which slide is active.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'navigation',
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
function before_render() {
global $et_pb_slider_has_video, $et_pb_slider_parallax, $et_pb_slider_parallax_method, $et_pb_slider_show_mobile, $et_pb_slider_custom_icon, $et_pb_slider_custom_icon_tablet, $et_pb_slider_custom_icon_phone, $et_pb_slider_item_num, $et_pb_slider_button_rel;
global $et_pb_slider_parent_type;
$et_pb_slider_parent_type = $this->slug;
$et_pb_slider_item_num = 0;
$sticky = et_pb_sticky_options();
$parallax = $this->props['parallax'];
$parallax_method = $this->props['parallax_method'];
$show_content_on_mobile = $this->props['show_content_on_mobile'];
$show_cta_on_mobile = $this->props['show_cta_on_mobile'];
$button_rel = $this->props['button_rel'];
$button_custom = $this->props['custom_button'];
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$et_pb_slider_has_video = false;
$et_pb_slider_parallax = $parallax;
$et_pb_slider_parallax_method = $parallax_method;
$et_pb_slider_show_mobile = array(
'show_content_on_mobile' => $show_content_on_mobile,
'show_cta_on_mobile' => $show_cta_on_mobile,
);
$et_pb_slider_custom_icon = 'on' === $button_custom ? $custom_icon : '';
$et_pb_slider_custom_icon_tablet = 'on' === $button_custom ? $custom_icon_tablet : '';
$et_pb_slider_custom_icon_phone = 'on' === $button_custom ? $custom_icon_phone : '';
$et_pb_slider_button_rel = $button_rel;
// BG Overlay Color.
$bg_overlay_color = $this->props['bg_overlay_color'];
$bg_overlay_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'bg_overlay_color' );
$bg_overlay_color_tablet = isset( $bg_overlay_color_values['tablet'] ) ? $bg_overlay_color_values['tablet'] : '';
$bg_overlay_color_phone = isset( $bg_overlay_color_values['phone'] ) ? $bg_overlay_color_values['phone'] : '';
// Text Overlay Color.
$text_overlay_color = $this->props['text_overlay_color'];
$text_overlay_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'text_overlay_color' );
$text_overlay_color_tablet = isset( $text_overlay_color_values['tablet'] ) ? $text_overlay_color_values['tablet'] : '';
$text_overlay_color_phone = isset( $text_overlay_color_values['phone'] ) ? $text_overlay_color_values['phone'] : '';
// Text Border Radius.
$text_border_radius = $this->props['text_border_radius'];
$text_border_radius_values = et_pb_responsive_options()->get_property_values( $this->props, 'text_border_radius' );
$text_border_radius_tablet = isset( $text_border_radius_values['tablet'] ) ? $text_border_radius_values['tablet'] : '';
$text_border_radius_phone = isset( $text_border_radius_values['phone'] ) ? $text_border_radius_values['phone'] : '';
// Arrows Color.
$arrows_custom_color = $this->props['arrows_custom_color'];
$arrows_custom_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'arrows_custom_color' );
$arrows_custom_color_tablet = isset( $arrows_custom_color_values['tablet'] ) ? $arrows_custom_color_values['tablet'] : '';
$arrows_custom_color_phone = isset( $arrows_custom_color_values['phone'] ) ? $arrows_custom_color_values['phone'] : '';
// Dot Nav Custom Color.
$dot_nav_custom_color = $this->props['dot_nav_custom_color'];
$dot_nav_custom_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'dot_nav_custom_color' );
$dot_nav_custom_color_tablet = isset( $dot_nav_custom_color_values['tablet'] ) ? $dot_nav_custom_color_values['tablet'] : '';
$dot_nav_custom_color_phone = isset( $dot_nav_custom_color_values['phone'] ) ? $dot_nav_custom_color_values['phone'] : '';
// Pass Fullwidth Slider Module settings to Slide Item
global $et_pb_slider;
$et_pb_slider = array(
'background_last_edited' => $this->props['background_last_edited'],
'background__hover_enabled' => isset( $this->props['background__hover_enabled'] ) ? $this->props['background__hover_enabled'] : '',
// Background Color.
'background_enable_color' => $this->props['background_enable_color'],
'background_enable_color_tablet' => $this->props['background_enable_color_tablet'],
'background_enable_color_phone' => $this->props['background_enable_color_phone'],
'background_enable_color__hover' => isset( $this->props['background_enable_color__hover'] ) ? $this->props['background_enable_color__hover'] : '',
'background_color' => $this->props['background_color'],
'background_color_tablet' => $this->props['background_color_tablet'],
'background_color_phone' => $this->props['background_color_phone'],
'background_color__hover' => isset( $this->props['background_color__hover'] ) ? $this->props['background_color__hover'] : '',
// Background Gradient.
'use_background_color_gradient' => $this->props['use_background_color_gradient'],
'use_background_color_gradient_tablet' => $this->props['use_background_color_gradient_tablet'],
'use_background_color_gradient_phone' => $this->props['use_background_color_gradient_phone'],
'use_background_color_gradient__hover' => isset( $this->props['use_background_color_gradient__hover'] ) ? $this->props['use_background_color_gradient__hover'] : '',
'background_color_gradient_type' => $this->props['background_color_gradient_type'],
'background_color_gradient_type_tablet' => $this->props['background_color_gradient_type_tablet'],
'background_color_gradient_type_phone' => $this->props['background_color_gradient_type_phone'],
'background_color_gradient_type__hover' => isset( $this->props['background_color_gradient_type__hover'] ) ? $this->props['background_color_gradient_type__hover'] : '',
'background_color_gradient_direction' => $this->props['background_color_gradient_direction'],
'background_color_gradient_direction_tablet' => $this->props['background_color_gradient_direction_tablet'],
'background_color_gradient_direction_phone' => $this->props['background_color_gradient_direction_phone'],
'background_color_gradient_direction__hover' => isset( $this->props['background_color_gradient_direction__hover'] ) ? $this->props['background_color_gradient_direction__hover'] : '',
'background_color_gradient_direction_radial' => $this->props['background_color_gradient_direction_radial'],
'background_color_gradient_direction_radial_tablet' => $this->props['background_color_gradient_direction_radial_tablet'],
'background_color_gradient_direction_radial_phone' => $this->props['background_color_gradient_direction_radial_phone'],
'background_color_gradient_direction_radial__hover' => isset( $this->props['background_color_gradient_direction_radial__hover'] ) ? $this->props['background_color_gradient_direction_radial__hover'] : '',
'background_color_gradient_start' => $this->props['background_color_gradient_start'],
'background_color_gradient_start_tablet' => $this->props['background_color_gradient_start_tablet'],
'background_color_gradient_start_phone' => $this->props['background_color_gradient_start_phone'],
'background_color_gradient_start__hover' => isset( $this->props['background_color_gradient_start__hover'] ) ? $this->props['background_color_gradient_start__hover'] : '',
'background_color_gradient_end' => $this->props['background_color_gradient_end'],
'background_color_gradient_end_tablet' => $this->props['background_color_gradient_end_tablet'],
'background_color_gradient_end_phone' => $this->props['background_color_gradient_end_phone'],
'background_color_gradient_end__hover' => isset( $this->props['background_color_gradient_end__hover'] ) ? $this->props['background_color_gradient_end__hover'] : '',
'background_color_gradient_start_position' => $this->props['background_color_gradient_start_position'],
'background_color_gradient_start_position_tablet' => $this->props['background_color_gradient_start_position_tablet'],
'background_color_gradient_start_position_phone' => $this->props['background_color_gradient_start_position_phone'],
'background_color_gradient_start_position__hover' => isset( $this->props['background_color_gradient_start_position__hover'] ) ? $this->props['background_color_gradient_start_position__hover'] : '',
'background_color_gradient_end_position' => $this->props['background_color_gradient_end_position'],
'background_color_gradient_end_position_tablet' => $this->props['background_color_gradient_end_position_tablet'],
'background_color_gradient_end_position_phone' => $this->props['background_color_gradient_end_position_phone'],
'background_color_gradient_end_position__hover' => isset( $this->props['background_color_gradient_end_position__hover'] ) ? $this->props['background_color_gradient_end_position__hover'] : '',
'background_color_gradient_overlays_image' => $this->props['background_color_gradient_overlays_image'],
'background_color_gradient_overlays_image_tablet' => $this->props['background_color_gradient_overlays_image_tablet'],
'background_color_gradient_overlays_image_phone' => $this->props['background_color_gradient_overlays_image_phone'],
'background_color_gradient_overlays_image__hover' => isset( $this->props['background_color_gradient_overlays_image__hover'] ) ? $this->props['background_color_gradient_overlays_image__hover'] : '',
// Background Image.
'background_enable_image' => $this->props['background_enable_image'],
'background_enable_image_tablet' => $this->props['background_enable_image_tablet'],
'background_enable_image_phone' => $this->props['background_enable_image_phone'],
'background_enable_image__hover' => isset( $this->props['background_enable_image__hover'] ) ? $this->props['background_enable_image__hover'] : '',
'background_image' => $this->props['background_image'],
'background_image_tablet' => $this->props['background_image_tablet'],
'background_image_phone' => $this->props['background_image_phone'],
'background_image__hover' => isset( $this->props['background_image__hover'] ) ? $this->props['background_image__hover'] : '',
'background_size' => $this->props['background_size'],
'background_size_tablet' => $this->props['background_size_tablet'],
'background_size_phone' => $this->props['background_size_phone'],
'background_size__hover' => isset( $this->props['background_size__hover'] ) ? $this->props['background_size__hover'] : '',
'background_position' => $this->props['background_position'],
'background_position_tablet' => $this->props['background_position_tablet'],
'background_position_phone' => $this->props['background_position_phone'],
'background_position__hover' => isset( $this->props['background_position__hover'] ) ? $this->props['background_position__hover'] : '',
'background_repeat' => $this->props['background_repeat'],
'background_repeat_tablet' => $this->props['background_repeat_tablet'],
'background_repeat_phone' => $this->props['background_repeat_phone'],
'background_repeat__hover' => isset( $this->props['background_repeat__hover'] ) ? $this->props['background_repeat__hover'] : '',
'background_blend' => $this->props['background_blend'],
'background_blend_tablet' => $this->props['background_blend_tablet'],
'background_blend_phone' => $this->props['background_blend_phone'],
'background_blend__hover' => isset( $this->props['background_blend__hover'] ) ? $this->props['background_blend__hover'] : '',
'parallax' => $this->props['parallax'],
'parallax_tablet' => $this->props['parallax_tablet'],
'parallax_phone' => $this->props['parallax_phone'],
'parallax__hover' => isset( $this->props['parallax__hover'] ) ? $this->props['parallax__hover'] : '',
'parallax_method' => $this->props['parallax_method'],
'parallax_method_tablet' => $this->props['parallax_method_tablet'],
'parallax_method_phone' => $this->props['parallax_method_phone'],
'parallax_method__hover' => isset( $this->props['parallax_method__hover'] ) ? $this->props['parallax_method__hover'] : '',
// Background Video.
'background_enable_video_mp4' => $this->props['background_enable_video_mp4'],
'background_enable_video_mp4_tablet' => $this->props['background_enable_video_mp4_tablet'],
'background_enable_video_mp4_phone' => $this->props['background_enable_video_mp4_phone'],
'background_enable_video_mp4__hover' => isset( $this->props['background_enable_video_mp4__hover'] ) ? $this->props['background_enable_video_mp4__hover'] : '',
'background_enable_video_webm' => $this->props['background_enable_video_webm'],
'background_enable_video_webm_tablet' => $this->props['background_enable_video_webm_tablet'],
'background_enable_video_webm_phone' => $this->props['background_enable_video_webm_phone'],
'background_enable_video_webm__hover' => isset( $this->props['background_enable_video_webm__hover'] ) ? $this->props['background_enable_video_webm__hover'] : '',
'background_video_mp4' => $this->props['background_video_mp4'],
'background_video_mp4_tablet' => $this->props['background_video_mp4_tablet'],
'background_video_mp4_phone' => $this->props['background_video_mp4_phone'],
'background_video_mp4__hover' => isset( $this->props['background_video_mp4__hover'] ) ? $this->props['background_video_mp4__hover'] : '',
'background_video_webm' => $this->props['background_video_webm'],
'background_video_webm_tablet' => $this->props['background_video_webm_tablet'],
'background_video_webm_phone' => $this->props['background_video_webm_phone'],
'background_video_webm__hover' => isset( $this->props['background_video_webm__hover'] ) ? $this->props['background_video_webm__hover'] : '',
'background_video_width' => $this->props['background_video_width'],
'background_video_width_tablet' => $this->props['background_video_width_tablet'],
'background_video_width_phone' => $this->props['background_video_width_phone'],
'background_video_width__hover' => isset( $this->props['background_video_width__hover'] ) ? $this->props['background_video_width__hover'] : '',
'background_video_height' => $this->props['background_video_height'],
'background_video_height_tablet' => $this->props['background_video_height_tablet'],
'background_video_height_phone' => $this->props['background_video_height_phone'],
'background_video_height__hover' => isset( $this->props['background_video_height__hover'] ) ? $this->props['background_video_height__hover'] : '',
'header_level' => $this->props['header_level'],
'use_bg_overlay' => $this->props['use_bg_overlay'],
'bg_overlay_color' => $bg_overlay_color,
'bg_overlay_color_slider_last_edited' => $this->props['bg_overlay_color_last_edited'],
'bg_overlay_color_tablet' => $bg_overlay_color_tablet,
'bg_overlay_color_phone' => $bg_overlay_color_phone,
'bg_overlay_color__sticky' => $sticky->get_value( 'bg_overlay_color', $this->props ),
'use_text_overlay' => $this->props['use_text_overlay'],
'text_overlay_color' => $text_overlay_color,
'text_overlay_color_slider_last_edited' => $this->props['text_overlay_color_last_edited'],
'text_overlay_color_tablet' => $text_overlay_color_tablet,
'text_overlay_color_phone' => $text_overlay_color_phone,
'text_overlay_color__sticky' => $sticky->get_value( 'text_overlay_color', $this->props ),
'text_border_radius' => $text_border_radius,
'text_border_radius_slider_last_edited' => $this->props['text_border_radius_last_edited'],
'text_border_radius_tablet' => $text_border_radius_tablet,
'text_border_radius_phone' => $text_border_radius_phone,
'text_border_radius__sticky' => $sticky->get_value( 'text_border_radius', $this->props ),
'arrows_custom_color' => $arrows_custom_color,
'arrows_custom_color_slider_last_edited' => $this->props['arrows_custom_color_last_edited'],
'arrows_custom_color_tablet' => $arrows_custom_color_tablet,
'arrows_custom_color_phone' => $arrows_custom_color_phone,
'arrows_custom_color__sticky' => $sticky->get_value( 'arrows_custom_color', $this->props ),
'dot_nav_custom_color' => $dot_nav_custom_color,
'dot_nav_custom_color_slider_last_edited' => $this->props['dot_nav_custom_color_last_edited'],
'dot_nav_custom_color_tablet' => $dot_nav_custom_color_tablet,
'dot_nav_custom_color_phone' => $dot_nav_custom_color_phone,
'dot_nav_custom_color__sticky' => $sticky->get_value( 'dot_nav_custom_color', $this->props ),
// Sticky classname position relies to slider's sticky status if the style selector
// begins with slider-level selector.
'is_sticky_module' => $sticky->is_sticky_module( $this->props ),
// Module item has no sticky options hence this needs to be inherited to setup transition.
'sticky_transition' => et_()->array_get( $this->props, 'sticky_transition', 'on' ),
);
// Hover Options attribute doesn't have field definition and rendered on the fly, thus the use of array_get()
$background_hover_enabled_key = et_pb_hover_options()->get_hover_enabled_field( 'background' );
$background_color_hover_key = et_pb_hover_options()->get_hover_field( 'background_color' );
$et_pb_slider[ $background_hover_enabled_key ] = self::$_->array_get( $this->props, $background_hover_enabled_key, '' );
$et_pb_slider[ $background_color_hover_key ] = self::$_->array_get( $this->props, $background_color_hover_key, '' );
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['dot_nav_custom_color'] = array( 'background-color' => et_pb_slider_options()->get_dots_selector() );
$fields['arrows_custom_color'] = array( 'all' => et_pb_slider_options()->get_arrows_selector() );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$show_arrows = $this->props['show_arrows'];
$show_pagination = $this->props['show_pagination'];
$parallax = $this->props['parallax'];
$parallax_method = $this->props['parallax_method'];
$auto = $this->props['auto'];
$auto_speed = $this->props['auto_speed'];
$auto_ignore_hover = $this->props['auto_ignore_hover'];
$show_image_video_mobile = $this->props['show_image_video_mobile'];
$background_position = $this->props['background_position'];
$background_size = $this->props['background_size'];
global $et_pb_slider_has_video, $et_pb_slider_parallax, $et_pb_slider_parallax_method, $et_pb_slider_show_mobile, $et_pb_slider_custom_icon, $et_pb_slider_custom_icon_tablet, $et_pb_slider_custom_icon_phone, $et_pb_slider;
$content = $this->content;
if ( '' !== $background_position && 'default' !== $background_position && 'off' === $parallax ) {
$processed_position = str_replace( '_', ' ', $background_position );
$style = array(
'selector' => '%%order_class%% .et_pb_slide',
'declaration' => sprintf(
'background-position: %1$s;',
esc_html( $processed_position )
),
);
ET_Builder_Module::set_style( $render_slug, $style );
}
if ( '' !== $background_size && 'default' !== $background_size && 'off' === $parallax ) {
$style = array(
'selector' => '%%order_class%% .et_pb_slide',
'declaration' => sprintf(
'-moz-background-size: %1$s;
-webkit-background-size: %1$s;
background-size: %1$s;',
esc_html( $background_size )
),
);
ET_Builder_Module::set_style( $render_slug, $style );
}
// Module classnames
$this->add_classname( $render_slug );
$this->add_classname( 'et_pb_slider' );
if ( $et_pb_slider_has_video ) {
$this->add_classname( 'et_pb_preload' );
}
if ( 'off' === $show_arrows ) {
$this->add_classname( 'et_pb_slider_no_arrows' );
}
if ( 'off' === $show_pagination ) {
$this->add_classname( 'et_pb_slider_no_pagination' );
}
if ( 'on' === $parallax ) {
$this->add_classname( 'et_pb_slider_parallax' );
}
if ( 'on' === $auto ) {
$this->add_classname(
array(
'et_slider_auto',
"et_slider_speed_{$auto_speed}",
)
);
}
if ( 'on' === $auto_ignore_hover ) {
$this->add_classname( 'et_slider_auto_ignore_hover' );
}
if ( 'on' === $show_image_video_mobile ) {
$this->add_classname( 'et_pb_slider_show_image' );
}
$this->generate_responsive_hover_style( 'arrows_custom_color', et_pb_slider_options()->get_arrows_selector(), 'color' );
$this->generate_responsive_hover_style( 'dot_nav_custom_color', et_pb_slider_options()->get_dots_selector(), 'background-color' );
// Remove automatically added classnames
$this->remove_classname( 'et_pb_fullwidth_slider' );
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_slider_no_arrows' => array(
'show_arrows' => 'off',
),
'et_pb_slider_no_pagination' => array(
'show_pagination' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%1$s"%5$s>
<div class="et_pb_slides">
%2$s
</div>
%4$s
</div>
',
$this->module_classname( $render_slug ),
$content,
$this->module_id(),
$this->inner_shadow_back_compatibility( $render_slug ),
$multi_view_data_attr // $5
);
// Reset passed slider item value
$et_pb_slider = array();
return $output;
}
private function inner_shadow_back_compatibility( $functions_name ) {
$utils = ET_Core_Data_Utils::instance();
$atts = $this->props;
$style = '';
if (
version_compare( $utils->array_get( $atts, '_builder_version', '3.0.93' ), '3.0.99', 'lt' )
) {
$class = self::get_module_order_class( $functions_name );
$style = sprintf(
'<style>%1$s</style>',
sprintf(
'.%1$s.et_pb_slider .et_pb_slide {'
. '-webkit-box-shadow: none; '
. '-moz-box-shadow: none; '
. 'box-shadow: none; '
. '}',
esc_attr( $class )
)
);
if ( 'off' !== $utils->array_get( $atts, 'show_inner_shadow' ) ) {
$style .= sprintf(
'<style>%1$s</style>',
sprintf(
'.%1$s > .box-shadow-overlay { '
. '-webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. '-moz-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. 'box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. '}',
esc_attr( $class )
)
);
}
}
return $style;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Fullwidth_Slider();
}

View File

@ -0,0 +1,766 @@
<?php
class ET_Builder_Module_Gallery extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Gallery', 'et_builder' );
$this->plural = esc_html__( 'Galleries', 'et_builder' );
$this->slug = 'et_pb_gallery';
$this->vb_support = 'on';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => esc_html__( 'Images', 'et_builder' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'overlay' => et_builder_i18n( 'Overlay' ),
'image' => array(
'title' => et_builder_i18n( 'Image' ),
),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
),
),
);
$this->main_css_element = '%%order_class%%.et_pb_gallery';
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_gallery_title",
'hover' => "{$this->main_css_element} .et_pb_gallery_title:hover",
),
'header_level' => array(
'default' => 'h3',
),
),
'caption' => array(
'label' => esc_html__( 'Caption', 'et_builder' ),
'use_all_caps' => true,
'css' => array(
'main' => "{$this->main_css_element} .mfp-title, {$this->main_css_element} .et_pb_gallery_caption",
'hover' => "{$this->main_css_element} .mfp-title:hover, {$this->main_css_element} .et_pb_gallery_caption:hover",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'depends_show_if' => 'off',
),
'pagination' => array(
'label' => esc_html__( 'Pagination', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_gallery_pagination a",
'hover' => "{$this->main_css_element} .et_pb_gallery_pagination a:hover",
'text_align' => "{$this->main_css_element} .et_pb_gallery_pagination ul",
),
'text_align' => array(
'options' => et_builder_get_text_orientation_options( array( 'justified' ), array() ),
),
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_gallery_item",
'border_styles' => "{$this->main_css_element} .et_pb_gallery_item",
),
),
),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_gallery_image",
'border_styles' => "{$this->main_css_element} .et_pb_gallery_image",
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'depends_on' => array( 'fullwidth' ),
'depends_show_if' => 'off',
),
),
'box_shadow' => array(
'default' => array(
'show_if' => array(
'fullwidth' => 'on',
),
),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'show_if' => array(
'fullwidth' => 'off',
),
'css' => array(
'main' => '%%order_class%% .et_pb_gallery_image',
'overlay' => 'inset',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_gallery.et_pb_module',
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => implode(
', ',
array(
"{$this->main_css_element} .et_pb_gallery_title",
"{$this->main_css_element} .mfp-title",
"{$this->main_css_element} .et_pb_gallery_caption",
"{$this->main_css_element} .et_pb_gallery_pagination a",
)
),
'text_shadow' => "{$this->main_css_element}.et_pb_gallery_grid",
),
'options' => array(
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_gallery_image img',
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
);
$this->custom_css_fields = array(
'gallery_item' => array(
'label' => esc_html__( 'Gallery Item', 'et_builder' ),
'selector' => '.et_pb_gallery_item',
),
'overlay' => array(
'label' => et_builder_i18n( 'Overlay' ),
'selector' => '.et_overlay',
),
'overlay_icon' => array(
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
'selector' => '.et_overlay:before',
),
'gallery_item_title' => array(
'label' => esc_html__( 'Gallery Item Title', 'et_builder' ),
'selector' => '.et_pb_gallery_title',
),
'gallery_item_caption' => array(
'label' => esc_html__( 'Gallery Item Caption', 'et_builder' ),
'selector' => '.et_pb_gallery_caption',
),
'gallery_pagination' => array(
'label' => esc_html__( 'Gallery Pagination', 'et_builder' ),
'selector' => '.et_pb_gallery_pagination',
),
'gallery_pagination_active' => array(
'label' => esc_html__( 'Pagination Active Page', 'et_builder' ),
'selector' => '.et_pb_gallery_pagination a.active',
),
);
$this->help_videos = array(
array(
'id' => 'BRjX-pNHk-s',
'name' => esc_html__( 'An introduction to the Gallery module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'gallery_ids' => array(
'label' => esc_html__( 'Images', 'et_builder' ),
'description' => esc_html__( 'Choose the images that you would like to appear in the image gallery.', 'et_builder' ),
'type' => 'upload-gallery',
'computed_affects' => array(
'__gallery',
),
'option_category' => 'basic_option',
'toggle_slug' => 'main_content',
),
'gallery_orderby' => array(
'label' => esc_html__( 'Image Order', 'et_builder' ),
'description' => esc_html__( 'Select an ordering method for the gallery. This controls which gallery items appear first in the list.', 'et_builder' ),
'type' => $this->is_loading_bb_data() ? 'hidden' : 'select',
'options' => array(
'' => et_builder_i18n( 'Default' ),
'rand' => esc_html__( 'Random', 'et_builder' ),
),
'default' => 'off',
'class' => array( 'et-pb-gallery-ids-field' ),
'computed_affects' => array(
'__gallery',
),
'toggle_slug' => 'main_content',
),
'gallery_captions' => array(
'type' => 'hidden',
'class' => array( 'et-pb-gallery-captions-field' ),
'computed_affects' => array(
'__gallery',
),
),
'fullwidth' => array(
'label' => et_builder_i18n( 'Layout' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'off' => esc_html__( 'Grid', 'et_builder' ),
'on' => esc_html__( 'Slider', 'et_builder' ),
),
'default_on_front' => 'off',
'description' => esc_html__( 'Toggle between the various gallery layout types.', 'et_builder' ),
'affects' => array(
'zoom_icon_color',
'caption_font',
'caption_text_color',
'caption_line_height',
'caption_font_size',
'caption_all_caps',
'caption_letter_spacing',
'hover_icon',
'hover_overlay_color',
'auto',
'posts_number',
'show_title_and_caption',
'show_pagination',
'orientation',
'border_radii_image',
'border_styles_image',
),
'computed_affects' => array(
'__gallery',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
),
'posts_number' => array(
'default' => 4,
'label' => esc_html__( 'Image Count', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'description' => esc_html__( 'Define the number of images that should be displayed per page.', 'et_builder' ),
'depends_show_if' => 'off',
'toggle_slug' => 'main_content',
),
'orientation' => array(
'label' => esc_html__( 'Thumbnail Orientation', 'et_builder' ),
'type' => 'select',
'options_category' => 'configuration',
'options' => array(
'landscape' => esc_html__( 'Landscape', 'et_builder' ),
'portrait' => esc_html__( 'Portrait', 'et_builder' ),
),
'default_on_front' => 'landscape',
'description' => sprintf(
'%1$s<br><small><em><strong>%2$s:</strong> %3$s <a href="//wordpress.org/plugins/force-regenerate-thumbnails" target="_blank">%4$s</a>.</em></small>',
esc_html__( 'Choose the orientation of the gallery thumbnails.', 'et_builder' ),
esc_html__( 'Note', 'et_builder' ),
esc_html__( 'If this option appears to have no effect, you might need to', 'et_builder' ),
esc_html__( 'regenerate your thumbnails', 'et_builder' )
),
'depends_show_if' => 'off',
'computed_affects' => array(
'__gallery',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
),
'show_title_and_caption' => array(
'label' => esc_html__( 'Show Title and Caption', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'description' => esc_html__( 'Whether or not to show the title and caption for images (if available).', 'et_builder' ),
'depends_show_if' => 'off',
'toggle_slug' => 'elements',
'mobile_options' => true,
'hover' => 'tabs',
),
'show_pagination' => array(
'label' => esc_html__( 'Show Pagination', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'description' => esc_html__( 'Enable or disable pagination for this feed.', 'et_builder' ),
'depends_show_if' => 'off',
'toggle_slug' => 'elements',
'computed_affects' => array(
'__gallery',
),
'mobile_options' => true,
'hover' => 'tabs',
),
'zoom_icon_color' => array(
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the zoom icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Overlay Background Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'__gallery' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Gallery', 'get_gallery' ),
'computed_depends_on' => array(
'gallery_ids',
'gallery_orderby',
'gallery_captions',
'fullwidth',
'orientation',
'show_pagination',
),
),
);
return $fields;
}
/**
* Get attachment data for gallery module
*
* @param array $args {
* Gallery Options
*
* @type array $gallery_ids Attachment Ids of images to be included in gallery.
* @type string $gallery_orderby `orderby` arg for query. Optional.
* @type string $fullwidth on|off to determine grid / slider layout
* @type string $orientation Orientation of thumbnails (landscape|portrait).
* }
* @param array $conditional_tags
* @param array $current_page
*
* @return array Attachments data
*/
static function get_gallery( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$attachments = array();
$defaults = array(
'gallery_ids' => array(),
'gallery_orderby' => '',
'gallery_captions' => array(),
'fullwidth' => 'off',
'orientation' => 'landscape',
);
$args = wp_parse_args( $args, $defaults );
$attachments_args = array(
'include' => $args['gallery_ids'],
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => 'ASC',
'orderby' => 'post__in',
);
// Woo Gallery module shouldn't display placeholder image when no Gallery image is
// available.
// @see https://github.com/elegantthemes/submodule-builder/pull/6706#issuecomment-542275647
if ( isset( $args['attachment_id'] ) ) {
$attachments_args['attachment_id'] = $args['attachment_id'];
}
if ( 'rand' === $args['gallery_orderby'] ) {
$attachments_args['orderby'] = 'rand';
}
if ( 'on' === $args['fullwidth'] ) {
$width = 1080;
$height = 9999;
} else {
$width = 400;
$height = ( 'landscape' === $args['orientation'] ) ? 284 : 516;
}
$width = (int) apply_filters( 'et_pb_gallery_image_width', $width );
$height = (int) apply_filters( 'et_pb_gallery_image_height', $height );
$_attachments = get_posts( $attachments_args );
foreach ( $_attachments as $key => $val ) {
$attachments[ $key ] = $_attachments[ $key ];
$attachments[ $key ]->image_alt_text = get_post_meta( $val->ID, '_wp_attachment_image_alt', true );
$attachments[ $key ]->image_src_full = wp_get_attachment_image_src( $val->ID, 'full' );
$attachments[ $key ]->image_src_thumb = wp_get_attachment_image_src( $val->ID, array( $width, $height ) );
}
return $attachments;
}
/**
* Wrapper for ET_Builder_Module_Gallery::get_gallery() which is intended to be extended by
* module which uses gallery module renderer so relevant argument for other module can be added
*
* @since 3.29
* @see ET_Builder_Module_Gallery::get_gallery()
* @param array $args {
* Gallery Options
*
* @type array $gallery_ids Attachment Ids of images to be included in gallery.
* @type string $gallery_orderby `orderby` arg for query. Optional.
* @type string $fullwidth on|off to determine grid / slider layout
* @type string $orientation Orientation of thumbnails (landscape|portrait).
* }
*
* @return array
*/
public function get_attachments( $args = array() ) {
return self::get_gallery( $args );
}
public function get_pagination_alignment() {
$text_orientation = isset( $this->props['pagination_text_align'] ) ? $this->props['pagination_text_align'] : '';
return et_pb_get_alignment( $text_orientation );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$gallery_ids = $this->props['gallery_ids'];
$fullwidth = $this->props['fullwidth'];
$show_title_and_caption = $this->props['show_title_and_caption'];
$posts_number = $this->props['posts_number'];
$show_pagination = $this->props['show_pagination'];
$gallery_orderby = $this->props['gallery_orderby'];
$auto = $this->props['auto'];
$auto_speed = $this->props['auto_speed'];
$orientation = $this->props['orientation'];
$pagination_text_align = $this->get_pagination_alignment();
$header_level = $this->props['title_level'];
$hover_icon = $this->props['hover_icon'];
$hover_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'hover_icon' );
$hover_icon_tablet = isset( $hover_icon_values['tablet'] ) ? $hover_icon_values['tablet'] : '';
$hover_icon_phone = isset( $hover_icon_values['phone'] ) ? $hover_icon_values['phone'] : '';
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
// Zoom Icon Color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'zoom_icon_color',
'selector' => '%%order_class%% .et_overlay:before',
'css_property' => 'color',
'render_slug' => $render_slug,
'important' => true,
'type' => 'color',
)
);
// Hover Overlay Color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => '%%order_class%% .et_overlay',
'css_property' => array( 'background-color', 'border-color' ),
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Get gallery item data
$attachments = $this->get_attachments(
array(
'gallery_ids' => $gallery_ids,
'gallery_orderby' => $gallery_orderby,
'fullwidth' => $fullwidth,
'orientation' => $orientation,
)
);
if ( empty( $attachments ) ) {
return '';
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$posts_number = 0 === intval( $posts_number ) ? 4 : intval( $posts_number );
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( 'on' === $fullwidth ) {
$this->add_classname(
array(
'et_pb_slider',
'et_pb_gallery_fullwidth',
)
);
} else {
$this->add_classname( 'et_pb_gallery_grid' );
}
if ( 'on' === $auto && 'on' === $fullwidth ) {
$this->add_classname(
array(
'et_slider_auto',
"et_slider_speed_{$auto_speed}",
'clearfix',
)
);
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$output = sprintf(
'<div%1$s class="%2$s"%4$s>%5$s%6$s
<div class="et_pb_gallery_items et_post_gallery clearfix" data-per_page="%3$d">',
$this->module_id(),
$this->module_classname( $render_slug ),
esc_attr( $posts_number ),
et_core_esc_previously( $data_background_layout ),
$parallax_image_background,
$video_background
);
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
$generate_css_filters_item = $this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
);
}
// Overlay output.
$overlay_output = 'on' === $fullwidth ? '' : ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_tablet' => $hover_icon_tablet,
'icon_phone' => $hover_icon_phone,
'icon_sticky' => $hover_icon_sticky,
)
);
if ( 'on' !== $fullwidth ) {
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => '%%order_class%% .et_overlay:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
}
$images_count = 0;
foreach ( $attachments as $id => $attachment ) {
$image_attrs = array(
'alt' => $attachment->image_alt_text,
);
if ( 'on' !== $fullwidth ) {
$image_attrs['srcset'] = $attachment->image_src_full[0] . ' 479w, ' . $attachment->image_src_thumb[0] . ' 480w';
$image_attrs['sizes'] = '(max-width:479px) 479px, 100vw';
}
$image_attachment_class = et_pb_media_options()->get_image_attachment_class( $this->props, '', $attachment->ID );
if ( ! empty( $image_attachment_class ) ) {
$image_attrs['class'] = esc_attr( $image_attachment_class );
}
$image_output = sprintf(
'<a href="%1$s" title="%2$s">
%3$s
%4$s
</a>',
esc_url( $attachment->image_src_full[0] ),
esc_attr( $attachment->post_title ),
$this->render_image( $attachment->image_src_thumb[0], $image_attrs, false ),
et_core_esc_previously( $overlay_output )
);
$gallery_order = self::_get_index( array( self::INDEX_MODULE_ORDER, $render_slug ) );
$item_class = sprintf( ' et_pb_gallery_item_%1$s_%2$s', $gallery_order, $images_count );
$output .= sprintf(
'<div class="et_pb_gallery_item%2$s%1$s%3$s%4$s">',
esc_attr( ' ' . implode( ' ', $background_layout_class_names ) ),
( 'on' !== $fullwidth ? ' et_pb_grid_item' : '' ),
$generate_css_filters_item,
$item_class
);
$images_count++;
$output .= "
<div class='et_pb_gallery_image {$orientation}'>
$image_output
</div>";
if ( 'on' !== $fullwidth && $multi_view->has_value( 'show_title_and_caption', 'on' ) ) {
if ( trim( $attachment->post_title ) ) {
$output .= $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h3' ),
'content' => wptexturize( $attachment->post_title ),
'attrs' => array(
'class' => 'et_pb_gallery_title',
),
'visibility' => array(
'show_title_and_caption' => 'on',
),
)
);
}
if ( trim( $attachment->post_excerpt ) ) {
$output .= $multi_view->render_element(
array(
'tag' => 'p',
'content' => wptexturize( $attachment->post_excerpt ),
'attrs' => array(
'class' => 'et_pb_gallery_caption',
),
'visibility' => array(
'show_title_and_caption' => 'on',
),
)
);
}
}
$output .= '</div>';
}
$output .= '</div>';
if ( 'on' !== $fullwidth && $multi_view->has_value( 'show_pagination', 'on' ) ) {
$pagination_classes = array( 'et_pb_gallery_pagination' );
if ( 'justify' === $pagination_text_align ) {
$pagination_classes[] = 'et_pb_gallery_pagination_justify';
}
$output .= $multi_view->render_element(
array(
'tag' => 'div',
'attrs' => array(
'class' => implode( ' ', $pagination_classes ),
),
'visibility' => array(
'show_pagination' => 'on',
),
)
);
}
$output .= '</div>';
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Gallery();
}

View File

@ -0,0 +1,449 @@
<?php
/**
* Icon module class.
*
* @package Divi
* @subpackage Builder
* @since ?
*/
/**
* Handles setting up everything for icon module.
*
* @since ?
*/
class ET_Builder_Module_Icon extends ET_Builder_Module {
/**
* Initialize the module class.
*
* @since ?
*
* @return void
*/
public function init() {
$this->name = et_builder_i18n( 'Icon' );
$this->plural = esc_html__( 'Icons', 'et_builder' );
$this->slug = 'et_pb_icon';
$this->vb_support = 'on';
$this->icon_element_selector = '%%order_class%% .et_pb_icon_wrap .et-pb-icon';
$this->icon_element_classname = 'et-pb-icon';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Icon' ),
'link' => et_builder_i18n( 'Link' ),
),
),
'advanced' => array(
'toggles' => array(
'icon_settings' => esc_html__( 'Icon', 'et_builder' ),
'alignment' => esc_html__( 'Alignment', 'et_builder' ),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
'attributes' => array(
'title' => esc_html__( 'Attributes', 'et_builder' ),
'priority' => 95,
),
),
),
);
$this->advanced_fields = array(
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_icon_wrap',
'hover' => '%%order_class%% .et_pb_icon_wrap:hover',
'padding' => '%%order_class%% .et_pb_icon_wrap',
'margin' => '%%order_class%% .et_pb_icon_wrap',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_icon_wrap',
'border_styles' => '%%order_class%% .et_pb_icon_wrap',
'border_radii_hover' => '%%order_class%% .et_pb_icon_wrap:hover',
'border_styles_hover' => '%%order_class%% .et_pb_icon_wrap:hover',
),
),
),
),
'background' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_icon_wrap',
'hover' => '%%order_class%% .et_pb_icon_wrap:hover',
),
'use_background_image_parallax' => false,
'use_background_video' => false,
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_icon_wrap',
'overlay' => 'inset',
),
),
),
'transform' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_icon_wrap',
'hover' => '%%order_class%% .et_pb_icon_wrap:hover',
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_icon_wrap',
'hover' => '%%order_class%% .et_pb_icon_wrap:hover',
),
),
'max_width' => array(
'use_max_width' => false,
'use_width' => false,
'use_module_alignment' => false,
),
'height' => array(
'use_height' => false,
'use_max_height' => false,
'use_min_height' => false,
),
'fonts' => false,
'text' => false,
'button' => false,
'link_options' => false,
);
$this->custom_css_fields = array(
'icon_element' => array(
'label' => esc_html__( 'Icon Element', 'et_builder' ),
'selector' => $this->icon_element_selector,
),
);
$this->help_videos = array(
array(
'id' => 'cYwqxoHnjNA',
'name' => esc_html__( 'An introduction to the Icon module', 'et_builder' ),
),
);
}
/**
* Get's the module fields.
*
* @since ?
*
* @return array $fields Module Fields.
*/
public function get_fields() {
$fields = array(
'font_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'basic_option',
'default' => '&#x21;||divi',
'class' => array( 'et-pb-font-icon' ),
'toggle_slug' => 'main_content',
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'icon_color' => array(
'default' => et_builder_accent_color(),
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'type' => 'color-alpha',
'description' => esc_html__( 'Here you can define a custom color for your icon.', 'et_builder' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'icon_settings',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'icon_width' => array(
'label' => esc_html__( 'Icon Size', 'et_builder' ),
'default' => '96px',
'range_settings' => array(
'min' => '1',
'max' => '200',
'step' => '1',
),
'toggle_slug' => 'icon_settings',
'description' => esc_html__( 'Here you can choose icon width.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'mobile_options' => true,
'validate_unit' => true,
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'responsive' => true,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'title_text' => array(
'label' => esc_html__( 'Icon Title Text', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'on',
'description' => esc_html__( 'This defines the HTML Title text.', 'et_builder' ),
'tab_slug' => 'custom_css',
'toggle_slug' => 'attributes',
'dynamic_content' => 'text',
),
'url' => array(
'label' => esc_html__( 'Icon Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'off',
'description' => esc_html__( 'If you would like your image to be a link, input your destination URL here. No link will be created if this field is left blank.', 'et_builder' ),
'toggle_slug' => 'link',
'dynamic_content' => 'url',
'affects' => array(
'title_text',
),
),
'url_new_window' => array(
'label' => esc_html__( 'Icon Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'default_on_front' => 'off',
'depends_show_if' => 'off',
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
),
'align' => array(
'label' => esc_html__( 'Icon Alignment', 'et_builder' ),
'type' => 'text_align',
'option_category' => 'layout',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'default_on_front' => 'center',
'tab_slug' => 'advanced',
'toggle_slug' => 'alignment',
'description' => esc_html__( 'Here you can choose the image alignment.', 'et_builder' ),
'options_icon' => 'module_align',
'mobile_options' => true,
),
);
return $fields;
}
/**
* Return an alignment value by device.
*
* @param string $device Device mode.
*
* @return string
*/
public function get_alignment( $device = 'desktop' ) {
$is_desktop = 'desktop' === $device;
$suffix = ! $is_desktop ? "_{$device}" : '';
$alignment = $is_desktop && isset( $this->props['align'] ) ? $this->props['align'] : '';
if ( ! $is_desktop && et_pb_responsive_options()->is_responsive_enabled( $this->props, 'align' ) ) {
$alignment = et_pb_responsive_options()->get_any_value( $this->props, "align{$suffix}" );
}
return et_pb_get_alignment( $alignment );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content = null, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$title_text = $this->props['title_text'];
$url = $this->props['url'];
$url_new_window = $this->props['url_new_window'];
$align = $this->get_alignment();
$align_tablet = $this->get_alignment( 'tablet' );
$align_phone = $this->get_alignment( 'phone' );
$animation_style = $this->props['animation_style'];
$box_shadow_style = self::$_->array_get( $this->props, 'box_shadow_style', '' );
// Responsive Icon Alignment.
// Set CSS properties and values for the image alignment.
// 1. Text Align is necessary, just set it from current image alignment value.
// 2. Margin {Side} is optional. Used to pull the image to right/left side.
// 3. Margin Left and Right are optional. Used by Center to reset custom margin of point 2.
$align_values = array(
'desktop' => array(
'text-align' => esc_html( $align ),
"margin-{$align}" => ! empty( $align ) && 'center' !== $align ? '0' : '',
),
'tablet' => array(
'text-align' => esc_html( $align_tablet ),
'margin-left' => 'left' !== $align_tablet ? 'auto' : '',
'margin-right' => 'left' !== $align_tablet ? 'auto' : '',
"margin-{$align_tablet}" => ! empty( $align_tablet ) && 'center' !== $align_tablet ? '0' : '',
),
'phone' => array(
'text-align' => esc_html( $align_phone ),
'margin-left' => 'left' !== $align_phone ? 'auto' : '',
'margin-right' => 'left' !== $align_phone ? 'auto' : '',
"margin-{$align_phone}" => ! empty( $align_phone ) && 'center' !== $align_phone ? '0' : '',
),
);
et_pb_responsive_options()->generate_responsive_css( $align_values, '%%order_class%%', '', $render_slug, '', 'alignment' );
if ( empty( $title_text ) ) {
$title_text = et_builder_resolve_dynamic_content( 'post_featured_image_title_text', array(), get_the_ID(), 'display' );
}
$icon_hover_selector = str_replace( $this->icon_element_classname, $this->icon_element_classname . ':hover', $this->icon_element_selector );
// Font Icon Style.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'font_icon',
'important' => true,
'selector' => $this->icon_element_selector,
'hover_selector' => $icon_hover_selector,
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Font Icon Color Style.
$this->generate_styles(
array(
'base_attr_name' => 'icon_color',
'selector' => $this->icon_element_selector,
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'hover_selector' => $icon_hover_selector,
)
);
// Font Icon Size Style.
$this->generate_styles(
array(
'base_attr_name' => 'icon_width',
'selector' => $this->icon_element_selector,
'css_property' => 'font-size',
'render_slug' => $render_slug,
'type' => 'range',
'hover_selector' => $icon_hover_selector,
)
);
$output = $multi_view->render_element(
array(
'content' => '{{font_icon}}',
'attrs' => array(
'class' => $this->icon_element_classname,
),
'hover_selector' => $this->icon_element_selector,
)
);
$box_shadow_overlay_wrap_class = 'none' !== $box_shadow_style
? 'has-box-shadow-overlay'
: '';
$box_shadow_overlay_element = 'none' !== $box_shadow_style
? '<div class="box-shadow-overlay"></div>'
: '';
$output = sprintf(
'<span class="et_pb_icon_wrap %1$s">%2$s%3$s</span>',
$box_shadow_overlay_wrap_class,
$box_shadow_overlay_element,
$output
);
$title_text = ! empty( $title_text ) ? sprintf( 'title="%1$s"', esc_attr( $title_text ) ) : '';
if ( '' !== $url ) {
$output = sprintf(
'<a href="%1$s"%3$s %4$s>%2$s</a>',
esc_url( $url ),
$output,
( 'on' === $url_new_window ? ' target="_blank"' : '' ),
$title_text
);
}
// Module classnames.
if ( ! in_array( $animation_style, array( '', 'none' ), true ) ) {
$this->add_classname( 'et-waypoint' );
}
$output = sprintf(
'<div%3$s class="%2$s">
%1$s
</div>',
$output,
$this->module_classname( $render_slug ),
$this->module_id()
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
if ( $raw_value && 'font_icon' === $name ) {
return et_pb_get_extended_font_icon_value( $raw_value, true );
}
return $raw_value;
}
/**
* Transition fields for Icon module.
*
* @since ?
*
* @return array Fields list in array.
*/
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['icon_color'] = array( 'color' => $this->icon_element_selector );
return $fields;
}
}
new ET_Builder_Module_Icon();

View File

@ -0,0 +1,593 @@
<?php
class ET_Builder_Module_Image extends ET_Builder_Module {
function init() {
$this->name = et_builder_i18n( 'Image' );
$this->plural = esc_html__( 'Images', 'et_builder' );
$this->slug = 'et_pb_image';
$this->vb_support = 'on';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Image' ),
'link' => et_builder_i18n( 'Link' ),
),
),
'advanced' => array(
'toggles' => array(
'overlay' => et_builder_i18n( 'Overlay' ),
'alignment' => esc_html__( 'Alignment', 'et_builder' ),
'width' => array(
'title' => et_builder_i18n( 'Sizing' ),
'priority' => 65,
),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
'attributes' => array(
'title' => esc_html__( 'Attributes', 'et_builder' ),
'priority' => 95,
),
),
),
);
$this->advanced_fields = array(
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ),
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_image_wrap',
'border_styles' => '%%order_class%% .et_pb_image_wrap',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_image_wrap',
'overlay' => 'inset',
),
),
),
'max_width' => array(
'options' => array(
'width' => array(
'depends_show_if' => 'off',
),
'max_width' => array(
'depends_show_if' => 'off',
),
),
),
'height' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_image_wrap img',
),
),
'fonts' => false,
'text' => false,
'button' => false,
'link_options' => false,
);
$this->help_videos = array(
array(
'id' => 'cYwqxoHnjNA',
'name' => esc_html__( 'An introduction to the Image module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'src' => array(
'label' => et_builder_i18n( 'Image' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'hide_metadata' => true,
'affects' => array(
'alt',
'title_text',
),
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'alt' => array(
'label' => esc_html__( 'Image Alternative Text', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'on',
'depends_on' => array(
'src',
),
'description' => esc_html__( 'This defines the HTML ALT text. A short description of your image can be placed here.', 'et_builder' ),
'tab_slug' => 'custom_css',
'toggle_slug' => 'attributes',
'dynamic_content' => 'text',
),
'title_text' => array(
'label' => esc_html__( 'Image Title Text', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'on',
'depends_on' => array(
'src',
),
'description' => esc_html__( 'This defines the HTML Title text.', 'et_builder' ),
'tab_slug' => 'custom_css',
'toggle_slug' => 'attributes',
'dynamic_content' => 'text',
),
'show_in_lightbox' => array(
'label' => esc_html__( 'Open in Lightbox', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'url',
'url_new_window',
),
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not the image should open in Lightbox. Note: if you select to open the image in Lightbox, url options below will be ignored.', 'et_builder' ),
),
'url' => array(
'label' => esc_html__( 'Image Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'depends_show_if' => 'off',
'description' => esc_html__( 'If you would like your image to be a link, input your destination URL here. No link will be created if this field is left blank.', 'et_builder' ),
'toggle_slug' => 'link',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Image Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'default_on_front' => 'off',
'depends_show_if' => 'off',
'toggle_slug' => 'link',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
),
'use_overlay' => array(
'label' => esc_html__( 'Image Overlay', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'Off' ),
'on' => et_builder_i18n( 'On' ),
),
'default_on_front' => 'off',
'affects' => array(
'overlay_icon_color',
'hover_overlay_color',
'hover_icon',
),
'show_if' => array(
'function.showImageUseOverlayField' => 'on',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'If enabled, an overlay color and icon will be displayed when a visitors hovers over the image', 'et_builder' ),
),
'overlay_icon_color' => array(
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom color for the overlay icon', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Hover Overlay Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Hover Icon Picker', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
),
'show_bottom_space' => array(
'label' => esc_html__( 'Show Space Below The Image', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'margin_padding',
'description' => esc_html__( 'Here you can choose whether or not the image should have a space below it.', 'et_builder' ),
'mobile_options' => true,
),
'align' => array(
'label' => esc_html__( 'Image Alignment', 'et_builder' ),
'type' => 'text_align',
'option_category' => 'layout',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'default_on_front' => 'left',
'tab_slug' => 'advanced',
'toggle_slug' => 'alignment',
'description' => esc_html__( 'Here you can choose the image alignment.', 'et_builder' ),
'options_icon' => 'module_align',
'mobile_options' => true,
),
'force_fullwidth' => array(
'label' => esc_html__( 'Force Fullwidth', 'et_builder' ),
'description' => esc_html__( "When enabled, this will force your image to extend 100% of the width of the column it's in.", 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'affects' => array(
'max_width',
'width',
),
),
);
return $fields;
}
public function get_alignment( $device = 'desktop' ) {
$is_desktop = 'desktop' === $device;
$suffix = ! $is_desktop ? "_{$device}" : '';
$alignment = $is_desktop && isset( $this->props['align'] ) ? $this->props['align'] : '';
if ( ! $is_desktop && et_pb_responsive_options()->is_responsive_enabled( $this->props, 'align' ) ) {
$alignment = et_pb_responsive_options()->get_any_value( $this->props, "align{$suffix}" );
}
return et_pb_get_alignment( $alignment );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$src = $this->props['src'];
$alt = $this->props['alt'];
$title_text = $this->props['title_text'];
$url = $this->props['url'];
$url_new_window = $this->props['url_new_window'];
$show_in_lightbox = $this->props['show_in_lightbox'];
$align = $this->get_alignment();
$align_tablet = $this->get_alignment( 'tablet' );
$align_phone = $this->get_alignment( 'phone' );
$force_fullwidth = $this->props['force_fullwidth'];
$hover_icon = $this->props['hover_icon'];
$hover_icon_tablet = $this->props['hover_icon_tablet'];
$hover_icon_phone = $this->props['hover_icon_phone'];
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
$use_overlay = $this->props['use_overlay'];
$animation_style = $this->props['animation_style'];
$box_shadow_style = self::$_->array_get( $this->props, 'box_shadow_style', '' );
$width = $this->props['width'];
$height = $this->props['height'];
$max_height = $this->props['max_height'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$show_bottom_space = $this->props['show_bottom_space'];
$show_bottom_space_values = et_pb_responsive_options()->get_property_values( $this->props, 'show_bottom_space' );
$show_bottom_space_tablet = isset( $show_bottom_space_values['tablet'] ) ? $show_bottom_space_values['tablet'] : '';
$show_bottom_space_phone = isset( $show_bottom_space_values['phone'] ) ? $show_bottom_space_values['phone'] : '';
// Handle svg image behaviour
$src_pathinfo = pathinfo( $src );
$is_src_svg = isset( $src_pathinfo['extension'] ) ? 'svg' === $src_pathinfo['extension'] : false;
// overlay can be applied only if image has link or if lightbox enabled
$is_overlay_applied = 'on' === $use_overlay && ( 'on' === $show_in_lightbox || ( 'off' === $show_in_lightbox && '' !== $url ) ) ? 'on' : 'off';
if ( 'on' === $force_fullwidth ) {
$el_style = array(
'selector' => '%%order_class%%',
'declaration' => 'width: 100%; max-width: 100% !important;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
$el_style = array(
'selector' => '%%order_class%% .et_pb_image_wrap, %%order_class%% img',
'declaration' => 'width: 100%;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
// Responsive Image Alignment.
// Set CSS properties and values for the image alignment.
// 1. Text Align is necessary, just set it from current image alignment value.
// 2. Margin {Side} is optional. Used to pull the image to right/left side.
// 3. Margin Left and Right are optional. Used by Center to reset custom margin of point 2.
$align_values = array(
'desktop' => array(
'text-align' => esc_html( $align ),
"margin-{$align}" => ! empty( $align ) && 'center' !== $align ? '0' : '',
),
);
if ( ! empty( $align_tablet ) ) {
$align_values['tablet'] = array(
'text-align' => esc_html( $align_tablet ),
'margin-left' => 'left' !== $align_tablet ? 'auto' : '',
'margin-right' => 'left' !== $align_tablet ? 'auto' : '',
"margin-{$align_tablet}" => ! empty( $align_tablet ) && 'center' !== $align_tablet ? '0' : '',
);
}
if ( ! empty( $align_phone ) ) {
$align_values['phone'] = array(
'text-align' => esc_html( $align_phone ),
'margin-left' => 'left' !== $align_phone ? 'auto' : '',
'margin-right' => 'left' !== $align_phone ? 'auto' : '',
"margin-{$align_phone}" => ! empty( $align_phone ) && 'center' !== $align_phone ? '0' : '',
);
}
et_pb_responsive_options()->generate_responsive_css( $align_values, '%%order_class%%', '', $render_slug, '', 'alignment' );
// Load up Dynamic Content (if needed) to capture Featured Image objects.
// In this way we can process `alt` and `title` attributes defined in
// the WP Media Library when they haven't been specified by the user in
// Module Settings.
if ( empty( $alt ) || empty( $title_text ) ) {
$raw_src = et_()->array_get( $this->attrs_unprocessed, 'src' );
$src_value = et_builder_parse_dynamic_content( $raw_src );
if ( $src_value->is_dynamic() && $src_value->get_content() === 'post_featured_image' ) {
// If there is no user-specified ALT attribute text, check the WP
// Media Library entry for text that may have been added there.
if ( empty( $alt ) ) {
$alt = et_builder_resolve_dynamic_content( 'post_featured_image_alt_text', array(), get_the_ID(), 'display' );
}
// If there is no user-specified TITLE attribute text, check the WP
// Media Library entry for text that may have been added there.
if ( empty( $title_text ) ) {
$title_text = et_builder_resolve_dynamic_content( 'post_featured_image_title_text', array(), get_the_ID(), 'display' );
}
}
}
if ( 'on' === $is_overlay_applied ) {
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'overlay_icon_color',
'selector' => '%%order_class%% .et_overlay:before',
'css_property' => 'color',
'render_slug' => $render_slug,
'important' => true,
'type' => 'color',
)
);
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => '%%order_class%% .et_overlay',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
$overlay_output = ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_tablet' => $hover_icon_tablet,
'icon_phone' => $hover_icon_phone,
'icon_sticky' => $hover_icon_sticky,
)
);
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => '%%order_class%% .et_overlay:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
}
// Set display block for svg image to avoid disappearing svg image
if ( $is_src_svg ) {
$el_style = array(
'selector' => '%%order_class%% .et_pb_image_wrap',
'declaration' => 'display: block;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
$box_shadow_overlay_wrap_class = 'none' !== $box_shadow_style
? 'has-box-shadow-overlay'
: '';
$box_shadow_overlay_element = 'none' !== $box_shadow_style
? '<div class="box-shadow-overlay"></div>'
: '';
$image_attrs = array(
'src' => '{{src}}',
'alt' => esc_attr( $alt ),
'title' => esc_attr( $title_text ),
);
// Only if force fullwidth is not set.
if ( 'on' !== $force_fullwidth ) {
// Only height or max-height is set, no width set.
if ( 'auto' === $width && 'auto' !== $height || 'none' !== $max_height ) {
$el_style = array(
'selector' => '%%order_class%% .et_pb_image_wrap img',
'declaration' => 'width: auto;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
}
$image_attachment_class = et_pb_media_options()->get_image_attachment_class( $this->props, 'src' );
if ( ! empty( $image_attachment_class ) ) {
$image_attrs['class'] = esc_attr( $image_attachment_class );
}
$image_html = $multi_view->render_element(
array(
'tag' => 'img',
'attrs' => $image_attrs,
'required' => 'src',
)
);
$output = sprintf(
'<span class="et_pb_image_wrap %3$s">%4$s%1$s%2$s</span>',
$image_html,
'on' === $is_overlay_applied ? $overlay_output : '',
$box_shadow_overlay_wrap_class,
$box_shadow_overlay_element
);
if ( 'on' === $show_in_lightbox ) {
$output = sprintf(
'<a href="%1$s" class="et_pb_lightbox_image" title="%3$s">%2$s</a>',
esc_attr( $src ),
$output,
esc_attr( $alt )
);
} elseif ( '' !== $url ) {
$output = sprintf(
'<a href="%1$s"%3$s>%2$s</a>',
esc_url( $url ),
$output,
( 'on' === $url_new_window ? ' target="_blank"' : '' )
);
}
// Module classnames
if ( ! in_array( $animation_style, array( '', 'none' ) ) ) {
$this->add_classname( 'et-waypoint' );
}
if ( 'on' !== $show_bottom_space ) {
$this->add_classname( 'et_pb_image_sticky' );
}
if ( ! empty( $show_bottom_space_tablet ) ) {
if ( 'on' === $show_bottom_space_tablet ) {
$this->add_classname( 'et_pb_image_bottom_space_tablet' );
} elseif ( 'off' === $show_bottom_space_tablet ) {
$this->add_classname( 'et_pb_image_sticky_tablet' );
}
}
if ( ! empty( $show_bottom_space_phone ) ) {
if ( 'on' === $show_bottom_space_phone ) {
$this->add_classname( 'et_pb_image_bottom_space_phone' );
} elseif ( 'off' === $show_bottom_space_phone ) {
$this->add_classname( 'et_pb_image_sticky_phone' );
}
}
if ( 'on' === $is_overlay_applied ) {
$this->add_classname( 'et_pb_has_overlay' );
}
$output = sprintf(
'<div%3$s class="%2$s">
%5$s
%4$s
%1$s
</div>',
$output,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background
);
return $output;
}
}
// This adds the upload label for Image module
// TODO: Remove when BB is removed.
function _et_bb_module_image_add_src_label( $filed ) {
if ( ! isset( $filed['label'] ) ) {
$filed['label'] = esc_html__( 'Image URL', 'et_builder' );
}
return $filed;
}
add_filter( 'et_builder_module_fields_et_pb_image_field_src', '_et_bb_module_image_add_src_label' );
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Image();
}

View File

@ -0,0 +1,491 @@
<?php
class ET_Builder_Module_Login extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Login', 'et_builder' );
$this->plural = esc_html__( 'Logins', 'et_builder' );
$this->slug = 'et_pb_login';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_login';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'redirect' => esc_html__( 'Redirect', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h2, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
'important' => 'all',
),
'header_level' => array(
'default' => 'h2',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'line_height' => "{$this->main_css_element} p",
'font' => "{$this->main_css_element}, {$this->main_css_element} .et_pb_newsletter_description_content, {$this->main_css_element} p, {$this->main_css_element} span",
'text_shadow' => "{$this->main_css_element}, {$this->main_css_element} .et_pb_newsletter_description_content, {$this->main_css_element} p, {$this->main_css_element} span",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
'css' => array(
'main' => "{$this->main_css_element}",
),
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_newsletter_button.et_pb_button",
'limited_main' => "{$this->main_css_element} .et_pb_newsletter_button.et_pb_button",
),
'no_rel_attr' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'background' => array(
'has_background_color_toggle' => true,
'use_background_color' => true,
'options' => array(
'background_color' => array(
'depends_show_if' => 'on',
'default' => et_builder_accent_color(),
),
'use_background_color' => array(
'default' => 'on',
),
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
'background_layout' => array(
'default' => 'dark',
'hover' => 'tabs',
),
),
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .et_pb_module_header',
'%%order_class%% .et_pb_newsletter_description_content',
'%%order_class%% .et_pb_forgot_password a',
)
),
),
),
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Fields', 'et_builder' ),
'css' => array(
'main' => '%%order_class%% input[type="password"], %%order_class%% input[type="text"], %%order_class%% textarea, %%order_class%% .input',
'hover' => '%%order_class%% input[type="text"]:hover, %%order_class%% textarea:hover, %%order_class%% .input:hover',
'focus' => '%%order_class%% .et_pb_newsletter_form p input:focus',
'focus_hover' => '%%order_class%% .et_pb_newsletter_form p input:focus:hover',
'placeholder_focus' => '%%order_class%% .et_pb_newsletter_form p input:focus::-webkit-input-placeholder, %%order_class%% .et_pb_newsletter_form p input:focus::-moz-placeholder, %%order_class%% .et_pb_newsletter_form p input:focus:-ms-input-placeholder',
'padding' => '%%order_class%% .et_pb_newsletter_form .input',
'margin' => '%%order_class%% .et_pb_newsletter_form .et_pb_contact_form_field',
'important' => array( 'padding', 'margin' ),
),
'box_shadow' => array(
'name' => 'fields',
'css' => array(
'main' => '%%order_class%% .et_pb_newsletter_form .input',
),
),
'border_styles' => array(
'form_field' => array(
'name' => 'fields',
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_newsletter_form p input',
'border_styles' => '%%order_class%% .et_pb_newsletter_form p input',
),
),
'label_prefix' => esc_html__( 'Fields', 'et_builder' ),
),
'form_field_focus' => array(
'name' => 'fields_focus',
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_newsletter_form p input:focus',
'border_styles' => '%%order_class%% .et_pb_newsletter_form p input:focus',
),
),
'label_prefix' => esc_html__( 'Fields Focus', 'et_builder' ),
),
),
'font_field' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_newsletter_form .input',
'hover' => '%%order_class%% .et_pb_newsletter_form .input:hover',
'text_shadow' => "{$this->main_css_element} input",
'important' => 'plugin_only',
),
),
),
),
);
$this->custom_css_fields = array(
'newsletter_title' => array(
'label' => esc_html__( 'Login Title', 'et_builder' ),
'selector' => "{$this->main_css_element} h2, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
),
'newsletter_description' => array(
'label' => esc_html__( 'Login Description', 'et_builder' ),
'selector' => '.et_pb_newsletter_description',
),
'newsletter_form' => array(
'label' => esc_html__( 'Login Form', 'et_builder' ),
'selector' => '.et_pb_newsletter_form',
),
'newsletter_fields' => array(
'label' => esc_html__( 'Login Fields', 'et_builder' ),
'selector' => '.et_pb_newsletter_form input',
),
'newsletter_button' => array(
'label' => esc_html__( 'Login Button', 'et_builder' ),
'selector' => '.et_pb_login .et_pb_login_form .et_pb_newsletter_button.et_pb_button',
'no_space_before_selector' => true,
),
);
$this->help_videos = array(
array(
'id' => '6ZEw-Izfjg8',
'name' => esc_html__( 'An introduction to the Login module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Choose a title of your login box.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'current_page_redirect' => array(
'label' => esc_html__( 'Redirect To The Current Page', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'toggle_slug' => 'redirect',
'description' => esc_html__( 'Here you can choose whether the user should be redirected back to the current page after logging in.', 'et_builder' ),
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the main text content for your module here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
return parent::get_transition_fields_css_props();
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$module_id = $this->props['module_id'];
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['header_level'], 'h2' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_module_header',
),
)
);
$background_color = $this->props['background_color'];
$use_background_color = $this->props['use_background_color'];
$current_page_redirect = $this->props['current_page_redirect'];
$button_custom = $this->props['custom_button'];
$header_level = $this->props['header_level'];
$content = $this->content;
$use_focus_border_color = $this->props['use_focus_border_color'];
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$redirect_url = 'on' === $current_page_redirect
? ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']
: '';
if ( is_user_logged_in() && ! is_customize_preview() && ! is_et_pb_preview() ) {
$current_user = wp_get_current_user();
$content .= sprintf(
'<br/>%1$s <a href="%2$s">%3$s</a>',
sprintf( esc_html__( 'Logged in as %1$s', 'et_builder' ), esc_html( $current_user->display_name ) ),
esc_url( wp_logout_url( $redirect_url ) ),
esc_html__( 'Log out', 'et_builder' )
);
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$form = '';
if ( ! is_user_logged_in() || is_customize_preview() || is_et_pb_preview() ) {
$username = esc_html__( 'Username', 'et_builder' );
$password = esc_html__( 'Password', 'et_builder' );
$form = sprintf(
'
<div class="et_pb_newsletter_form et_pb_login_form">
<form action="%7$s" method="post">
<p class="et_pb_contact_form_field">
<label class="et_pb_contact_form_label" for="user_login_%11$s" style="display: none;">%3$s</label>
<input id="user_login_%11$s" placeholder="%4$s" class="input" type="text" value="" name="log" />
</p>
<p class="et_pb_contact_form_field">
<label class="et_pb_contact_form_label" for="user_pass_%11$s" style="display: none;">%5$s</label>
<input id="user_pass_%11$s" placeholder="%6$s" class="input" type="password" value="" name="pwd" />
</p>
<p class="et_pb_forgot_password"><a href="%2$s">%1$s</a></p>
<p>
<button type="submit" name="et_builder_submit_button" class="et_pb_newsletter_button et_pb_button"%10$s%12$s%13$s>%8$s</button>
%9$s
</p>
</form>
</div>',
esc_html__( 'Forgot your password?', 'et_builder' ),
esc_url( wp_lostpassword_url() ),
esc_html( $username ),
esc_attr( $username ),
esc_html( $password ), // #5
esc_attr( $password ),
esc_url( site_url( 'wp-login.php', 'login_post' ) ),
esc_html__( 'Login', 'et_builder' ),
( 'on' === $current_page_redirect
? sprintf( '<input type="hidden" name="redirect_to" value="%1$s" />', esc_url( $redirect_url ) )
: ''
),
'' !== $custom_icon && 'on' === $button_custom ? sprintf(
' data-icon="%1$s"',
esc_attr( et_pb_process_font_icon( $custom_icon ) )
) : '', // #10
// Prevent an accidental "duplicate ID" error if there's more than one instance of this module
( '' !== $module_id ? esc_attr( $module_id ) : uniqid() ),
'' !== $custom_icon_tablet && 'on' === $button_custom ? sprintf( ' data-icon-tablet="%1$s"', esc_attr( et_pb_process_font_icon( $custom_icon_tablet ) ) ) : '',
'' !== $custom_icon_phone && 'on' === $button_custom ? sprintf( ' data-icon-phone="%1$s"', esc_attr( et_pb_process_font_icon( $custom_icon_phone ) ) ) : ''
);
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
// Module classnames
$this->add_classname(
array(
'et_pb_newsletter',
'clearfix',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( is_customize_preview() || is_et_pb_preview() ) {
$this->add_classname( 'et_pb_in_customizer' );
}
if ( 'on' === $use_focus_border_color ) {
$this->add_classname( 'et_pb_with_focus_border' );
}
if ( ! $multi_view->has_value( 'title' ) ) {
$this->add_classname( 'et_pb_newsletter_description_no_title' );
}
if ( ! $multi_view->has_value( 'content' ) ) {
$this->add_classname( 'et_pb_newsletter_description_no_content' );
}
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
'required' => false,
'attrs' => array(
'class' => 'et_pb_newsletter_description_content',
),
)
);
$content_wrapper = $multi_view->render_element(
array(
'tag' => 'div',
'content' => "{$title}{$content}",
'attrs' => array(
'class' => 'et_pb_newsletter_description',
),
'classes' => array(
'et_multi_view_hidden' => array(
'title' => '__empty',
'content' => '__empty',
),
),
)
);
$wrapper_multi_view_classes = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_newsletter_description_no_title' => array(
'title' => '__empty',
),
'et_pb_newsletter_description_no_content' => array(
'content' => '__empty',
),
),
)
);
$output = sprintf(
'<div%4$s class="%2$s"%7$s%7$s>
%6$s
%5$s
%3$s
%1$s
</div>',
$form,
$this->module_classname( $render_slug ),
et_core_esc_previously( $content_wrapper ),
$this->module_id(),
$video_background, // #5
$parallax_image_background,
et_core_esc_previously( $data_background_layout ),
$wrapper_multi_view_classes
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
if ( is_user_logged_in() && ! is_customize_preview() && ! is_et_pb_preview() && 'content' === $name ) {
$current_user = wp_get_current_user();
$redirect_url = 'on' === $this->props['current_page_redirect']
? ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']
: '';
$raw_value .= sprintf(
'%4$s%1$s <a href="%2$s">%3$s</a>',
sprintf( esc_html__( 'Logged in as %1$s', 'et_builder' ), esc_html( $current_user->display_name ) ),
esc_url( wp_logout_url( esc_url( $redirect_url ) ) ),
esc_html__( 'Log out', 'et_builder' ),
'' === $raw_value && ! $multi_view->has_value( 'title' ) ? '' : '<br/>'
);
}
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Login();
}

View File

@ -0,0 +1,309 @@
<?php
class ET_Builder_Module_Map extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Map', 'et_builder' );
$this->plural = esc_html__( 'Maps', 'et_builder' );
$this->slug = 'et_pb_map';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_map_pin';
$this->child_item_text = esc_html__( 'Pin', 'et_builder' );
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'map' => esc_html__( 'Map', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'controls' => esc_html__( 'Controls', 'et_builder' ),
'child_filters' => array(
'title' => esc_html__( 'Map', 'et_builder' ),
'priority' => 51,
),
),
),
);
$this->advanced_fields = array(
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'label' => esc_html__( 'Map', 'et_builder' ),
),
),
'child_filters' => array(
'css' => array(
'main' => '%%order_class%% .gm-style>div>div>div>div>div>img',
),
),
'height' => array(
'css' => array(
'main' => '%%order_class%% > .et_pb_map',
),
'options' => array(
'height' => array(
'default' => '440px',
'default_tablet' => '350px',
'default_phone' => '200px',
),
),
),
'fonts' => false,
'text' => false,
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => 'rV3rxmACDmw',
'name' => esc_html__( 'An introduction to the Map module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'google_maps_script_notice' => array(
'type' => 'warning',
'value' => et_pb_enqueue_google_maps_script(),
'display_if' => false,
'message' => esc_html__(
sprintf(
'The Google Maps API Script is currently disabled in the <a href="%s" target="_blank">Theme Options</a>. This module will not function properly without the Google Maps API.',
admin_url( 'admin.php?page=et_divi_options' )
),
'et_builder'
),
'toggle_slug' => 'map',
),
'google_api_key' => array(
'label' => esc_html__( 'Google API Key', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'attributes' => 'readonly',
'additional_button' => sprintf(
' <a href="%2$s" target="_blank" class="et_pb_update_google_key button" data-empty_text="%3$s">%1$s</a>',
esc_html__( 'Change API Key', 'et_builder' ),
esc_url( et_pb_get_options_page_link() ),
esc_attr__( 'Add Your API Key', 'et_builder' )
),
'additional_button_type' => 'change_google_api_key',
'class' => array( 'et_pb_google_api_key', 'et-pb-helper-field' ),
'description' => et_get_safe_localization( sprintf( __( 'The Maps module uses the Google Maps API and requires a valid Google API Key to function. Before using the map module, please make sure you have added your API key inside the Divi Theme Options panel. Learn more about how to create your Google API Key <a href="%1$s" target="_blank">here</a>.', 'et_builder' ), esc_url( 'http://www.elegantthemes.com/gallery/divi/documentation/map/#gmaps-api-key' ) ) ),
'toggle_slug' => 'map',
),
'address' => array(
'label' => esc_html__( 'Map Center Address', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'additional_button' => sprintf(
' <a href="#" class="et_pb_find_address button">%1$s</a>',
esc_html__( 'Find', 'et_builder' )
),
'class' => array( 'et_pb_address' ),
'description' => esc_html__( 'Enter an address for the map center point, and the address will be geocoded and displayed on the map below.', 'et_builder' ),
'toggle_slug' => 'map',
),
'zoom_level' => array(
'type' => 'hidden',
'class' => array( 'et_pb_zoom_level' ),
'default' => '18',
),
'address_lat' => array(
'type' => 'hidden',
'class' => array( 'et_pb_address_lat' ),
),
'address_lng' => array(
'type' => 'hidden',
'class' => array( 'et_pb_address_lng' ),
),
'map_center_map' => array(
'type' => 'center_map',
'use_container_wrapper' => false,
'option_category' => 'basic_option',
'toggle_slug' => 'map',
),
'mouse_wheel' => array(
'label' => esc_html__( 'Mouse Wheel Zoom', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'controls',
'description' => esc_html__( 'Here you can choose whether the zoom level will be controlled by mouse wheel or not.', 'et_builder' ),
'default_on_front' => 'on',
),
'mobile_dragging' => array(
'label' => esc_html__( 'Draggable On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'controls',
'description' => esc_html__( 'Here you can choose whether or not the map will be draggable on mobile devices.', 'et_builder' ),
'default_on_front' => 'on',
),
'use_grayscale_filter' => array(
'label' => esc_html__( 'Use Grayscale Filter', 'et_builder' ),
'description' => esc_html__( 'Applying the grayscale filter will change the map colors to black and white.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'affects' => array(
'grayscale_filter_amount',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'default_on_front' => 'off',
),
'grayscale_filter_amount' => array(
'label' => esc_html__( 'Grayscale Filter Amount (%)', 'et_builder' ),
'description' => esc_html__( 'Adjusting the grayscale filter will allow you to change the color saturation of the map.', 'et_builder' ),
'type' => 'range',
'default' => '0',
'option_category' => 'configuration',
'tab_slug' => 'advanced',
'toggle_slug' => 'child_filters',
'depends_show_if' => 'on',
'unitless' => false,
'mobile_options' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$filters = $this->get_transition_filters_fields_css_props( 'child_filters' );
return array_merge( $fields, $filters );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$address_lat = $this->props['address_lat'];
$address_lng = $this->props['address_lng'];
$zoom_level = $this->props['zoom_level'];
$mouse_wheel = $this->props['mouse_wheel'];
$mobile_dragging = $this->props['mobile_dragging'];
$use_grayscale_filter = $this->props['use_grayscale_filter'];
// Grayscale Filter.
$grayscale_filter_amount_values = et_pb_responsive_options()->get_property_values( $this->props, 'grayscale_filter_amount' );
$grayscale_filter_amount = isset( $grayscale_filter_amount_values['desktop'] ) ? $grayscale_filter_amount_values['desktop'] : '';
$grayscale_filter_amount_tablet = isset( $grayscale_filter_amount_values['tablet'] ) ? $grayscale_filter_amount_values['tablet'] : '';
$grayscale_filter_amount_phone = isset( $grayscale_filter_amount_values['phone'] ) ? $grayscale_filter_amount_values['phone'] : '';
if ( et_pb_enqueue_google_maps_script() ) {
wp_enqueue_script( 'google-maps-api' );
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$all_pins_content = $this->content;
$grayscale_filter_data = '';
$grayscale_filter_data_tablet = '';
$grayscale_filter_data_phone = '';
if ( 'on' === $use_grayscale_filter ) {
if ( '' !== $grayscale_filter_amount ) {
$grayscale_filter_data = sprintf( ' data-grayscale="%1$s"', esc_attr( $grayscale_filter_amount ) );
}
if ( '' !== $grayscale_filter_amount_tablet ) {
$grayscale_filter_data_tablet = sprintf( ' data-grayscale-tablet="%1$s"', esc_attr( $grayscale_filter_amount_tablet ) );
}
if ( '' !== $grayscale_filter_amount_phone ) {
$grayscale_filter_data_phone = sprintf( ' data-grayscale-phone="%1$s"', esc_attr( $grayscale_filter_amount_phone ) );
}
}
// Map Tiles: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'child_filters', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['child_filters'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['child_filters']['css'], 'main', '%%order_class%%' )
)
);
}
// Module classnames
$this->add_classname(
array(
'et_pb_map_container',
)
);
$this->remove_classname( $render_slug );
$output = sprintf(
'<div%5$s class="%6$s"%8$s%12$s%13$s>
%11$s
%10$s
<div class="et_pb_map" data-center-lat="%1$s" data-center-lng="%2$s" data-zoom="%3$d" data-mouse-wheel="%7$s" data-mobile-dragging="%9$s"></div>
%4$s
</div>',
esc_attr( et_()->to_css_decimal( $address_lat ) ),
esc_attr( et_()->to_css_decimal( $address_lng ) ),
esc_attr( $zoom_level ),
$all_pins_content,
$this->module_id(), // #5
$this->module_classname( $render_slug ),
esc_attr( $mouse_wheel ),
$grayscale_filter_data,
esc_attr( $mobile_dragging ),
$video_background, // #10
$parallax_image_background,
$grayscale_filter_data_tablet,
$grayscale_filter_data_phone
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Map();
}

View File

@ -0,0 +1,200 @@
<?php
class ET_Builder_Module_Map_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Pin', 'et_builder' );
$this->plural = esc_html__( 'Pins', 'et_builder' );
$this->slug = 'et_pb_map_pin';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'title';
$this->custom_css_tab = false;
$this->advanced_setting_title_text = esc_html__( 'New Pin', 'et_builder' );
$this->settings_text = esc_html__( 'Pin Settings', 'et_builder' );
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'map' => esc_html__( 'Map', 'et_builder' ),
),
),
);
$this->advanced_fields = false;
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'The title will be used within the tab button for this tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'pin_address' => array(
'label' => esc_html__( 'Map Pin Address', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'class' => array( 'et_pb_pin_address' ),
'description' => esc_html__( 'Enter an address for this map pin, and the address will be geocoded and displayed on the map below.', 'et_builder' ),
'additional_button' => sprintf(
'<a href="#" class="et_pb_find_address button">%1$s</a>',
esc_html__( 'Find', 'et_builder' )
),
'toggle_slug' => 'map',
),
'zoom_level' => array(
'type' => 'hidden',
'class' => array( 'et_pb_zoom_level' ),
'default' => '18',
'default_on_front' => '',
'option_category' => 'basic_option',
),
'pin_address_lat' => array(
'type' => 'hidden',
'class' => array( 'et_pb_pin_address_lat' ),
'option_category' => 'basic_option',
),
'pin_address_lng' => array(
'type' => 'hidden',
'class' => array( 'et_pb_pin_address_lng' ),
'option_category' => 'basic_option',
),
'map_center_map' => array(
'type' => 'center_map',
'option_category' => 'basic_option',
'use_container_wrapper' => false,
'toggle_slug' => 'map',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Here you can define the content that will be placed within the infobox for the pin.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_tab_titles;
$multi_view = et_pb_multi_view_options( $this );
$title = $multi_view->render_element(
array(
'tag' => 'h3',
'content' => '{{title}}',
'styles' => array(
'margin-top' => '10px',
),
)
);
$pin_address_lat = $this->props['pin_address_lat'];
$pin_address_lng = $this->props['pin_address_lng'];
$replace_htmlentities = array(
'&#8221;' => '',
'&#8243;' => '',
);
if ( ! empty( $pin_address_lat ) ) {
$pin_address_lat = strtr( $pin_address_lat, $replace_htmlentities );
}
if ( ! empty( $pin_address_lng ) ) {
$pin_address_lng = strtr( $pin_address_lng, $replace_htmlentities );
}
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
'attrs' => array(
'class' => 'infowindow',
),
'required_some' => array( 'title', 'content' ),
)
);
$title_multi_view_data_attr = $multi_view->render_attrs(
array(
'attrs' => array(
'data-title' => '{{title}}',
),
)
);
$output = sprintf(
'<div class="et_pb_map_pin" data-lat="%1$s" data-lng="%2$s" data-title="%5$s"%6$s>
%3$s
%4$s
</div>',
esc_attr( et_()->to_css_decimal( $pin_address_lat ) ),
esc_attr( et_()->to_css_decimal( $pin_address_lng ) ),
et_core_esc_previously( $title ),
et_core_esc_previously( $content ),
esc_attr( $multi_view->get_value( 'title' ) ),
$title_multi_view_data_attr
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Map_Item();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,303 @@
<?php
class ET_Builder_Module_Number_Counter extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Number Counter', 'et_builder' );
$this->plural = esc_html__( 'Number Counters', 'et_builder' );
$this->slug = 'et_pb_number_counter';
$this->vb_support = 'on';
$this->custom_css_fields = array(
'percent' => array(
'label' => esc_html__( 'Percent', 'et_builder' ),
'selector' => '.percent',
),
'number_counter_title' => array(
'label' => esc_html__( 'Number Counter Title', 'et_builder' ),
'selector' => 'h3',
),
);
$this->main_css_element = '%%order_class%%.et_pb_number_counter';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h3, {$this->main_css_element} h1.title, {$this->main_css_element} h2.title, {$this->main_css_element} h4.title, {$this->main_css_element} h5.title, {$this->main_css_element} h6.title",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h3',
),
),
'number' => array(
'label' => esc_html__( 'Number', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .percent p",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'text_color' => array(
'old_option_ref' => 'counter_color',
'default' => et_builder_accent_color(),
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ),
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_number_counter.et_pb_module',
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'text_orientation' => array(
'default' => 'center',
),
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => '%%order_class%% .title, %%order_class%% .percent',
),
),
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
);
if ( et_builder_has_limitation( 'force_use_global_important' ) ) {
$this->advanced_fields['fonts']['number']['css']['important'] = 'all';
}
$this->help_videos = array(
array(
'id' => 'qEE6z2t2oJ8',
'name' => esc_html__( 'An introduction to the Number Counter module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input a title for the counter.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'number' => array(
'label' => esc_html__( 'Number', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'value_type' => 'float',
'description' => esc_html__( "Define a number for the counter. (Don't include the percentage sign, use the option below.)", 'et_builder' ),
'toggle_slug' => 'main_content',
'default_on_front' => '0',
'mobile_options' => true,
'hover' => 'tabs',
),
'percent_sign' => array(
'label' => esc_html__( 'Percent Sign', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'On' ),
'off' => et_builder_i18n( 'Off' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether the percent sign should be added after the number set above.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'counter_color' => array(
'type' => 'hidden',
'default' => '',
'tab_slug' => 'advanced',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$number = $this->props['number'];
$percent_sign = $this->props['percent_sign'];
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['title_level'], 'h3' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'title',
),
)
);
$counter_color = $this->props['counter_color'];
if ( et_builder_has_limitation( 'register_fittext_script' ) ) {
wp_enqueue_script( 'fittext' );
}
$separator = strpos( $number, ',' ) ? ',' : '';
$number = str_ireplace( array( '%', ',' ), '', $number );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( '' !== $title ) {
$this->add_classname( 'et_pb_with_title' );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$multi_view_data_attr = $multi_view->render_attrs(
array(
'attrs' => array(
'data-number-value' => '{{number}}',
'data-number-separator' => '{{number}}',
'data-percent-sign' => '{{percent_sign}}',
),
'classes' => array(
'et_pb_with_title' => array(
'title' => '__not_empty',
),
),
)
);
$output = sprintf(
'<div%1$s class="%2$s" data-number-value="%3$s" data-number-separator="%7$s"%10$s>
%9$s
%8$s
<div class="percent" %4$s%11$s><p><span class="percent-value"></span><span class="percent-sign">%5$s</span></p></div>
%6$s
</div>',
$this->module_id(),
$this->module_classname( $render_slug ),
esc_attr( $number ),
( '' !== $counter_color ? sprintf( ' style="color:%s"', esc_attr( $counter_color ) ) : '' ),
( 'on' == $multi_view->get_value( 'percent_sign' ) ? '%' : '' ), // #5
$title,
esc_attr( $separator ),
$video_background,
$parallax_image_background,
et_core_esc_previously( $data_background_layout ), // #10
$multi_view_data_attr
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$attr_key = isset( $args['attr_key'] ) ? $args['attr_key'] : '';
if ( 'number' === $name ) {
if ( 'data-number-separator' === $attr_key ) {
return strpos( $raw_value, ',' ) ? ',' : '';
}
return str_replace( '%', '', $raw_value );
} elseif ( 'percent_sign' === $name ) {
return 'on' === $raw_value ? '%' : '&nbsp;';
}
$fields_need_escape = array(
'title',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Number_Counter();
}

View File

@ -0,0 +1,878 @@
<?php
class ET_Builder_Module_Portfolio extends ET_Builder_Module_Type_PostBased {
function init() {
$this->name = esc_html__( 'Portfolio', 'et_builder' );
$this->plural = esc_html__( 'Portfolios', 'et_builder' );
$this->slug = 'et_pb_portfolio';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%% .et_pb_portfolio_item';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Content' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'overlay' => et_builder_i18n( 'Overlay' ),
'image' => array(
'title' => et_builder_i18n( 'Image' ),
),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h2, {$this->main_css_element} h2 a, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h1.et_pb_module_header a, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header a, {$this->main_css_element} h4.et_pb_module_header, {$this->main_css_element} h4.et_pb_module_header a, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header a, {$this->main_css_element} h6.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header a",
'important' => 'all',
'hover' => "{$this->main_css_element} h2:hover, {$this->main_css_element} h2:hover a, {$this->main_css_element} h1.et_pb_module_header:hover, {$this->main_css_element} h1.et_pb_module_header:hover a, {$this->main_css_element} h3.et_pb_module_header:hover, {$this->main_css_element} h3.et_pb_module_header:hover a, {$this->main_css_element} h4.et_pb_module_header:hover, {$this->main_css_element} h4.et_pb_module_header:hover a, {$this->main_css_element} h5.et_pb_module_header:hover, {$this->main_css_element} h5.et_pb_module_header:hover a, {$this->main_css_element} h6.et_pb_module_header:hover, {$this->main_css_element} h6.et_pb_module_header:hover a",
),
'header_level' => array(
'default' => 'h2',
),
),
'caption' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .post-meta, {$this->main_css_element} .post-meta a",
'hover' => "{$this->main_css_element} .post-meta a:hover",
),
),
'pagination' => array(
'label' => esc_html__( 'Pagination', 'et_builder' ),
'css' => array(
'main' => function_exists( 'wp_pagenavi' ) ? '%%order_class%% .wp-pagenavi a, %%order_class%% .wp-pagenavi span' : '%%order_class%% .pagination a',
'important' => function_exists( 'wp_pagenavi' ) ? 'all' : array(),
'text_align' => '%%order_class%% .wp-pagenavi',
'hover' => function_exists( 'wp_pagenavi' ) ? '%%order_class%% .wp-pagenavi a:hover, %%order_class%% .wp-pagenavi span:hover' : '%%order_class%% .pagination a:hover',
),
'hide_text_align' => ! function_exists( 'wp_pagenavi' ),
'text_align' => array(
'options' => et_builder_get_text_orientation_options( array( 'justified' ), array() ),
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => $this->main_css_element,
'border_styles' => $this->main_css_element,
),
),
),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_portfolio_image",
'border_styles' => "{$this->main_css_element} .et_portfolio_image",
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => false,
),
),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_portfolio_item .et_portfolio_image',
'overlay' => 'inset',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%%',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => '%%order_class%% .et_pb_module_header, %%order_class%% .post-meta',
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_portfolio_image',
),
),
'scroll_effects' => array(
'grid_support' => 'yes',
),
'button' => false,
);
$this->custom_css_fields = array(
'portfolio_image' => array(
'label' => esc_html__( 'Portfolio Image', 'et_builder' ),
'selector' => '.et_portfolio_image',
),
'overlay' => array(
'label' => et_builder_i18n( 'Overlay' ),
'selector' => '.et_overlay',
),
'overlay_icon' => array(
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
'selector' => '.et_overlay:before',
),
'portfolio_title' => array(
'label' => esc_html__( 'Portfolio Title', 'et_builder' ),
'selector' => '.et_pb_portfolio_item h2',
),
'portfolio_post_meta' => array(
'label' => esc_html__( 'Portfolio Post Meta', 'et_builder' ),
'selector' => '.et_pb_portfolio_item .post-meta',
),
'pagination' => array(
'label' => esc_html__( 'Portfolio Pagination', 'et_builder' ),
'selector' => function_exists( 'wp_pagenavi' ) ? '%%order_class%% .wp-pagenavi a, %%order_class%% .wp-pagenavi span' : '%%order_class%% .pagination a',
),
);
$this->help_videos = array(
array(
'id' => '6NpHdiLciDU',
'name' => esc_html__( 'An introduction to the Portfolio module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'fullwidth' => array(
'label' => et_builder_i18n( 'Layout' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'on' => esc_html__( 'Fullwidth', 'et_builder' ),
'off' => esc_html__( 'Grid', 'et_builder' ),
),
'default_on_front' => 'on',
'affects' => array(
'hover_icon',
'zoom_icon_color',
'hover_overlay_color',
),
'description' => esc_html__( 'Choose your desired portfolio layout style.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
),
'posts_number' => array(
'default' => 10,
'label' => esc_html__( 'Post Count', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'description' => esc_html__( 'Define the number of projects that should be displayed per page.', 'et_builder' ),
'computed_affects' => array(
'__projects',
),
'toggle_slug' => 'main_content',
),
'include_categories' => array(
'label' => esc_html__( 'Included Categories', 'et_builder' ),
'type' => 'categories',
'meta_categories' => array(
'all' => esc_html__( 'All Categories', 'et_builder' ),
'current' => esc_html__( 'Current Category', 'et_builder' ),
),
'option_category' => 'basic_option',
'description' => esc_html__( 'Select the categories that you would like to include in the feed.', 'et_builder' ),
'toggle_slug' => 'main_content',
'computed_affects' => array(
'__projects',
),
'taxonomy_name' => 'project_category',
),
'show_title' => array(
'label' => esc_html__( 'Show Title', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn project titles on or off.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_categories' => array(
'label' => esc_html__( 'Show Categories', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn the category links on or off.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_pagination' => array(
'label' => esc_html__( 'Show Pagination', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Enable or disable pagination for this feed.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'zoom_icon_color' => array(
'label' => esc_html__( 'Zoom Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the zoom icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_overlay_color' => array(
'label' => esc_html__( 'Hover Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'hover_icon' => array(
'label' => esc_html__( 'Hover Icon Picker', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
'type' => 'select_icon',
'option_category' => 'configuration',
'class' => array( 'et-pb-font-icon' ),
'depends_show_if' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'__projects' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Portfolio', 'get_portfolio_item' ),
'computed_depends_on' => array(
'posts_number',
'include_categories',
'fullwidth',
'__page',
),
),
'__page' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Portfolio', 'get_portfolio_item' ),
'computed_affects' => array(
'__projects',
),
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['max_width'] = array( 'max-width' => '%%order_class%%, %%order_class%% .et_pb_portfolio_item' );
$fields['width'] = array( 'width' => '%%order_class%%, %%order_class%% .et_pb_portfolio_item' );
return $fields;
}
/**
* Get portfolio objects for portfolio module
*
* @param array $args arguments that affect et_pb_portfolio query
* @param array $conditional_tags conditional tag for update process
* @param array $current_page current page params
*
* @return mixed portfolio item data
*/
static function get_portfolio_item( $args = array(), $conditional_tags = array(), $current_page = array() ) {
global $et_fb_processing_shortcode_object, $post;
$global_processing_original_value = $et_fb_processing_shortcode_object;
$defaults = array(
'posts_number' => 10,
'include_categories' => '',
'fullwidth' => 'on',
);
$args = wp_parse_args( $args, $defaults );
// Native conditional tag only works on page load. Data update needs $conditional_tags data
$is_front_page = et_fb_conditional_tag( 'is_front_page', $conditional_tags );
$is_search = et_fb_conditional_tag( 'is_search', $conditional_tags );
// Prepare query arguments
$query_args = array(
'posts_per_page' => (int) $args['posts_number'],
'post_type' => 'project',
'post_status' => array( 'publish', 'private' ),
'perm' => 'readable',
);
// Conditionally get paged data
if ( defined( 'DOING_AJAX' ) && isset( $current_page['paged'] ) ) {
$et_paged = intval( $current_page['paged'] );
} else {
$et_paged = $is_front_page ? get_query_var( 'page' ) : get_query_var( 'paged' );
}
if ( $is_front_page ) {
global $paged;
$paged = $et_paged; // phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited
}
// support pagination in VB
if ( isset( $args['__page'] ) ) {
$et_paged = $args['__page'];
}
if ( ! is_search() ) {
$query_args['paged'] = $et_paged;
}
// Passed categories parameter
$include_categories = self::filter_include_categories( $args['include_categories'], 0, 'project_category' );
if ( ! empty( $include_categories ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'project_category',
'field' => 'id',
'terms' => $include_categories,
'operator' => 'IN',
),
);
}
// Get portfolio query
$query = new WP_Query( $query_args );
// Format portfolio output, and add supplementary data
$width = 'on' === $args['fullwidth'] ? 1080 : 400;
$width = (int) apply_filters( 'et_pb_portfolio_image_width', $width );
$height = 'on' === $args['fullwidth'] ? 9999 : 284;
$height = (int) apply_filters( 'et_pb_portfolio_image_height', $height );
$classtext = 'on' === $args['fullwidth'] ? 'et_pb_post_main_image' : '';
$titletext = get_the_title();
// Loop portfolio item data and add supplementary data
if ( $query->have_posts() ) {
$post_index = 0;
while ( $query->have_posts() ) {
$query->the_post();
ET_Post_Stack::replace( $post );
$categories = array();
$categories_object = get_the_terms( get_the_ID(), 'project_category' );
if ( ! empty( $categories_object ) ) {
foreach ( $categories_object as $category ) {
$categories[] = array(
'id' => $category->term_id,
'label' => $category->name,
'permalink' => get_term_link( $category ),
);
}
}
// need to disable processnig to make sure get_thumbnail() doesn't generate errors
$et_fb_processing_shortcode_object = false;
// Capture the ALT text defined in WP Media Library
$alttext = get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true );
// Get thumbnail
$thumbnail = get_thumbnail( $width, $height, $classtext, $alttext, $titletext, false, 'Blogimage' );
$et_fb_processing_shortcode_object = $global_processing_original_value;
// Append value to query post
$query->posts[ $post_index ]->post_permalink = get_permalink();
$query->posts[ $post_index ]->featured_image = isset( $thumbnail['fullpath'] ) ? $thumbnail['fullpath'] : null;
$query->posts[ $post_index ]->post_thumbnail = print_thumbnail( $thumbnail['thumb'], $thumbnail['use_timthumb'], $titletext, $width, $height, '', false, true );
$query->posts[ $post_index ]->post_categories = $categories;
$query->posts[ $post_index ]->post_class_name = get_post_class( '', get_the_ID() );
$post_index++;
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
$query->posts_next = array(
'label' => esc_html__( '&laquo; Older Entries', 'et_builder' ),
'url' => self::get_next_link( $et_paged, $query->max_num_pages ),
);
$query->posts_prev = array(
'label' => esc_html__( 'Next Entries &raquo;', 'et_builder' ),
'url' => self::get_previous_link( $et_paged ),
);
// Added wp_pagenavi support
$query->wp_pagenavi = function_exists( 'wp_pagenavi' ) ? wp_pagenavi(
array(
'query' => $query,
'echo' => false,
)
) : false;
} elseif ( self::is_processing_computed_prop() ) {
// This is for the VB
$query = array( 'posts' => self::get_no_results_template() );
}
return $query;
}
/**
* Get the next link
*
* @param int $paged Current page.
* @param int $max Max number of pages.
*
* @return string|null
*/
private static function get_next_link( $paged, $max ) {
if ( ! $paged ) {
$paged = 1;
}
$next_page = (int) $paged + 1;
return $next_page <= $max ? get_pagenum_link( $next_page ) : null;
}
/**
* Get the previous link
*
* @param int $paged Current page.
*
* @return string|null
*/
private static function get_previous_link( $paged ) {
$previous_page = (int) $paged - 1;
return $previous_page >= 1 ? get_pagenum_link( $previous_page ) : null;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $post;
$sticky = et_pb_sticky_options();
$multi_view = et_pb_multi_view_options( $this );
$fullwidth = $this->props['fullwidth'];
$posts_number = $this->props['posts_number'];
$include_categories = $this->props['include_categories'];
$show_title = $this->props['show_title'];
$show_categories = $this->props['show_categories'];
$show_pagination = $this->props['show_pagination'];
$header_level = $this->props['title_level'];
global $paged;
$processed_header_level = et_pb_process_header_level( $header_level, 'h2' );
// Set inline style
// Zoom Icon color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'zoom_icon_color',
'selector' => '%%order_class%% .et_overlay:before',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Hover Overlay color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'hover_overlay_color',
'selector' => '%%order_class%% .et_overlay',
'css_property' => array( 'background-color', 'border-color' ),
'render_slug' => $render_slug,
'type' => 'color',
)
);
$container_is_closed = false;
// Get loop data
$portfolio = self::get_portfolio_item(
array(
'posts_number' => $posts_number,
'include_categories' => $include_categories,
'fullwidth' => $fullwidth,
)
);
// setup overlay
$overlay = '';
if ( 'on' !== $fullwidth ) {
$hover_icon = $this->props['hover_icon'];
$hover_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'hover_icon' );
$hover_icon_tablet = isset( $hover_icon_values['tablet'] ) ? $hover_icon_values['tablet'] : '';
$hover_icon_phone = isset( $hover_icon_values['phone'] ) ? $hover_icon_values['phone'] : '';
$hover_icon_sticky = $sticky->get_value( 'hover_icon', $this->props );
$overlay = 'on' === $fullwidth ? '' : ET_Builder_Module_Helper_Overlay::render(
array(
'icon' => $hover_icon,
'icon_tablet' => $hover_icon_tablet,
'icon_phone' => $hover_icon_phone,
'icon_sticky' => $hover_icon_sticky,
)
);
// Overlay Icon Styles.
$this->generate_styles(
array(
'hover' => false,
'utility_arg' => 'icon_font_family',
'render_slug' => $render_slug,
'base_attr_name' => 'hover_icon',
'important' => true,
'selector' => '%%order_class%% .et_overlay:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
}
ob_start();
$portfolio_order = self::_get_index( array( self::INDEX_MODULE_ORDER, $render_slug ) );
$items_count = 0;
if ( $portfolio->have_posts() ) {
while ( $portfolio->have_posts() ) {
$portfolio->the_post();
ET_Post_Stack::replace( $post );
// Get $post data of current loop
global $post;
array_push( $post->post_class_name, 'et_pb_portfolio_item' );
$item_class = sprintf( 'et_pb_portfolio_item_%1$s_%2$s', $portfolio_order, $items_count );
array_push( $post->post_class_name, $item_class );
$items_count++;
if ( 'on' !== $fullwidth ) {
array_push( $post->post_class_name, 'et_pb_grid_item' );
}
?>
<div id="post-<?php echo esc_attr( $post->ID ); ?>" class="<?php echo esc_attr( join( ' ', $post->post_class_name ) ); ?>">
<?php if ( '' !== $post->post_thumbnail ) { ?>
<a href="<?php echo esc_url( $post->post_permalink ); ?>" title="<?php echo esc_attr( get_the_title() ); ?>">
<?php if ( 'on' === $fullwidth ) { ?>
<span class="et_portfolio_image">
<?php
$this->render_image(
$post->post_thumbnail,
array(
'alt' => get_the_title(),
'width' => '1080',
'height' => '9999',
)
);
?>
</span>
<?php } else { ?>
<span class="et_portfolio_image">
<?php
$image_attrs = array(
'alt' => get_the_title(),
'width' => '400',
'height' => '284',
);
if ( ! empty( $post->featured_image ) ) {
$image_attrs['srcset'] = $post->featured_image . ' 479w, ' . $post->post_thumbnail . ' 480w';
$image_attrs['sizes'] = '(max-width:479px) 479px, 100vw';
}
$this->render_image( $post->post_thumbnail, $image_attrs );
?>
<?php echo et_core_esc_previously( $overlay ); ?>
</span>
<?php } ?>
</a>
<?php } ?>
<?php
$multi_view->render_element(
array(
'tag' => $processed_header_level,
'content' => sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', esc_url( $post->post_permalink ), esc_attr( get_the_title() ), esc_html( get_the_title() ) ),
'attrs' => array(
'class' => 'et_pb_module_header',
),
'visibility' => array(
'show_title' => 'on',
),
'required' => array(
'show_title' => 'on',
),
),
true
);
if ( $multi_view->has_value( 'show_categories', 'on' ) && ! empty( $post->post_categories ) ) :
$categories_links = '';
$category_index = 0;
foreach ( $post->post_categories as $category ) {
$category_index++;
$separator = $category_index < count( $post->post_categories ) ? ', ' : '';
$categories_links .= '<a href="' . esc_url( $category['permalink'] ) . '" title="' . esc_attr( $category['label'] ) . '">' . esc_html( $category['label'] ) . '</a>' . et_core_intentionally_unescaped( $separator, 'fixed_string' );
}
$multi_view->render_element(
array(
'tag' => 'p',
'content' => $categories_links,
'attrs' => array(
'class' => 'post-meta',
),
'visibility' => array(
'show_categories' => 'on',
),
'required' => array(
'show_categories' => 'on',
),
),
true
);
endif;
?>
</div>
<?php
ET_Post_Stack::pop();
}
ET_Post_Stack::reset();
if ( $multi_view->has_value( 'show_pagination', 'on' ) && ! is_search() ) {
if ( function_exists( 'wp_pagenavi' ) ) {
$pagination = $multi_view->render_element(
array(
'tag' => 'div',
'content' => wp_pagenavi(
array(
'query' => $portfolio,
'echo' => false,
)
),
'visibility' => array(
'show_pagination' => 'on',
),
'required' => array(
'show_pagination' => 'on',
),
)
);
} else {
$next_posts_link_html = $prev_posts_link_html = '';
if ( ! empty( $portfolio->posts_next['url'] ) ) {
$next_posts_link_html = sprintf(
'<div class="alignleft">
<a href="%1$s">%2$s</a>
</div>',
esc_url( $portfolio->posts_next['url'] ),
esc_html( $portfolio->posts_next['label'] )
);
}
if ( ! empty( $portfolio->posts_prev['url'] ) ) {
$prev_posts_link_html = sprintf(
'<div class="alignright">
<a href="%1$s">%2$s</a>
</div>',
esc_url( $portfolio->posts_prev['url'] ),
esc_html( $portfolio->posts_prev['label'] )
);
}
$pagination = sprintf(
'<div class="pagination clearfix"%3$s>
%1$s
%2$s
</div>',
$next_posts_link_html,
$prev_posts_link_html,
$multi_view->render_attrs(
array(
'visibility' => array(
'show_pagination' => 'on',
),
'required' => array(
'show_pagination' => 'on',
),
)
)
);
}
}
}
if ( ! $posts = ob_get_clean() ) {
$posts = self::get_no_results_template();
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$fullwidth = 'on' === $fullwidth;
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( ! $fullwidth ) {
$this->add_classname(
array(
'et_pb_portfolio_grid',
'clearfix',
)
);
$this->remove_classname( $render_slug );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$output = sprintf(
'<div%4$s class="%1$s"%10$s>
<div class="et_pb_ajax_pagination_container">
%6$s
%5$s
%7$s
%2$s
%8$s
%9$s
</div>
%3$s',
$this->module_classname( $render_slug ),
$posts,
( ! $container_is_closed ? '</div>' : '' ),
$this->module_id(),
$video_background, // #5
$parallax_image_background,
$fullwidth ? '' : '<div class="et_pb_portfolio_grid_items">',
$fullwidth ? '' : '</div>',
isset( $pagination ) ? $pagination : '',
et_core_esc_previously( $data_background_layout ) // #10
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Portfolio();
}

View File

@ -0,0 +1,20 @@
<?php
class ET_Builder_Module_PostContent extends ET_Builder_Module_Type_PostContent {
public $slug = 'et_pb_post_content';
public function init() {
$this->name = esc_html__( 'Post Content', 'et_builder' );
$this->plural = esc_html__( 'Post Content', 'et_builder' );
$this->vb_support = 'on';
$this->help_videos = array();
// Use specific selector to target only content inside the app when in VB
$this->main_css_element = '%%order_class%%';
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_PostContent();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,790 @@
<?php
class ET_Builder_Module_Post_Title extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Post Title', 'et_builder' );
$this->plural = esc_html__( 'Post Titles', 'et_builder' );
$this->slug = 'et_pb_post_title';
$this->vb_support = 'on';
$this->defaults = array();
$this->featured_image_background = true;
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'image_settings' => et_builder_i18n( 'Image' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element}.et_pb_featured_bg, {$this->main_css_element}",
'border_styles' => "{$this->main_css_element}.et_pb_featured_bg, {$this->main_css_element}",
),
),
),
),
'margin_padding' => array(
'css' => array(
'main' => ".et_pb_section {$this->main_css_element}.et_pb_post_title",
'margin' => ".et_pb_section {$this->main_css_element}.et_pb_post_title",
'important' => 'all',
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'use_all_caps' => true,
'css' => array(
'main' => "{$this->main_css_element} .et_pb_title_container h1.entry-title, {$this->main_css_element} .et_pb_title_container h2.entry-title, {$this->main_css_element} .et_pb_title_container h3.entry-title, {$this->main_css_element} .et_pb_title_container h4.entry-title, {$this->main_css_element} .et_pb_title_container h5.entry-title, {$this->main_css_element} .et_pb_title_container h6.entry-title",
),
'header_level' => array(
'default' => 'h1',
),
),
'meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container a",
'limited_main' => "{$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container a, {$this->main_css_element} .et_pb_title_container .et_pb_title_meta_container span",
),
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element}, {$this->main_css_element}.et_pb_featured_bg",
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '.et_pb_section %%order_class%%.et_pb_post_title.et_pb_module',
),
),
'text' => array(
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
),
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .entry-title',
'%%order_class%% .et_pb_title_meta_container',
)
),
),
),
'button' => false,
);
$this->custom_css_fields = array(
'post_title' => array(
'label' => et_builder_i18n( 'Title' ),
'selector' => 'h1',
),
'post_meta' => array(
'label' => esc_html__( 'Meta', 'et_builder' ),
'selector' => '.et_pb_title_meta_container',
),
'post_image' => array(
'label' => esc_html__( 'Featured Image', 'et_builder' ),
'selector' => '.et_pb_title_featured_container',
),
);
$this->help_videos = array(
array(
'id' => 'wb8c06U0uCU',
'name' => esc_html__( 'An introduction to the Post Title module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => esc_html__( 'Show Title', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Post Title', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'meta' => array(
'label' => esc_html__( 'Show Meta', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'author',
'date',
'comments',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'author' => array(
'label' => esc_html__( 'Show Author', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Author Name in Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'date' => array(
'label' => esc_html__( 'Show Date', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'affects' => array(
'date_format',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Date in Post Meta', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'date_format' => array(
'label' => esc_html__( 'Date Format', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'default_on_front' => 'M j, Y',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can define the Date Format in Post Meta. Default is \'M j, Y\'', 'et_builder' ),
),
'categories' => array(
'label' => esc_html__( 'Show Post Categories', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'show_if' => array(
'meta' => 'on',
'function.isPostOrTBLayout' => 'on',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Categories in Post Meta. Note: This option doesn\'t work with custom post types.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'comments' => array(
'label' => esc_html__( 'Show Comments Count', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Comments Count in Post Meta.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'featured_image' => array(
'label' => esc_html__( 'Show Featured Image', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'featured_placement',
),
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose whether or not display the Featured Image', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'featured_placement' => array(
'label' => esc_html__( 'Featured Image Placement', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'below' => esc_html__( 'Below Title', 'et_builder' ),
'above' => esc_html__( 'Above Title', 'et_builder' ),
'background' => esc_html__( 'Title/Meta Background Image', 'et_builder' ),
),
'default_on_front' => 'below',
'depends_show_if' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Here you can choose where to place the Featured Image', 'et_builder' ),
),
'force_fullwidth' => array(
'label' => esc_html__( 'Force Fullwidth', 'et_builder' ),
'description' => esc_html__( "When enabled, this will force your image to extend 100% of the width of the column it's in.", 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
),
'image_width' => array(
'label' => esc_html__( 'Featured Image Width', 'et_builder' ),
'description' => esc_html__( 'Adjust the width of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'width' ),
'default' => '100%',
'default_unit' => '%',
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
'sticky' => true,
),
'image_max_width' => array(
'label' => esc_html__( 'Featured Image Max Width', 'et_builder' ),
'description' => esc_html__( 'Adjust the max width of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-width' ),
'default' => 'none',
'default_unit' => '%',
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
'sticky' => true,
),
'image_height' => array(
'label' => esc_html__( 'Featured Image Height', 'et_builder' ),
'description' => esc_html__( 'Adjust the height of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'height' ),
'default' => 'auto',
'default_unit' => 'px',
'range_settings' => array(
'min' => '0',
'max' => '1000',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
'sticky' => true,
),
'image_max_height' => array(
'label' => esc_html__( 'Featured Image Max Height', 'et_builder' ),
'description' => esc_html__( 'Adjust the max height of the featured image.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-height' ),
'default' => 'none',
'default_unit' => 'px',
'range_settings' => array(
'min' => '0',
'max' => '1000',
'step' => '1',
),
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
),
'sticky' => true,
),
'image_alignment' => array(
'label' => esc_html__( 'Image Alignment', 'et_builder' ),
'description' => esc_html__( 'Align image to the left, right or center.', 'et_builder' ),
'type' => 'align',
'option_category' => 'layout',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image_settings',
'default' => 'center',
'responsive' => true,
'show_if' => array(
'featured_image' => 'on',
'featured_placement' => array( 'below', 'above' ),
'force_fullwidth' => 'off',
),
),
'text_color' => array(
'label' => esc_html__( 'Text Color', 'et_builder' ),
'type' => 'select',
'option_category' => 'color_option',
'options' => array(
'dark' => et_builder_i18n( 'Dark' ),
'light' => et_builder_i18n( 'Light' ),
),
'default_on_front' => 'dark',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'hover' => 'tabs',
'description' => esc_html__( 'Here you can choose the color for the Title/Meta text', 'et_builder' ),
),
'text_background' => array(
'label' => esc_html__( 'Use Text Background Color', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'color_option',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'text_bg_color',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'description' => esc_html__( 'Here you can choose whether or not use the background color for the Title/Meta text', 'et_builder' ),
),
'text_bg_color' => array(
'default' => 'rgba(255,255,255,0.9)',
'label' => esc_html__( 'Text Background Color', 'et_builder' ),
'description' => esc_html__( "Pick a color to use behind the post title text. Reducing the color's opacity will allow the background image to show through while still increasing text readability.", 'et_builder' ),
'type' => 'color-alpha',
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['text_color'] = array(
'color' => implode(
', ',
array(
'%%order_class%% .entry-title',
'%%order_class%% .et_pb_title_meta_container',
)
),
);
$fields['text_bg_color'] = array( 'background-color' => '%%order_class%% .et_pb_title_container' );
$fields['image_height'] = array( 'height' => '%%order_class%% .et_pb_title_featured_container img' );
$fields['image_max_height'] = array( 'max-height' => '%%order_class%% .et_pb_title_featured_container img' );
$fields['image_width'] = array( 'width' => '%%order_class%% .et_pb_title_featured_container' );
$fields['image_max_width'] = array( 'max-width' => '%%order_class%% .et_pb_title_featured_container' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$featured_placement = $this->props['featured_placement'];
$text_color = $this->props['text_color'];
$text_color_hover = et_pb_hover_options()->get_value( 'text_color', $this->props );
$text_background = $this->props['text_background'];
$header_level = $this->props['title_level'];
$post_id = get_the_ID();
// display the shortcode only on singlular pages
if ( ! is_singular() && ! is_et_pb_preview() ) {
$post_id = 0;
}
$output = '';
$featured_image_output = '';
$parallax_image_background = $this->get_parallax_image_background();
if ( $post_id && $multi_view->has_value( 'featured_image', 'on' ) && ( 'above' === $featured_placement || 'below' === $featured_placement ) ) {
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
$featured_image_src = et_()->array_get( wp_get_attachment_image_src( $post_thumbnail_id, 'full' ), 0 );
$featured_image_alt = get_post_meta( $post_thumbnail_id, '_wp_attachment_image_alt', true );
$featured_image_title = get_the_title( $post_thumbnail_id );
$featured_image_class = et_pb_media_options()->get_image_attachment_class( $this->props, '', $post_thumbnail_id );
$featured_image_attrs = array(
'src' => $featured_image_src,
'alt' => $featured_image_alt,
'title' => $featured_image_title,
);
if ( ! empty( $featured_image_class ) ) {
$featured_image_attrs['class'] = esc_attr( $featured_image_class );
}
$featured_image_content = $multi_view->render_element(
array(
'tag' => 'img',
'attrs' => $featured_image_attrs,
)
);
$featured_image_output = $multi_view->render_element(
array(
'tag' => 'div',
'content' => sprintf( '<span class="et_pb_image_wrap">%1$s</span>', $featured_image_content ),
'attrs' => array(
'class' => 'et_pb_title_featured_container',
),
'visibility' => array(
'featured_image' => 'on',
),
)
);
// Image height.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_height',
'selector' => '%%order_class%% .et_pb_title_featured_container img',
'css_property' => 'height',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image max height.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_max_height',
'selector' => '%%order_class%% .et_pb_title_featured_container img',
'css_property' => 'max-height',
'render_slug' => $render_slug,
'type' => 'range',
)
);
if ( 'off' === $this->props['force_fullwidth'] ) {
// Image width.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_width',
'selector' => '%%order_class%% .et_pb_title_featured_container',
'css_property' => 'width',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image max width.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'image_max_width',
'selector' => '%%order_class%% .et_pb_title_featured_container',
'css_property' => 'max-width',
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Image alignment style
$image_alignment_values = et_pb_responsive_options()->get_property_values( $this->props, 'image_alignment', 'none' );
et_pb_responsive_options()->generate_responsive_css(
$image_alignment_values,
'%%order_class%% .et_pb_title_featured_container',
'text-align',
$render_slug,
'',
'align'
);
$image_alignments = array(
'left' => 'auto auto auto 0',
'center' => 'auto',
'right' => 'auto 0 auto auto',
);
foreach ( $image_alignment_values as $breakpoint => $alignment ) {
$image_alignment_values[ $breakpoint ] = et_()->array_get(
$image_alignments,
$alignment,
''
);
}
et_pb_responsive_options()->generate_responsive_css(
$image_alignment_values,
'%%order_class%% .et_pb_title_featured_container',
'margin',
$render_slug,
'',
'align'
);
ET_Builder_Element::set_style(
$render_slug,
array(
'selector' => '%%order_class%% .et_pb_image_wrap',
'declaration' => 'width: auto;',
)
);
}
}
if ( $multi_view->has_value( 'title', 'on' ) ) {
if ( is_et_pb_preview() && isset( $_POST['post_title'] ) && wp_verify_nonce( $_POST['et_pb_preview_nonce'], 'et_pb_preview_nonce' ) ) {
$post_title = sanitize_text_field( wp_unslash( $_POST['post_title'] ) );
} else {
// Unescaped for backwards compat reasons.
$post_title = et_core_intentionally_unescaped( et_builder_get_current_title(), 'html' );
}
$output .= $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h1' ),
'content' => $post_title,
'attrs' => array(
'class' => 'entry-title',
),
'visibility' => array(
'title' => 'on',
),
)
);
}
if ( $post_id && $multi_view->has_value( 'meta', 'on' ) ) {
$post_meta_keys = array(
'author',
'date',
'categories',
'comments',
);
$post_metas = array(
'desktop' => array(),
'tablet' => array(),
'phone' => array(),
'hover' => array(),
);
foreach ( $post_metas as $mode => $post_meta ) {
foreach ( $post_meta_keys as $post_meta_key ) {
if ( $multi_view->has_value( $post_meta_key, 'on', $mode, true ) ) {
$post_meta[ $post_meta_key ] = $post_meta_key;
}
}
$post_metas[ $mode ] = implode( ',', $post_meta );
}
$multi_view->set_custom_prop( 'post_metas', $post_metas );
$output .= $multi_view->render_element(
array(
'tag' => 'p',
'content' => '{{post_metas}}',
'attrs' => array(
'class' => 'et_pb_title_meta_container',
),
'visibility' => array(
'meta' => 'on',
),
)
);
}
if ( 'on' === $text_background ) {
// Text Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'text_bg_color',
'selector' => '%%order_class%% .et_pb_title_container',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
'additional_css' => 'padding: 1em 1.5em;',
)
);
}
$video_background = $this->video_background();
$background_layout = 'dark' === $text_color ? 'light' : 'dark';
$data_background_layout = '';
$data_background_layout_hover = '';
if ( et_pb_hover_options()->is_enabled( 'text_color', $this->props ) && ! empty( $text_color_hover ) && $text_color !== $text_color_hover ) {
$data_background_layout = sprintf( ' data-background-layout="%1$s"', esc_attr( $text_color_hover ) );
$data_background_layout_hover = sprintf( ' data-background-layout-hover="%1$s"', esc_attr( $text_color ) );
}
// Module classnames
$this->add_classname(
array(
"et_pb_bg_layout_{$background_layout}",
$this->get_text_orientation_classname(),
)
);
if ( 'on' === $multi_view->get_value( 'featured_image' ) && 'background' === $featured_placement ) {
$this->add_classname( 'et_pb_featured_bg' );
}
$muti_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_featured_bg' => array(
'featured_image' => 'on',
'featured_placement' => 'background',
),
),
)
);
$output = sprintf(
'<div%3$s class="%2$s" %8$s %9$s %10$s>
%4$s
%7$s
%5$s
<div class="et_pb_title_container">
%1$s
</div>
%6$s
</div>',
$output,
$this->module_classname( $render_slug ),
$this->module_id(),
$parallax_image_background,
'above' === $featured_placement ? $featured_image_output : '', // #5
'below' === $featured_placement ? $featured_image_output : '',
$video_background,
et_core_esc_previously( $data_background_layout ),
et_core_esc_previously( $data_background_layout_hover ),
et_core_esc_previously( $muti_view_data_attr ) // #10
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$context = isset( $args['context'] ) ? $args['context'] : '';
if ( $raw_value && 'post_metas' === $name && 'content' === $context ) {
$post_metas = array();
foreach ( explode( ',', $raw_value ) as $post_meta ) {
if ( 'categories' === $post_meta && ! is_singular( 'post' ) ) {
continue;
}
$post_metas[] = $post_meta;
}
$raw_value = et_pb_postinfo_meta( $post_metas, $this->props['date_format'], esc_html__( '0 comments', 'et_builder' ), esc_html__( '1 comment', 'et_builder' ), '% ' . esc_html__( 'comments', 'et_builder' ) );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Post_Title();
}

View File

@ -0,0 +1,455 @@
<?php
class ET_Builder_Module_Posts_Navigation extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Post Navigation', 'et_builder' );
$this->plural = esc_html__( 'Post Navigations', 'et_builder' );
$this->slug = 'et_pb_post_nav';
$this->vb_support = 'on';
$this->main_css_element = '.et_pb_posts_nav%%order_class%%';
$this->defaults = array();
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'categories' => esc_html__( 'Categories', 'et_builder' ),
'navigation' => esc_html__( 'Navigation', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'title' => array(
'label' => esc_html__( 'Links', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} span a, {$this->main_css_element} span a span",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'letter_spacing' => array(
'default' => '0px',
),
'hide_text_align' => true,
),
),
'margin_padding' => array(
'css' => array(
'main' => "{$this->main_css_element} span.nav-previous a, {$this->main_css_element} span.nav-next a",
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element} a",
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} span.nav-previous a, {$this->main_css_element} span.nav-next a",
'border_styles' => "{$this->main_css_element} span.nav-previous a, {$this->main_css_element} span.nav-next a",
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .nav-previous a, %%order_class%% .nav-next a',
'overlay' => 'inset',
'important' => true,
),
),
),
'text' => false,
'button' => false,
'link_options' => false,
);
$this->custom_css_fields = array(
'links' => array(
'label' => esc_html__( 'Links', 'et_builder' ),
'selector' => 'span a',
),
'prev_link' => array(
'label' => esc_html__( 'Previous Link', 'et_builder' ),
'selector' => 'span.nav-previous a',
),
'prev_link_arrow' => array(
'label' => esc_html__( 'Previous Link Arrow', 'et_builder' ),
'selector' => 'span.nav-previous .meta-nav',
),
'next_link' => array(
'label' => esc_html__( 'Next Link', 'et_builder' ),
'selector' => 'span.nav-next a',
),
'next_link_arrow' => array(
'label' => esc_html__( 'Next Link Arrow', 'et_builder' ),
'selector' => 'span.nav-next .meta-nav',
),
);
$this->help_videos = array(
array(
'id' => 'q7SrK2sh7_o',
'name' => esc_html__( 'An introduction to the Post Navigation module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'in_same_term' => array(
'label' => esc_html__( 'Navigate Within Current Category', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'affects' => array(
'taxonomy_name',
),
'description' => esc_html__( 'Here you can define whether previous and next posts must be within the same taxonomy term as the current post', 'et_builder' ),
'toggle_slug' => 'categories',
'computed_affects' => array(
'__posts_navigation',
),
),
'taxonomy_name' => array(
'label' => esc_html__( 'Custom Taxonomy Name', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'depends_show_if' => 'on',
'description' => esc_html__( 'Leave blank if you\'re using this module on a Project or Post. Otherwise type the taxonomy name to make the \'In the Same Category\' option work correctly', 'et_builder' ),
'toggle_slug' => 'categories',
'computed_affects' => array(
'__posts_navigation',
),
),
'show_prev' => array(
'label' => esc_html__( 'Show Previous Post Link', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'prev_text',
),
'toggle_slug' => 'navigation',
'description' => esc_html__( 'Turn this on to show the previous post link', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_next' => array(
'label' => esc_html__( 'Show Next Post Link', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'affects' => array(
'next_text',
),
'toggle_slug' => 'navigation',
'description' => esc_html__( 'Turn this on to show the next post link', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'prev_text' => array(
'label' => esc_html__( 'Previous Link', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'depends_show_if' => 'on',
'computed_affects' => array(
'__posts_navigation',
),
'description' => et_get_safe_localization( __( 'Define custom text for the previous link. You can use the <strong>%title</strong> variable to include the post title. Leave blank for default.', 'et_builder' ) ),
'toggle_slug' => 'main_content',
'mobile_options' => true,
'hover' => 'tabs',
),
'next_text' => array(
'label' => esc_html__( 'Next Link', 'et_builder' ),
'type' => 'text',
'option_category' => 'configuration',
'depends_show_if' => 'on',
'computed_affects' => array(
'__posts_navigation',
),
'description' => et_get_safe_localization( __( 'Define custom text for the next link. You can use the <strong>%title</strong> variable to include the post title. Leave blank for default.', 'et_builder' ) ),
'toggle_slug' => 'main_content',
'mobile_options' => true,
'hover' => 'tabs',
),
'__posts_navigation' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Posts_Navigation', 'get_posts_navigation' ),
'computed_depends_on' => array(
'in_same_term',
'taxonomy_name',
'prev_text',
'next_text',
),
),
);
return $fields;
}
/**
* Get prev and next post link data for frontend builder's post navigation module component
*
* @param int post ID
* @param bool show posts which uses same link only or not
* @param string excluded terms name
* @param string taxonomy name for in_same_terms
*
* @return string JSON encoded array of post's next and prev link
*/
static function get_posts_navigation( $args = array(), $conditional_tags = array(), $current_page = array() ) {
global $post;
$defaults = array(
'in_same_term' => 'off',
'taxonomy_name' => 'category',
'prev_text' => '%title',
'next_text' => '%title',
);
$args = wp_parse_args( $args, $defaults );
// taxonomy name overwrite if in_same_term option is set to off and no taxonomy name defined
if ( '' === $args['taxonomy_name'] || 'on' !== $args['in_same_term'] ) {
$is_singular_project = isset( $conditional_tags['is_singular_project'] ) ? $conditional_tags['is_singular_project'] === 'true' : is_singular( 'project' );
$args['taxonomy_name'] = $is_singular_project ? 'project_category' : 'category';
}
$in_same_term = ! $args['in_same_term'] || 'off' === $args['in_same_term'] ? false : true;
et_core_nonce_verified_previously();
if ( ! isset( $post ) && defined( 'DOING_AJAX' ) && DOING_AJAX && ! empty( $_POST['et_post_id'] ) ) {
$post_id = sanitize_text_field( $_POST['et_post_id'] );
} elseif ( isset( $current_page['id'] ) ) {
// Overwrite global $post value in this scope
$post_id = intval( $current_page['id'] );
} elseif ( is_object( $post ) && isset( $post->ID ) ) {
$post_id = $post->ID;
} else {
return array(
'next' => '',
'prev' => '',
);
}
// Set current post as global $post
$post = get_post( $post_id ); // phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited
// Get next post
$next_post = get_next_post( $in_same_term, '', $args['taxonomy_name'] );
$next = new stdClass();
if ( ! empty( $next_post ) ) {
$next_title = isset( $next_post->post_title ) ? esc_html( $next_post->post_title ) : esc_html__( 'Next Post' );
$next_date = mysql2date( get_option( 'date_format' ), $next_post->post_date );
$next_permalink = isset( $next_post->ID ) ? esc_url( get_the_permalink( $next_post->ID ) ) : '';
$next_processed_title = '' === $args['next_text'] ? '%title' : $args['next_text'];
// process WordPress' wildcards
$next_processed_title = str_replace( '%title', $next_title, $next_processed_title );
$next_processed_title = str_replace( '%date', $next_date, $next_processed_title );
$next_processed_title = str_replace( '%link', $next_permalink, $next_processed_title );
$next->title = $next_processed_title;
$next->id = isset( $next_post->ID ) ? intval( $next_post->ID ) : '';
$next->permalink = $next_permalink;
}
// Get prev post
$prev_post = get_previous_post( $in_same_term, '', $args['taxonomy_name'] );
$prev = new stdClass();
if ( ! empty( $prev_post ) ) {
$prev_title = isset( $prev_post->post_title ) ? esc_html( $prev_post->post_title ) : esc_html__( 'Previous Post' );
$prev_date = mysql2date( get_option( 'date_format' ), $prev_post->post_date );
$prev_permalink = isset( $prev_post->ID ) ? esc_url( get_the_permalink( $prev_post->ID ) ) : '';
$prev_processed_title = '' === $args['prev_text'] ? '%title' : $args['prev_text'];
// process WordPress' wildcards
$prev_processed_title = str_replace( '%title', $prev_title, $prev_processed_title );
$prev_processed_title = str_replace( '%date', $prev_date, $prev_processed_title );
$prev_processed_title = str_replace( '%link', $prev_permalink, $prev_processed_title );
$prev->title = $prev_processed_title;
$prev->id = isset( $prev_post->ID ) ? intval( $prev_post->ID ) : '';
$prev->permalink = $prev_permalink;
}
// Formatting returned value
$posts_navigation = array(
'next' => $next,
'prev' => $prev,
);
return $posts_navigation;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$in_same_term = $this->props['in_same_term'];
$taxonomy_name = $this->props['taxonomy_name'];
$show_prev = $this->props['show_prev'];
$show_next = $this->props['show_next'];
$prev_text = $this->props['prev_text'];
$next_text = $this->props['next_text'];
// do not output anything if both prev and next links are disabled
if ( ! $multi_view->has_value( 'show_prev', 'on' ) && ! $multi_view->has_value( 'show_next', 'on' ) ) {
return;
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$posts_navigation = self::get_posts_navigation(
array(
'in_same_term' => $in_same_term,
'taxonomy_name' => $taxonomy_name,
'prev_text' => $prev_text,
'next_text' => $next_text,
)
);
ob_start();
$background_classname = array();
if ( '' !== $video_background ) {
$background_classname[] = 'et_pb_section_video';
$background_classname[] = 'et_pb_preload';
}
if ( '' !== $parallax_image_background ) {
$background_classname[] = 'et_pb_section_parallax';
}
$background_class_attr = empty( $background_classname ) ? '' : sprintf( ' class="%s"', esc_attr( implode( ' ', $background_classname ) ) );
if ( $multi_view->has_value( 'show_prev', 'on' ) && ! empty( $posts_navigation['prev']->permalink ) ) {
?>
<span class="nav-previous"
<?php
$multi_view->render_attrs(
array(
'visibility' => array(
'show_prev' => 'on',
),
),
true
);
?>
>
<a href="<?php echo esc_url( $posts_navigation['prev']->permalink ); ?>" rel="prev"<?php echo et_core_esc_previously( $background_class_attr ); ?>>
<?php
echo et_core_esc_previously( $parallax_image_background );
echo et_core_esc_previously( $video_background );
?>
<span class="meta-nav">&larr; </span><span class="nav-label"<?php $multi_view->render_attrs( array( 'content' => '{{prev_text}}' ), true ); ?>><?php echo esc_html( $posts_navigation['prev']->title ); ?></span>
</a>
</span>
<?php
}
if ( $multi_view->has_value( 'show_next', 'on' ) && ! empty( $posts_navigation['next']->permalink ) ) {
?>
<span class="nav-next"
<?php
$multi_view->render_attrs(
array(
'visibility' => array(
'show_next' => 'on',
),
),
true
);
?>
>
<a href="<?php echo esc_url( $posts_navigation['next']->permalink ); ?>" rel="next"<?php echo et_core_esc_previously( $background_class_attr ); ?>>
<?php
echo et_core_esc_previously( $parallax_image_background );
echo et_core_esc_previously( $video_background );
?>
<span class="nav-label"<?php $multi_view->render_attrs( array( 'content' => '{{next_text}}' ), true ); ?>><?php echo esc_html( $posts_navigation['next']->title ); ?></span><span class="meta-nav"> &rarr;</span>
</a>
</span>
<?php
}
$page_links = ob_get_contents();
ob_end_clean();
// Module classname
$this->add_classname(
array(
'et_pb_posts_nav',
'nav-single',
)
);
// Remove automatically added module classname
$this->remove_classname(
array(
$render_slug,
'et_pb_section_video',
'et_pb_preload',
'et_pb_section_parallax',
)
);
$output = sprintf(
'<div class="%2$s"%1$s>
%3$s
</div>',
$this->module_id(),
$this->module_classname( $render_slug ),
$page_links
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Posts_Navigation();
}

View File

@ -0,0 +1,942 @@
<?php
class ET_Builder_Module_Pricing_Tables extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Pricing Tables', 'et_builder' );
$this->plural = esc_html__( 'Pricing Tables', 'et_builder' );
$this->slug = 'et_pb_pricing_tables';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%';
$this->child_slug = 'et_pb_pricing_table';
$this->child_item_text = esc_html__( 'Pricing Table', 'et_builder' );
$this->additional_shortcode = 'et_pb_pricing_item';
$this->custom_css_fields = array(
'pricing_heading' => array(
'label' => esc_html__( 'Pricing Heading', 'et_builder' ),
'selector' => '.et_pb_pricing_heading',
),
'pricing_title' => array(
'label' => esc_html__( 'Pricing Title', 'et_builder' ),
'selector' => '.et_pb_pricing_heading h2',
),
'pricing_subtitle' => array(
'label' => esc_html__( 'Pricing Subtitle', 'et_builder' ),
'selector' => '.et_pb_pricing_heading .et_pb_best_value',
),
'pricing_top' => array(
'label' => esc_html__( 'Pricing Top', 'et_builder' ),
'selector' => '.et_pb_pricing_content_top',
),
'price' => array(
'label' => esc_html__( 'Price', 'et_builder' ),
'selector' => '.et_pb_et_price',
),
'currency' => array(
'label' => esc_html__( 'Currency', 'et_builder' ),
'selector' => '.et_pb_dollar_sign',
),
'frequency' => array(
'label' => esc_html__( 'Frequency', 'et_builder' ),
'selector' => '.et_pb_frequency',
),
'pricing_content' => array(
'label' => esc_html__( 'Pricing Content', 'et_builder' ),
'selector' => '.et_pb_pricing_content',
),
'pricing_item' => array(
'label' => esc_html__( 'Pricing Item', 'et_builder' ),
'selector' => 'ul.et_pb_pricing li',
),
'pricing_item_excluded' => array(
'label' => esc_html__( 'Excluded Item', 'et_builder' ),
'selector' => 'ul.et_pb_pricing li.et_pb_not_available',
),
'pricing_button' => array(
'label' => esc_html__( 'Pricing Button', 'et_builder' ),
'selector' => '.et_pb_pricing_table_button',
),
'featured_table' => array(
'label' => esc_html__( 'Featured Table', 'et_builder' ),
'selector' => '.et_pb_featured_table',
),
);
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'bullet' => esc_html__( 'Bullet', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
// @TODO
'additional_elements' => array(
array(
"{$this->main_css_element} .et_pb_pricing_content_top" => array( 'bottom' ),
),
),
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_pricing_table",
'border_styles' => "{$this->main_css_element} .et_pb_pricing_table",
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#bebebe',
'style' => 'solid',
),
),
),
'price' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_pricing_content_top",
'border_styles' => "{$this->main_css_element} .et_pb_pricing_content_top",
),
),
'option_category' => 'border',
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#bebebe',
'style' => 'solid',
),
'composite' => array(
'border_bottom' => array(
'border_width_bottom' => '1px',
),
),
),
),
),
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing_heading h2, {$this->main_css_element} .et_pb_pricing_heading h1.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h3.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h4.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h5.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h6.et_pb_pricing_title",
'important' => 'all',
),
'letter_spacing' => array(
'default' => '0px',
),
'header_level' => array(
'default' => 'h2',
),
'options_priority' => array(
'header_text_color' => 9,
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing li",
'limited_main' => "{$this->main_css_element} .et_pb_pricing li, {$this->main_css_element} .et_pb_pricing li span, {$this->main_css_element} .et_pb_pricing li a",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'letter_spacing' => array(
'default' => '0px',
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
'options_priority' => array(
'body_text_color' => 9,
),
),
'subheader' => array(
'label' => esc_html__( 'Subtitle', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_best_value",
),
'letter_spacing' => array(
'default' => '0px',
),
'line_height' => array(
'default' => '1em',
),
'options_priority' => array(
'subheader_text_color' => 9,
),
),
'price' => array(
'label' => esc_html__( 'Price', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_sum",
'text_align' => "{$this->main_css_element} .et_pb_pricing_content_top",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'options_priority' => array(
'price_text_color' => 8,
),
),
'currency_frequency' => array(
'label' => esc_html__( 'Currency &amp; Frequency', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_dollar_sign, {$this->main_css_element} .et_pb_frequency",
),
'hide_text_align' => true,
'options_priority' => array(
'currency_frequency_text_color' => 9,
),
),
'excluded' => array(
'label' => esc_html__( 'Excluded Item', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing li.et_pb_not_available, {$this->main_css_element} .et_pb_pricing li.et_pb_not_available span, {$this->main_css_element} .et_pb_pricing li.et_pb_not_available a",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'options_priority' => array(
'excluded_text_color' => 9,
),
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing_table",
),
'settings' => array(
'color' => 'alpha',
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing_table_button.et_pb_button",
'limited_main' => "{$this->main_css_element} .et_pb_pricing_table_button.et_pb_button",
'alignment' => "{$this->main_css_element} .et_pb_button_wrapper",
),
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all', // needed to overwrite last module margin-bottom styling
'main' => '%%order_class%% .et_pb_pricing_heading, %%order_class%% .et_pb_pricing_content_top, %%order_class%% .et_pb_pricing_content',
'padding-right' => '%%order_class%% .et_pb_button_wrapper',
'padding-bottom' => '%%order_class%% .et_pb_pricing_table',
'padding-left' => '%%order_class%% .et_pb_button_wrapper',
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% .et_pb_pricing_table, %%order_class%% .et_pb_pricing_content',
'text_shadow' => '%%order_class%% .et_pb_pricing_heading, %%order_class%% .et_pb_pricing_content_top, %%order_class%% .et_pb_pricing_content',
),
),
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => 'BVzu4WnjgYI',
'name' => esc_html__( 'An introduction to the Pricing Tables module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'featured_table_background_color' => array(
'label' => esc_html__( 'Featured Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to be used for the background of featured pricing tables. This helps featured tables stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'priority' => 23,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_header_background_color' => array(
'label' => esc_html__( 'Featured Header Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for the background behind pricing table titles in featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'header',
'priority' => 21,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_header_text_color' => array(
'label' => esc_html__( 'Featured Title Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for title text in featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'header',
'priority' => 20,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'header_background_color' => array(
'label' => esc_html__( 'Table Header Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the background behind pricing table titles.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'header',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_subheader_text_color' => array(
'label' => esc_html__( 'Featured Subtitle Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for subtitles in featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'subheader',
'priority' => 20,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_text_color' => array(
'label' => esc_html__( 'Featured Body Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for body text in featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'body',
'sub_toggle' => 'p',
'priority' => 8,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'show_bullet' => array(
'label' => esc_html__( 'Show Bullets', 'et_builder' ),
'description' => esc_html__( "Disabling bullets will remove the bullet points that appear next to each list item within the pricing table's feature area.", 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'affects' => array(
'bullet_color',
),
'mobile_options' => true,
'hover' => 'tabs',
),
'featured_table_bullet_color' => array(
'label' => esc_html__( 'Featured Bullet Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for the bullets that appear next to each list items within featured tabes. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'bullet',
'priority' => 22,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'bullet_color' => array(
'label' => esc_html__( 'Bullet Color', 'et_builder' ),
'description' => esc_html__( "Pick a color to use for the bullets that appear next to each list item within the pricing table's feature area.", 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'bullet',
'depends_show_if' => 'on',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'show_featured_drop_shadow' => array(
'label' => esc_html__( 'Show Featured Drop Shadow', 'et_builder' ),
'description' => esc_html__( 'Featured pricing tables have a drop shadow that helps them stand out from the rest. This shadow can be disabled if you wish.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'priority' => 24,
'mobile_options' => true,
),
'featured_table_excluded_text_color' => array(
'label' => esc_html__( 'Featured Excluded Item Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for excluded list items within featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'excluded',
'priority' => 20,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_price_background_color' => array(
'label' => esc_html__( 'Featured Pricing Area Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for the background area that appears behind the pricing text in featured tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'priority' => 18,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_price_color' => array(
'label' => esc_html__( 'Featured Price Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for price text within featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'priority' => 19,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'featured_table_currency_frequency_text_color' => array(
'label' => esc_html__( 'Featured Currency &amp; Frequency Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a unique color to use for currency and frequency text within featured pricing tables. Unique colors can help featured items stand out from the rest.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'currency_frequency',
'priority' => 20,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'price_background_color' => array(
'label' => esc_html__( 'Pricing Area Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the background area that appears behind the pricing text.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'priority' => 21,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['bullet_color'] = array( 'border-color' => '%%order_class%% .et_pb_pricing li span:before' );
$fields['featured_table_bullet_color'] = array( 'border-color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing li span:before' );
$fields['featured_table_header_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_heading' );
$fields['featured_table_header_text_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_heading h2, %%order_class%% .et_pb_featured_table .et_pb_pricing_heading .et_pb_pricing_title' );
$fields['header_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_pricing_heading' );
$fields['featured_table_text_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_content li, %%order_class%% .et_pb_featured_table .et_pb_pricing_content li span, %%order_class%% .et_pb_featured_table .et_pb_pricing_content li a' );
$fields['featured_table_subheader_text_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_best_value' );
$fields['featured_table_price_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_sum' );
$fields['featured_table_currency_frequency_text_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_dollar_sign, %%order_class%% .et_pb_featured_table .et_pb_frequency' );
$fields['featured_table_excluded_text_color'] = array( 'color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available, %%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available span, %%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available a' );
$fields['featured_table_price_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_content_top' );
$fields['price_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_pricing_content_top' );
return $fields;
}
function before_render() {
global $et_pb_pricing_tables_num,
$et_pb_pricing_tables_icon,
$et_pb_pricing_tables_icon_tablet,
$et_pb_pricing_tables_icon_phone,
$et_pb_pricing_tab,
$et_pb_pricing_tables_button_rel,
$et_pb_pricing_tables_header_level,
$et_pb_pricing_tables_sticky,
$et_pb_pricing_tables_sticky_transition;
$button_custom = $this->props['custom_button'];
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$et_pb_pricing_tables_num = 0;
$et_pb_pricing_tables_icon = 'on' === $button_custom ? $custom_icon : '';
$et_pb_pricing_tables_icon_tablet = 'on' === $button_custom ? $custom_icon_tablet : '';
$et_pb_pricing_tables_icon_phone = 'on' === $button_custom ? $custom_icon_phone : '';
$et_pb_pricing_tables_button_rel = $this->props['button_rel'];
$et_pb_pricing_tables_header_level = 'h2' === $this->props['header_level'] ? '' : $this->props['header_level'];
// Pass down sticky module status for correct selector suffix placement.
$et_pb_pricing_tables_sticky = et_pb_sticky_options()->is_sticky_module( $this->props );
// Module item has no sticky options hence this needs to be inherited to setup transition.
$et_pb_pricing_tables_sticky_transition = et_()->array_get( $this->props, 'sticky_transition', 'on' );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$featured_table = $this->get_featured_table( $content );
$show_featured_drop_shadow = $this->props['show_featured_drop_shadow'];
$show_featured_drop_shadow_values = et_pb_responsive_options()->get_property_values( $this->props, 'show_featured_drop_shadow' );
$show_featured_drop_shadow_tablet = isset( $show_featured_drop_shadow_values['tablet'] ) ? $show_featured_drop_shadow_values['tablet'] : '';
$show_featured_drop_shadow_phone = isset( $show_featured_drop_shadow_values['phone'] ) ? $show_featured_drop_shadow_values['phone'] : '';
$body_text_align_values = et_pb_responsive_options()->get_property_values( $this->props, 'body_text_align' );
global $et_pb_pricing_tables_num, $et_pb_pricing_tables_icon, $et_pb_pricing_tables_icon_tablet, $et_pb_pricing_tables_icon_phone;
// Show Featured Drop Shadow.
$disabled_shadow = 'none';
$reset_shadow = '0 0 12px rgba(0,0,0,0.1)';
$featured_shadow = '';
$featured_shadow_tablet = '';
$featured_shadow_phone = '';
if ( 'on' !== $show_featured_drop_shadow ) {
$featured_shadow = 'none';
}
if ( '' !== $show_featured_drop_shadow_tablet ) {
if ( 'on' !== $show_featured_drop_shadow_tablet ) {
$featured_shadow_tablet = $disabled_shadow;
} elseif ( 'on' === $show_featured_drop_shadow_tablet && 'on' !== $featured_shadow ) {
$featured_shadow_tablet = $reset_shadow;
}
if ( $featured_shadow_tablet === $featured_shadow ) {
$featured_shadow_tablet = '';
}
}
if ( '' !== $show_featured_drop_shadow_phone ) {
if ( 'on' !== $show_featured_drop_shadow_phone ) {
$featured_shadow_phone = $disabled_shadow;
} elseif ( 'on' === $show_featured_drop_shadow_phone && 'on' !== $featured_shadow_tablet ) {
$featured_shadow_phone = $reset_shadow;
}
if ( $featured_shadow_phone === $featured_shadow_tablet ) {
$featured_shadow_phone = '';
}
}
$featured_shadow_values = array(
'desktop' => esc_html( $featured_shadow ),
'tablet' => esc_html( $featured_shadow_tablet ),
'phone' => esc_html( $featured_shadow_phone ),
);
et_pb_responsive_options()->generate_responsive_css( $featured_shadow_values, '%%order_class%% .et_pb_featured_table', array( '-moz-box-shadow', '-webkit-box-shadow', 'box-shadow' ), $render_slug, '', 'shadow' );
// Featured Table Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_background_color',
'selector' => '%%order_class%% .et_pb_featured_table',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Header Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'header_background_color',
'selector' => '%%order_class%% .et_pb_pricing_heading',
'hover_selector' => '%%order_class%% .et_pb_pricing_table:hover .et_pb_pricing_heading',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Featured Table Header Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_header_background_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_heading',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing_heading',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Title Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_header_text_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_heading h2, %%order_class%% .et_pb_featured_table .et_pb_pricing_heading .et_pb_pricing_title',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing_heading h2, %%order_class%% .et_pb_featured_table:hover .et_pb_pricing_heading .et_pb_pricing_title',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Sutitle Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_subheader_text_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_best_value',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_best_value',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Price Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_price_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_sum',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_sum',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Body Text Color.
$featured_table_text_color_selector = et_builder_has_limitation( 'use_additional_limiting_styles' ) ? '%%order_class%% .et_pb_featured_table .et_pb_pricing_content li, %%order_class%% .et_pb_featured_table .et_pb_pricing_content li span, %%order_class%% .et_pb_featured_table .et_pb_pricing_content li a' : '%%order_class%% .et_pb_featured_table .et_pb_pricing_content li';
$featured_table_text_color_selector_hover = et_is_builder_plugin_active() ? '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing_content li, %%order_class%% .et_pb_featured_table:hover .et_pb_pricing_content li span, %%order_class%% .et_pb_featured_table:hover .et_pb_pricing_content li a' : '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing_content li';
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_text_color',
'selector' => $featured_table_text_color_selector,
'hover_selector' => $featured_table_text_color_selector_hover,
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Bullet Color.
$this->generate_styles(
array(
'base_attr_name' => 'bullet_color',
'selector' => '%%order_class%% .et_pb_pricing li span:before',
'hover_selector' => '%%order_class%% .et_pb_pricing:hover li span:before',
'css_property' => 'border-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Featured Table Bullet Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_bullet_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_pricing li span:before',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing li span:before',
'css_property' => 'border-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Featured Table Currency Frequency Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_currency_frequency_text_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_dollar_sign, %%order_class%% .et_pb_featured_table .et_pb_frequency',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_dollar_sign, %%order_class%% .et_pb_featured_table:hover .et_pb_frequency',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Excluded Item Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_excluded_text_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available, %%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available span, %%order_class%% .et_pb_featured_table .et_pb_pricing li.et_pb_not_available a',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing li.et_pb_not_available, %%order_class%% .et_pb_featured_table:hover .et_pb_pricing li.et_pb_not_available span, %%order_class%% .et_pb_featured_table:hover .et_pb_pricing li.et_pb_not_available a',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'important' => true,
)
);
// Featured Table Price Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'featured_table_price_background_color',
'selector' => '%%order_class%% .et_pb_featured_table .et_pb_pricing_content_top',
'hover_selector' => '%%order_class%% .et_pb_featured_table:hover .et_pb_pricing_content_top',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Price Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'price_background_color',
'selector' => '%%order_class%% .et_pb_pricing_content_top',
'hover_selector' => '%%order_class%%:hover .et_pb_pricing_content_top',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Custom Padding Left On Center.
if ( ! empty( $body_text_align_values ) ) {
foreach ( $body_text_align_values as $body_text_align_device => $body_text_align_value ) {
if ( 'center' !== $body_text_align_value ) {
continue;
}
$padding_left_style = array(
'selector' => '%%order_class%% .et_pb_pricing li',
'declaration' => esc_html( 'padding-left: 0;' ),
);
if ( 'desktop' !== $body_text_align_device ) {
$current_media_query = 'tablet' === $body_text_align_device ? 'max_width_980' : 'max_width_767';
$padding_left_style['media_query'] = ET_Builder_Element::get_media_query( $current_media_query );
}
ET_Builder_Element::set_style( $render_slug, $padding_left_style );
}
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$content = $this->content;
// Module classnames
$this->add_classname(
array(
'et_pb_pricing',
'clearfix',
"et_pb_pricing_{$et_pb_pricing_tables_num}",
$featured_table,
)
);
if ( 'off' === $multi_view->get_value( 'show_bullet' ) ) {
$this->add_classname( 'et_pb_pricing_no_bullet' );
}
// Remove automatically added classnames
$this->remove_classname(
array(
$render_slug,
)
);
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_pricing_no_bullet' => array(
'show_bullet' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%2$s"%6$s>
%5$s
%4$s
<div class="et_pb_pricing_table_wrap">
%1$s
</div>
</div>',
$content,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background,
$multi_view_data_attr
);
$output .= $this->keep_box_shadow_compatibility( $attrs, $content, $render_slug );
return $output;
}
/**
* Additional module output.
*
* @param array $atts List of attributes.
* @param string $content Content being processed.
* @param string $function_name Slug of module that is used for rendering output.
*
* @return string
*/
public function additional_render( $atts, $content, $function_name ) {
$attributes = shortcode_atts(
array(
'available' => 'on',
),
$atts
);
$output = sprintf(
'<li%2$s><span>%1$s</span></li>',
$content,
( 'on' !== $attributes['available'] ? ' class="et_pb_not_available"' : '' )
);
return $output;
}
private function get_featured_table( $content ) {
// Extract `et_pb_pricing_table` shortcode attributes
preg_match_all( '/\[et_pb_pricing_table(\s+[^\]]*)\]/', $content, $matches );
if ( ! isset( $matches[1] ) || 0 === count( $matches[1] ) ) {
return '';
}
$list = array();
foreach ( $matches[1] as $match ) {
// Check if the shortcode has the `feature` attribute on
// TODO: Find a better way to do that
$list[] = (bool) preg_match( '/[\s]featured=[\'|"]on[\'|"]/', $match );
}
// We need to know only the first 4 tables status,
// because in a row are maximum 4 tables
$count = count( $list ) > 4 ? 4 : count( $list );
for ( $i = 0; $i < $count; $i ++ ) {
if ( true === $list[ $i ] ) {
switch ( $i ) {
case 0:
return '';
case 1:
return 'et_pb_second_featured';
case 2:
return 'et_pb_third_featured';
case 3:
return 'et_pb_fourth_featured';
}
}
}
return 'et_pb_no_featured_in_first_row';
}
private function keep_box_shadow_compatibility( $atts, $content, $function_name ) {
/**
* @var ET_Builder_Module_Field_BoxShadow $box_shadow
*/
$box_shadow = ET_Builder_Module_Fields_Factory::get( 'BoxShadow' );
$utils = ET_Core_Data_Utils::instance();
if (
! is_admin()
&&
version_compare( $utils->array_get( $atts, '_builder_version', '3.0.93' ), '3.0.97', 'lt' )
&&
$box_shadow->is_inset( $box_shadow->get_value( $atts ) )
) {
$class = '.' . self::get_module_order_class( $function_name );
$overlay_shadow = $box_shadow->get_style( $class, $atts );
return sprintf(
'<style type="text/css">%1$s %2$s %3$s</style>',
'.et_pb_pricing > .box-shadow-overlay { z-index: 11; }',
sprintf( '%1$s { box-shadow: none; }', esc_attr( $class ) ),
sprintf( '%1$s { %2$s }', esc_attr( $overlay_shadow['selector'] ), esc_attr( $overlay_shadow['declaration'] ) )
);
}
return '';
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Pricing_Tables();
}

View File

@ -0,0 +1,725 @@
<?php
class ET_Builder_Module_Pricing_Tables_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Pricing Table', 'et_builder' );
$this->plural = esc_html__( 'Pricing Tables', 'et_builder' );
$this->slug = 'et_pb_pricing_table';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%';
$this->type = 'child';
$this->child_title_var = 'title';
$this->advanced_setting_title_text = esc_html__( 'New Pricing Table', 'et_builder' );
$this->settings_text = esc_html__( 'Pricing Table Settings', 'et_builder' );
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'bullet' => esc_html__( 'Bullet', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '.et_pb_pricing .et_pb_pricing_table%%order_class%%',
'border_styles' => '.et_pb_pricing .et_pb_pricing_table%%order_class%%',
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#bebebe',
'style' => 'solid',
),
),
),
'price' => array(
'css' => array(
'main' => array(
'border_radii' => '.et_pb_pricing %%order_class%% .et_pb_pricing_content_top',
'border_styles' => '.et_pb_pricing %%order_class%% .et_pb_pricing_content_top',
),
),
'option_category' => 'border',
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#bebebe',
'style' => 'solid',
),
'composite' => array(
'border_bottom' => array(
'border_width_bottom' => '1px',
),
),
),
),
),
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing_heading h2, {$this->main_css_element} .et_pb_pricing_heading h1.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h3.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h4.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h5.et_pb_pricing_title, {$this->main_css_element} .et_pb_pricing_heading h6.et_pb_pricing_title,
{$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h2, {$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h1.et_pb_pricing_title, {$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h3.et_pb_pricing_title, {$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h4.et_pb_pricing_title, {$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h5.et_pb_pricing_title, {$this->main_css_element}.et_pb_featured_table .et_pb_pricing_heading h6.et_pb_pricing_title",
'important' => 'all',
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'header_level' => array(
'default' => 'h2',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing li",
'limited_main' => "{$this->main_css_element} .et_pb_pricing li, {$this->main_css_element} .et_pb_pricing li span, {$this->main_css_element} .et_pb_pricing li a",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
'subheader' => array(
'label' => esc_html__( 'Subtitle', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_pricing_heading .et_pb_best_value",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
),
'price' => array(
'label' => esc_html__( 'Price', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_et_price .et_pb_sum",
'text_align' => "{$this->main_css_element} .et_pb_pricing_content_top",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'options_priority' => array(
'price_text_color' => 8,
),
),
'currency_frequency' => array(
'label' => esc_html__( 'Currency &amp; Frequency', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_dollar_sign, {$this->main_css_element} .et_pb_frequency",
),
'hide_text_align' => true,
),
'excluded' => array(
'label' => esc_html__( 'Excluded Item', 'et_builder' ),
'css' => array(
'main' => '%%order_class%% ul.et_pb_pricing li.et_pb_not_available, %%order_class%% ul.et_pb_pricing li.et_pb_not_available span, %%order_class%% ul.et_pb_pricing li.et_pb_not_available a',
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element}.et_pb_pricing_table",
),
'settings' => array(
'color' => 'alpha',
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => ".et_pb_pricing {$this->main_css_element} .et_pb_pricing_table_button.et_pb_button",
'limited_main' => ".et_pb_pricing {$this->main_css_element} .et_pb_pricing_table_button.et_pb_button",
'alignment' => ".et_pb_pricing {$this->main_css_element} .et_pb_button_wrapper",
),
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button.et_pb_pricing_table_button',
),
),
),
),
'margin_padding' => array(
'use_margin' => false,
'css' => array(
'important' => 'all', // Need to overwrite pricing table's styling
'main' => '.et_pb_pricing %%order_class%% .et_pb_pricing_heading, .et_pb_pricing %%order_class%% .et_pb_pricing_content_top, .et_pb_pricing %%order_class%% .et_pb_pricing_content',
'padding-right' => '%%order_class%% .et_pb_button_wrapper',
'padding-bottom' => '.et_pb_pricing %%order_class%%',
'padding-left' => '%%order_class%% .et_pb_button_wrapper',
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%%.et_pb_pricing_table, %%order_class%% .et_pb_pricing_content',
'text_shadow' => '%%order_class%% .et_pb_pricing_heading, %%order_class%% .et_pb_pricing_content_top, %%order_class%% .et_pb_pricing_content',
),
),
'max_width' => false,
'height' => false,
'sticky' => false,
);
$this->custom_css_fields = array(
'pricing_heading' => array(
'label' => esc_html__( 'Pricing Heading', 'et_builder' ),
'selector' => '.et_pb_pricing_heading',
),
'pricing_title' => array(
'label' => esc_html__( 'Pricing Title', 'et_builder' ),
'selector' => '.et_pb_pricing_heading h2',
),
'pricing_subtitle' => array(
'label' => esc_html__( 'Pricing Subtitle', 'et_builder' ),
'selector' => '.et_pb_pricing_heading .et_pb_best_value',
),
'pricing_top' => array(
'label' => esc_html__( 'Pricing Top', 'et_builder' ),
'selector' => '.et_pb_pricing_content_top',
),
'price' => array(
'label' => esc_html__( 'Price', 'et_builder' ),
'selector' => '.et_pb_et_price',
),
'currency' => array(
'label' => esc_html__( 'Currency', 'et_builder' ),
'selector' => '.et_pb_dollar_sign',
),
'frequency' => array(
'label' => esc_html__( 'Frequency', 'et_builder' ),
'selector' => '.et_pb_frequency',
),
'pricing_content' => array(
'label' => esc_html__( 'Pricing Content', 'et_builder' ),
'selector' => '.et_pb_pricing_content',
),
'pricing_item' => array(
'label' => esc_html__( 'Pricing Item', 'et_builder' ),
'selector' => 'ul.et_pb_pricing li',
),
'pricing_item_excluded' => array(
'label' => esc_html__( 'Excluded Item', 'et_builder' ),
'selector' => 'ul.et_pb_pricing li.et_pb_not_available',
),
'pricing_button' => array(
'label' => esc_html__( 'Pricing Button', 'et_builder' ),
'selector' => '.et_pb_pricing_table_button',
),
);
}
function get_fields() {
$fields = array(
'featured' => array(
'label' => esc_html__( 'Make This Table Featured', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'basic_option',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'description' => esc_html__( 'Featuring a table will make it stand out from the rest.', 'et_builder' ),
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define a title for the pricing table.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'subtitle' => array(
'label' => esc_html__( 'Subtitle', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Define a sub title for the table if desired.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'currency' => array(
'label' => esc_html__( 'Currency', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input your desired currency symbol here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'per' => array(
'label' => esc_html__( 'Frequency', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'If your pricing is subscription based, input the subscription payment cycle here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'sum' => array(
'label' => esc_html__( 'Price', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the value of the product here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'button_url' => array(
'label' => esc_html__( 'Button Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the destination URL for the signup button.', 'et_builder' ),
'toggle_slug' => 'link_options',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Button Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'toggle_slug' => 'link_options',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
'default_on_front' => 'off',
),
'button_text' => array(
'label' => et_builder_i18n( 'Button' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Adjust the text used from the signup button.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => sprintf(
'%1$s<br/> + %2$s<br/> - %3$s',
esc_html__( 'Input a list of features that are/are not included in the product. Separate items on a new line, and begin with either a + or - symbol: ', 'et_builder' ),
esc_html__( 'Included option', 'et_builder' ),
esc_html__( 'Excluded option', 'et_builder' )
),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'bullet_color' => array(
'label' => esc_html__( 'Bullet Color', 'et_builder' ),
'description' => esc_html__( "Pick a color to use for the bullets that appear next to each list item within the pricing table's feature area.", 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'bullet',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'price_background_color' => array(
'label' => esc_html__( 'Pricing Area Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the background area that appears behind the pricing text.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'price',
'priority' => 21,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'header_background_color' => array(
'label' => esc_html__( 'Table Header Background Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'header',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['bullet_color'] = array( 'border-color' => '%%order_class%% ul.et_pb_pricing li span:before' );
$fields['header_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_pricing_heading' );
$fields['price_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_pricing_content_top' );
return $fields;
}
/**
* Inherit value from pricing tables (parent) module
*
* @since 4.6.0
*/
public function maybe_inherit_values() {
global $et_pb_pricing_tables_sticky_transition;
// Module item has no sticky option so we can go ahead and inherit parent's sticky attr.
$this->props['sticky_transition'] = $et_pb_pricing_tables_sticky_transition;
}
/**
* Generates the module's HTML output based on {@see self::$props}.
*
* @since 1.0
*
* @param array $attrs List of unprocessed attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string The module's HTML output.
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_pricing_tables_num,
$et_pb_pricing_tables_icon,
$et_pb_pricing_tables_icon_tablet,
$et_pb_pricing_tables_icon_phone,
$et_pb_pricing_tables_button_rel,
$et_pb_pricing_tables_header_level,
$et_pb_pricing_tables_sticky;
$multi_view = et_pb_multi_view_options( $this );
$featured = $this->props['featured'];
$button_url = $this->props['button_url'];
$button_rel = $this->props['button_rel'];
$button_text = $this->_esc_attr( 'button_text', 'limited' );
$url_new_window = $this->props['url_new_window'];
$button_custom = $this->props['custom_button'];
$header_level = $this->props['header_level'];
$body_text_align_values = et_pb_responsive_options()->get_property_values( $this->props, 'body_text_align' );
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
// Overwrite button rel with pricin tables' button_rel if needed
if ( in_array( $button_rel, array( '', 'off|off|off|off|off' ) ) && '' !== $et_pb_pricing_tables_button_rel ) {
$button_rel = $et_pb_pricing_tables_button_rel;
}
$et_pb_pricing_tables_num++;
$custom_table_icon = 'on' === $button_custom && '' !== $custom_icon ? $custom_icon : $et_pb_pricing_tables_icon;
$custom_table_icon_tablet = 'on' === $button_custom && '' !== $custom_icon_tablet ? $custom_icon_tablet : $et_pb_pricing_tables_icon_tablet;
$custom_table_icon_phone = 'on' === $button_custom && '' !== $custom_icon_phone ? $custom_icon_phone : $et_pb_pricing_tables_icon_phone;
// Bullet color.
$this->generate_styles(
array(
'base_attr_name' => 'bullet_color',
'selector' => '%%order_class%% .et_pb_pricing_content ul.et_pb_pricing li span:before',
'hover_selector' => '%%order_class%% .et_pb_pricing_content ul.et_pb_pricing:hover li span:before',
'css_property' => 'border-color',
'render_slug' => $render_slug,
'type' => 'color',
// Selector begins with current module item selector so this will never be sticky.
'is_sticky_module' => false,
)
);
// Header Background Color. In the parent item, header BG color doesn't has higher selector
// because it uses .et_pb_pricing_table as hover location. So, we should append the same
// parent class here because there is no class can be used to make current selector higher.
$this->generate_styles(
array(
'base_attr_name' => 'header_background_color',
'selector' => '.et_pb_pricing %%order_class%%.et_pb_pricing_table .et_pb_pricing_heading',
'hover_selector' => '.et_pb_pricing %%order_class%%.et_pb_pricing_table:hover .et_pb_pricing_heading',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
// Selector begins with parent module selector so this should use value inherited
// from the parent module for accuracy.
'is_sticky_module' => $et_pb_pricing_tables_sticky,
)
);
// Pricing Area Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'price_background_color',
'selector' => '%%order_class%%.et_pb_pricing_table .et_pb_pricing_content_top',
'hover_selector' => '%%order_class%%.et_pb_pricing_table:hover .et_pb_pricing_content_top',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
// Selector begins with current module item selector so this will never be sticky.
'is_sticky_module' => false,
)
);
// Custom Padding Left On Center.
if ( ! empty( $body_text_align_values ) ) {
foreach ( $body_text_align_values as $body_text_align_device => $body_text_align_value ) {
if ( 'center' !== $body_text_align_value ) {
continue;
}
$padding_left_style = array(
'selector' => '%%order_class%%.et_pb_pricing_table .et_pb_pricing li',
'declaration' => esc_html( 'padding-left: 0;' ),
);
if ( 'desktop' !== $body_text_align_device ) {
$current_media_query = 'tablet' === $body_text_align_device ? 'max_width_980' : 'max_width_767';
$padding_left_style['media_query'] = ET_Builder_Element::get_media_query( $current_media_query );
}
ET_Builder_Element::set_style( $render_slug, $padding_left_style );
}
}
$button_url = trim( $button_url );
$button = $this->render_button(
array(
'button_classname' => array( 'et_pb_pricing_table_button' ),
'button_custom' => '' !== $custom_table_icon || '' !== $custom_table_icon_tablet || '' !== $custom_table_icon_phone ? 'on' : 'off',
'button_rel' => $button_rel,
'button_text' => $button_text,
'button_text_escaped' => true,
'button_url' => $button_url,
'custom_icon' => $custom_table_icon,
'custom_icon_tablet' => $custom_table_icon_tablet,
'custom_icon_phone' => $custom_table_icon_phone,
'url_new_window' => $url_new_window,
'display_button' => ( '' !== $button_url && $multi_view->has_value( 'button_text' ) ),
'multi_view_data' => $multi_view->render_attrs(
array(
'content' => '{{button_text}}',
'visibility' => array(
'button_text' => '__not_empty',
'button_url' => '__not_empty',
),
)
),
)
);
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// inherit header level from parent settings
$header_level = '' === $header_level && '' !== $et_pb_pricing_tables_header_level ? $et_pb_pricing_tables_header_level : $header_level;
$title = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h2' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_pricing_title',
),
)
);
$subtitle = $multi_view->render_element(
array(
'content' => '{{subtitle}}',
'attrs' => array(
'class' => 'et_pb_best_value',
),
)
);
$currency = $multi_view->render_element(
array(
'content' => '{{currency}}',
'attrs' => array(
'class' => 'et_pb_dollar_sign',
),
)
);
$per = $multi_view->render_element(
array(
'content' => '<span class="et_pb_frequency_slash">/</span>{{per}}',
'attrs' => array(
'class' => 'et_pb_frequency',
),
)
);
$sum = $multi_view->render_element(
array(
'content' => '{{sum}}',
'attrs' => array(
'class' => 'et_pb_sum',
),
)
);
// Module classnames
if ( 'off' !== $featured ) {
$this->add_classname( 'et_pb_featured_table' );
}
// Remove automatically added classnames
$this->remove_classname(
array(
'et_pb_module',
)
);
$content = $multi_view->render_element(
array(
'tag' => 'ul',
'content' => '{{content}}',
'attrs' => array(
'class' => 'et_pb_pricing',
),
)
);
$output = sprintf(
'<div class="%1$s">
%10$s
%9$s
<div class="et_pb_pricing_heading">
%2$s
%3$s
</div>
<div class="et_pb_pricing_content_top">
<span class="et_pb_et_price">%6$s%7$s%8$s</span>
</div>
<div class="et_pb_pricing_content">
%4$s
</div>
%5$s
</div>',
$this->module_classname( $render_slug ),
et_core_esc_previously( $title ),
et_core_esc_previously( $subtitle ),
et_core_esc_previously( $content ),
et_core_esc_previously( $button ),
et_core_esc_previously( $currency ),
et_core_esc_previously( $sum ),
et_core_esc_previously( $per ),
$video_background,
$parallax_image_background
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
$context = isset( $args['context'] ) ? $args['context'] : '';
if ( $raw_value && 'content' === $name && 'content' === $context ) {
return do_shortcode( et_pb_fix_shortcodes( et_pb_extract_items( $raw_value ) ) );
}
$fields_need_escape = array(
'title',
'subtitle',
'currency',
'per',
'sum',
'button_text',
);
if ( $raw_value && 'content' === $context && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Pricing_Tables_Item();
}

View File

@ -0,0 +1,433 @@
<?php
class ET_Builder_Module_Search extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Search', 'et_builder' );
$this->plural = esc_html__( 'Searches', 'et_builder' );
$this->slug = 'et_pb_search';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'elements' => et_builder_i18n( 'Elements' ),
'exceptions' => esc_html__( 'Exceptions', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'width' => array(
'title' => et_builder_i18n( 'Sizing' ),
'priority' => 65,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} input.et_pb_searchsubmit",
'important' => array( 'line-height', 'text-shadow' ),
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'letter_spacing' => array(
'default' => '0px',
),
'hide_text_align' => true,
),
),
'margin_padding' => array(
'css' => array(
'padding' => "{$this->main_css_element} input.et_pb_s",
'important' => 'all',
),
'custom_padding' => array(
'default' => '0.715em|0.715em|0.715em|0.715em|false|false',
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element} input.et_pb_s",
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element}.et_pb_search, {$this->main_css_element} input.et_pb_s",
'border_styles' => "{$this->main_css_element}.et_pb_search",
),
),
'defaults' => array(
'border_radii' => 'on|3px|3px|3px|3px',
'border_styles' => array(
'width' => '1px',
'color' => '#dddddd',
'style' => 'solid',
),
),
),
),
'text' => array(
'use_background_layout' => true,
'css' => array(
'main' => "{$this->main_css_element} input.et_pb_searchsubmit, {$this->main_css_element} input.et_pb_s",
'text_shadow' => "{$this->main_css_element} input.et_pb_searchsubmit, {$this->main_css_element} input.et_pb_s",
),
'text_orientation' => array(
'exclude_options' => array( 'justified' ),
),
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
),
'button' => false,
'link_options' => false,
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Field', 'et_builder' ),
'css' => array(
'main' => '%%order_class%% form input.et_pb_s',
'hover' => '%%order_class%% form input.et_pb_s:hover',
'focus' => '%%order_class%% form input.et_pb_s:focus',
'focus_hover' => '%%order_class%% form input.et_pb_s:focus:hover',
),
'placeholder' => false,
'margin_padding' => false,
'box_shadow' => false,
'border_styles' => false,
'font_field' => array(
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% form input.et_pb_s',
'%%order_class%% form input.et_pb_s::placeholder',
'%%order_class%% form input.et_pb_s::-webkit-input-placeholder',
'%%order_class%% form input.et_pb_s::-ms-input-placeholder',
'%%order_class%% form input.et_pb_s::-moz-placeholder',
)
),
'placeholder' => true,
'important' => array( 'line-height', 'text-shadow' ),
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
),
),
'overflow' => array(
'default' => 'hidden',
),
);
$this->custom_css_fields = array(
'input_field' => array(
'label' => esc_html__( 'Input Field', 'et_builder' ),
'selector' => 'input.et_pb_s',
),
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'selector' => 'input.et_pb_searchsubmit',
),
);
$this->help_videos = array(
array(
'id' => 'HNmb20Mdvno',
'name' => esc_html__( 'An introduction to the Search module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'exclude_pages' => array(
'label' => esc_html__( 'Exclude Pages', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'description' => esc_html__( 'Turning this on will exclude Pages from search results', 'et_builder' ),
'toggle_slug' => 'exceptions',
),
'exclude_posts' => array(
'label' => esc_html__( 'Exclude Posts', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default' => 'off',
'affects' => array(
'include_categories',
),
'description' => esc_html__( 'Turning this on will exclude Posts from search results', 'et_builder' ),
'toggle_slug' => 'exceptions',
),
'include_categories' => array(
'label' => esc_html__( 'Exclude Categories', 'et_builder' ),
'type' => 'categories',
'option_category' => 'basic_option',
'renderer_options' => array(
'use_terms' => false,
),
'depends_show_if' => 'off',
'description' => esc_html__( 'Choose which categories you would like to exclude from the search results.', 'et_builder' ),
'toggle_slug' => 'exceptions',
),
'show_button' => array(
'label' => esc_html__( 'Show Button', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'Turn this on to show the Search button', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'placeholder' => array(
'label' => esc_html__( 'Input Placeholder', 'et_builder' ),
'type' => 'text',
'description' => esc_html__( 'Type the text you want to use as placeholder for the search field.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'button_color' => array(
'label' => esc_html__( 'Button and Border Color', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'button',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'placeholder_color' => array(
'label' => esc_html__( 'Placeholder Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to be used for the placeholder written inside input fields.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'form_field',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['button_color'] = array(
'background-color' => '%%order_class%% input.et_pb_searchsubmit',
'border-color' => array(
'%%order_class%% input.et_pb_searchsubmit',
'%%order_class%% input.et_pb_s',
),
);
$fields['placeholder_color'] = array(
'color' => array(
'%%order_class%% form input.et_pb_s::placeholder',
'%%order_class%% form input.et_pb_s::-webkit-input-placeholder',
'%%order_class%% form input.et_pb_s::-ms-input-placeholder',
'%%order_class%% form input.et_pb_s::-moz-placeholder',
),
);
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$exclude_categories = $this->props['include_categories'];
$exclude_posts = $this->props['exclude_posts'];
$exclude_pages = $this->props['exclude_pages'];
$show_button = $this->props['show_button'];
$placeholder = $multi_view->render_element(
array(
'tag' => 'input',
'attrs' => array(
'type' => 'text',
'name' => 's',
'class' => 'et_pb_s',
'placeholder' => '{{placeholder}}',
),
)
);
$input_line_height = $this->props['form_field_line_height'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$this->content = et_builder_replace_code_content_entities( $this->content );
// Button Color.
$this->generate_styles(
array(
'base_attr_name' => 'button_color',
'selector' => '%%order_class%% input.et_pb_searchsubmit',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => array( 'background-color', 'border-color' ),
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
$this->generate_styles(
array(
'base_attr_name' => 'button_color',
'selector' => '%%order_class%% input.et_pb_s',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'border-color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Placeholder Color.
$placeholder_selectors = array(
'%%order_class%% form input.et_pb_s::-webkit-input-placeholder',
'%%order_class%% form input.et_pb_s::-moz-placeholder',
'%%order_class%% form input.et_pb_s:-ms-input-placeholder',
);
$this->generate_styles(
array(
'base_attr_name' => 'placeholder_color',
'selector' => join( ', ', $placeholder_selectors ),
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
if ( '' !== $input_line_height ) {
$el_style = array(
'selector' => '%%order_class%% input.et_pb_s',
'declaration' => 'height: auto; min-height: 0;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname( true ),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( 'on' !== $show_button ) {
$this->add_classname( 'et_pb_hide_search_button' );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$multi_view_show_button_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_hide_search_button' => array(
'show_button' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%2$s"%12$s%13$s>
%11$s
%10$s
<form role="search" method="get" class="et_pb_searchform" action="%1$s">
<div>
<label class="screen-reader-text" for="s">%8$s</label>
%7$s
<input type="hidden" name="et_pb_searchform_submit" value="et_search_proccess" />
%4$s
%5$s
%6$s
<input type="submit" value="%9$s" class="et_pb_searchsubmit">
</div>
</form>
</div>',
esc_url( home_url( '/' ) ),
$this->module_classname( $render_slug ),
$this->module_id(),
'' !== $exclude_categories ? sprintf( '<input type="hidden" name="et_pb_search_cat" value="%1$s" />', esc_attr( $exclude_categories ) ) : '',
'on' !== $exclude_posts ? '<input type="hidden" name="et_pb_include_posts" value="yes" />' : '', // #5
'on' !== $exclude_pages ? '<input type="hidden" name="et_pb_include_pages" value="yes" />' : '',
$placeholder,
esc_html__( 'Search for:', 'et_builder' ),
esc_attr__( 'Search', 'et_builder' ),
$video_background, // #10
$parallax_image_background,
et_core_esc_previously( $data_background_layout ),
$multi_view_show_button_data_attr
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Search();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,261 @@
<?php
class ET_Builder_Module_Sidebar extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Sidebar', 'et_builder' );
$this->plural = esc_html__( 'Sidebars', 'et_builder' );
$this->slug = 'et_pb_sidebar';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_widget_area';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Content' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h3:first-of-type, {$this->main_css_element} h4:first-of-type, {$this->main_css_element} h5:first-of-type, {$this->main_css_element} h6:first-of-type, {$this->main_css_element} h2:first-of-type, {$this->main_css_element} h1:first-of-type, {$this->main_css_element} .widget-title, {$this->main_css_element} .widgettitle",
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element}, {$this->main_css_element} li, {$this->main_css_element} li:before, {$this->main_css_element} a",
'line_height' => "{$this->main_css_element} p",
),
),
),
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%%',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => '%%order_class%%, %%order_class%% .widgettitle',
),
),
'button' => false,
);
$this->custom_css_fields = array(
'widget' => array(
'label' => esc_html__( 'Widget', 'et_builder' ),
'selector' => '.et_pb_widget',
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'selector' => 'h4.widgettitle',
),
);
$this->help_videos = array(
array(
'id' => '468VROeyKq4',
'name' => esc_html__( 'An introduction to the Sidebar module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'orientation' => array(
'label' => esc_html__( 'Alignment', 'et_builder' ),
'type' => 'select',
'option_category' => 'layout',
'options' => array(
'left' => et_builder_i18n( 'Left' ),
'right' => et_builder_i18n( 'Right' ),
),
'default_on_front' => 'left',
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
'description' => esc_html__( 'Choose which side of the page your sidebar will be on. This setting controls text orientation and border position.', 'et_builder' ),
),
'area' => array(
'label' => esc_html__( 'Widget Area', 'et_builder' ),
'type' => 'select_sidebar',
'option_category' => 'basic_option',
'description' => esc_html__( 'Select a widget-area that you would like to display. You can create new widget areas within the Appearances > Widgets tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'computed_affects' => array(
'__sidebars',
),
),
'show_border' => array(
'label' => esc_html__( 'Show Border Separator', 'et_builder' ),
'description' => esc_html__( 'Disabling the border separator will remove the solid line that appears to the left or right of sidebar widgets.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'layout',
),
'__sidebars' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Sidebar', 'get_sidebar' ),
'computed_depends_on' => array(
'area',
),
),
);
return $fields;
}
static function get_default_area() {
global $wp_registered_sidebars;
if ( ! empty( $wp_registered_sidebars ) ) {
// Pluck sidebar ids
$sidebar_ids = wp_list_pluck( $wp_registered_sidebars, 'id' );
// Return first sidebar id
return array_shift( $sidebar_ids );
}
return '';
}
/**
* Get sidebar data for sidebar module
*
* @param string comma separated gallery ID
* @param string on|off to determine grid / slider layout
* @param array passed current page params
*
* @return string JSON encoded array of attachments data
*/
static function get_sidebar( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'area' => '',
);
$args = wp_parse_args( $args, $defaults );
// Get any available widget areas so it isn't empty
if ( '' === $args['area'] ) {
$args['area'] = self::get_default_area();
}
// Outputs sidebar
$widgets = '';
ob_start();
if ( is_active_sidebar( $args['area'] ) ) {
dynamic_sidebar( $args['area'] );
}
$widgets = ob_get_contents();
ob_end_clean();
return $widgets;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$orientation = $this->props['orientation'];
$area = '' === $this->props['area'] ? self::get_default_area() : $this->props['area'];
$show_border = $this->props['show_border'];
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$widgets = '';
ob_start();
if ( is_active_sidebar( $area ) ) {
dynamic_sidebar( $area );
}
$widgets = ob_get_contents();
ob_end_clean();
// Module classnames
$this->add_classname(
array(
'et_pb_widget_area',
'clearfix',
"et_pb_widget_area_{$orientation}",
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( 'on' !== $show_border ) {
$this->add_classname( 'et_pb_sidebar_no_border' );
}
// Remove automatically added classnames
$this->remove_classname(
array(
$render_slug,
)
);
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$output = sprintf(
'<div%3$s class="%2$s"%6$s>
%5$s
%4$s
%1$s
</div>',
$widgets,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background, // #5
et_core_esc_previously( $data_background_layout )
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Sidebar();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,207 @@
<?php
class ET_Builder_Module_Signup_Item extends ET_Builder_Module {
public $child_title_var = 'field_title';
public $bb_support = false;
public $main_css_element = '.et_pb_newsletter_form %%order_class%%';
public $no_render = true;
public $slug = 'et_pb_signup_custom_field';
public $type = 'child';
public $vb_support = 'on';
public function init() {
$this->name = esc_html__( 'Custom Field', 'et_builder' );
$this->plural = esc_html__( 'Custom Fields', 'et_builder' );
$this->advanced_setting_title_text = $this->name;
$this->settings_text = esc_html__( 'Custom Field Settings', 'et_builder' );
}
public function get_advanced_fields_config() {
return array(
'background' => array(
'css' => array(
'main' => '%%order_class%%',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', '.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%%' ),
'border_styles' => sprintf( '%1$s .input, %1$s .input[type="checkbox"] + label i, %1$s .input[type="radio"] + label i', '.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%%' ),
),
'important' => 'plugin_only',
),
'label_prefix' => esc_html__( 'Input', 'et_builder' ),
'defaults' => array(
'border_radii' => 'on|3px|3px|3px|3px',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
'fields_after' => array(
'use_focus_border_color' => array(
'label' => esc_html__( 'Use Focus Borders', 'et_builder' ),
'description' => esc_html__( 'Enabling this option will add borders to input fields when focused.', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'color_option',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'affects' => array(
'border_radii_focus',
'border_styles_focus',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'border',
'default_on_front' => 'off',
),
),
),
'focus' => array(
'label_prefix' => esc_html__( 'Input Focus', 'et_builder' ),
'css' => array(
'main' => array(
'border_radii' => sprintf( '%1$s .input:focus, %1$s .input[type="checkbox"]:focus + label i, %1$s .input[type="radio"]:focus + label i', '.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%%' ),
'border_styles' => sprintf( '%1$s .input:focus, %1$s .input[type="checkbox"]:focus + label i, %1$s .input[type="radio"]:focus + label i', '.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%%' ),
),
'important' => 'plugin_only',
),
'option_category' => 'border',
'tab_slug' => 'advanced',
'toggle_slug' => 'border',
'depends_on' => array( 'use_focus_border_color' ),
'depends_show_if' => 'on',
'defaults' => array(
'border_radii' => 'on|3px|3px|3px|3px',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% input',
'%%order_class%% select',
'%%order_class%% textarea',
'%%order_class%% .et_pb_contact_field_options_list label > i',
)
),
'important' => true,
),
),
),
'filters' => array(
'css' => array(
'main' => array(
'%%order_class%% input',
'%%order_class%% textarea',
'%%order_class%% label',
),
),
),
'margin_padding' => array(
'css' => array(
'main' => '.et_pb_newsletter_form p%%order_class%%',
'padding' => '.et_pb_newsletter_form p%%order_class%%.et_pb_newsletter_field.et_pb_signup_custom_field',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% input, %%order_class%% textarea, %%order_class%% label',
),
),
'text_shadow' => array(
// Don't add text-shadow fields since they already are via font-options
'default' => false,
),
'form_field' => array(
'form_field' => array(
'label' => esc_html__( 'Field', 'et_builder' ),
'css' => array(
'main' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input',
'background_color' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% input[type="text"], .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% select, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="checkbox"] + label i, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="radio"] + label i',
'background_color_hover' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% input[type="text"]:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% select:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="checkbox"] + label:hover i, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="radio"] + label:hover i',
'focus_background_color' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% input.input:focus, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:focus, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% select:focus',
'form_text_color' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% input[type="text"], .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% select, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="checkbox"] + label i:before',
'form_text_color_hover' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% input[type="text"]:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% select:hover, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input[type="checkbox"] + label:hover i:before',
'focus_text_color' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input:focus',
'placeholder_focus' => '.et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input:focus::-webkit-input-placeholder, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input:focus::-moz-placeholder, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% .input:focus:-ms-input-placeholder, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:focus::-webkit-input-placeholder, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:focus::-moz-placeholder, .et_pb_newsletter_form .et_pb_newsletter_fields %%order_class%% textarea:focus:-ms-input-placeholder',
'important' => array( 'form_text_color', 'padding', 'margin' ),
),
'margin_padding' => false,
'box_shadow' => false,
'border_styles' => false,
'font_field' => array(
'css' => array(
'main' => array(
'%%order_class%%.et_pb_contact_field .et_pb_contact_field_options_title',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input::-webkit-input-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input::-moz-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input:-ms-input-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input[type=checkbox] + label',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input[type=radio] + label',
),
'hover' => array(
'%%order_class%%.et_pb_contact_field .et_pb_contact_field_options_title:hover',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input:hover',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input:hover::-webkit-input-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input:hover::-moz-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input:hover:-ms-input-placeholder',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input[type=checkbox] + label:hover',
'.et_pb_newsletter_form .et_pb_newsletter_fields p%%order_class%% .input[type=radio] + label:hover',
),
'important' => 'plugin_only',
),
),
),
),
'sticky' => false,
);
}
public function get_fields() {
$fields = ET_Core_API_Email_Fields::get_definitions( 'builder' );
// Remove field background color because we already have one that support responsive settings
// on Form Field element.
if ( isset( $fields['field_background_color'] ) ) {
unset( $fields['field_background_color'] );
}
return $fields;
}
public function get_settings_modal_toggles() {
return array(
'general' => array(
'toggles' => array(
'main_content' => esc_html__( 'Field', 'et_builder' ),
'field_options' => esc_html__( 'Field Options', 'et_builder' ),
'conditional_logic' => esc_html__( 'Conditional Logic', 'et_builder' ),
'background' => et_builder_i18n( 'Background' ),
),
),
'advanced' => array(
'toggles' => array(
'layout' => et_builder_i18n( 'Layout' ),
),
),
);
}
}
new ET_Builder_Module_Signup_Item();

View File

@ -0,0 +1,819 @@
<?php
require_once 'helpers/Slider.php';
class ET_Builder_Module_Slider extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Slider', 'et_builder' );
$this->plural = esc_html__( 'Sliders', 'et_builder' );
$this->slug = 'et_pb_slider';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_slide';
$this->child_item_text = et_builder_i18n( 'Slide' );
$this->main_css_element = '%%order_class%%.et_pb_slider';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'overlay' => et_builder_i18n( 'Overlay' ),
'navigation' => esc_html__( 'Navigation', 'et_builder' ),
'image' => et_builder_i18n( 'Image' ),
'layout' => et_builder_i18n( 'Layout' ),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 90,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_slide_description .et_pb_slide_title",
'limited_main' => "{$this->main_css_element} .et_pb_slide_description .et_pb_slide_title, {$this->main_css_element} .et_pb_slide_description .et_pb_slide_title a",
'font_size_tablet' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_description .et_pb_slide_title",
'font_size_phone' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_description .et_pb_slide_title",
'important' => array( 'size', 'font-size', 'plugin_all' ),
),
'header_level' => array(
'default' => 'h2',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'line_height' => "{$this->main_css_element}",
'main' => "{$this->main_css_element} .et_pb_slide_content",
'line_height_tablet' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_content",
'line_height_phone' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_content",
'font_size_tablet' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_content",
'font_size_phone' => "{$this->main_css_element} .et_pb_slides .et_pb_slide_content",
'important' => array( 'size', 'font-size' ),
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
),
'borders' => array(
'default' => array(),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_slide_image img',
'border_styles' => '%%order_class%% .et_pb_slide_image img',
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'depends_show_if' => 'off',
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_slide_image img',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'button' => array(
'button' => array(
'label' => et_builder_i18n( 'Button' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_more_button.et_pb_button",
'limited_main' => "{$this->main_css_element} .et_pb_more_button.et_pb_button",
'alignment' => "{$this->main_css_element} .et_pb_button_wrapper",
),
'use_alignment' => true,
'box_shadow' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_button',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
),
),
'background' => array(
'use_background_color' => 'fields_only',
'use_background_color_gradient' => 'fields_only',
'use_background_image' => 'fields_only',
'options' => array(
'parallax_method' => array(
'default' => 'off',
),
),
),
'margin_padding' => array(
'css' => array(
'main' => '%%order_class%%',
'padding' => '%%order_class%% .et_pb_slide_description, .et_pb_slider_fullwidth_off%%order_class%% .et_pb_slide_description',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => array(
'css' => array(
'text_orientation' => '%%order_class%% .et_pb_slide .et_pb_slide_description',
'text_shadow' => '%%order_class%% .et_pb_slide .et_pb_slide_description',
),
'options' => array(
'text_orientation' => array(
'default' => 'center',
),
),
),
'height' => array(
'css' => array(
'main' => '%%order_class%%, %%order_class%% .et_pb_slide',
),
),
'image' => array(
'css' => array(
'main' => array(
'%%order_class%% .et_pb_slide_image',
'%%order_class%% .et_pb_section_video_bg',
),
),
),
'max_width' => array(
'extra' => array(
'content' => array(
'use_module_alignment' => false,
'css' => array(
'main' => '%%order_class%% .et_pb_slide > .et_pb_container',
),
'options' => array(
'width' => array(
'label' => esc_html__( 'Content Width', 'et_builder' ),
'default' => '100%',
),
'max_width' => array(
'label' => esc_html__( 'Content Max Width', 'et_builder' ),
),
),
),
),
),
'position_fields' => array(
'default' => 'relative',
),
'overflow' => array(
'default' => 'hidden',
),
);
$this->custom_css_fields = array(
'slide_description' => array(
'label' => esc_html__( 'Slide Description', 'et_builder' ),
'selector' => '.et_pb_slide_description',
),
'slide_title' => array(
'label' => esc_html__( 'Slide Title', 'et_builder' ),
'selector' => '.et_pb_slide_description .et_pb_slide_title',
),
'slide_button' => array(
'label' => esc_html__( 'Slide Button', 'et_builder' ),
'selector' => '.et_pb_slider .et_pb_slide .et_pb_slide_description a.et_pb_more_button.et_pb_button',
'no_space_before_selector' => true,
),
'slide_controllers' => array(
'label' => esc_html__( 'Slide Controllers', 'et_builder' ),
'selector' => '.et-pb-controllers',
),
'slide_active_controller' => array(
'label' => esc_html__( 'Slide Active Controller', 'et_builder' ),
'selector' => '.et-pb-controllers .et-pb-active-control',
),
'slide_image' => array(
'label' => esc_html__( 'Slide Image', 'et_builder' ),
'selector' => '.et_pb_slide_image',
),
'slide_arrows' => array(
'label' => esc_html__( 'Slide Arrows', 'et_builder' ),
'selector' => '.et-pb-slider-arrows a',
),
);
$this->help_videos = array(
array(
'id' => '-YeoR2xSLOY',
'name' => esc_html__( 'An introduction to the Slider module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'show_arrows' => array(
'label' => esc_html__( 'Show Arrows', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'This setting will turn on and off the navigation arrows.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_pagination' => array(
'label' => esc_html__( 'Show Controls', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'This setting will turn on and off the circle buttons at the bottom of the slider.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_content_on_mobile' => array(
'label' => esc_html__( 'Show Content On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'show_cta_on_mobile' => array(
'label' => esc_html__( 'Show CTA On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'show_image_video_mobile' => array(
'label' => esc_html__( 'Show Image / Video On Mobile', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'layout',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
),
'use_bg_overlay' => array(
'label' => esc_html__( 'Use Background Overlay', 'et_builder' ),
'description' => esc_html__( 'When enabled, a custom overlay color will be added above your background image and behind your slider content.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
// Uses cached uppercase translation but keeps the lowercase not change definition content.
'on' => strtolower( et_builder_i18n( 'Yes' ) ),
),
'default_on_front' => '',
'affects' => array(
'bg_overlay_color',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
),
'bg_overlay_color' => array(
'label' => esc_html__( 'Background Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Use the color picker to choose a color for the background overlay.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
'mobile_options' => true,
'sticky' => true,
),
'use_text_overlay' => array(
'label' => esc_html__( 'Use Text Overlay', 'et_builder' ),
'description' => esc_html__( 'When enabled, a background color is added behind the slider text to make it more readable atop background images.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
// Uses cached uppercase translation but keeps the lowercase not change definition content.
'on' => strtolower( et_builder_i18n( 'Yes' ) ),
),
'default_on_front' => '',
'affects' => array(
'text_overlay_color',
'text_border_radius',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
),
'text_overlay_color' => array(
'label' => esc_html__( 'Text Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Use the color picker to choose a color for the text overlay.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'option_category' => 'configuration',
'mobile_options' => true,
'sticky' => true,
),
'text_border_radius' => array(
'label' => esc_html__( 'Text Overlay Border Radius', 'et_builder' ),
'description' => esc_html__( 'Increasing the border radius will increase the roundness of the overlay corners. Setting this value to 0 will result in squared corners.', 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '3',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'mobile_options' => true,
'sticky' => true,
),
'arrows_custom_color' => array(
'label' => esc_html__( 'Arrow Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the slider arrows that are used to navigate through each slide.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'navigation',
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'dot_nav_custom_color' => array(
'label' => esc_html__( 'Dot Navigation Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the dot navigation that appears at the bottom of the slider to designate which slide is active.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'navigation',
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['dot_nav_custom_color'] = array( 'background-color' => et_pb_slider_options()->get_dots_selector() );
$fields['arrows_custom_color'] = array( 'all' => et_pb_slider_options()->get_arrows_selector() );
return $fields;
}
function before_render() {
global $et_pb_slider_has_video, $et_pb_slider_parallax, $et_pb_slider_parallax_method, $et_pb_slider_show_mobile, $et_pb_slider_custom_icon, $et_pb_slider_custom_icon_tablet, $et_pb_slider_custom_icon_phone, $et_pb_slider_item_num, $et_pb_slider_button_rel;
global $et_pb_slider_parent_type;
$et_pb_slider_parent_type = $this->slug;
$et_pb_slider_item_num = 0;
$sticky = et_pb_sticky_options();
$parallax = $this->props['parallax'];
$parallax_method = $this->props['parallax_method'];
$show_content_on_mobile = $this->props['show_content_on_mobile'];
$show_cta_on_mobile = $this->props['show_cta_on_mobile'];
$button_rel = $this->props['button_rel'];
$button_custom = $this->props['custom_button'];
$custom_icon_values = et_pb_responsive_options()->get_property_values( $this->props, 'button_icon' );
$custom_icon = isset( $custom_icon_values['desktop'] ) ? $custom_icon_values['desktop'] : '';
$custom_icon_tablet = isset( $custom_icon_values['tablet'] ) ? $custom_icon_values['tablet'] : '';
$custom_icon_phone = isset( $custom_icon_values['phone'] ) ? $custom_icon_values['phone'] : '';
$et_pb_slider_has_video = false;
$et_pb_slider_parallax = $parallax;
$et_pb_slider_parallax_method = $parallax_method;
$et_pb_slider_show_mobile = array(
'show_content_on_mobile' => $show_content_on_mobile,
'show_cta_on_mobile' => $show_cta_on_mobile,
);
$et_pb_slider_custom_icon = 'on' === $button_custom ? $custom_icon : '';
$et_pb_slider_custom_icon_tablet = 'on' === $button_custom ? $custom_icon_tablet : '';
$et_pb_slider_custom_icon_phone = 'on' === $button_custom ? $custom_icon_phone : '';
$et_pb_slider_button_rel = $button_rel;
// BG Overlay Color.
$bg_overlay_color = $this->props['bg_overlay_color'];
$bg_overlay_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'bg_overlay_color' );
$bg_overlay_color_tablet = isset( $bg_overlay_color_values['tablet'] ) ? $bg_overlay_color_values['tablet'] : '';
$bg_overlay_color_phone = isset( $bg_overlay_color_values['phone'] ) ? $bg_overlay_color_values['phone'] : '';
// Text Overlay Color.
$text_overlay_color = $this->props['text_overlay_color'];
$text_overlay_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'text_overlay_color' );
$text_overlay_color_tablet = isset( $text_overlay_color_values['tablet'] ) ? $text_overlay_color_values['tablet'] : '';
$text_overlay_color_phone = isset( $text_overlay_color_values['phone'] ) ? $text_overlay_color_values['phone'] : '';
// Text Border Radius.
$text_border_radius = $this->props['text_border_radius'];
$text_border_radius_values = et_pb_responsive_options()->get_property_values( $this->props, 'text_border_radius' );
$text_border_radius_tablet = isset( $text_border_radius_values['tablet'] ) ? $text_border_radius_values['tablet'] : '';
$text_border_radius_phone = isset( $text_border_radius_values['phone'] ) ? $text_border_radius_values['phone'] : '';
// Arrows Color.
$arrows_custom_color = $this->props['arrows_custom_color'];
$arrows_custom_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'arrows_custom_color' );
$arrows_custom_color_tablet = isset( $arrows_custom_color_values['tablet'] ) ? $arrows_custom_color_values['tablet'] : '';
$arrows_custom_color_phone = isset( $arrows_custom_color_values['phone'] ) ? $arrows_custom_color_values['phone'] : '';
// Dot Nav Custom Color.
$dot_nav_custom_color = $this->props['dot_nav_custom_color'];
$dot_nav_custom_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'dot_nav_custom_color' );
$dot_nav_custom_color_tablet = isset( $dot_nav_custom_color_values['tablet'] ) ? $dot_nav_custom_color_values['tablet'] : '';
$dot_nav_custom_color_phone = isset( $dot_nav_custom_color_values['phone'] ) ? $dot_nav_custom_color_values['phone'] : '';
// Pass Slider Module setting to Slide Item
global $et_pb_slider;
$et_pb_slider = array(
'background_last_edited' => $this->props['background_last_edited'],
'background__hover_enabled' => isset( $this->props['background__hover_enabled'] ) ? $this->props['background__hover_enabled'] : '',
// Background Color.
'background_enable_color' => $this->props['background_enable_color'],
'background_enable_color_tablet' => $this->props['background_enable_color_tablet'],
'background_enable_color_phone' => $this->props['background_enable_color_phone'],
'background_enable_color__hover' => isset( $this->props['background_enable_color__hover'] ) ? $this->props['background_enable_color__hover'] : '',
'background_color' => $this->props['background_color'],
'background_color_tablet' => $this->props['background_color_tablet'],
'background_color_phone' => $this->props['background_color_phone'],
'background_color__hover' => isset( $this->props['background_color__hover'] ) ? $this->props['background_color__hover'] : '',
// Background Gradient.
'use_background_color_gradient' => $this->props['use_background_color_gradient'],
'use_background_color_gradient_tablet' => $this->props['use_background_color_gradient_tablet'],
'use_background_color_gradient_phone' => $this->props['use_background_color_gradient_phone'],
'use_background_color_gradient__hover' => isset( $this->props['use_background_color_gradient__hover'] ) ? $this->props['use_background_color_gradient__hover'] : '',
'background_color_gradient_type' => $this->props['background_color_gradient_type'],
'background_color_gradient_type_tablet' => $this->props['background_color_gradient_type_tablet'],
'background_color_gradient_type_phone' => $this->props['background_color_gradient_type_phone'],
'background_color_gradient_type__hover' => isset( $this->props['background_color_gradient_type__hover'] ) ? $this->props['background_color_gradient_type__hover'] : '',
'background_color_gradient_direction' => $this->props['background_color_gradient_direction'],
'background_color_gradient_direction_tablet' => $this->props['background_color_gradient_direction_tablet'],
'background_color_gradient_direction_phone' => $this->props['background_color_gradient_direction_phone'],
'background_color_gradient_direction__hover' => isset( $this->props['background_color_gradient_direction__hover'] ) ? $this->props['background_color_gradient_direction__hover'] : '',
'background_color_gradient_direction_radial' => $this->props['background_color_gradient_direction_radial'],
'background_color_gradient_direction_radial_tablet' => $this->props['background_color_gradient_direction_radial_tablet'],
'background_color_gradient_direction_radial_phone' => $this->props['background_color_gradient_direction_radial_phone'],
'background_color_gradient_direction_radial__hover' => isset( $this->props['background_color_gradient_direction_radial__hover'] ) ? $this->props['background_color_gradient_direction_radial__hover'] : '',
'background_color_gradient_start' => $this->props['background_color_gradient_start'],
'background_color_gradient_start_tablet' => $this->props['background_color_gradient_start_tablet'],
'background_color_gradient_start_phone' => $this->props['background_color_gradient_start_phone'],
'background_color_gradient_start__hover' => isset( $this->props['background_color_gradient_start__hover'] ) ? $this->props['background_color_gradient_start__hover'] : '',
'background_color_gradient_end' => $this->props['background_color_gradient_end'],
'background_color_gradient_end_tablet' => $this->props['background_color_gradient_end_tablet'],
'background_color_gradient_end_phone' => $this->props['background_color_gradient_end_phone'],
'background_color_gradient_end__hover' => isset( $this->props['background_color_gradient_end__hover'] ) ? $this->props['background_color_gradient_end__hover'] : '',
'background_color_gradient_start_position' => $this->props['background_color_gradient_start_position'],
'background_color_gradient_start_position_tablet' => $this->props['background_color_gradient_start_position_tablet'],
'background_color_gradient_start_position_phone' => $this->props['background_color_gradient_start_position_phone'],
'background_color_gradient_start_position__hover' => isset( $this->props['background_color_gradient_start_position__hover'] ) ? $this->props['background_color_gradient_start_position__hover'] : '',
'background_color_gradient_end_position' => $this->props['background_color_gradient_end_position'],
'background_color_gradient_end_position_tablet' => $this->props['background_color_gradient_end_position_tablet'],
'background_color_gradient_end_position_phone' => $this->props['background_color_gradient_end_position_phone'],
'background_color_gradient_end_position__hover' => isset( $this->props['background_color_gradient_end_position__hover'] ) ? $this->props['background_color_gradient_end_position__hover'] : '',
'background_color_gradient_overlays_image' => $this->props['background_color_gradient_overlays_image'],
'background_color_gradient_overlays_image_tablet' => $this->props['background_color_gradient_overlays_image_tablet'],
'background_color_gradient_overlays_image_phone' => $this->props['background_color_gradient_overlays_image_phone'],
'background_color_gradient_overlays_image__hover' => isset( $this->props['background_color_gradient_overlays_image__hover'] ) ? $this->props['background_color_gradient_overlays_image__hover'] : '',
// Background Image.
'background_enable_image' => $this->props['background_enable_image'],
'background_enable_image_tablet' => $this->props['background_enable_image_tablet'],
'background_enable_image_phone' => $this->props['background_enable_image_phone'],
'background_enable_image__hover' => isset( $this->props['background_enable_image__hover'] ) ? $this->props['background_enable_image__hover'] : '',
'background_image' => $this->props['background_image'],
'background_image_tablet' => $this->props['background_image_tablet'],
'background_image_phone' => $this->props['background_image_phone'],
'background_image__hover' => isset( $this->props['background_image__hover'] ) ? $this->props['background_image__hover'] : '',
'background_size' => $this->props['background_size'],
'background_size_tablet' => $this->props['background_size_tablet'],
'background_size_phone' => $this->props['background_size_phone'],
'background_size__hover' => isset( $this->props['background_size__hover'] ) ? $this->props['background_size__hover'] : '',
'background_position' => $this->props['background_position'],
'background_position_tablet' => $this->props['background_position_tablet'],
'background_position_phone' => $this->props['background_position_phone'],
'background_position__hover' => isset( $this->props['background_position__hover'] ) ? $this->props['background_position__hover'] : '',
'background_repeat' => $this->props['background_repeat'],
'background_repeat_tablet' => $this->props['background_repeat_tablet'],
'background_repeat_phone' => $this->props['background_repeat_phone'],
'background_repeat__hover' => isset( $this->props['background_repeat__hover'] ) ? $this->props['background_repeat__hover'] : '',
'background_blend' => $this->props['background_blend'],
'background_blend_tablet' => $this->props['background_blend_tablet'],
'background_blend_phone' => $this->props['background_blend_phone'],
'background_blend__hover' => isset( $this->props['background_blend__hover'] ) ? $this->props['background_blend__hover'] : '',
'parallax' => $this->props['parallax'],
'parallax_tablet' => $this->props['parallax_tablet'],
'parallax_phone' => $this->props['parallax_phone'],
'parallax__hover' => isset( $this->props['parallax__hover'] ) ? $this->props['parallax__hover'] : '',
'parallax_method' => $this->props['parallax_method'],
'parallax_method_tablet' => $this->props['parallax_method_tablet'],
'parallax_method_phone' => $this->props['parallax_method_phone'],
'parallax_method__hover' => isset( $this->props['parallax_method__hover'] ) ? $this->props['parallax_method__hover'] : '',
// Background Video.
'background_enable_video_mp4' => $this->props['background_enable_video_mp4'],
'background_enable_video_mp4_tablet' => $this->props['background_enable_video_mp4_tablet'],
'background_enable_video_mp4_phone' => $this->props['background_enable_video_mp4_phone'],
'background_enable_video_mp4__hover' => isset( $this->props['background_enable_video_mp4__hover'] ) ? $this->props['background_enable_video_mp4__hover'] : '',
'background_enable_video_webm' => $this->props['background_enable_video_webm'],
'background_enable_video_webm_tablet' => $this->props['background_enable_video_webm_tablet'],
'background_enable_video_webm_phone' => $this->props['background_enable_video_webm_phone'],
'background_enable_video_webm__hover' => isset( $this->props['background_enable_video_webm__hover'] ) ? $this->props['background_enable_video_webm__hover'] : '',
'background_video_mp4' => $this->props['background_video_mp4'],
'background_video_mp4_tablet' => $this->props['background_video_mp4_tablet'],
'background_video_mp4_phone' => $this->props['background_video_mp4_phone'],
'background_video_mp4__hover' => isset( $this->props['background_video_mp4__hover'] ) ? $this->props['background_video_mp4__hover'] : '',
'background_video_webm' => $this->props['background_video_webm'],
'background_video_webm_tablet' => $this->props['background_video_webm_tablet'],
'background_video_webm_phone' => $this->props['background_video_webm_phone'],
'background_video_webm__hover' => isset( $this->props['background_video_webm__hover'] ) ? $this->props['background_video_webm__hover'] : '',
'background_video_width' => $this->props['background_video_width'],
'background_video_width_tablet' => $this->props['background_video_width_tablet'],
'background_video_width_phone' => $this->props['background_video_width_phone'],
'background_video_width__hover' => isset( $this->props['background_video_width__hover'] ) ? $this->props['background_video_width__hover'] : '',
'background_video_height' => $this->props['background_video_height'],
'background_video_height_tablet' => $this->props['background_video_height_tablet'],
'background_video_height_phone' => $this->props['background_video_height_phone'],
'background_video_height__hover' => isset( $this->props['background_video_height__hover'] ) ? $this->props['background_video_height__hover'] : '',
'header_level' => $this->props['header_level'],
'use_bg_overlay' => $this->props['use_bg_overlay'],
'bg_overlay_color' => $bg_overlay_color,
'bg_overlay_color_slider_last_edited' => $this->props['bg_overlay_color_last_edited'],
'bg_overlay_color_tablet' => $bg_overlay_color_tablet,
'bg_overlay_color_phone' => $bg_overlay_color_phone,
'bg_overlay_color__sticky' => $sticky->get_value( 'bg_overlay_color', $this->props ),
'use_text_overlay' => $this->props['use_text_overlay'],
'text_overlay_color' => $text_overlay_color,
'text_overlay_color_slider_last_edited' => $this->props['text_overlay_color_last_edited'],
'text_overlay_color_tablet' => $text_overlay_color_tablet,
'text_overlay_color_phone' => $text_overlay_color_phone,
'text_overlay_color__sticky' => $sticky->get_value( 'text_overlay_color', $this->props ),
'text_border_radius' => $text_border_radius,
'text_border_radius_slider_last_edited' => $this->props['text_border_radius_last_edited'],
'text_border_radius_tablet' => $text_border_radius_tablet,
'text_border_radius_phone' => $text_border_radius_phone,
'text_border_radius__sticky' => $sticky->get_value( 'text_border_radius', $this->props ),
'arrows_custom_color' => $arrows_custom_color,
'arrows_custom_color_slider_last_edited' => $this->props['arrows_custom_color_last_edited'],
'arrows_custom_color_tablet' => $arrows_custom_color_tablet,
'arrows_custom_color_phone' => $arrows_custom_color_phone,
'arrows_custom_color__sticky' => $sticky->get_value( 'arrows_custom_color', $this->props ),
'dot_nav_custom_color' => $dot_nav_custom_color,
'dot_nav_custom_color_slider_last_edited' => $this->props['dot_nav_custom_color_last_edited'],
'dot_nav_custom_color_tablet' => $dot_nav_custom_color_tablet,
'dot_nav_custom_color_phone' => $dot_nav_custom_color_phone,
'dot_nav_custom_color__sticky' => $sticky->get_value( 'dot_nav_custom_color', $this->props ),
// Sticky classname position relies to slider's sticky status if the style selector
// begins with slider-level selector.
'is_sticky_module' => $sticky->is_sticky_module( $this->props ),
// Module item has no sticky options hence this needs to be inherited to setup transition.
'sticky_transition' => et_()->array_get( $this->props, 'sticky_transition', 'on' ),
);
// Hover Options attribute doesn't have field definition and rendered on the fly, thus the use of array_get()
$background_hover_enabled_key = et_pb_hover_options()->get_hover_enabled_field( 'background' );
$background_color_hover_key = et_pb_hover_options()->get_hover_field( 'background_color' );
$et_pb_slider[ $background_hover_enabled_key ] = self::$_->array_get( $this->props, $background_hover_enabled_key, '' );
$et_pb_slider[ $background_color_hover_key ] = self::$_->array_get( $this->props, $background_color_hover_key, '' );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$show_arrows = $this->props['show_arrows'];
$show_pagination = $this->props['show_pagination'];
$parallax = $this->props['parallax'];
$parallax_method = $this->props['parallax_method'];
$auto = $this->props['auto'];
$auto_speed = $this->props['auto_speed'];
$auto_ignore_hover = $this->props['auto_ignore_hover'];
$body_font_size = $this->props['body_font_size'];
$show_content_on_mobile = $this->props['show_content_on_mobile'];
$show_cta_on_mobile = $this->props['show_cta_on_mobile'];
$show_image_video_mobile = $this->props['show_image_video_mobile'];
$background_position = $this->props['background_position'];
$background_size = $this->props['background_size'];
global $et_pb_slider_has_video, $et_pb_slider_parallax, $et_pb_slider_parallax_method, $et_pb_slider_show_mobile, $et_pb_slider_custom_icon, $et_pb_slider_custom_icon_tablet, $et_pb_slider_custom_icon_phone, $et_pb_slider;
$content = $this->content;
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
if ( '' !== $background_position && 'default' !== $background_position && 'off' === $parallax ) {
$processed_position = str_replace( '_', ' ', $background_position );
ET_Builder_Module::set_style(
$render_slug,
array(
'selector' => '%%order_class%% .et_pb_slide',
'declaration' => sprintf(
'background-position: %1$s;',
esc_html( $processed_position )
),
)
);
}
// Handle slider's previous background size default value ("default") as well
if ( '' !== $background_size && 'default' !== $background_size && 'off' === $parallax ) {
$el_style = array(
'selector' => '%%order_class%% .et_pb_slide',
'declaration' => sprintf(
'-moz-background-size: %1$s;
-webkit-background-size: %1$s;
background-size: %1$s;',
esc_html( $background_size )
),
);
ET_Builder_Module::set_style( $render_slug, $el_style );
}
// Module classnames
$this->add_classname( 'et_pb_slider_fullwidth_off' );
if ( ! $multi_view->has_value( 'show_arrows', 'on' ) ) {
$this->add_classname( 'et_pb_slider_no_arrows' );
}
if ( ! $multi_view->has_value( 'show_pagination', 'on' ) ) {
$this->add_classname( 'et_pb_slider_no_pagination' );
}
if ( 'on' === $parallax ) {
$this->add_classname( 'et_pb_slider_parallax' );
}
if ( 'on' === $auto ) {
$this->add_classname(
array(
'et_slider_auto',
"et_slider_speed_{$auto_speed}",
)
);
}
if ( 'on' === $auto_ignore_hover ) {
$this->add_classname( 'et_slider_auto_ignore_hover' );
}
if ( 'on' === $show_image_video_mobile ) {
$this->add_classname( 'et_pb_slider_show_image' );
}
$this->generate_responsive_hover_style( 'arrows_custom_color', et_pb_slider_options()->get_arrows_selector(), 'color' );
$this->generate_responsive_hover_style( 'dot_nav_custom_color', et_pb_slider_options()->get_dots_selector(), 'background-color' );
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_slider_no_arrows' => array(
'show_arrows' => 'off',
),
'et_pb_slider_no_pagination' => array(
'show_pagination' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%1$s"%5$s>
<div class="et_pb_slides">
%2$s
</div>
%4$s
</div>
',
$this->module_classname( $render_slug ),
$content,
$this->module_id(),
$this->inner_shadow_back_compatibility( $render_slug ),
$multi_view_data_attr
);
// Reset passed slider item value
$et_pb_slider = array();
return $output;
}
private function inner_shadow_back_compatibility( $functions_name ) {
$utils = ET_Core_Data_Utils::instance();
$atts = $this->props;
$style = '';
if (
version_compare( $utils->array_get( $atts, '_builder_version', '3.0.93' ), '3.0.99', 'lt' )
) {
$class = self::get_module_order_class( $functions_name );
$style = sprintf(
'<style>%1$s</style>',
sprintf(
'.%1$s.et_pb_slider .et_pb_slide {'
. '-webkit-box-shadow: none; '
. '-moz-box-shadow: none; '
. 'box-shadow: none; '
. '}',
esc_attr( $class )
)
);
if ( 'off' !== $utils->array_get( $atts, 'show_inner_shadow' ) ) {
$style .= sprintf(
'<style>%1$s</style>',
sprintf(
'.%1$s > .box-shadow-overlay { '
. '-webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. '-moz-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. 'box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); '
. '}',
esc_attr( $class )
)
);
}
}
return $style;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Slider();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,360 @@
<?php
class ET_Builder_Module_Social_Media_Follow extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Social Media Follow', 'et_builder' );
$this->plural = esc_html__( 'Social Media Follows', 'et_builder' );
$this->slug = 'et_pb_social_media_follow';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_social_media_follow_network';
$this->child_item_text = esc_html__( 'Social Network', 'et_builder' );
$this->main_css_element = 'ul%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'alignment' => esc_html__( 'Alignment', 'et_builder' ),
'icon' => esc_html__( 'Icon', 'et_builder' ),
'text' => et_builder_i18n( 'Text' ),
),
),
);
$this->custom_css_fields = array(
'before' => array(
'label' => et_builder_i18n( 'Before' ),
'selector' => 'ul%%order_class%%:before',
),
'main_element' => array(
'label' => et_builder_i18n( 'Main Element' ),
'selector' => 'ul%%order_class%%',
),
'after' => array(
'label' => et_builder_i18n( 'After' ),
'selector' => 'ul%%order_class%%:after',
),
'social_follow' => array(
'label' => esc_html__( 'Social Follow', 'et_builder' ),
'selector' => 'li',
),
'social_icon' => array(
'label' => esc_html__( 'Social Icon', 'et_builder' ),
'selector' => 'li a.icon',
),
'follow_button' => array(
'label' => esc_html__( 'Follow Button', 'et_builder' ),
'selector' => 'li a.follow_button',
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} a.icon",
'border_styles' => "{$this->main_css_element} a",
),
),
'defaults' => array(
'border_radii' => 'on|3px|3px|3px|3px',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_social_icon a',
),
),
),
'margin_padding' => array(
'css' => array(
'main' => 'ul%%order_class%%',
'important' => array( 'custom_margin', 'custom_padding' ), // needed to overwrite last module margin-bottom styling and default ul padding on post
),
),
'text' => array(
'use_background_layout' => true,
'text_orientation' => array(
'exclude_options' => array( 'justified' ),
),
'options' => array(
'text_orientation' => array(
'label' => esc_html__( 'Module Alignment', 'et_builder' ),
'toggle_slug' => 'alignment',
'options_icon' => 'module_align',
),
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
),
'fonts' => false,
'button' => array(
'button' => array(
'label' => esc_html__( 'Follow Button', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .follow_button",
),
'hide_icon' => true,
'hide_custom_padding' => true,
'no_rel_attr' => true,
'text_size' => array(
'default' => '14px',
),
'border_width' => array(
'default' => '0px',
),
'box_shadow' => array(
'css' => array(
'main' => "{$this->main_css_element} .follow_button",
),
),
),
),
'link_options' => false,
);
$this->help_videos = array(
array(
'id' => '8b0BlM_rlHQ',
'name' => esc_html__( 'An introduction to the Social Media Follow module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'url_new_window' => array(
'label' => esc_html__( 'Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'toggle_slug' => 'icon',
'description' => esc_html__( 'Here you can choose whether or not your link opens in a new window', 'et_builder' ),
'default_on_front' => 'on',
),
'follow_button' => array(
'label' => esc_html__( 'Follow Button', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'Off' ),
'on' => et_builder_i18n( 'On' ),
),
'default_on_front' => 'off',
'toggle_slug' => 'icon',
'description' => esc_html__( 'Here you can choose whether or not to include the follow button next to the icon.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'icon_color' => array(
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the social network icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['icon_color'] = array( 'color' => '%%order_class%% li a.icon:before' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%% li a.icon:before',
'line-height' => '%%order_class%% li a.icon:before',
'height' => '%%order_class%% li a.icon:before',
'width' => '%%order_class%% li a.icon:before',
'height' => '%%order_class%% li a.icon',
'width' => '%%order_class%% li a.icon',
);
return $fields;
}
function before_render() {
global $et_pb_social_media_follow_link,
$et_pb_social_media_follow_sticky;
$url_new_window = $this->props['url_new_window'];
$follow_button = et_pb_multi_view_options( $this )->get_values( 'follow_button' );
$et_pb_social_media_follow_link = array(
'url_new_window' => $url_new_window,
'follow_button' => $follow_button,
);
$et_pb_social_media_follow_sticky = et_pb_sticky_options()->is_sticky_module( $this->props );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_social_media_follow_link;
$multi_view = et_pb_multi_view_options( $this );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$use_icon_font_size = $this->props['use_icon_font_size'];
// Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'icon_color',
'selector' => '%%order_class%% li.et_pb_social_icon a.icon:before',
'selector_wrapper' => '%%order_class%% li a.icon',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
// Calculate icon size + its wrapper dimension.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%% li a.icon:before',
'selector_wrapper' => '%%order_class%% li a.icon',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'css_property' => 'right',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_social_media_icon_font_size',
),
)
);
}
// Get custom borders, if any
$attrs = $this->props;
// Module classnames
$this->add_classname(
array(
'clearfix',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( $multi_view->has_value( 'follow_button', 'on' ) ) {
$this->add_classname( 'has_follow_button' );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$muti_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'has_follow_button' => array(
'follow_button' => 'on',
),
),
)
);
$output = sprintf(
'<ul%3$s class="%2$s"%6$s%7$s>
%5$s
%4$s
%1$s
</ul>',
$this->content,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background, // #5
et_core_esc_previously( $data_background_layout ),
et_core_esc_previously( $muti_view_data_attr )
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Social_Media_Follow();
}

View File

@ -0,0 +1,766 @@
<?php
class ET_Builder_Module_Social_Media_Follow_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Social Network', 'et_builder' );
$this->plural = esc_html__( 'Social Networks', 'et_builder' );
$this->slug = 'et_pb_social_media_follow_network';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'content';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => esc_html__( 'Network', 'et_builder' ),
'link' => et_builder_i18n( 'Link' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
),
),
);
$this->advanced_setting_title_text = esc_html__( 'New Social Network', 'et_builder' );
$this->settings_text = esc_html__( 'Social Network Settings', 'et_builder' );
$this->custom_css_fields = array(
'before' => array(
'label' => et_builder_i18n( 'Before' ),
'selector' => '.et_pb_social_media_follow li%%order_class%%:before',
),
'main_element' => array(
'label' => et_builder_i18n( 'Main Element' ),
'selector' => '.et_pb_social_media_follow li%%order_class%%',
),
'after' => array(
'label' => et_builder_i18n( 'After' ),
'selector' => '.et_pb_social_media_follow li%%order_class%%:after',
),
'social_icon' => array(
'label' => esc_html__( 'Social Icon', 'et_builder' ),
'selector' => '.et_pb_social_network_link a.icon',
'no_space_before_selector' => true,
),
'follow_button' => array(
'label' => esc_html__( 'Follow Button', 'et_builder' ),
'selector' => '.et_pb_social_network_link a.follow_button',
'no_space_before_selector' => true,
),
);
$this->advanced_fields = array(
'background' => array(
'css' => array(
'main' => '%%order_class%% a.icon',
'important' => 'all',
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%%.et_pb_social_icon a.icon',
'border_styles' => '%%order_class%%.et_pb_social_icon a.icon',
),
),
'defaults' => array(
'border_radii' => 'on|3px|3px|3px|3px',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%% a',
'important' => true,
),
),
),
'margin_padding' => array(
'css' => array(
'padding' => '.et_pb_social_media_follow li%%order_class%% a',
'main' => '%%order_class%%',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'fonts' => false,
'text' => false,
'max_width' => false,
'height' => false,
'button' => array(
'button' => array(
'label' => esc_html__( 'Follow Button', 'et_builder' ),
'css' => array(
'main' => '.et_pb_social_media_follow li%%order_class%% .follow_button',
),
'hide_icon' => true,
'hide_custom_padding' => true,
'no_rel_attr' => true,
'text_size' => array(
'default' => '14px',
),
'border_width' => array(
'default' => '0px',
),
'box_shadow' => array(
'css' => array(
'main' => '.et_pb_social_media_follow li%%order_class%% .follow_button',
),
),
),
),
'link_options' => false,
'sticky' => false,
);
}
function get_fields() {
$fields = array(
'social_network' => array(
'label' => esc_html__( 'Social Network', 'et_builder' ),
'type' => 'select',
'option_category' => 'basic_option',
'class' => 'et-pb-social-network',
'options' => array(
'' => esc_html__( 'Select a Network', 'et_builder' ),
'amazon' => array(
'value' => esc_html__( 'Amazon', 'et_builder' ),
'data' => array(
'color' => '#ff9900',
),
),
'bandcamp' => array(
'value' => esc_html__( 'Bandcamp', 'et_builder' ),
'data' => array(
'color' => '#629aa9',
),
),
'behance' => array(
'value' => esc_html__( 'Behance', 'et_builder' ),
'data' => array(
'color' => '#0057ff',
),
),
'bitbucket' => array(
'value' => esc_html__( 'BitBucket', 'et_builder' ),
'data' => array(
'color' => '#205081',
),
),
'buffer' => array(
'value' => esc_html__( 'Buffer', 'et_builder' ),
'data' => array(
'color' => '#000000',
),
),
'codepen' => array(
'value' => esc_html__( 'CodePen', 'et_builder' ),
'data' => array(
'color' => '#000000',
),
),
'deviantart' => array(
'value' => esc_html__( 'DeviantArt', 'et_builder' ),
'data' => array(
'color' => '#05cc47',
),
),
'dribbble' => array(
'value' => esc_html__( 'dribbble', 'et_builder' ),
'data' => array(
'color' => '#ea4c8d',
),
),
'facebook' => array(
'value' => esc_html__( 'Facebook', 'et_builder' ),
'data' => array(
'color' => '#3b5998',
),
),
'flikr' => array(
'value' => esc_html__( 'Flickr', 'et_builder' ),
'data' => array(
'color' => '#ff0084',
),
),
'flipboard' => array(
'value' => esc_html__( 'FlipBoard', 'et_builder' ),
'data' => array(
'color' => '#e12828',
),
),
'foursquare' => array(
'value' => esc_html__( 'Foursquare', 'et_builder' ),
'data' => array(
'color' => '#f94877',
),
),
'github' => array(
'value' => esc_html__( 'GitHub', 'et_builder' ),
'data' => array(
'color' => '#333333',
),
),
'goodreads' => array(
'value' => esc_html__( 'Goodreads', 'et_builder' ),
'data' => array(
'color' => '#553b08',
),
),
'google' => array(
'value' => esc_html__( 'Google', 'et_builder' ),
'data' => array(
'color' => '#4285f4',
),
),
'google-plus' => array(
'value' => esc_html__( 'Google+', 'et_builder' ),
'data' => array(
'color' => '#dd4b39',
),
),
'houzz' => array(
'value' => esc_html__( 'Houzz', 'et_builder' ),
'data' => array(
'color' => '#7ac142',
),
),
'instagram' => array(
'value' => esc_html__( 'Instagram', 'et_builder' ),
'data' => array(
'color' => '#ea2c59',
),
),
'itunes' => array(
'value' => esc_html__( 'iTunes', 'et_builder' ),
'data' => array(
'color' => '#fe7333',
),
),
'last_fm' => array(
'value' => esc_html__( 'Last.fm', 'et_builder' ),
'data' => array(
'color' => '#b90000',
),
),
'line' => array(
'value' => esc_html__( 'Line', 'et_builder' ),
'data' => array(
'color' => '#00c300',
),
),
'linkedin' => array(
'value' => esc_html__( 'LinkedIn', 'et_builder' ),
'data' => array(
'color' => '#007bb6',
),
),
'medium' => array(
'value' => esc_html__( 'Medium', 'et_builder' ),
'data' => array(
'color' => '#00ab6c',
),
),
'meetup' => array(
'value' => esc_html__( 'Meetup', 'et_builder' ),
'data' => array(
'color' => '#e0393e',
),
),
'myspace' => array(
'value' => esc_html__( 'MySpace', 'et_builder' ),
'data' => array(
'color' => '#3b5998',
),
),
'odnoklassniki' => array(
'value' => esc_html__( 'Odnoklassniki', 'et_builder' ),
'data' => array(
'color' => '#ed812b',
),
),
'patreon' => array(
'value' => esc_html__( 'Patreon', 'et_builder' ),
'data' => array(
'color' => '#f96854',
),
),
'periscope' => array(
'value' => esc_html__( 'Periscope', 'et_builder' ),
'data' => array(
'color' => '#3aa4c6',
),
),
'pinterest' => array(
'value' => esc_html__( 'Pinterest', 'et_builder' ),
'data' => array(
'color' => '#cb2027',
),
),
'quora' => array(
'value' => esc_html__( 'Quora', 'et_builder' ),
'data' => array(
'color' => '#a82400',
),
),
'reddit' => array(
'value' => esc_html__( 'Reddit', 'et_builder' ),
'data' => array(
'color' => '#ff4500',
),
),
'researchgate' => array(
'value' => esc_html__( 'ResearchGate', 'et_builder' ),
'data' => array(
'color' => '#40ba9b',
),
),
'rss' => array(
'value' => esc_html__( 'RSS', 'et_builder' ),
'data' => array(
'color' => '#ff8a3c',
),
),
'skype' => array(
'value' => esc_html__( 'skype', 'et_builder' ),
'data' => array(
'color' => '#12A5F4',
),
),
'snapchat' => array(
'value' => esc_html__( 'Snapchat', 'et_builder' ),
'data' => array(
'color' => '#fffc00',
),
),
'soundcloud' => array(
'value' => esc_html__( 'SoundCloud', 'et_builder' ),
'data' => array(
'color' => '#ff8800',
),
),
'spotify' => array(
'value' => esc_html__( 'Spotify', 'et_builder' ),
'data' => array(
'color' => '#1db954',
),
),
'steam' => array(
'value' => esc_html__( 'Steam', 'et_builder' ),
'data' => array(
'color' => '#00adee',
),
),
'telegram' => array(
'value' => esc_html__( 'Telegram', 'et_builder' ),
'data' => array(
'color' => '#179cde',
),
),
'tiktok' => array(
'value' => esc_html__( 'TikTok', 'et_builder' ),
'data' => array(
'color' => '#fe2c55',
),
),
'tripadvisor' => array(
'value' => esc_html__( 'TripAdvisor', 'et_builder' ),
'data' => array(
'color' => '#00af87',
),
),
'tumblr' => array(
'value' => esc_html__( 'tumblr', 'et_builder' ),
'data' => array(
'color' => '#32506d',
),
),
'twitch' => array(
'value' => esc_html__( 'Twitch', 'et_builder' ),
'data' => array(
'color' => '#6441a5',
),
),
'twitter' => array(
'value' => esc_html__( 'Twitter', 'et_builder' ),
'data' => array(
'color' => '#00aced',
),
),
'vimeo' => array(
'value' => esc_html__( 'Vimeo', 'et_builder' ),
'data' => array(
'color' => '#45bbff',
),
),
'vk' => array(
'value' => esc_html__( 'VK', 'et_builder' ),
'data' => array(
'color' => '#45668e',
),
),
'weibo' => array(
'value' => esc_html__( 'Weibo', 'et_builder' ),
'data' => array(
'color' => '#eb7350',
),
),
'whatsapp' => array(
'value' => esc_html__( 'WhatsApp', 'et_builder' ),
'data' => array(
'color' => '#25D366',
),
),
'xing' => array(
'value' => esc_html__( 'XING', 'et_builder' ),
'data' => array(
'color' => '#026466',
),
),
'yelp' => array(
'value' => esc_html__( 'Yelp', 'et_builder' ),
'data' => array(
'color' => '#af0606',
),
),
'youtube' => array(
'value' => esc_html__( 'Youtube', 'et_builder' ),
'data' => array(
'color' => '#a82400',
),
),
),
'affects' => array(
'url',
'skype_url',
'skype_action',
),
'overwrite_onchange' => array(
'background_color',
),
'description' => esc_html__( 'Choose the social network', 'et_builder' ),
'toggle_slug' => 'main_content',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'hidden',
'toggle_slug' => 'main_content',
),
'url' => array(
'label' => esc_html__( 'Account Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'The URL for this social network link.', 'et_builder' ),
'depends_show_if_not' => 'skype',
'depends_on' => array(
'social_network',
),
'toggle_slug' => 'link',
'default_on_front' => '#',
'dynamic_content' => 'url',
),
'skype_url' => array(
'label' => esc_html__( 'Account Name', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'The Skype account name.', 'et_builder' ),
'depends_show_if' => 'skype',
'depends_on' => array(
'social_network',
),
'toggle_slug' => 'main_content',
),
'skype_action' => array(
'label' => esc_html__( 'Skype Button Action', 'et_builder' ),
'type' => 'select',
'option_category' => 'basic_option',
'options' => array(
'call' => esc_html__( 'Call', 'et_builder' ),
'chat' => esc_html__( 'Chat', 'et_builder' ),
),
'depends_show_if' => 'skype',
'depends_on' => array(
'social_network',
),
'description' => esc_html__( 'Here you can choose which action to execute on button click', 'et_builder' ),
'toggle_slug' => 'main_content',
'default_on_front' => 'call',
),
'icon_color' => array(
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the social network icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'hover' => 'tabs',
'sticky' => true,
),
);
// Automatically parse social_network's option as value_overwrite
foreach ( $fields['social_network']['options'] as $value_overwrite_key => $value_overwrite ) {
if ( is_array( $value_overwrite ) && isset( $value_overwrite['data'] ) && $value_overwrite['data']['color'] ) {
$fields['social_network']['value_overwrite'][ $value_overwrite_key ] = $value_overwrite['data']['color'];
}
}
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['icon_color'] = array( 'color' => '.et_pb_social_media_follow %%order_class%% .icon:before' );
$fields['icon_font_size'] = array(
'font-size' => '.et_pb_social_media_follow %%order_class%% .icon:before',
'line-height' => '.et_pb_social_media_follow %%order_class%% .icon:before',
'height' => '.et_pb_social_media_follow %%order_class%% .icon:before',
'width' => '.et_pb_social_media_follow %%order_class%% .icon:before',
'height' => '.et_pb_social_media_follow %%order_class%% .icon',
'width' => '.et_pb_social_media_follow %%order_class%% .icon',
);
return $fields;
}
function get_network_name( $network ) {
$all_fields = $this->get_fields();
$network_names_mapping = $all_fields['social_network']['options'];
if ( isset( $network_names_mapping[ $network ] ) && isset( $network_names_mapping[ $network ]['value'] ) ) {
return $network_names_mapping[ $network ]['value'];
}
return $network;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_social_media_follow_link,
$et_pb_social_media_follow_sticky;
$multi_view = et_pb_multi_view_options( $this );
$multi_view->set_custom_prop( 'follow_button', $et_pb_social_media_follow_link['follow_button'] );
$social_network = $this->props['social_network'];
$url = $this->props['url'];
$skype_url = $this->props['skype_url'];
$skype_action = $this->props['skype_action'];
$custom_padding = $this->props['custom_padding'];
$custom_padding_tablet = $this->props['custom_padding_tablet'];
$custom_padding_phone = $this->props['custom_padding_phone'];
$follow_button = '';
$is_skype = false;
$network_name = esc_attr( $this->get_network_name( trim( wp_strip_all_tags( $content ) ) ) );
$use_icon_font_size = $this->props['use_icon_font_size'];
if ( 'skype' === $social_network ) {
$skype_url = sprintf(
'skype:%1$s?%2$s',
sanitize_text_field( $skype_url ),
sanitize_text_field( $skype_action )
);
$is_skype = true;
}
if ( $multi_view->has_value( 'follow_button', 'on' ) ) {
$follow_button_multi_view_attr = $multi_view->render_attrs(
array(
'visibility' => array(
'follow_button' => 'on',
),
)
);
$follow_button = sprintf(
'<a href="%1$s" class="follow_button" title="%2$s"%3$s%5$s>%4$s</a>',
! $is_skype ? esc_url( $url ) : $skype_url,
$network_name,
( 'on' === $et_pb_social_media_follow_link['url_new_window'] ? ' target="_blank"' : '' ),
esc_html__( 'Follow', 'et_builder' ),
$follow_button_multi_view_attr
);
}
if ( '' !== $custom_padding || '' !== $custom_padding_tablet || '' !== $custom_padding_phone ) {
$el_style = array(
'selector' => '.et_pb_social_media_follow li%%order_class%% a',
'declaration' => 'width: auto; height: auto;',
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
// Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'icon_color',
'selector' => '.et_pb_social_media_follow %%order_class%%.et_pb_social_icon .icon:before',
'hover_selector' => '.et_pb_social_media_follow %%order_class%%.et_pb_social_icon:hover .icon:before',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
'is_sticky_module' => $et_pb_social_media_follow_sticky,
)
);
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
// Calculate icon size + its wrapper dimension.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '.et_pb_social_media_follow %%order_class%% .icon:before',
'selector_wrapper' => '.et_pb_social_media_follow %%order_class%% .icon',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'css_property' => 'right',
'is_sticky_module' => $et_pb_social_media_follow_sticky,
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr. Processor required is 100%
// identical to social media follow module's. Thus it is being re-used.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_social_media_icon_font_size',
),
)
);
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$social_network_link_url = ! $is_skype ? esc_url( $url ) : $skype_url;
$social_network_link_target = 'on' === $et_pb_social_media_follow_link['url_new_window'] ? ' target="_blank"' : '';
// Get custom borders, if any
$attrs = $this->props;
// Module classnames
$this->add_classname(
array(
'et_pb_social_icon',
'et_pb_social_network_link',
)
);
if ( '' !== $social_network ) {
$this->add_classname( sprintf( ' et-social-%s', esc_attr( $social_network ) ) );
if ( ! empty( $this->props['social_network'] ) && in_array( $this->props['social_network'], et_pb_get_social_net_fa_icons(), true ) ) {
$this->add_classname( 'et-pb-social-fa-icon' );
}
}
// Remove automatically added classnames
$this->remove_classname(
array(
$render_slug,
'et_pb_module',
'et_pb_section_video',
'et_pb_preload',
'et_pb_section_parallax',
)
);
// Format i18n link title
$social_network_link_title = sprintf(
esc_html__( 'Follow on %s', 'et_builder' ),
$network_name
);
// Format i18n link text (visible, but ignored by screen readers)
$social_network_link_text = esc_html__( 'Follow', 'et_builder' );
// Prepare CSS classes for the link
$social_network_link_classes = array( 'icon', 'et_pb_with_border' );
if ( '' !== $video_background ) {
array_push(
$social_network_link_classes,
'et_pb_section_video',
'et_pb_preload',
$video_background
);
}
if ( '' !== $parallax_image_background ) {
array_push(
$social_network_link_classes,
'et_pb_section_parallax'
);
}
$social_network_link_classes = implode( ' ', $social_network_link_classes );
$output = "<li
class='{$this->module_classname( $render_slug )}'><a
href='{$social_network_link_url}'
class='{$social_network_link_classes}'
title='{$social_network_link_title}'
{$social_network_link_target}>{$parallax_image_background}<span
class='et_pb_social_media_follow_network_name'
aria-hidden='true'
>{$social_network_link_text}</span></a>{$follow_button}</li>";
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Social_Media_Follow_Item();
}

View File

@ -0,0 +1,319 @@
<?php
class ET_Builder_Module_Tabs extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Tabs', 'et_builder' );
$this->plural = esc_html__( 'Tabs', 'et_builder' );
$this->slug = 'et_pb_tabs';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_tab';
$this->child_item_text = esc_html__( 'Tab', 'et_builder' );
$this->main_css_element = '%%order_class%%.et_pb_tabs';
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => $this->main_css_element,
'border_styles' => $this->main_css_element,
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#d9d9d9',
'style' => 'solid',
),
),
),
),
'fonts' => array(
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_all_tabs .et_pb_tab",
'limited_main' => "{$this->main_css_element} .et_pb_all_tabs .et_pb_tab, {$this->main_css_element} .et_pb_all_tabs .et_pb_tab p",
'line_height' => "{$this->main_css_element} .et_pb_tab p",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
'tab' => array(
'label' => esc_html__( 'Tab', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_tabs_controls li, {$this->main_css_element} .et_pb_tabs_controls li a",
'color' => "{$this->main_css_element} .et_pb_tabs_controls li a",
'hover' => "{$this->main_css_element} .et_pb_tabs_controls li:hover, {$this->main_css_element} .et_pb_tabs_controls li:hover a",
'color_hover' => "{$this->main_css_element} .et_pb_tabs_controls li:hover a",
),
'hide_text_align' => true,
'options_priority' => array(
'tab_text_color' => 9,
),
),
),
'background' => array(
'css' => array(
'main' => "{$this->main_css_element} .et_pb_all_tabs",
),
'settings' => array(
'color' => 'alpha',
),
),
'margin_padding' => array(
'css' => array(
'padding' => '%%order_class%% .et_pb_tab',
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'text' => false,
'button' => false,
);
$this->custom_css_fields = array(
'tabs_controls' => array(
'label' => esc_html__( 'Tabs Controls', 'et_builder' ),
'selector' => '.et_pb_tabs_controls',
),
'tab' => array(
'label' => esc_html__( 'Tab', 'et_builder' ),
'selector' => '.et_pb_tabs_controls li',
),
'active_tab' => array(
'label' => esc_html__( 'Active Tab', 'et_builder' ),
'selector' => '.et_pb_tabs_controls li.et_pb_tab_active',
),
'tabs_content' => array(
'label' => esc_html__( 'Tabs Content', 'et_builder' ),
'selector' => '.et_pb_tab',
),
);
$this->help_videos = array(
array(
'id' => 'xk2Ite-oFhg',
'name' => esc_html__( 'An introduction to the Tabs module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'active_tab_background_color' => array(
'label' => esc_html__( 'Active Tab Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to be used for active tab backgrounds. You can assign a unique color to active tabs to differentiate them from inactive tabs.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'tab',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'inactive_tab_background_color' => array(
'label' => esc_html__( 'Inactive Tab Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to be used for inactive tab backgrounds. You can assign a unique color to inactive tabs to differentiate them from active tabs.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'tab',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'active_tab_text_color' => array(
'label' => esc_html__( 'Active Tab Text Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for tab text within active tabs. You can assign a unique color to active tabs to differentiate them from inactive tabs.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'tab',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['inactive_tab_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_tabs_controls li' );
$fields['active_tab_background_color'] = array( 'background-color' => '%%order_class%% .et_pb_tabs_controls li' );
$fields['active_tab_text_color'] = array( 'color' => '%%order_class%% .et_pb_tabs_controls li a' );
return $fields;
}
/**
* Outputs tabs module nav markup
* The nav output is abstracted into method so tabs module can be extended
*
* @since 3.29
*
* @return string
*/
public function get_tabs_nav() {
global $et_pb_tab_titles;
global $et_pb_tab_classes;
$tabs = '';
$i = 0;
if ( ! empty( $et_pb_tab_titles ) ) {
foreach ( $et_pb_tab_titles as $tab_title ) {
++$i;
$tabs .= sprintf(
'<li class="%3$s%1$s">%2$s</li>',
( 1 === $i ? ' et_pb_tab_active' : '' ),
et_pb_multi_view_options( $this )->render_element(
array(
'tag' => 'a',
'content' => '{{tab_title}}',
'attrs' => array(
'href' => '#',
),
'custom_props' => array(
'tab_title' => $tab_title,
),
)
),
esc_attr( ltrim( $et_pb_tab_classes[ $i - 1 ] ) )
);
}
}
return $tabs;
}
/**
* Outputs tabs content markup
* The tabs content is abstracted into method so tabs module can be extended
*
* @since 3.29
*
* @return string
*/
public function get_tabs_content() {
return $this->content;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$all_tabs_content = $this->get_tabs_content();
global $et_pb_tab_titles;
global $et_pb_tab_classes;
// Inactive Tab Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'inactive_tab_background_color',
'selector' => '%%order_class%% .et_pb_tabs_controls li',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Active Tab Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'active_tab_background_color',
'selector' => '%%order_class%% .et_pb_tabs_controls li.et_pb_tab_active',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Active Text Color
$this->generate_styles(
array(
'base_attr_name' => 'active_tab_text_color',
'selector' => '%%order_class%%.et_pb_tabs .et_pb_tabs_controls li.et_pb_tab_active a',
'hover_selector' => '%%order_class%% .et_pb_tabs_controls li.et_pb_tab_active:hover a',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
$tabs = $this->get_tabs_nav();
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$et_pb_tab_titles = $et_pb_tab_classes = array();
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
$output = sprintf(
'<div%3$s class="%4$s" %7$s>
%6$s
%5$s
<ul class="et_pb_tabs_controls clearfix">
%1$s
</ul>
<div class="et_pb_all_tabs">
%2$s
</div>
</div>',
$tabs,
$all_tabs_content,
$this->module_id(),
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background,
/* 7$s */ 'et_pb_wc_tabs' === $render_slug ? $this->get_multi_view_attrs() : ''
);
return $output;
}
public function process_box_shadow( $function_name ) {
$boxShadow = ET_Builder_Module_Fields_Factory::get( 'BoxShadow' );
$style = $boxShadow->get_value( $this->props );
if ( $boxShadow->is_inset( $style ) ) {
$this->advanced_fields['box_shadow'] = array(
'default' => array(
'css' => array(
'main' => '%%order_class%% .et-pb-active-slide',
),
),
);
}
parent::process_box_shadow( $function_name );
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Tabs();
}

View File

@ -0,0 +1,232 @@
<?php
class ET_Builder_Module_Tabs_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Tab', 'et_builder' );
$this->plural = esc_html__( 'Tabs', 'et_builder' );
$this->slug = 'et_pb_tab';
$this->vb_support = 'on';
$this->type = 'child';
$this->child_title_var = 'title';
$this->advanced_setting_title_text = esc_html__( 'New Tab', 'et_builder' );
$this->settings_text = esc_html__( 'Tab Settings', 'et_builder' );
$this->main_css_element = '%%order_class%%';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => ".et_pb_tabs .et_pb_all_tabs {$this->main_css_element}.et_pb_tab",
'line_height' => ".et_pb_tabs {$this->main_css_element}.et_pb_tab p",
'limited_main' => ".et_pb_tabs .et_pb_all_tabs {$this->main_css_element}.et_pb_tab, .et_pb_tabs .et_pb_all_tabs {$this->main_css_element}.et_pb_tab p",
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
'tab' => array(
'label' => esc_html__( 'Tab', 'et_builder' ),
'css' => array(
'main' => ".et_pb_tabs .et_pb_tabs_controls li{$this->main_css_element}, .et_pb_tabs .et_pb_tabs_controls li{$this->main_css_element} a",
'color' => ".et_pb_tabs .et_pb_tabs_controls li{$this->main_css_element} a",
'important' => 'all',
),
'line_height' => array(
'range_settings' => array(
'min' => '1',
'max' => '100',
'step' => '1',
),
),
'hide_text_align' => true,
),
),
'background' => array(
'css' => array(
'main' => ".et_pb_tabs {$this->main_css_element}.et_pb_tab",
),
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => false,
),
'margin_padding' => array(
'use_margin' => false,
'css' => array(
'padding' => '.et_pb_tabs .et_pb_tab%%order_class%%',
),
),
'box_shadow' => array(
'default' => false,
),
'text' => false,
'max_width' => false,
'height' => false,
'button' => false,
'scroll_effects' => false,
'sticky' => false,
);
$this->custom_css_fields = array(
'main_element' => array(
'label' => et_builder_i18n( 'Main Element' ),
'selector' => ".et_pb_tabs div{$this->main_css_element}.et_pb_tab",
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'description' => esc_html__( 'The title will be used within the tab button for this tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'option_category' => 'basic_option',
'mobile_options' => true,
'hover' => 'tabs',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'description' => esc_html__( 'Here you can define the content that will be placed within the current tab.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'option_category' => 'basic_option',
'mobile_options' => true,
'hover' => 'tabs',
),
);
return $fields;
}
/**
* Set the `product` prop on TabItem.
*
* `product` prop is only available w/ the Parents' Tab module and not w/ TabsItem module.
*
* The global $et_pb_wc_tabs variable is set
*/
function maybe_inherit_values() {
// Inheriting Tabs attribute.
global $et_pb_wc_tabs;
if ( isset( $et_pb_wc_tabs ) && ! empty( $et_pb_wc_tabs['product'] ) ) {
$this->props['product'] = $et_pb_wc_tabs['product'];
}
}
/**
* Return the Product ID when set. Otherwise return parent::get_the_ID()
*
* $this->props['product'] is set using
*
* @see ET_Builder_Module_Tabs_Item->maybe_inherit_values()
*
* @return bool|int
*/
function get_the_ID() {
if ( ! isset( $this->props['product'] ) ) {
return parent::get_the_ID();
}
$product = wc_get_product( absint( $this->props['product'] ) );
if ( $product instanceof WC_Product ) {
return $product->get_id();
}
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_tab_titles;
global $et_pb_tab_classes;
$multi_view = et_pb_multi_view_options( $this );
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$i = 0;
$multi_view->set_default_value( 'title', esc_html__( 'Tab', 'et_builder' ) );
$et_pb_tab_titles[] = $multi_view->get_values( 'title' );
$et_pb_tab_classes[] = ET_Builder_Element::get_module_order_class( $render_slug );
// Module classnames
$this->add_classname(
array(
'clearfix',
$this->get_text_orientation_classname(),
)
);
if ( 1 === count( $et_pb_tab_titles ) ) {
$this->add_classname( 'et_pb_active_content' );
}
// Remove automatically added classnames
$this->remove_classname(
array(
'et_pb_module',
)
);
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
'attrs' => array(
'class' => 'et_pb_tab_content',
),
)
);
$output = sprintf(
'<div class="%2$s">
%4$s
%3$s
%1$s
</div>',
$content,
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Tabs_Item();
}

View File

@ -0,0 +1,621 @@
<?php
class ET_Builder_Module_Team_Member extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Person', 'et_builder' );
$this->plural = esc_html__( 'Persons', 'et_builder' );
$this->slug = 'et_pb_team_member';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_team_member';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'image' => et_builder_i18n( 'Image' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
'image' => et_builder_i18n( 'Image' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
),
),
'custom_css' => array(
'toggles' => array(
'animation' => array(
'title' => esc_html__( 'Image Animation', 'et_builder' ),
'priority' => 90,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'header' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h4, {$this->main_css_element} h1.et_pb_module_header, {$this->main_css_element} h2.et_pb_module_header, {$this->main_css_element} h3.et_pb_module_header, {$this->main_css_element} h5.et_pb_module_header, {$this->main_css_element} h6.et_pb_module_header",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h4',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element}",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
'position' => array(
'label' => et_builder_i18n( 'Position' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_member_position",
),
'line_height' => array(
'default' => '1.7em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => array(),
'image' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_team_member_image",
'border_styles' => "{$this->main_css_element} .et_pb_team_member_image",
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'box_shadow' => array(
'default' => array(),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_team_member_image',
'custom_style' => true,
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_team_member.et_pb_module',
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .et_pb_module_header',
'%%order_class%% .et_pb_member_position',
'%%order_class%% .et_pb_team_member_description p',
)
),
),
),
'filters' => array(
'css' => array(
'main' => '%%order_class%%',
),
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_team_member_image',
),
),
'button' => false,
);
$this->custom_css_fields = array(
'member_image' => array(
'label' => esc_html__( 'Member Image', 'et_builder' ),
'selector' => '.et_pb_team_member_image',
),
'member_description' => array(
'label' => esc_html__( 'Member Description', 'et_builder' ),
'selector' => '.et_pb_team_member_description',
),
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'selector' => '.et_pb_team_member_description h4',
),
'member_position' => array(
'label' => esc_html__( 'Member Position', 'et_builder' ),
'selector' => '.et_pb_member_position',
),
'member_social_links' => array(
'label' => esc_html__( 'Member Social Links', 'et_builder' ),
'selector' => '.et_pb_member_social_links',
),
);
$this->help_videos = array(
array(
'id' => 'rrKmaQ0n7Hw',
'name' => esc_html__( 'An introduction to the Person module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'name' => array(
'label' => esc_html__( 'Name', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the name of the person', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'position' => array(
'label' => et_builder_i18n( 'Position' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( "Input the person's position.", 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'image_url' => array(
'label' => et_builder_i18n( 'Image' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display.', 'et_builder' ),
'toggle_slug' => 'image',
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'facebook_url' => array(
'label' => esc_html__( 'Facebook Profile Url', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input Facebook Profile Url.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'url',
),
'twitter_url' => array(
'label' => esc_html__( 'Twitter Profile Url', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input Twitter Profile Url', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'url',
),
'google_url' => array(
'label' => esc_html__( 'Google+ Profile Url', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input Google+ Profile Url', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'url',
),
'linkedin_url' => array(
'label' => esc_html__( 'LinkedIn Profile Url', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input LinkedIn Profile Url', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'url',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the main text content for your module here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'icon_color' => array(
'label' => esc_html__( 'Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['icon_color'] = array( 'color' => '%%order_class%% .et_pb_member_social_links a' );
$fields['icon_font_size'] = array( 'font-size' => '%%order_class%% .et_pb_member_social_links a' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$name = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $this->props['header_level'], 'h4' ),
'content' => '{{name}}',
'attrs' => array(
'class' => 'et_pb_module_header',
),
)
);
$position = $multi_view->render_element(
array(
'tag' => 'p',
'content' => '{{position}}',
'attrs' => array(
'class' => 'et_pb_member_position',
),
)
);
$image_url = $this->props['image_url'];
$animation = $this->props['animation'];
$facebook_url = $this->props['facebook_url'];
$twitter_url = $this->props['twitter_url'];
$google_url = $this->props['google_url'];
$linkedin_url = $this->props['linkedin_url'];
$use_icon_font_size = $this->props['use_icon_font_size'];
$image = $social_links = '';
// Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'icon_color',
'selector' => '%%order_class%% .et_pb_member_social_links a',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
if ( '' !== $facebook_url ) {
$social_links .= sprintf(
'<li><a href="%1$s" class="et_pb_font_icon et_pb_facebook_icon"><span>%2$s</span></a></li>',
esc_url( $facebook_url ),
esc_html__( 'Facebook', 'et_builder' )
);
}
if ( '' !== $twitter_url ) {
$social_links .= sprintf(
'<li><a href="%1$s" class="et_pb_font_icon et_pb_twitter_icon"><span>%2$s</span></a></li>',
esc_url( $twitter_url ),
esc_html__( 'Twitter', 'et_builder' )
);
}
if ( '' !== $google_url ) {
$social_links .= sprintf(
'<li><a href="%1$s" class="et_pb_font_icon et_pb_google_icon"><span>%2$s</span></a></li>',
esc_url( $google_url ),
esc_html__( 'Google+', 'et_builder' )
);
}
if ( '' !== $linkedin_url ) {
$social_links .= sprintf(
'<li><a href="%1$s" class="et_pb_font_icon et_pb_linkedin_icon"><span>%2$s</span></a></li>',
esc_url( $linkedin_url ),
esc_html__( 'LinkedIn', 'et_builder' )
);
}
if ( '' !== $social_links ) {
$social_links = sprintf( '<ul class="et_pb_member_social_links">%1$s</ul>', $social_links );
}
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%% .et_pb_member_social_links .et_pb_font_icon',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'font-size',
'render_slug' => $render_slug,
'type' => 'range',
)
);
}
// Added for backward compatibility
if ( empty( $animation ) ) {
$animation = 'top';
}
if ( $multi_view->has_value( 'image_url' ) ) {
$team_member_image_classes = array(
'et_pb_team_member_image',
'et-waypoint',
'et_pb_animation_' . $animation,
);
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
$generate_css_filters = $this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
);
if ( $generate_css_filters ) {
$team_member_image_classes[] = $generate_css_filters;
}
}
$image_attrs = array(
'src' => '{{image_url}}',
'alt' => '{{name}}',
);
$image_attachment_class = et_pb_media_options()->get_image_attachment_class( $this->props, 'image_url' );
if ( ! empty( $image_attachment_class ) ) {
$image_attrs['class'] = esc_attr( $image_attachment_class );
}
$image = $multi_view->render_element(
array(
'tag' => 'div',
'content' => $multi_view->render_element(
array(
'tag' => 'img',
'attrs' => $image_attrs,
)
),
'attrs' => array(
'class' => implode( ' ', $team_member_image_classes ),
),
'classes' => array(
'et-svg' => array(
'image_url' => true,
),
),
)
);
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Module classnames
$this->add_classname(
array(
'clearfix',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( '' === $image ) {
$this->add_classname( 'et_pb_team_member_no_image' );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
)
);
$muti_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_team_member_no_image' => array(
'image' => '__empty',
),
),
)
);
$output = sprintf(
'<div%3$s class="%4$s"%10$s%11$s>
%9$s
%8$s
%2$s
<div class="et_pb_team_member_description">
%5$s
%6$s
%1$s
%7$s
</div>
</div>',
$content,
et_core_esc_previously( $image ),
$this->module_id(),
$this->module_classname( $render_slug ),
et_core_esc_previously( $name ), // #5
et_core_esc_previously( $position ),
$social_links,
$video_background,
$parallax_image_background,
et_core_esc_previously( $data_background_layout ), // #10
et_core_esc_previously( $muti_view_data_attr )
);
return $output;
}
/**
* Check if image has svg extension
*
* @param string $image_url Image URL.
*
* @return bool
*/
public function is_svg( $image_url ) {
if ( ! $image_url ) {
return false;
}
$image_pathinfo = pathinfo( $image_url );
return isset( $image_pathinfo['extension'] ) ? 'svg' === $image_pathinfo['extension'] : false;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = et_()->array_get( $args, 'name', '' );
$mode = et_()->array_get( $args, 'mode', '' );
$context = et_()->array_get( $args, 'context', '' );
$fields_need_escape = array(
'name',
'position',
);
if ( $raw_value && in_array( $name, $fields_need_escape, true ) ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
if ( 'image_url' === $name && 'classes' === $context ) {
$raw_value = $raw_value ? $this->is_svg( $raw_value ) : false;
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Team_Member();
}

View File

@ -0,0 +1,803 @@
<?php
class ET_Builder_Module_Testimonial extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Testimonial', 'et_builder' );
$this->plural = esc_html__( 'Testimonials', 'et_builder' );
$this->slug = 'et_pb_testimonial';
$this->vb_support = 'on';
$this->main_css_element = '%%order_class%%.et_pb_testimonial';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'image' => et_builder_i18n( 'Image' ),
'elements' => et_builder_i18n( 'Elements' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Quote Icon', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 51,
),
'image' => array(
'title' => et_builder_i18n( 'Image' ),
'priority' => 49,
),
'animation' => array(
'title' => esc_html__( 'Animation', 'et_builder' ),
'priority' => 100,
),
),
),
);
$this->advanced_fields = array(
'fonts' => array(
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element} *",
),
'hide_text_shadow' => true,
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
'author' => array(
'label' => esc_html__( 'Author', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_testimonial_author",
),
'font' => array(
'default' => '|700|||||||',
),
'line_height' => array(
'default' => floatval( et_get_option( 'body_font_height', '1.5' ) ) . 'em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'position' => array(
'label' => et_builder_i18n( 'Position' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_testimonial_position, {$this->main_css_element} .et_pb_testimonial_separator",
),
'hide_text_align' => true,
'line_height' => array(
'default' => floatval( et_get_option( 'body_font_height', '1.5' ) ) . 'em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'company' => array(
'label' => esc_html__( 'Company', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} .et_pb_testimonial_company, {$this->main_css_element} .et_pb_testimonial_company a",
),
'hide_text_align' => true,
'line_height' => array(
'default' => floatval( et_get_option( 'body_font_height', '1.5' ) ) . 'em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
),
'background' => array(
'has_background_color_toggle' => true,
'use_background_color' => true,
'options' => array(
'use_background_color' => array(
'default' => 'on',
),
'background_color' => array(
'depends_show_if' => 'on',
'default' => '#f5f5f5',
),
),
'settings' => array(
'color' => 'alpha',
),
),
'borders' => array(
'default' => array(),
'portrait' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%% .et_pb_testimonial_portrait, %%order_class%% .et_pb_testimonial_portrait:before',
'border_styles' => '%%order_class%% .et_pb_testimonial_portrait',
),
),
'label_prefix' => et_builder_i18n( 'Image' ),
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'defaults' => array(
'border_radii' => 'on|90px|90px|90px|90px',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(),
'image' => array(
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'css' => array(
'main' => '%%order_class%% .et_pb_testimonial_portrait:before',
),
'default_on_fronts' => array(
'color' => '',
'position' => '',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'text' => array(
'use_background_layout' => true,
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
'css' => array(
'main' => implode(
', ',
array(
'%%order_class%% .et_pb_testimonial_description p',
'%%order_class%% .et_pb_testimonial_description a',
'%%order_class%% .et_pb_testimonial_description .et_pb_testimonial_author',
)
),
),
),
'filters' => array(
'child_filters_target' => array(
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
),
),
'image' => array(
'css' => array(
'main' => '%%order_class%% .et_pb_testimonial_portrait',
),
),
'position_fields' => array(
'default' => 'relative',
),
);
$this->custom_css_fields = array(
'testimonial_portrait' => array(
'label' => esc_html__( 'Testimonial Portrait', 'et_builder' ),
'selector' => '.et_pb_testimonial_portrait',
),
'testimonial_description' => array(
'label' => esc_html__( 'Testimonial Description', 'et_builder' ),
'selector' => '.et_pb_testimonial_description',
),
'testimonial_author' => array(
'label' => esc_html__( 'Testimonial Author', 'et_builder' ),
'selector' => '.et_pb_testimonial_author',
),
'testimonial_meta' => array(
'label' => esc_html__( 'Testimonial Meta', 'et_builder' ),
'selector' => '.et_pb_testimonial_meta',
),
);
$this->help_videos = array(
array(
'id' => 'FkQuawiGWUw',
'name' => esc_html__( 'An introduction to the Testimonial module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'author' => array(
'label' => esc_html__( 'Author', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the name of the testimonial author.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'job_title' => array(
'label' => esc_html__( 'Job Title', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the job title.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'company_name' => array(
'label' => esc_html__( 'Company', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the name of the company.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'url' => array(
'label' => esc_html__( 'Company Link URL', 'et_builder' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the website of the author or leave blank for no link.', 'et_builder' ),
'toggle_slug' => 'link_options',
'dynamic_content' => 'url',
),
'url_new_window' => array(
'label' => esc_html__( 'Company Link Target', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'off' => esc_html__( 'In The Same Window', 'et_builder' ),
'on' => esc_html__( 'In The New Tab', 'et_builder' ),
),
'toggle_slug' => 'link_options',
'description' => esc_html__( 'Choose whether or not the URL should open in a new window.', 'et_builder' ),
'default_on_front' => 'off',
),
'portrait_url' => array(
'label' => et_builder_i18n( 'Image' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display.', 'et_builder' ),
'toggle_slug' => 'image',
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'quote_icon' => array(
'label' => esc_html__( 'Show Quote Icon', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'description' => esc_html__( 'Choose whether or not the quote icon should be visible.', 'et_builder' ),
'toggle_slug' => 'elements',
'mobile_options' => true,
'hover' => 'tabs',
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the main text content for your module here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'quote_icon_color' => array(
'label' => esc_html__( 'Quote Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the quote icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'quote_icon_background_color' => array(
'label' => esc_html__( 'Quote Icon Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the circular background area behind the quote icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '#f5f5f5',
'default_on_front' => '',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'font_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'toggle_slug' => 'icon',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'portrait_width' => array(
'label' => esc_html__( 'Image Width', 'et_builder' ),
'description' => esc_html__( "Adjust the width of the person's portrait photo within the testimonial.", 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'default_unit' => 'px',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '1',
'max' => '200',
'step' => '1',
),
'mobile_options' => true,
'sticky' => true,
),
'portrait_height' => array(
'label' => esc_html__( 'Image Height', 'et_builder' ),
'description' => esc_html__( "Adjust the height of the person's portrait photo within the testimonial.", 'et_builder' ),
'type' => 'range',
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'image',
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '1',
'max' => '200',
'step' => '1',
),
'mobile_options' => true,
'sticky' => true,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Quote Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Quote Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '32px',
'default_unit' => 'px',
'default_on_front' => '',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['portrait_width'] = array( 'width' => '%%order_class%% .et_pb_testimonial_portrait' );
$fields['portrait_height'] = array( 'height' => '%%order_class%% .et_pb_testimonial_portrait' );
$fields['quote_icon_color'] = array( 'color' => '%%order_class%%.et_pb_testimonial:before' );
$fields['quote_icon_background_color'] = array( 'background-color' => '%%order_class%%.et_pb_testimonial:before' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%%:before',
'border-radius' => '%%order_class%%:before',
'height' => '%%order_class%% .et-fb-quick-access-item-testimonial-icon',
'width' => '%%order_class%% .et-fb-quick-access-item-testimonial-icon',
'top' => '%%order_class%%:before, %%order_class%% .et-fb-quick-access-item-testimonial-icon',
'margin-left' => '%%order_class%%:before, %%order_class%% .et-fb-quick-access-item-testimonial-icon',
);
return $fields;
}
public function get_transition_image_fields_css_props() {
$fields = parent::get_transition_image_fields_css_props();
$fields = array_merge( $this->get_transition_borders_fields_css_props( 'portrait' ), $fields );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
// Allowing full html for backwards compatibility.
$author = $this->_esc_attr( 'author', 'full' );
$job_title = $this->_esc_attr( 'job_title' );
$portrait_url = $this->props['portrait_url'];
// Allowing full html for backwards compatibility.
$company_name = $this->_esc_attr( 'company_name', 'full' );
$url = $this->props['url'];
$quote_icon = $this->props['quote_icon'];
$url_new_window = $this->props['url_new_window'];
$use_background_color = $this->props['use_background_color'];
$background_color = $this->props['background_color'];
$background_color_hover = $this->get_hover_value( 'background_color' );
$use_icon_font_size = $this->props['use_icon_font_size'];
// Potrait Width.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'portrait_width',
'selector' => '%%order_class%% .et_pb_testimonial_portrait',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'width',
'important' => true,
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Potrait Height.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'portrait_height',
'selector' => '%%order_class%% .et_pb_testimonial_portrait',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'height',
'important' => true,
'render_slug' => $render_slug,
'type' => 'range',
)
);
// Quote Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'quote_icon_color',
'selector' => '%%order_class%%.et_pb_testimonial:before',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Quote Icon Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'quote_icon_background_color',
'selector' => '%%order_class%%.et_pb_testimonial:before',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Quote Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'font_icon',
'important' => true,
'selector' => '%%order_class%%.et_pb_testimonial:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Icon Size.
// $icon_selector = '%%order_class%%:before';.
if ( 'off' !== $quote_icon && 'off' !== $use_icon_font_size ) {
// Icon Font Size.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%%:before',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'processor_declaration_format' => 'font-size:%1$s; border-radius:%1$s; top:-%2$s; margin-left:-%2$s;',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_overlay_icon_font_size',
),
)
);
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$portrait_image = $multi_view->render_element(
array(
'tag' => 'div',
'attrs' => array(
'class' => 'et_pb_testimonial_portrait',
),
'styles' => array(
'background-image' => 'url({{portrait_url}})',
),
'required' => 'portrait_url',
)
);
$metas = array();
// Job title data.
$job_title = $multi_view->render_element(
array(
'content' => '{{job_title}}',
'attrs' => array(
'class' => 'et_pb_testimonial_position',
),
)
);
if ( $job_title ) {
$metas['job_title'] = $job_title;
}
// Company name data.
$company_name = $multi_view->render_element(
array(
'content' => '{{company_name}}',
'attrs' => array(
'class' => 'et_pb_testimonial_company',
),
)
);
if ( $company_name ) {
$metas['company_name'] = $company_name;
}
// Author data.
$author = $multi_view->render_element(
array(
'tag' => 'span',
'content' => '{{author}}',
'attrs' => array(
'class' => 'et_pb_testimonial_author',
),
)
);
// Images: Add CSS Filters and Mix Blend Mode rules (if set)
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
$this->add_classname(
$this->generate_css_filters(
$render_slug,
'child_',
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
)
);
}
// Module classnames
$this->add_classname(
array(
'clearfix',
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
if ( ! $multi_view->has_value( 'quote_icon', 'on', 'desktop' ) ) {
$this->add_classname( 'et_pb_icon_off' );
}
if ( ! $multi_view->has_value( 'portrait_url', 'desktop' ) ) {
$this->add_classname( 'et_pb_testimonial_no_image' );
}
if ( 'off' === $use_background_color ) {
$this->add_classname( 'et_pb_testimonial_no_bg' );
}
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
if ( 'on' === $use_background_color ) {
$el_style = array(
'selector' => '%%order_class%%.et_pb_testimonial',
'declaration' => sprintf(
'background-color: %1$s;',
esc_html( $background_color )
),
);
ET_Builder_Element::set_style( $render_slug, $el_style );
if ( et_builder_is_hover_enabled( 'background_color', $this->props ) ) {
$el_style = array(
'selector' => $this->add_hover_to_order_class( '%%order_class%%.et_pb_testimonial' ),
'declaration' => sprintf(
'background-color: %1$s;',
esc_html( $background_color_hover )
),
);
ET_Builder_Element::set_style( $render_slug, $el_style );
}
}
$multi_view_testimonial_content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
'attrs' => array(
'class' => 'et_pb_testimonial_content',
),
)
);
$multi_view_icon_off_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_icon_off' => array(
'quote_icon' => 'off',
),
'et_pb_testimonial_no_image' => array(
'portrait_url' => '__empty',
),
),
)
);
// Added span wrapper for comma between Job Title and Company Title
$testimonials_metas_string = implode( '<span class="et_pb_testimonial_separator">,</span> ', $metas );
$output = sprintf(
'<div%3$s class="%4$s"%10$s%11$s>
%9$s
%8$s
%7$s
<div class="et_pb_testimonial_description">
<div class="et_pb_testimonial_description_inner">%1$s</div>
%2$s
<p class="et_pb_testimonial_meta">%5$s</p>
</div>
</div>',
$multi_view_testimonial_content,
et_core_esc_previously( $author ),
$this->module_id(),
$this->module_classname( $render_slug ),
et_core_esc_previously( $testimonials_metas_string ), // #5
'', // Deprecated
$portrait_image,
$video_background,
$parallax_image_background,
et_core_esc_previously( $data_background_layout ), // #10
et_core_esc_previously( $multi_view_icon_off_data_attr )
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$context = et_()->array_get( $args, 'context', '' );
$name = et_()->array_get( $args, 'name', '' );
$mode = et_()->array_get( $args, 'mode', '' );
$url = $this->props['url'];
$link_target = 'on' === $this->props['url_new_window'] ? 'target="_blank"' : '';
$fields_need_escape = array(
'author',
'job_title',
'company_name',
);
if ( ! $raw_value ) {
return $raw_value;
}
if ( $raw_value && 'content' === $context && in_array( $name, $fields_need_escape, true ) ) {
$raw_value = $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
if ( $url && $raw_value ) {
if ( 'author' === $name && ! $this->_esc_attr( $multi_view->get_name_by_mode( 'company_name', $mode ) ) ) {
$raw_value = sprintf(
'<a href="%2$s" %3$s>%1$s</a>',
$raw_value,
esc_url( $url ),
et_core_intentionally_unescaped( $link_target, 'fixed_string' )
);
} elseif ( 'company_name' === $name ) {
$raw_value = sprintf(
'<a href="%2$s" %3$s>%1$s</a>',
$raw_value,
esc_url( $url ),
et_core_intentionally_unescaped( $link_target, 'fixed_string' )
);
}
}
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Testimonial();
}

View File

@ -0,0 +1,625 @@
<?php
class ET_Builder_Module_Text extends ET_Builder_Module {
function init() {
$this->name = et_builder_i18n( 'Text' );
$this->plural = esc_html__( 'Texts', 'et_builder' );
$this->slug = 'et_pb_text';
$this->vb_support = 'on';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
),
),
'advanced' => array(
'toggles' => array(
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 45,
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
'sub_toggles' => array(
'p' => array(
'name' => 'P',
'icon' => 'text-left',
),
'a' => array(
'name' => 'A',
'icon' => 'text-link',
),
'ul' => array(
'name' => 'UL',
'icon' => 'list',
),
'ol' => array(
'name' => 'OL',
'icon' => 'numbered-list',
),
'quote' => array(
'name' => 'QUOTE',
'icon' => 'text-quote',
),
),
),
'header' => array(
'title' => esc_html__( 'Heading Text', 'et_builder' ),
'priority' => 49,
'tabbed_subtoggles' => true,
'sub_toggles' => array(
'h1' => array(
'name' => 'H1',
'icon' => 'text-h1',
),
'h2' => array(
'name' => 'H2',
'icon' => 'text-h2',
),
'h3' => array(
'name' => 'H3',
'icon' => 'text-h3',
),
'h4' => array(
'name' => 'H4',
'icon' => 'text-h4',
),
'h5' => array(
'name' => 'H5',
'icon' => 'text-h5',
),
'h6' => array(
'name' => 'H6',
'icon' => 'text-h6',
),
),
),
'width' => array(
'title' => et_builder_i18n( 'Sizing' ),
'priority' => 65,
),
),
),
);
$this->main_css_element = '%%order_class%%';
$this->advanced_fields = array(
'fonts' => array(
'text' => array(
'label' => et_builder_i18n( 'Text' ),
'css' => array(
'line_height' => "{$this->main_css_element}",
'color' => "{$this->main_css_element}.et_pb_text",
),
'line_height' => array(
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'toggle_slug' => 'text',
'sub_toggle' => 'p',
'hide_text_align' => true,
),
'link' => array(
'label' => et_builder_i18n( 'Link' ),
'css' => array(
'main' => "{$this->main_css_element} a",
'color' => "{$this->main_css_element}.et_pb_text a",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
),
'toggle_slug' => 'text',
'sub_toggle' => 'a',
),
'ul' => array(
'label' => esc_html__( 'Unordered List', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} ul li",
'color' => "{$this->main_css_element}.et_pb_text ul li, {$this->main_css_element}.et_pb_text ol li > ul li",
'line_height' => "{$this->main_css_element} ul li",
'item_indent' => "{$this->main_css_element} ul",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'toggle_slug' => 'text',
'sub_toggle' => 'ul',
),
'ol' => array(
'label' => esc_html__( 'Ordered List', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} ol li",
'color' => "{$this->main_css_element}.et_pb_text ol li",
'line_height' => "{$this->main_css_element} ol li",
'item_indent' => "{$this->main_css_element} ol",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'toggle_slug' => 'text',
'sub_toggle' => 'ol',
),
'quote' => array(
'label' => esc_html__( 'Blockquote', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} blockquote",
'color' => "{$this->main_css_element}.et_pb_text blockquote",
),
'line_height' => array(
'default' => '1em',
),
'font_size' => array(
'default' => '14px',
),
'toggle_slug' => 'text',
'sub_toggle' => 'quote',
),
'header' => array(
'label' => esc_html__( 'Heading', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h1",
),
'font_size' => array(
'default' => absint( et_get_option( 'body_header_size', '30' ) ) . 'px',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h1',
),
'header_2' => array(
'label' => esc_html__( 'Heading 2', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h2",
),
'font_size' => array(
'default' => '26px',
),
'line_height' => array(
'default' => '1em',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h2',
),
'header_3' => array(
'label' => esc_html__( 'Heading 3', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h3",
),
'font_size' => array(
'default' => '22px',
),
'line_height' => array(
'default' => '1em',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h3',
),
'header_4' => array(
'label' => esc_html__( 'Heading 4', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h4",
),
'font_size' => array(
'default' => '18px',
),
'line_height' => array(
'default' => '1em',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h4',
),
'header_5' => array(
'label' => esc_html__( 'Heading 5', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h5",
),
'font_size' => array(
'default' => '16px',
),
'line_height' => array(
'default' => '1em',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h5',
),
'header_6' => array(
'label' => esc_html__( 'Heading 6', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element} h6",
),
'font_size' => array(
'default' => '14px',
),
'line_height' => array(
'default' => '1em',
),
'toggle_slug' => 'header',
'sub_toggle' => 'h6',
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'text' => array(
'use_background_layout' => true,
'sub_toggle' => 'p',
'options' => array(
'text_orientation' => array(
'default' => 'left',
),
'background_layout' => array(
'default' => 'light',
'hover' => 'tabs',
),
),
),
'text_shadow' => array(
// Don't add text-shadow fields since they already are via font-options
'default' => false,
),
'button' => false,
);
$this->help_videos = array(
array(
'id' => 'oL00RjEKZaU',
'name' => esc_html__( 'An introduction to the Text module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Here you can create the content that will be used within the module.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'ul_type' => array(
'label' => esc_html__( 'Unordered List Style Type', 'et_builder' ),
'description' => esc_html__( 'This setting adjusts the shape of the bullet point that begins each list item.', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'disc' => et_builder_i18n( 'Disc' ),
'circle' => et_builder_i18n( 'Circle' ),
'square' => et_builder_i18n( 'Square' ),
'none' => et_builder_i18n( 'None' ),
),
'priority' => 80,
'default' => 'disc',
'default_on_front' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ul',
'mobile_options' => true,
),
'ul_position' => array(
'label' => esc_html__( 'Unordered List Style Position', 'et_builder' ),
'description' => esc_html__( 'The bullet point that begins each list item can be placed either inside or outside the parent list wrapper. Placing list items inside will indent them further within the list.', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'outside' => et_builder_i18n( 'Outside' ),
'inside' => et_builder_i18n( 'Inside' ),
),
'priority' => 85,
'default' => 'outside',
'default_on_front' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ul',
'mobile_options' => true,
),
'ul_item_indent' => array(
'label' => esc_html__( 'Unordered List Item Indent', 'et_builder' ),
'description' => esc_html__( 'Increasing indentation will push list items further towards the center of the text content, giving the list more visible separation from the the rest of the text.', 'et_builder' ),
'type' => 'range',
'option_category' => 'configuration',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ul',
'priority' => 90,
'default' => '0px',
'default_unit' => 'px',
'default_on_front' => '',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'mobile_options' => true,
),
'ol_type' => array(
'label' => esc_html__( 'Ordered List Style Type', 'et_builder' ),
'description' => esc_html__( 'Here you can choose which types of characters are used to distinguish between each item in the ordered list.', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'decimal' => 'decimal',
'armenian' => 'armenian',
'cjk-ideographic' => 'cjk-ideographic',
'decimal-leading-zero' => 'decimal-leading-zero',
'georgian' => 'georgian',
'hebrew' => 'hebrew',
'hiragana' => 'hiragana',
'hiragana-iroha' => 'hiragana-iroha',
'katakana' => 'katakana',
'katakana-iroha' => 'katakana-iroha',
'lower-alpha' => 'lower-alpha',
'lower-greek' => 'lower-greek',
'lower-latin' => 'lower-latin',
'lower-roman' => 'lower-roman',
'upper-alpha' => 'upper-alpha',
'upper-greek' => 'upper-greek',
'upper-latin' => 'upper-latin',
'upper-roman' => 'upper-roman',
'none' => 'none',
),
'priority' => 80,
'default' => 'decimal',
'default_on_front' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ol',
'mobile_options' => true,
),
'ol_position' => array(
'label' => esc_html__( 'Ordered List Style Position', 'et_builder' ),
'description' => esc_html__( 'The characters that begins each list item can be placed either inside or outside the parent list wrapper. Placing list items inside will indent them further within the list.', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'inside' => et_builder_i18n( 'Inside' ),
'outside' => et_builder_i18n( 'Outside' ),
),
'priority' => 85,
'default' => 'inside',
'default_on_front' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ol',
'mobile_options' => true,
),
'ol_item_indent' => array(
'label' => esc_html__( 'Ordered List Item Indent', 'et_builder' ),
'description' => esc_html__( 'Increasing indentation will push list items further towards the center of the text content, giving the list more visible separation from the the rest of the text.', 'et_builder' ),
'type' => 'range',
'option_category' => 'configuration',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'ol',
'priority' => 90,
'default' => '0px',
'default_unit' => 'px',
'default_on_front' => '',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'mobile_options' => true,
),
'quote_border_weight' => array(
'label' => esc_html__( 'Blockquote Border Weight', 'et_builder' ),
'description' => esc_html__( 'Block quotes are given a border to separate them from normal text. You can increase or decrease the size of that border using this setting.', 'et_builder' ),
'type' => 'range',
'option_category' => 'configuration',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'quote',
'priority' => 85,
'default' => '5px',
'default_unit' => 'px',
'default_on_front' => '',
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => '0',
'max' => '100',
'step' => '1',
),
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
'quote_border_color' => array(
'label' => esc_html__( 'Blockquote Border Color', 'et_builder' ),
'description' => esc_html__( 'Block quotes are given a border to separate them from normal text. Pick a color to use for that border.', 'et_builder' ),
'type' => 'color-alpha',
'option_category' => 'configuration',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => 'quote',
'field_template' => 'color',
'priority' => 90,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
function convert_embeds( $matches ) {
$url = $matches[1];
if ( strpos( $url, '?v=' ) ) {
// e.g. https://www.youtube.com/watch?v=Wx6bTxiOmRc
$pieces = explode( 'v=', $url );
$video_id = $pieces[1];
} else {
// e.g. https://youtu.be/UABdOJQ3pdo
$pieces = explode( '/', $url );
$video_id = end( $pieces );
}
return sprintf(
'<p><iframe width="1080" height="608" src="%s" allow="%s" allowfullscreen></iframe></p>',
sprintf( 'https://www.youtube.com/embed/%s', esc_attr( $video_id ) ),
'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture'
);
}
/**
* Transition fields for Text module.
*
* @since 3.26
*
* @return array Fields list in array.
*/
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['quote_border_weight'] = array( 'border-width' => '%%order_class%% blockquote' );
$fields['quote_border_color'] = array( 'border-color' => '%%order_class%% blockquote' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$ul_type_values = et_pb_responsive_options()->get_property_values( $this->props, 'ul_type' );
$ul_position_values = et_pb_responsive_options()->get_property_values( $this->props, 'ul_position' );
$ul_item_indent_values = et_pb_responsive_options()->get_property_values( $this->props, 'ul_item_indent' );
$ol_type_values = et_pb_responsive_options()->get_property_values( $this->props, 'ol_type' );
$ol_position_values = et_pb_responsive_options()->get_property_values( $this->props, 'ol_position' );
$ol_item_indent_values = et_pb_responsive_options()->get_property_values( $this->props, 'ol_item_indent' );
$background_layout = $this->props['background_layout'];
$background_layout_hover = et_pb_hover_options()->get_value( 'background_layout', $this->props, 'light' );
$background_layout_hover_enabled = et_pb_hover_options()->is_enabled( 'background_layout', $this->props );
$background_layout_values = et_pb_responsive_options()->get_property_values( $this->props, 'background_layout' );
$background_layout_tablet = isset( $background_layout_values['tablet'] ) ? $background_layout_values['tablet'] : '';
$background_layout_phone = isset( $background_layout_values['phone'] ) ? $background_layout_values['phone'] : '';
$this->content = et_builder_replace_code_content_entities( $this->content );
// Un-autop converted GB block comments
$this->content = preg_replace( '/(<p>)?<!-- (\/)?divi:(.+?) (\/?)-->(<\/p>)?/', '<!-- $2divi:$3 $4-->', $this->content );
// Convert GB embeds to iframes
$this->content = preg_replace_callback(
'/<!-- divi:core-embed\/youtube {"url":"([^"]+)"[\s\S]+?<!-- \/divi:core-embed\/youtube -->/',
array( $this, 'convert_embeds' ),
$this->content
);
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// UL.
et_pb_responsive_options()->generate_responsive_css( $ul_type_values, '%%order_class%% ul', 'list-style-type', $render_slug, ' !important;', 'type' );
et_pb_responsive_options()->generate_responsive_css( $ul_position_values, '%%order_class%% ul', 'list-style-position', $render_slug, '', 'type' );
et_pb_responsive_options()->generate_responsive_css( $ul_item_indent_values, '%%order_class%% ul', 'padding-left', $render_slug, ' !important;' );
// OL.
et_pb_responsive_options()->generate_responsive_css( $ol_type_values, '%%order_class%% ol', 'list-style-type', $render_slug, ' !important;', 'type' );
et_pb_responsive_options()->generate_responsive_css( $ol_position_values, '%%order_class%% ol', 'list-style-position', $render_slug, ' !important;', 'type' );
et_pb_responsive_options()->generate_responsive_css( $ol_item_indent_values, '%%order_class%% ol', 'padding-left', $render_slug, ' !important;' );
// Quote.
$this->generate_styles(
array(
'base_attr_name' => 'quote_border_weight',
'selector' => '%%order_class%% blockquote',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'border-width',
'important' => array( 'hover' ),
'render_slug' => $render_slug,
'type' => 'range',
)
);
$this->generate_styles(
array(
'base_attr_name' => 'quote_border_color',
'selector' => '%%order_class%% blockquote',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'border-color',
'important' => array( 'hover' ),
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Module classnames
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$content = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{content}}',
'attrs' => array(
'class' => 'et_pb_text_inner',
),
)
);
$output = sprintf(
'<div%3$s class="%2$s"%6$s>
%5$s
%4$s
%1$s
</div>',
$content,
$this->module_classname( $render_slug ),
$this->module_id(),
$video_background,
$parallax_image_background, // #5
et_core_esc_previously( $data_background_layout )
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Text();
}

View File

@ -0,0 +1,676 @@
<?php
class ET_Builder_Module_Toggle extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Toggle', 'et_builder' );
$this->plural = esc_html__( 'Toggles', 'et_builder' );
$this->slug = 'et_pb_toggle';
$this->vb_support = 'on';
$this->additional_shortcode_slugs = array( 'et_pb_accordion_item' );
$this->main_css_element = '%%order_class%%.et_pb_toggle';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => et_builder_i18n( 'Text' ),
'state' => esc_html__( 'State', 'et_builder' ),
),
),
'advanced' => array(
'toggles' => array(
'icon' => esc_html__( 'Icon', 'et_builder' ),
'text' => array(
'title' => et_builder_i18n( 'Text' ),
'priority' => 49,
),
'toggle' => esc_html__( 'Toggle', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => ".et_pb_module{$this->main_css_element}",
'border_styles' => ".et_pb_module{$this->main_css_element}",
),
),
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '1px',
'color' => '#d9d9d9',
'style' => 'solid',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'important' => true,
),
),
),
'fonts' => array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'css' => array(
'main' => "{$this->main_css_element} h5, {$this->main_css_element} h1.et_pb_toggle_title, {$this->main_css_element} h2.et_pb_toggle_title, {$this->main_css_element} h3.et_pb_toggle_title, {$this->main_css_element} h4.et_pb_toggle_title, {$this->main_css_element} h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'header_level' => array(
'default' => 'h5',
),
'options_priority' => array(
'title_text_color' => 9,
),
),
'closed_title' => array(
'label' => esc_html__( 'Closed Title', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_toggle_close h5, {$this->main_css_element}.et_pb_toggle_close h1.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h2.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h3.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h4.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'hide_text_color' => true,
'line_height' => array(
'default' => '1.7em',
),
'font_size' => array(
'default' => '16px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'closed_title' => array(
'label' => esc_html__( 'Closed Title', 'et_builder' ),
'css' => array(
'main' => "{$this->main_css_element}.et_pb_toggle_close h5, {$this->main_css_element}.et_pb_toggle_close h1.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h2.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h3.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h4.et_pb_toggle_title, {$this->main_css_element}.et_pb_toggle_close h6.et_pb_toggle_title",
'important' => 'plugin_only',
),
'hide_text_color' => true,
'default_from' => 'title',
'line_height' => array(
'default' => '1.7em',
),
'font_size' => array(
'default' => '16px',
),
'letter_spacing' => array(
'default' => '0px',
),
),
'body' => array(
'label' => et_builder_i18n( 'Body' ),
'css' => array(
'main' => "{$this->main_css_element}",
'limited_main' => "{$this->main_css_element}, {$this->main_css_element} p, {$this->main_css_element} .et_pb_toggle_content",
'line_height' => "{$this->main_css_element} p",
'text_shadow' => "{$this->main_css_element} .et_pb_toggle_content",
),
'block_elements' => array(
'tabbed_subtoggles' => true,
'bb_icons_support' => true,
),
),
),
'background' => array(
'settings' => array(
'color' => 'alpha',
),
),
'margin_padding' => array(
'css' => array(
'important' => 'all',
),
),
'button' => false,
'position_fields' => array(
'default' => 'relative',
),
'z_index' => array(
'default' => '1',
),
);
$this->custom_css_fields = array(
'open_toggle' => array(
'label' => esc_html__( 'Open Toggle', 'et_builder' ),
'selector' => '.et_pb_toggle.et_pb_toggle_open',
'no_space_before_selector' => true,
),
'toggle_title' => array(
'label' => esc_html__( 'Toggle Title', 'et_builder' ),
'selector' => '.et_pb_toggle_title',
),
'toggle_icon' => array(
'label' => esc_html__( 'Toggle Icon', 'et_builder' ),
'selector' => '.et_pb_toggle_title:before',
),
'toggle_content' => array(
'label' => esc_html__( 'Toggle Content', 'et_builder' ),
'selector' => '.et_pb_toggle_content',
),
);
$this->help_videos = array(
array(
'id' => 'hFgp_A_u7mg',
'name' => esc_html__( 'An introduction to the Toggle module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'title' => array(
'label' => et_builder_i18n( 'Title' ),
'type' => 'text',
'option_category' => 'basic_option',
'description' => esc_html__( 'The title will appear above the content and when the toggle is closed.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'open' => array(
'label' => esc_html__( 'State', 'et_builder' ),
'type' => 'select',
'option_category' => 'basic_option',
'options' => array(
'off' => esc_html__( 'Close', 'et_builder' ),
'on' => esc_html__( 'Open', 'et_builder' ),
),
'default_on_front' => 'off',
'toggle_slug' => 'state',
'description' => esc_html__( 'Choose whether or not this toggle should start in an open or closed state.', 'et_builder' ),
),
'content' => array(
'label' => et_builder_i18n( 'Body' ),
'type' => 'tiny_mce',
'option_category' => 'basic_option',
'description' => esc_html__( 'Input the main text content for your module here.', 'et_builder' ),
'toggle_slug' => 'main_content',
'dynamic_content' => 'text',
'mobile_options' => true,
'hover' => 'tabs',
),
'open_toggle_text_color' => array(
'label' => esc_html__( 'Open Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the open state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'title',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'open_toggle_background_color' => array(
'label' => esc_html__( 'Open Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the open state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_text_color' => array(
'label' => esc_html__( 'Closed Title Text Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique text colors for toggle titles when they are open and closed. Choose the closed state title color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'closed_title',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'closed_toggle_background_color' => array(
'label' => esc_html__( 'Closed Toggle Background Color', 'et_builder' ),
'description' => esc_html__( 'You can pick unique background colors for toggles when they are in their open and closed states. Choose the closed state background color here.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'toggle',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
// Closed icon styling.
'icon_color' => array(
'label' => esc_html__( 'Closed Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the toggle icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'toggle_icon' => array(
'label' => esc_html__( 'Closed Icon', 'et_builder' ),
'toggle_slug' => 'icon',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Closed Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Closed Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
// Open icon styling.
'open_icon_color' => array(
'label' => esc_html__( 'Open Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the toggle icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'open_toggle_icon' => array(
'label' => esc_html__( 'Open Icon', 'et_builder' ),
'toggle_slug' => 'icon',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'open_use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Open Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'open_icon_font_size',
),
'depends_show_if' => 'on',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'option_category' => 'font_option',
),
'open_icon_font_size' => array(
'label' => esc_html__( 'Open Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'icon',
'default' => '16px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$title = '%%order_class%% .et_pb_toggle .et_pb_toggle_title';
$fields['icon_color'] = array( 'color' => '%%order_class%% .et_pb_toggle_title:before' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%% .et_pb_toggle_title:before',
'margin-top' => '%%order_class%% .et_pb_toggle_title:before',
'right' => '%%order_class%% .et_pb_toggle_title:before',
);
$fields['toggle_text_color'] = array( 'color' => $title );
$fields['toggle_font_size'] = array( 'font-size' => $title );
$fields['toggle_letter_spacing'] = array( 'letter-spacing' => $title );
$fields['toggle_line_height'] = array( 'line-height' => $title );
$fields['toggle_text_shadow_style'] = array( 'text-shadow' => $title );
$fields['closed_toggle_text_color'] = array( 'color' => '%%order_class%%.et_pb_toggle_close .et_pb_toggle_title' );
$fields['closed_toggle_background_color'] = array( 'background-color' => '%%order_class%%.et_pb_toggle_close' );
$fields['open_toggle_text_color'] = array( 'color' => '%%order_class%%.et_pb_toggle_open .et_pb_toggle_title' );
$fields['open_toggle_background_color'] = array( 'background-color' => '%%order_class%%.et_pb_toggle_open' );
return $fields;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$open = $this->props['open'];
$header_level = $this->props['title_level'];
$use_icon_font_size = $this->props['use_icon_font_size'];
$accordion_item_class = 'et_pb_accordion_item' === $render_slug ? '.et_pb_accordion_item' : '';
// Open Toggle Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'open_toggle_background_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Closed Toggle Background Color.
$this->generate_styles(
array(
'base_attr_name' => 'closed_toggle_background_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Open Toggle Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'open_toggle_text_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h5.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h1.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h2.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h3.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h4.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_open h6.et_pb_toggle_title",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Closed Toggle Text Color.
$this->generate_styles(
array(
'base_attr_name' => 'closed_toggle_text_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h5.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h1.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h2.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h3.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h4.et_pb_toggle_title, {$accordion_item_class}%%order_class%%.et_pb_toggle.et_pb_toggle_close h6.et_pb_toggle_title",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Icon Size.
if ( ! empty( $this->props['open_use_icon_font_size'] ) && 'off' !== $this->props['open_use_icon_font_size'] ) {
// Calculate icon font size and its right position.
$this->generate_styles(
array(
'base_attr_name' => 'open_icon_font_size',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_open .et_pb_toggle_title:before",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'css_property' => 'font-size',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_toggle_title_icon_font_size',
),
)
);
}
// Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'open_icon_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_open .et_pb_toggle_title:before",
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Toggle Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'open_toggle_icon',
'important' => true,
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_open .et_pb_toggle_title:before",
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Closed Icon Size.
if ( ! empty( $this->props['use_icon_font_size'] ) && 'off' !== $this->props['use_icon_font_size'] ) {
// Calculate icon font size and its right position.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_close .et_pb_toggle_title:before",
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'css_property' => 'font-size',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_toggle_title_icon_font_size',
),
)
);
}
// Closed Icon Color.
$this->generate_styles(
array(
'base_attr_name' => 'icon_color',
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_close .et_pb_toggle_title:before",
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Closed Toggle Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'toggle_icon',
'important' => true,
'selector' => "{$accordion_item_class}%%order_class%%.et_pb_toggle_close .et_pb_toggle_title:before",
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
if ( 'et_pb_accordion_item' === $render_slug ) {
global $et_pb_accordion_item_number, $et_pb_accordion_header_level;
$open = 1 === $et_pb_accordion_item_number ? 'on' : 'off';
$et_pb_accordion_item_number++;
// Respect the individual level first.
if ( '' !== $this->props['toggle_level'] ) {
$header_level = $this->props['toggle_level'];
} else {
// If individual tag is not there choose global.
$header_level = $et_pb_accordion_header_level;
}
$this->add_classname( 'et_pb_accordion_item' );
}
// Adding "_item" class for toggle module for customizer targetting. There's no proper selector
// for toggle module styles since both accordion and toggle module use the same selector.
if ( 'et_pb_toggle' === $render_slug ) {
$this->add_classname( 'et_pb_toggle_item' );
}
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
$heading = $multi_view->render_element(
array(
'tag' => et_pb_process_header_level( $header_level, 'h5' ),
'content' => '{{title}}',
'attrs' => array(
'class' => 'et_pb_toggle_title',
),
'required' => false,
)
);
$multi_view_content = $multi_view->render_attrs(
array(
'content' => '{{content}}',
)
);
// Module classnames.
$this->add_classname(
array(
$this->get_text_orientation_classname(),
)
);
if ( 'on' === $open ) {
$this->add_classname( 'et_pb_toggle_open' );
} else {
$this->add_classname( 'et_pb_toggle_close' );
}
$output = sprintf(
'<div%4$s class="%2$s">
%6$s
%5$s
%1$s
<div class="et_pb_toggle_content clearfix"%7$s>%3$s</div>
</div>',
$heading,
$this->module_classname( $render_slug ),
$this->content,
$this->module_id(),
$video_background, // #5
$parallax_image_background,
et_core_esc_previously( $multi_view_content )
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
$mode = isset( $args['mode'] ) ? $args['mode'] : '';
if ( $raw_value && 'title' === $name ) {
return $this->_esc_attr( $multi_view->get_name_by_mode( $name, $mode ), 'none', $raw_value );
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Toggle();
}

View File

@ -0,0 +1,497 @@
<?php
class ET_Builder_Module_Video extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Video', 'et_builder' );
$this->plural = esc_html__( 'Videos', 'et_builder' );
$this->slug = 'et_pb_video';
$this->vb_support = 'on';
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => esc_html__( 'Video', 'et_builder' ),
'overlay' => et_builder_i18n( 'Overlay' ),
),
),
'advanced' => array(
'toggles' => array(
'play_icon' => esc_html__( 'Play Icon', 'et_builder' ),
'overlay' => et_builder_i18n( 'Overlay' ),
),
),
);
$this->custom_css_fields = array(
'video_icon' => array(
'label' => esc_html__( 'Video Icon', 'et_builder' ),
'selector' => '.et_pb_video_play',
),
);
$this->advanced_fields = array(
'background' => array(
'options' => array(
'background_color' => array(
'depends_on' => array(
'custom_padding',
),
'depends_on_responsive' => array(
'custom_padding',
),
'depends_show_if_not' => array(
'',
'|||',
),
'is_toggleable' => true,
),
),
),
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => '%%order_class%%, %%order_class%% iframe',
),
),
),
),
'box_shadow' => array(
'default' => array(
'css' => array(
'overlay' => 'inset',
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
'custom_padding' => array(
'responsive_affects' => array(
'background_color',
),
),
),
'fonts' => false,
'text' => false,
'button' => false,
'link_options' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => '3jXN8CBz0TU',
'name' => esc_html__( 'An introduction to the Video module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'src' => array(
'label' => esc_html__( 'Video MP4 File Or Youtube URL', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'data_type' => 'video',
'upload_button_text' => esc_attr__( 'Upload a video', 'et_builder' ),
'choose_text' => esc_attr__( 'Choose a Video MP4 File', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Video', 'et_builder' ),
'description' => esc_html__( 'Upload your desired video in .MP4 format, or type in the URL to the video you would like to display', 'et_builder' ),
'toggle_slug' => 'main_content',
'computed_affects' => array(
'__video',
),
'mobile_options' => true,
'hover' => 'tabs',
),
'src_webm' => array(
'label' => esc_html__( 'Video WEBM File', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'data_type' => 'video',
'upload_button_text' => esc_attr__( 'Upload a video', 'et_builder' ),
'choose_text' => esc_attr__( 'Choose a Video WEBM File', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Video', 'et_builder' ),
'description' => esc_html__( 'Upload the .WEBM version of your video here. All uploaded videos should be in both .MP4 .WEBM formats to ensure maximum compatibility in all browsers.', 'et_builder' ),
'toggle_slug' => 'main_content',
'computed_affects' => array(
'__video',
),
'mobile_options' => true,
'hover' => 'tabs',
),
'image_src' => array(
'label' => esc_html__( 'Overlay Image', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'additional_button' => sprintf(
'<input type="button" class="button et-pb-video-image-button" value="%1$s" />',
esc_attr__( 'Generate Image From Video', 'et_builder' )
),
'additional_button_type' => 'generate_image_url_from_video',
'additional_button_attrs' => array(
'video_source' => 'src',
),
'classes' => 'et_pb_video_overlay',
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display over your video. You can also generate a still image from your video.', 'et_builder' ),
'toggle_slug' => 'overlay',
'computed_affects' => array(
'__video_cover_src',
),
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'play_icon_color' => array(
'label' => esc_html__( 'Play Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the play icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'play_icon',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'font_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'toggle_slug' => 'play_icon',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'__video' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Video', 'get_video' ),
'computed_depends_on' => array(
'src',
'src_webm',
),
'computed_minimum' => array(
'src',
'src_webm',
),
),
'__video_cover_src' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Video', 'get_video_cover_src' ),
'computed_depends_on' => array(
'image_src',
),
'computed_minimum' => array(
'image_src',
),
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Custom Icon Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'play_icon',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Play Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'play_icon',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '96px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
'thumbnail_overlay_color' => array(
'label' => esc_html__( 'Overlay Background Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the overlay that appears behind the play icon when hovering over the video.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'overlay',
'default_on_front' => 'rgba(0,0,0,.6)',
'mobile_options' => true,
'sticky' => true,
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['play_icon_color'] = array( 'color' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
'line-height' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
'margin-top' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
'margin-left' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
);
return $fields;
}
static function get_video( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'src' => '',
'src_webm' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( empty( $args['src'] ) && empty( $args['src_webm'] ) ) {
return '';
}
$video_src = '';
if ( false !== et_pb_check_oembed_provider( esc_url( $args['src'] ) ) ) {
$video_src = et_builder_get_oembed( esc_url( $args['src'] ) );
} else {
$video_src = sprintf(
'
<video controls>
%1$s
%2$s
</video>',
( '' !== $args['src'] ? sprintf( '<source type="video/mp4" src="%s" />', esc_url( $args['src'] ) ) : '' ),
( '' !== $args['src_webm'] ? sprintf( '<source type="video/webm" src="%s" />', esc_url( $args['src_webm'] ) ) : '' )
);
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'wp-mediaelement' );
}
return $video_src;
}
static function get_video_cover_src( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$post_id = isset( $current_page['id'] ) ? $current_page['id'] : self::get_current_post_id();
$defaults = array(
'image_src' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( isset( $args['image_src'] ) ) {
$dynamic_value = et_builder_parse_dynamic_content( stripslashes( $args['image_src'] ) );
if ( $dynamic_value->is_dynamic() && current_user_can( 'edit_post', $post_id ) ) {
$args['image_src'] = $dynamic_value->resolve( $post_id );
}
}
$image_output = '';
if ( '' !== $args['image_src'] ) {
$image_output = et_pb_set_video_oembed_thumbnail_resolution( $args['image_src'], 'high' );
}
return $image_output;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$src = $this->props['src'];
$src_webm = $this->props['src_webm'];
$image_src = $this->props['image_src'];
$use_icon_font_size = $this->props['use_icon_font_size'];
foreach ( $multi_view->get_modes() as $mode ) {
$video_srcs[ $mode ] = self::get_video(
array(
'src' => $multi_view->get_inherit_value( 'src', $mode ),
'src_webm' => $multi_view->get_inherit_value( 'src_webm', $mode ),
)
);
}
$multi_view->set_custom_prop( 'video_srcs', $video_srcs );
$video_src = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{video_srcs}}',
'attrs' => array(
'class' => 'et_pb_video_box',
),
)
);
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Play Icon color.
$this->generate_styles(
array(
'base_attr_name' => 'play_icon_color',
'selector' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Play Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'font_icon',
'important' => true,
'selector' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
// Icon Font Size.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%% .et_pb_video_overlay .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_overlay_icon_font_size',
),
)
);
}
// Thumbnail Overlay Color.
$this->generate_styles(
array(
'hover' => 'false',
'base_attr_name' => 'thumbnail_overlay_color',
'selector' => '%%order_class%% .et_pb_video_overlay_hover:hover',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
$muti_view_video_overlay = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '<div class="et_pb_video_overlay_hover"><a href="#" class="et_pb_video_play"></a></div>',
'attrs' => array(
'class' => 'et_pb_video_overlay',
),
'styles' => array(
'background-image' => 'url({{image_src}})',
),
'visibility' => array(
'image_src' => '__not_empty',
),
'required' => 'image_src',
)
);
$output = sprintf(
'<div%2$s class="%3$s">
%6$s
%5$s
%1$s
%4$s
</div>',
( '' !== $video_src ? $video_src : '' ),
$this->module_id(),
$this->module_classname( $render_slug ),
$muti_view_video_overlay,
$video_background,
$parallax_image_background
);
return $output;
}
/**
* Filter multi view value.
*
* @since 3.27.1
*
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
*
* @param mixed $raw_value Props raw value.
* @param array $args {
* Context data.
*
* @type string $context Context param: content, attrs, visibility, classes.
* @type string $name Module options props name.
* @type string $mode Current data mode: desktop, hover, tablet, phone.
* @type string $attr_key Attribute key for attrs context data. Example: src, class, etc.
* @type string $attr_sub_key Attribute sub key that availabe when passing attrs value as array such as styes. Example: padding-top, margin-botton, etc.
* }
*
* @return mixed
*/
public function multi_view_filter_value( $raw_value, $args ) {
$name = isset( $args['name'] ) ? $args['name'] : '';
if ( $raw_value && 'image_src' === $name ) {
$raw_value = self::get_video_cover_src(
array(
'image_src' => $raw_value,
)
);
}
return $raw_value;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Video();
}

View File

@ -0,0 +1,386 @@
<?php
class ET_Builder_Module_Video_Slider extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Video Slider', 'et_builder' );
$this->plural = esc_html__( 'Video Sliders', 'et_builder' );
$this->slug = 'et_pb_video_slider';
$this->vb_support = 'on';
$this->child_slug = 'et_pb_video_slider_item';
$this->child_item_text = esc_html__( 'Video', 'et_builder' );
$this->main_css_element = '.et_pb_video_slider%%order_class%%';
$this->has_box_shadow = false;
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'elements' => et_builder_i18n( 'Elements' ),
'overlay' => et_builder_i18n( 'Overlay' ),
),
),
'advanced' => array(
'toggles' => array(
'colors' => esc_html__( 'Controls', 'et_builder' ),
),
),
);
$this->custom_css_fields = array(
'play_button' => array(
'label' => esc_html__( 'Play Button', 'et_builder' ),
'selector' => '.et_pb_video_play',
),
'thumbnail_item' => array(
'label' => esc_html__( 'Thumbnail Item', 'et_builder' ),
'selector' => '.et_pb_carousel_item',
),
'arrows' => array(
'label' => esc_html__( 'Slider Arrows', 'et_builder' ),
'selector' => '.et-pb-slider-arrows a',
),
);
$this->advanced_fields = array(
'borders' => array(
'default' => array(
'css' => array(
'main' => array(
'border_radii' => "{$this->main_css_element} .et_pb_slider, {$this->main_css_element} .et_pb_carousel_item",
'border_styles' => "{$this->main_css_element} .et_pb_slider, {$this->main_css_element} .et_pb_carousel_item",
),
),
),
),
'margin_padding' => array(
'css' => array(
'important' => array( 'custom_margin' ), // needed to overwrite last module margin-bottom styling
),
),
'max_width' => array(
'css' => array(
'module_alignment' => '%%order_class%%.et_pb_video_slider.et_pb_module',
),
),
'fonts' => false,
'text' => false,
'button' => false,
'box_shadow' => array(
'default' => array(
'css' => array(
'main' => '%%order_class%%>.et_pb_slider, %%order_class%%>.et_pb_carousel .et_pb_carousel_item',
'overlay' => 'inset',
),
),
),
'link_options' => false,
'position_fields' => array(
'default' => 'relative',
),
);
$this->help_videos = array(
array(
'id' => 'gwTruYDcxoE',
'name' => esc_html__( 'An introduction to the Video Slider module', 'et_builder' ),
),
);
}
function get_fields() {
$fields = array(
'show_image_overlay' => array(
'label' => esc_html__( 'Show Image Overlays on Main Video', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'off',
'toggle_slug' => 'overlay',
'description' => esc_html__( 'This option will cover the player UI on the main video. This image can either be uploaded in each video setting or auto-generated by Divi.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_arrows' => array(
'label' => esc_html__( 'Show Arrows', 'et_builder' ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'This setting will turn on and off the navigation arrows.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'show_thumbnails' => array(
'label' => esc_html__( 'Slider Controls', 'et_builder' ),
'type' => 'select',
'option_category' => 'configuration',
'options' => array(
'on' => esc_html__( 'Use Thumbnail Track', 'et_builder' ),
'off' => esc_html__( 'Use Dot Navigation', 'et_builder' ),
),
'default_on_front' => 'on',
'toggle_slug' => 'elements',
'description' => esc_html__( 'This setting will let you choose to use the thumbnail track controls below the slider or dot navigation at the bottom of the slider.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
),
'play_icon_color' => array(
'label' => esc_html__( 'Play Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the play icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'colors',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
'font_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'toggle_slug' => 'colors',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Play Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'colors',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Play Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'colors',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '96px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
'thumbnail_overlay_color' => array(
'label' => esc_html__( 'Thumbnail Overlay Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the overlay that appears behind the play icon when hovering over the video.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'colors',
'mobile_options' => true,
'sticky' => true,
),
'controls_color' => array(
'label' => esc_html__( 'Slider Controls Color', 'et_builder' ),
'type' => 'select',
'option_category' => 'color_option',
'options' => array(
'light' => et_builder_i18n( 'Light' ),
'dark' => et_builder_i18n( 'Dark' ),
),
'tab_slug' => 'advanced',
'toggle_slug' => 'colors',
'description' => esc_html__( 'This setting will make your slider controls either light or dark in color. Slider controls are either the arrows on the thumbnail track or the circles in dot navigation.', 'et_builder' ),
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['play_icon_color'] = array( 'color' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play',
'margin-left' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play',
'margin-top' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play',
'line-height' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play',
);
return $fields;
}
function before_render() {
global $et_pb_slider_image_overlay,
$et_pb_video_slider_sticky;
$show_image_overlay = et_pb_multi_view_options( $this )->get_values( 'show_image_overlay' );
$et_pb_slider_image_overlay = $show_image_overlay;
$et_pb_video_slider_sticky = et_pb_sticky_options()->is_sticky_module( $this->props );
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
$multi_view = et_pb_multi_view_options( $this );
$show_arrows = $this->props['show_arrows'];
$show_thumbnails = $this->props['show_thumbnails'];
$controls_color = $this->props['controls_color'];
$use_icon_font_size = $this->props['use_icon_font_size'];
global $et_pb_slider_image_overlay;
$video_background = $this->video_background();
$parallax_image_background = $this->get_parallax_image_background();
// Play Icon color.
$this->generate_styles(
array(
'base_attr_name' => 'play_icon_color',
'selector' => '%%order_class%% .et_pb_video_play, %%order_class%% .et_pb_carousel .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Play Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'font_icon',
'important' => true,
'selector' => '%%order_class%% .et_pb_video_play:before, %%order_class%% .et_pb_carousel .et_pb_video_play:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
// Icon Font Size.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '%%order_class%% .et_pb_video_wrap .et_pb_video_play, %%order_class%% .et_pb_video_wrap .et_pb_carousel .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_overlay_icon_font_size',
),
)
);
}
// Thumbnail Overlay Color.
$this->generate_styles(
array(
'hover' => false,
'base_attr_name' => 'thumbnail_overlay_color',
'selector' => '%%order_class%% .et_pb_carousel_item .et_pb_video_overlay_hover:hover, %%order_class%%.et_pb_video_slider .et_pb_slider:hover .et_pb_video_overlay_hover, %%order_class%% .et_pb_carousel_item.et-pb-active-control .et_pb_video_overlay_hover',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'background-color',
'render_slug' => $render_slug,
'type' => 'color',
)
);
$slider_classname = '';
$slider_classname .= 'off' === $show_arrows ? ' et_pb_slider_no_arrows' : '';
$slider_classname .= 'on' === $show_thumbnails ? ' et_pb_slider_carousel et_pb_slider_no_pagination' : '';
$slider_classname .= 'off' === $show_thumbnails ? ' et_pb_slider_dots' : '';
$slider_classname .= " et_pb_controls_{$controls_color}";
$content = $this->content;
// Module classnames
if ( $this->has_box_shadow ) {
$this->add_classname( 'et_pb_has_box_shadow' );
}
$multi_view_data_attr = $multi_view->render_attrs(
array(
'classes' => array(
'et_pb_slider_no_arrows' => array(
'show_arrows' => 'off',
),
'et_pb_slider_carousel' => array(
'show_thumbnails' => 'on',
),
'et_pb_slider_no_pagination' => array(
'show_thumbnails' => 'on',
),
'et_pb_slider_dots' => array(
'show_thumbnails' => 'off',
),
),
)
);
$output = sprintf(
'<div%3$s class="%4$s">
%6$s
%5$s
<div class="et_pb_slider et_pb_preload%1$s"%7$s>
<div class="et_pb_slides">
%2$s
</div>
</div>
</div>
',
esc_attr( $slider_classname ),
$content,
$this->module_id(),
$this->module_classname( $render_slug ),
$video_background,
$parallax_image_background,
$multi_view_data_attr
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Video_Slider();
}

View File

@ -0,0 +1,544 @@
<?php
class ET_Builder_Module_Video_Slider_Item extends ET_Builder_Module {
function init() {
$this->name = esc_html__( 'Video', 'et_builder' );
$this->plural = esc_html__( 'Videos', 'et_builder' );
$this->slug = 'et_pb_video_slider_item';
$this->vb_support = 'on';
$this->type = 'child';
$this->custom_css_tab = false;
$this->child_title_var = 'admin_title';
$this->advanced_setting_title_text = esc_html__( 'New Video', 'et_builder' );
$this->settings_text = esc_html__( 'Video Settings', 'et_builder' );
$this->settings_modal_toggles = array(
'general' => array(
'toggles' => array(
'main_content' => esc_html__( 'Video', 'et_builder' ),
'overlay' => et_builder_i18n( 'Overlay' ),
'admin_label' => et_builder_i18n( 'Admin Label' ),
),
),
'advanced' => array(
'toggles' => array(
'arrows_color' => esc_html__( 'Controls', 'et_builder' ),
),
),
);
$this->advanced_fields = array(
'text' => array(
'use_text_orientation' => false,
'use_background_layout' => true,
'options' => array(
'background_layout' => array(
'label' => esc_html__( 'Slider Arrows Color', 'et_builder' ),
'option_category' => 'color_option',
'toggle_slug' => 'arrows_color',
'description' => esc_html__( 'This setting will make your slider arrows either light or dark in color.', 'et_builder' ),
'default' => 'dark',
'default_on_child' => true,
'hover' => 'tabs',
'priority' => 1,
),
),
),
'box_shadow' => array(
'default' => false,
),
'borders' => array(
'default' => false,
),
'text_shadow' => array(
'default' => false,
),
'background' => false,
'fonts' => false,
'max_width' => false,
'height' => false,
'margin_padding' => false,
'button' => false,
'link_options' => false,
'scroll_effects' => false,
);
}
function get_fields() {
$fields = array(
'admin_title' => array(
'label' => et_builder_i18n( 'Admin Label' ),
'type' => 'text',
'description' => esc_html__( 'This will change the label of the video in the builder for easy identification.', 'et_builder' ),
'toggle_slug' => 'admin_label',
),
'src' => array(
'label' => esc_html__( 'Video MP4/URL', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'data_type' => 'video',
'upload_button_text' => esc_attr__( 'Upload a video', 'et_builder' ),
'choose_text' => esc_attr__( 'Choose a Video MP4 File', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Video', 'et_builder' ),
'description' => esc_html__( 'Upload your desired video in .MP4 format, or type in the URL to the video you would like to display', 'et_builder' ),
'toggle_slug' => 'main_content',
'computed_affects' => array(
'__get_oembed',
'__oembed_thumbnail',
'__is_oembed',
),
'mobile_options' => true,
'hover' => 'tabs',
),
'src_webm' => array(
'label' => esc_html__( 'Video Webm', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'data_type' => 'video',
'upload_button_text' => esc_attr__( 'Upload a video', 'et_builder' ),
'choose_text' => esc_attr__( 'Choose a Video WEBM File', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Video', 'et_builder' ),
'description' => esc_html__( 'Upload the .WEBM version of your video here. All uploaded videos should be in both .MP4 .WEBM formats to ensure maximum compatibility in all browsers.', 'et_builder' ),
'toggle_slug' => 'main_content',
'mobile_options' => true,
'hover' => 'tabs',
),
'image_src' => array(
'label' => esc_html__( 'Image Overlay URL', 'et_builder' ),
'type' => 'upload',
'option_category' => 'basic_option',
'upload_button_text' => et_builder_i18n( 'Upload an image' ),
'choose_text' => esc_attr__( 'Choose an Image', 'et_builder' ),
'update_text' => esc_attr__( 'Set As Image', 'et_builder' ),
'additional_button' => sprintf(
'<input type="button" class="button et-pb-video-image-button" value="%1$s" />',
esc_attr__( 'Generate From Video', 'et_builder' )
),
'additional_button_type' => 'generate_image_url_from_video',
'additional_button_attrs' => array(
'video_source' => 'src',
),
'classes' => 'et_pb_video_overlay',
'description' => esc_html__( 'Upload your desired image, or type in the URL to the image you would like to display over your video. You can also generate a still image from your video.', 'et_builder' ),
'toggle_slug' => 'overlay',
'dynamic_content' => 'image',
'mobile_options' => true,
'hover' => 'tabs',
),
'__oembed_thumbnail' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Video_Slider_Item', 'get_oembed_thumbnail' ),
'computed_depends_on' => array(
'src',
'image_src',
),
'computed_minimum' => array(
'src',
),
),
'__is_oembed' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Video_Slider_Item', 'is_oembed' ),
'computed_depends_on' => array(
'src',
),
'computed_minimum' => array(
'src',
),
),
'__get_oembed' => array(
'type' => 'computed',
'computed_callback' => array( 'ET_Builder_Module_Video_Slider_Item', 'get_oembed' ),
'computed_depends_on' => array(
'src',
),
'computed_minimum' => array(
'src',
),
),
'play_icon_color' => array(
'label' => esc_html__( 'Play Icon Color', 'et_builder' ),
'description' => esc_html__( 'Here you can define a custom color for the play icon.', 'et_builder' ),
'type' => 'color-alpha',
'custom_color' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'arrows_color',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
'priority' => 5,
),
'use_icon_font_size' => array(
'label' => esc_html__( 'Use Play Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'If you would like to control the size of the icon, you must first enable this option.', 'et_builder' ),
'type' => 'yes_no_button',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default_on_front' => 'off',
'affects' => array(
'icon_font_size',
),
'tab_slug' => 'advanced',
'toggle_slug' => 'arrows_color',
'option_category' => 'font_option',
),
'icon_font_size' => array(
'label' => esc_html__( 'Play Icon Font Size', 'et_builder' ),
'description' => esc_html__( 'Control the size of the icon by increasing or decreasing the font size.', 'et_builder' ),
'type' => 'range',
'option_category' => 'font_option',
'tab_slug' => 'advanced',
'toggle_slug' => 'arrows_color',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default' => '96px',
'default_unit' => 'px',
'default_on_front' => '',
'range_settings' => array(
'min' => '1',
'max' => '120',
'step' => '1',
),
'mobile_options' => true,
'depends_show_if' => 'on',
'responsive' => true,
'sticky' => true,
'hover' => 'tabs',
),
'font_icon' => array(
'label' => esc_html__( 'Icon', 'et_builder' ),
'toggle_slug' => 'arrows_color',
'type' => 'select_icon',
'class' => array( 'et-pb-font-icon' ),
'description' => esc_html__( 'Choose an icon to display with your blurb.', 'et_builder' ),
'mobile_options' => true,
'hover' => 'tabs',
'sticky' => true,
'tab_slug' => 'advanced',
),
);
return $fields;
}
public function get_transition_fields_css_props() {
$fields = parent::get_transition_fields_css_props();
$fields['background_layout'] = array( 'color' => '%%order_class%% .et-pb-arrow-prev, %%order_class%% .et-pb-arrow-next' );
$fields['play_icon_color'] = array( 'color' => '%%order_class%%.et_pb_slide .et_pb_video_play' );
$fields['icon_font_size'] = array(
'font-size' => '%%order_class%%.et_pb_slide .et_pb_video_play',
'margin-left' => '%%order_class%%.et_pb_slide .et_pb_video_play',
'margin-top' => '%%order_class%%.et_pb_slide .et_pb_video_play',
'line-height' => '%%order_class%%.et_pb_slide .et_pb_video_play',
);
return $fields;
}
protected static function resolve_oembed_thumbnail( $src, $post_id ) {
$dynamic_value = et_builder_parse_dynamic_content( $src );
if ( $dynamic_value->is_dynamic() && current_user_can( 'edit_post', $post_id ) ) {
return $dynamic_value->resolve( $post_id );
}
return $src;
}
static function get_oembed_thumbnail( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$post_id = isset( $current_page['id'] ) ? $current_page['id'] : self::get_current_post_id();
$defaults = array(
'image_src' => '',
'src' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( '' !== $args['image_src'] ) {
return et_pb_set_video_oembed_thumbnail_resolution(
self::resolve_oembed_thumbnail( $args['image_src'], $post_id ),
'high'
);
} else {
if ( false !== et_pb_check_oembed_provider( esc_url( $args['src'] ) ) ) {
add_filter( 'oembed_dataparse', 'et_pb_video_oembed_data_parse', 10, 3 );
// Save thumbnail
$thumbnail_track_output = et_builder_get_oembed( esc_url( $args['src'] ), 'image', true );
// Set back to normal
remove_filter( 'oembed_dataparse', 'et_pb_video_oembed_data_parse', 10, 3 );
return $thumbnail_track_output;
} else {
return '';
}
}
}
static function is_oembed( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'src',
);
$args = wp_parse_args( $args, $defaults );
return et_pb_check_oembed_provider( esc_url( $args['src'] ) );
}
static function get_oembed( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'src' => '',
);
$args = wp_parse_args( $args, $defaults );
// Save thumbnail
$thumbnail_track_output = et_builder_get_oembed( esc_url( $args['src'] ), 'image', true );
return $thumbnail_track_output;
}
static function get_video( $args = array(), $conditional_tags = array(), $current_page = array() ) {
$defaults = array(
'src' => '',
'src_webm' => '',
);
$args = wp_parse_args( $args, $defaults );
$video_src = '';
if ( false !== et_pb_check_oembed_provider( esc_url( $args['src'] ) ) ) {
$video_src = et_builder_get_oembed( esc_url( $args['src'] ) );
} else {
$video_src = sprintf(
'
<video controls>
%1$s
%2$s
</video>',
( '' !== $args['src'] ? sprintf( '<source type="video/mp4" src="%1$s" />', esc_url( $args['src'] ) ) : '' ),
( '' !== $args['src_webm'] ? sprintf( '<source type="video/webm" src="%1$s" />', esc_url( $args['src_webm'] ) ) : '' )
);
wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'wp-mediaelement' );
}
return $video_src;
}
/**
* Renders the module output.
*
* @param array $attrs List of attributes.
* @param string $content Content being processed.
* @param string $render_slug Slug of module that is used for rendering output.
*
* @return string
*/
public function render( $attrs, $content, $render_slug ) {
global $et_pb_slider_image_overlay,
$et_pb_video_slider_sticky;
$multi_view = et_pb_multi_view_options( $this );
$multi_view->set_custom_prop( 'show_image_overlay', $et_pb_slider_image_overlay );
$src = $this->props['src'];
$src_webm = $this->props['src_webm'];
$image_src = $this->props['image_src'];
$video_src = '';
// Controls.
$use_icon_font_size = $this->props['use_icon_font_size'];
// Play Icon color.
$this->generate_styles(
array(
'base_attr_name' => 'play_icon_color',
'selector' => '%%order_class%%.et_pb_slide .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'css_property' => 'color',
'important' => true,
'render_slug' => $render_slug,
'type' => 'color',
)
);
// Play Icon Styles.
$this->generate_styles(
array(
'utility_arg' => 'icon_font_family_and_content',
'render_slug' => $render_slug,
'base_attr_name' => 'font_icon',
'important' => true,
'selector' => '%%order_class%%.et_pb_slide .et_pb_video_play:before',
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_extended_icon',
),
)
);
// Icon Size.
if ( 'off' !== $use_icon_font_size ) {
// Icon Font Size.
$this->generate_styles(
array(
'base_attr_name' => 'icon_font_size',
'selector' => '.et_pb_video_slider %%order_class%%.et_pb_slide .et_pb_video_wrap .et_pb_video_overlay .et_pb_video_play',
'hover_pseudo_selector_location' => 'suffix',
'sticky_pseudo_selector_location' => 'prefix',
'render_slug' => $render_slug,
'type' => 'range',
'is_sticky_module' => $et_pb_video_slider_sticky,
// processed attr value can't be directly assigned to single css property so
// custom processor is needed to render this attr.
'processor' => array(
'ET_Builder_Module_Helper_Style_Processor',
'process_overlay_icon_font_size',
),
)
);
}
global $et_pb_slider_image_overlay;
$video_srcs = array();
$image_srcs = array();
foreach ( $multi_view->get_modes() as $mode ) {
$src = $multi_view->get_value( 'src', $mode );
$src_webm = $multi_view->get_value( 'src_webm', $mode );
$image_src = $multi_view->get_value( 'image_src', $mode );
if ( $src || $src_webm ) {
$video_srcs[ $mode ] = self::get_video(
array(
'src' => $src,
'src_webm' => $src_webm,
)
);
}
if ( $src || $image_src ) {
$image_srcs[ $mode ] = self::get_oembed_thumbnail(
array(
'src' => $src,
'image_src' => $image_src,
)
);
}
}
if ( $video_srcs ) {
$multi_view->set_custom_prop( 'video_srcs', $video_srcs );
}
if ( $image_srcs ) {
$multi_view->set_custom_prop( 'image_srcs', $image_srcs );
}
$video_src = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '{{video_srcs}}',
'attrs' => array(
'class' => 'et_pb_video_box',
),
)
);
$video_overlay = $multi_view->render_element(
array(
'tag' => 'div',
'content' => '<div class="et_pb_video_overlay_hover"><a href="#" class="et_pb_video_play"></a></div>',
'attrs' => array(
'class' => 'et_pb_video_overlay',
),
'styles' => array(
'background-image' => 'url({{image_srcs}})',
),
'visibility' => array(
'show_image_overlay' => 'on',
),
)
);
$video_output = $multi_view->render_element(
array(
'tag' => 'div',
'content' => "{$video_src}{$video_overlay}",
'attrs' => array(
'class' => 'et_pb_video_wrap',
),
'required' => 'video_srcs',
)
);
if ( '' !== $image_src ) {
$image_overlay_output = et_pb_set_video_oembed_thumbnail_resolution( $image_src, 'high' );
$thumbnail_track_output = $image_src;
} else {
$image_overlay_output = '';
if ( false !== et_pb_check_oembed_provider( esc_url( $src ) ) ) {
add_filter( 'oembed_dataparse', 'et_pb_video_oembed_data_parse', 10, 3 );
// Save thumbnail
$thumbnail_track_output = et_builder_get_oembed( esc_url( $src ), 'image', true );
$image_overlay_output = $thumbnail_track_output;
// Set back to normal
remove_filter( 'oembed_dataparse', 'et_pb_video_oembed_data_parse', 10, 3 );
} else {
$thumbnail_track_output = '';
}
}
// Module classnames
$this->add_classname(
array(
'et_pb_slide',
)
);
// Background layout class names.
$background_layout_class_names = et_pb_background_layout_options()->get_background_layout_class( $this->props );
$this->add_classname( $background_layout_class_names );
// Remove automatically added classnames
$this->remove_classname(
array(
'et_pb_module',
$render_slug,
)
);
// Background layout data attributes.
$data_background_layout = et_pb_background_layout_options()->get_background_layout_attrs( $this->props );
$multi_view_image_srcs_data_attr = $multi_view->render_attrs(
array(
'attrs' => array(
'data-image' => '{{image_srcs}}',
),
)
);
$output = sprintf(
'<div class="%1$s"%3$s%4$s%5$s>
%2$s
</div>
',
$this->module_classname( $render_slug ),
( '' !== $video_output ? $video_output : '' ),
( '' !== $multi_view->get_value( 'image_srcs' ) ? sprintf( ' data-image="%1$s"', esc_attr( $multi_view->get_value( 'image_srcs' ) ) ) : '' ),
et_core_esc_previously( $data_background_layout ),
$multi_view_image_srcs_data_attr
);
return $output;
}
}
if ( et_builder_should_load_all_module_data() ) {
new ET_Builder_Module_Video_Slider_Item();
}

View File

@ -0,0 +1,10 @@
<?php
abstract class ET_Builder_Module_Field_Base {
/**
* @param array $args
*
* @return array
*/
abstract public function get_fields( array $args = array() );
}

View File

@ -0,0 +1,789 @@
<?php
/**
* Border Field.
*
* @package Divi
* @subpackage Builder
*/
/**
* Handles border field for modules.
*/
class ET_Builder_Module_Field_Border extends ET_Builder_Module_Field_Base {
/**
* @var ET_Core_Data_Utils
*/
protected static $_;
/**
* @var ET_Builder_Module_Helper_ResponsiveOptions
*
* @since 3.23
*/
public static $responsive = null;
protected static $_is_default = array();
/**
* List of no border reset.
*
* @since 3.23 Remove pricing tables from the list to allow border reset.
*
* @var array
*/
protected static $_no_border_reset = array(
'et_pb_accordion',
'et_pb_accordion_item',
'et_pb_pricing_table',
'et_pb_tabs',
'et_pb_toggle',
'et_pb_social_media_follow',
);
/**
* ET_Builder_Module_Field_Border constructor.
*/
public function __construct() {
$this->template = et_pb_option_template();
self::$_ = ET_Core_Data_Utils::instance();
$this->set_template();
}
/**
* Set option template for borders
*
* @since 3.28
*
* @return void
*/
public function set_template() {
$template = $this->template;
if ( $template->is_enabled() && ! $template->has( 'border' ) ) {
$template_placeholders = $template->placeholders(
array(
'suffix' => null,
'label_prefix' => null,
'tab_slug' => null,
'toggle_slug' => null,
'color_type' => null,
'depends_on' => null,
'depends_show_if' => null,
'sub_toggle' => null,
'defaults' => array(
'border_radii' => null,
'border_styles' => array(
'width' => null,
'color' => null,
'style' => null,
),
),
)
);
$template->add( 'border', $this->get_fields( $template_placeholders ) );
}
}
/**
* Get border fields.
*
* @since 3.28 Add option template support
* @since 3.23 Add support for responsive settings. Add allowed units for some range fields.
*
* @param array $args Border settings arguments.
* @param bool $return_template_id return template id
*
* @return array Border fields.
*/
public function get_fields( array $args = array(), $return_template_id = false ) {
$settings = shortcode_atts(
array(
'suffix' => '',
'label_prefix' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'border',
'color_type' => 'color-alpha',
'depends_on' => null,
'depends_show_if' => null,
'sub_toggle' => null,
'use_radius' => true,
'defaults' => array(
'border_radii' => 'on||||',
'border_styles' => array(
'width' => '0px',
'color' => '#333333',
'style' => 'solid',
),
),
),
$args
);
if ( $this->template->is_enabled() && $this->template->has( 'border' ) ) {
return $this->template->create( 'border', $settings, $return_template_id );
}
$additional_options = array();
$suffix = $settings['suffix'];
$defaults = $settings['defaults']['border_styles'];
$defaultUnit = 'px';
if ( $settings['use_radius'] ) {
$additional_options[ "border_radii{$suffix}" ] = array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Rounded Corners', 'et_builder' ) ),
'type' => 'border-radius',
'hover' => 'tabs',
'validate_input' => true,
'default' => $settings['defaults']['border_radii'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'sub_toggle' => $settings['sub_toggle'],
'attr_suffix' => $suffix,
'option_category' => 'border',
'description' => esc_html__( 'Here you can control the corner radius of this element. Enable the link icon to control all four corners at once, or disable to define custom values for each.', 'et_builder' ),
'tooltip' => esc_html__( 'Sync values', 'et_builder' ),
'mobile_options' => true,
'sticky' => true,
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
);
} else {
$additional_options[ "border_radii{$suffix}" ] = array();
}
$additional_options[ "border_styles{$suffix}" ] = array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Border Styles', 'et_builder' ) ),
'description' => esc_html__( 'You can add borders to any element, customize their appearance and assign unique styles to each edge.', 'et_builder' ),
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'sub_toggle' => $settings['sub_toggle'],
'type' => 'composite',
'attr_suffix' => $suffix,
'option_category' => 'border',
'composite_type' => 'tabbed',
'composite_structure' => array(
'border_all' => array(
'icon' => 'border-all',
'controls' => array(
"border_width_all{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Border Width', 'et_builder' ) ),
'description' => esc_html__( 'Increasing the width of the border will increase its size/thickness.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'default' => $defaults['width'],
'default_unit' => $defaultUnit,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => 0,
'max' => 50,
'step' => 1,
'min_limit' => 0,
),
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_color_all{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Border Color', 'et_builder' ) ),
'description' => esc_html__( 'Pick a color to be used for the border.', 'et_builder' ),
'type' => $settings['color_type'],
'hover' => 'tabs',
'default' => $defaults['color'],
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_style_all{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Border Style', 'et_builder' ) ),
'description' => esc_html__( 'Borders support various different styles, each of which will change the shape of the border element.', 'et_builder' ),
'type' => 'select',
'options' => et_builder_get_border_styles(),
'default' => $defaults['style'],
'context' => "border_styles{$suffix}",
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
),
),
'border_top' => array(
'icon' => 'border-top',
'controls' => array(
"border_width_top{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Top Border Width', 'et_builder' ) ),
'description' => esc_html__( 'Increasing the width of the border will increase its size/thickness.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'allow_empty' => true,
'default_from' => "border_all.controls.border_width_all{$suffix}",
'default_unit' => $defaultUnit,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => 0,
'max' => 50,
'step' => 1,
'min_limit' => 0,
),
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_color_top{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Top Border Color', 'et_builder' ) ),
'description' => esc_html__( 'Pick a color to be used for the border.', 'et_builder' ),
'type' => $settings['color_type'],
'hover' => 'tabs',
'default_from' => "border_all.controls.border_color_all{$suffix}",
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_style_top{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Top Border Style', 'et_builder' ) ),
'description' => esc_html__( 'Borders support various different styles, each of which will change the shape of the border element.', 'et_builder' ),
'type' => 'select',
'options' => et_builder_get_border_styles(),
'default_from' => "border_all.controls.border_style_all{$suffix}",
'context' => "border_styles{$suffix}",
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
),
),
'border_right' => array(
'icon' => 'border-right',
'controls' => array(
"border_width_right{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Right Border Width', 'et_builder' ) ),
'description' => esc_html__( 'Increasing the width of the border will increase its size/thickness.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'allow_empty' => true,
'default_from' => "border_all.controls.border_width_all{$suffix}",
'default_unit' => $defaultUnit,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => 0,
'max' => 50,
'step' => 1,
'min_limit' => 0,
),
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_color_right{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Right Border Color', 'et_builder' ) ),
'description' => esc_html__( 'Pick a color to be used for the border.', 'et_builder' ),
'type' => $settings['color_type'],
'hover' => 'tabs',
'default_from' => "border_all.controls.border_color_all{$suffix}",
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_style_right{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Right Border Style', 'et_builder' ) ),
'description' => esc_html__( 'Borders support various different styles, each of which will change the shape of the border element.', 'et_builder' ),
'type' => 'select',
'options' => et_builder_get_border_styles(),
'default_from' => "border_all.controls.border_style_all{$suffix}",
'context' => "border_styles{$suffix}",
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
),
),
'border_bottom' => array(
'icon' => 'border-bottom',
'controls' => array(
"border_width_bottom{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Bottom Border Width', 'et_builder' ) ),
'description' => esc_html__( 'Increasing the width of the border will increase its size/thickness.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'allow_empty' => true,
'default_from' => "border_all.controls.border_width_all{$suffix}",
'default_unit' => $defaultUnit,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => 0,
'max' => 50,
'step' => 1,
'min_limit' => 0,
),
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_color_bottom{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Bottom Border Color', 'et_builder' ) ),
'description' => esc_html__( 'Pick a color to be used for the border.', 'et_builder' ),
'type' => $settings['color_type'],
'hover' => 'tabs',
'default_from' => "border_all.controls.border_color_all{$suffix}",
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_style_bottom{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Bottom Border Style', 'et_builder' ) ),
'description' => esc_html__( 'Borders support various different styles, each of which will change the shape of the border element.', 'et_builder' ),
'type' => 'select',
'options' => et_builder_get_border_styles(),
'default_from' => "border_all.controls.border_style_all{$suffix}",
'context' => "border_styles{$suffix}",
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
),
),
'border_left' => array(
'icon' => 'border-left',
'controls' => array(
"border_width_left{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Left Border Width', 'et_builder' ) ),
'description' => esc_html__( 'Increasing the width of the border will increase its size/thickness.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'allow_empty' => true,
'default_from' => "border_all.controls.border_width_all{$suffix}",
'default_unit' => $defaultUnit,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'range_settings' => array(
'min' => 0,
'max' => 50,
'step' => 1,
'min_limit' => 0,
),
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_color_left{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Left Border Color', 'et_builder' ) ),
'description' => esc_html__( 'Pick a color to be used for the border.', 'et_builder' ),
'type' => $settings['color_type'],
'hover' => 'tabs',
'default_from' => "border_all.controls.border_color_all{$suffix}",
'context' => "border_styles{$suffix}",
'mobile_options' => true,
'sticky' => true,
),
"border_style_left{$suffix}" => array(
'label' => sprintf( '%1$s%2$s', '' !== $settings['label_prefix'] ? sprintf( '%1$s ', $settings['label_prefix'] ) : '', esc_html__( 'Left Border Style', 'et_builder' ) ),
'description' => esc_html__( 'Borders support various different styles, each of which will change the shape of the border element.', 'et_builder' ),
'type' => 'select',
'options' => et_builder_get_border_styles(),
'default_from' => "border_all.controls.border_style_all{$suffix}",
'context' => "border_styles{$suffix}",
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
),
),
),
),
);
// Override default_from. In some cases, we need to set different default from the parent
// modules. For example, in Pricing Tables -> Pricing Area borders, we only want to set
// default value for border bottom width, but keep the rest to inherit from border all.
if ( ! empty( $settings['defaults']['composite'] ) ) {
$composites = $additional_options[ "border_styles{$suffix}" ]['composite_structure'];
$new_composites = array();
foreach ( $settings['defaults']['composite'] as $border_position => $default_controls ) {
// Make sure the border position property exists on additional_options.
if ( ! isset( $composites[ $border_position ] ) ) {
continue;
}
// Make sure it has controls.
if ( ! isset( $composites[ $border_position ]['controls'] ) ) {
continue;
}
// Make sure target controls are not empty.
if ( ! empty( $default_controls ) ) {
foreach ( $default_controls as $control_key => $control_default ) {
// Make sure the target control exists on border_styles.
$control_suffix = $control_key . $suffix;
if ( isset( $composites[ $border_position ]['controls'][ $control_suffix ] ) ) {
// Unset default_from and set default attribute.
unset( $composites[ $border_position ]['controls'][ $control_suffix ]['default_from'] );
$composites[ $border_position ]['controls'][ $control_suffix ]['default'] = $control_default;
}
}
}
}
// Set composites structures back to additional options border styles.
$additional_options[ "border_styles{$suffix}" ]['composite_structure'] = $composites;
}
// Add options dependency
if ( ! is_null( $settings['depends_on'] ) ) {
foreach ( $additional_options as &$option ) {
$option['depends_on'] = $settings['depends_on'];
$option['depends_show_if'] = $settings['depends_show_if'];
}
}
return $additional_options;
}
/**
* Get border radii CSS styles.
*
* @since 3.23 Add responsive setting support.
* @since 4.6.0 Add sticky style support
*
* @param array $atts All module attributes.
* @param array $advanced_fields All module advanced fields definition.
* @param string $suffix Border options group or toggle name.
* @param boolean|string $overflow Overflow status or type.
* @param boolean $is_hover Hover options status.
* @param string $device Current active device.
* @param boolean $is_sticky Sticky options status.
*
* @return string Generated border radii styles.
*/
public function get_radii_style( array $atts, array $advanced_fields, $suffix = '', $overflow = true, $is_hover = false, $device = 'desktop', $is_sticky = false ) {
$style = '';
$important = '';
// Backward compatibility. Use `border` settings as default if exists.
$legacy_border = self::$_->array_get( $advanced_fields, 'border', array() );
$borders_fields = self::$_->array_get(
$advanced_fields,
'borders',
array(
'default' => $legacy_border,
)
);
if ( isset( $borders_fields['css']['important'] ) ) {
if ( 'plugin_only' === $borders_fields['css']['important'] ) {
$important = et_builder_has_limitation( 'force_use_global_important' ) ? '!important' : '';
} else {
$important = '!important';
}
}
// Border Radius CSS
$is_desktop = 'desktop' === $device;
$value_suffix = '';
if ( $is_hover ) {
$value_suffix = et_pb_hover_options()->get_suffix();
}
if ( $is_sticky ) {
$value_suffix = et_pb_sticky_options()->get_suffix();
}
$value_suffix = ! $is_hover && ! $is_sticky && ! $is_desktop ? "_{$device}" : $value_suffix;
// Get border settings based on main border_radii field on option template.
// This used to refer to module's advanced_fields property but for performance reason
// it is now fetched from option template field's instead.
// Rebuilt field on option template is cached on property so it is safe to get it on demand.
$border_advanced_setting = self::$_->array_get( $advanced_fields, "border{$suffix}", array() );
$border_template_id = ET_Builder_Module_Fields_Factory::get( 'Border' )->get_fields( $border_advanced_setting, true );
$border_fields = $this->template->is_enabled() ? $this->template->rebuild_field_template( $border_template_id ) : array();
// Border radii settings
$settings = self::$_->array_get( $border_fields, "border_radii{$suffix}", array() );
$radii = isset( $atts[ "border_radii{$suffix}{$value_suffix}" ] ) ? $atts[ "border_radii{$suffix}{$value_suffix}" ] : false;
// Bail early if current device value doesn't exist.
if ( false === $radii || empty( $radii ) ) {
return '';
}
// Bail early if current device is tablet/phone and responsive is disabled.
if ( ! $is_desktop && ! et_pb_responsive_options()->is_responsive_enabled( $atts, "border_radii{$suffix}" ) ) {
return '';
}
// We need the default radius value.
if ( ! isset( $settings['default'] ) ) {
$settings['default'] = 'on||||';
}
// Make sure current radii value is different with default value. Default of desktop is
// default. Default of tablet is desktop and default of phone is tablet.
if ( isset( $settings['default'] ) && ! $is_desktop ) {
// Get previous device value.
$previous_suffix = 'phone' === $device ? '_tablet' : '';
$radii_previous = isset( $atts[ "border_radii{$suffix}{$previous_suffix}" ] ) ? $atts[ "border_radii{$suffix}{$previous_suffix}" ] : false;
if ( $radii_previous ) {
$settings['default'] = $radii_previous;
}
}
if ( isset( $settings['default'] ) && ( $settings['default'] !== $radii ) ) {
$radii = explode( '|', $radii );
if ( count( $radii ) === 5 ) {
$top_left_radius = empty( $radii[1] ) ? '0' : esc_html( $radii[1] );
$top_right_radius = empty( $radii[2] ) ? '0' : esc_html( $radii[2] );
$bottom_right_radius = empty( $radii[3] ) ? '0' : esc_html( $radii[3] );
$bottom_left_radius = empty( $radii[4] ) ? '0' : esc_html( $radii[4] );
$important = et_core_intentionally_unescaped( $important, 'fixed_string' );
$style = "border-radius: {$top_left_radius} {$top_right_radius} {$bottom_right_radius} {$bottom_left_radius}{$important};";
if ( true === $overflow || in_array( $overflow, array( 'overflow-x', 'overflow-y' ) ) ) {
// $overflow can be either a boolean or a string: 'overflow-x' / 'overflow-y'
// If it is a boolean the CSS property is set to 'overflow'
$overflow_property = in_array( $overflow, array( 'overflow-x', 'overflow-y' ), true ) ? $overflow : 'overflow';
$style .= "{$overflow_property}: hidden{$important};";
}
}
}
return $style;
}
/**
* Get border styles CSS styles.
*
* @since 3.23 Add responsive setting support.
* @since 4.6.0 Add sticky style support
*
* @param array $attrs All module attributes.
* @param array $advanced_fields All module advanced fields definition.
* @param string $suffix Border options group or toggle name.
* @param boolean $is_hover Hover options status.
* @param string $device Current active device.
* @param boolean $is_sticky Sticky options status.
*
* @return string Generated border styles.
*/
public function get_borders_style( array $attrs, array $advanced_fields, $suffix = '', $is_hover = false, $device = 'desktop', $is_sticky = false ) {
$style = '';
$important = '';
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
$is_desktop = 'desktop' === $device;
$device_suffix = ! $is_desktop ? "_{$device}" : '';
self::$_is_default = array();
if ( self::$_->array_get( $advanced_fields, "border{$suffix}.css.important", false ) ) {
if ( 'plugin_only' === self::$_->array_get( $advanced_fields, "border{$suffix}.css.important", '' ) ) {
$important = et_builder_has_limitation( 'force_use_global_important' ) ? '!important' : '';
} else {
$important = '!important';
}
}
// Get border settings based on main border_style field on option template.
// This used to refer to module's advanced_fields property but for performance reason
// it is now fetched from option template field's instead.
// Rebuilt field on option template is cached on property so it is safe to get it on demand.
$border_advanced_setting = self::$_->array_get( $advanced_fields, "border{$suffix}", array() );
$border_template_id = ET_Builder_Module_Fields_Factory::get( 'Border' )->get_fields( $border_advanced_setting, true );
$border_fields = $this->template->is_enabled() ? $this->template->rebuild_field_template( $border_template_id ) : array();
// Border Style settings
$settings = self::$_->array_get( $border_fields, "border_styles{$suffix}", array() );
if ( ! isset( $settings['composite_structure'] ) || ! is_array( $settings['composite_structure'] ) ) {
return $style;
}
$styles = array();
$properties = array( 'width', 'style', 'color' );
$border_edges = array( 'top', 'right', 'bottom', 'left' );
// Individual edge tabs get their default values from the all edges tab. If a value in
// the all edges tab has been changed from the default, that value will be used as the
// default for the individual edge tabs, otherwise the all edges default value is used.
$value_suffix = '';
if ( $is_hover ) {
$value_suffix = $hover->get_suffix();
}
if ( $is_sticky ) {
$value_suffix = $sticky->get_suffix();
}
foreach ( $border_edges as $edge ) {
$edge = "{$edge}";
foreach ( $properties as $property ) {
// Set key to get all edges and edge value based on current active device.
$all_edges_key = "border_{$property}_all{$suffix}";
$all_edges_key_device = "border_{$property}_all{$suffix}{$device_suffix}";
$edge_key = "border_{$property}_{$edge}{$suffix}";
$edge_key_device = "border_{$property}_{$edge}{$suffix}{$device_suffix}";
$is_all_edges_responsive = et_pb_responsive_options()->is_responsive_enabled( $attrs, $all_edges_key );
$is_edge_responsive = et_pb_responsive_options()->is_responsive_enabled( $attrs, $edge_key );
$all_edges_desktop_value = et_pb_responsive_options()->get_any_value( $attrs, $all_edges_key );
$edge_desktop_value = et_pb_responsive_options()->get_any_value( $attrs, $edge_key );
// Don't output styles for default values unless the default value is actually
// a custom value from the all edges tab.
$value = false;
if ( $is_hover ) {
$default_hover_value = $hover->is_enabled( $edge_key, $attrs ) ? $edge_desktop_value : false;
$value = $hover->get_value( $edge_key, $attrs, $default_hover_value );
} elseif ( $is_sticky ) {
$default_sticky_value = $sticky->is_enabled( $edge_key, $attrs ) ? $edge_desktop_value : false;
$value = $sticky->get_value( $edge_key, $attrs, $default_sticky_value );
} elseif ( ! $is_desktop ) {
$value = $is_edge_responsive ? et_pb_responsive_options()->get_any_value( $attrs, $edge_key_device, '', true ) : et_pb_responsive_options()->get_any_value( $attrs, $edge_key );
} elseif ( $is_desktop ) {
$value = $edge_desktop_value;
}
if ( ! $value ) {
// If specific edge value doesn't exist, get from all active device.
$value = false;
if ( $is_hover ) {
$default_hover_value = $hover->is_enabled( $all_edges_key, $attrs ) ? $all_edges_desktop_value : false;
$value = $hover->get_value( $all_edges_key, $attrs, $default_hover_value );
} elseif ( $is_sticky ) {
$default_sticky_value = $sticky->is_enabled( $all_edges_key, $attrs ) ? $all_edges_desktop_value : false;
$value = $sticky->get_value( $all_edges_key, $attrs, $default_sticky_value );
} elseif ( $is_desktop || ( ! $is_desktop && $is_all_edges_responsive ) ) {
$value = et_pb_responsive_options()->get_any_value( $attrs, $all_edges_key_device );
}
if ( ! $value ) {
self::$_is_default[] = "{$edge_key}{$value_suffix}";
self::$_is_default[] = "{$all_edges_key}{$value_suffix}";
continue;
}
}
// Don't output wrongly migrated border-color value
if ( 'color' === $property && 'off' === $value ) {
continue;
}
if ( ! isset( $styles[ $property ] ) ) {
$styles[ $property ] = array();
}
// Sanitize value
if ( 'width' === $property ) {
$value = et_builder_process_range_value( $value );
}
$styles[ $property ][ $edge ] = esc_html( $value );
}
}
foreach ( $styles as $prop => $edges ) {
$all_values = array_values( $edges );
$all_edges = 4 === count( $all_values );
if ( $all_edges && 1 === count( array_unique( $all_values ) ) ) {
// All edges have the same value, so let's combine them into a single prop.
$style .= "border-{$prop}:{$all_values[0]}{$important};";
} elseif ( $all_edges && $edges['top'] === $edges['bottom'] && $edges['left'] === $edges['right'] ) {
// Let's combine them into a single prop.
$style .= "border-{$prop}:{$edges['top']} {$edges['left']}{$important};";
} elseif ( $all_edges ) {
// You know the drill.
$style .= "border-{$prop}:{$edges['top']} {$edges['right']} {$edges['bottom']} {$edges['left']}{$important};";
} else {
// We're not going to mess with the other shorthand variants, so separate styles it is!
foreach ( $edges as $edge => $value ) {
$style .= "border-{$edge}-{$prop}:{$value}{$important};";
}
}
}
return $style;
}
/**
* Whether or not the provided module needs the border reset CSS class.
*
* @param string $module_slug
* @param array $attrs
*
* @return bool
*/
public function needs_border_reset_class( $module_slug, $attrs ) {
if ( in_array( $module_slug, self::$_no_border_reset ) ) {
return false;
}
foreach ( $attrs as $attr => $value ) {
if ( ! $value || 0 === strpos( $attr, 'border_radii' ) ) {
continue;
}
// don't use 2 === substr_count( $attr, '_' ) because in some cases border option may have 3 underscores ( in case we have several border options in module ).
// It's enough to make sure we have more than 1 underscores.
$is_new_border_attr = 0 === strpos( $attr, 'border_' ) && substr_count( $attr, '_' ) > 1;
if ( $is_new_border_attr && ! in_array( $attr, self::$_is_default ) ) {
return true;
}
}
return false;
}
/**
* Check if attribute has border radius values.
*
* @param array $attrs border attrs.
*
* @return bool
*/
public function has_any_border_attrs( $attrs ) {
foreach ( $attrs as $attr => $value ) {
// Dont neglet border radius here.
// Since border and border radius are handled by same function.
// We should also check for border radius here.
if ( ! $value ) {
continue;
}
// don't use 2 === substr_count( $attr, '_' ) because in some cases border option may have 3 underscores ( in case we have several border options in module ).
// It's enough to make sure we have more than 1 underscores.
$is_new_border_attr = 0 === strpos( $attr, 'border_' ) && ( 'border_radii' === $attr || substr_count( $attr, '_' ) > 1 );
if ( $is_new_border_attr && ! in_array( $attr, self::$_is_default, true ) ) {
return true;
}
}
return false;
}
/**
* Add border reset class using filter. Obsolete method and only applied to old 3rd party modules without `modules_classname()` method
*
* @param string $output
* @param string $module_slug
*
* @return string
*/
public function add_border_reset_class( $output, $module_slug ) {
if ( in_array( $module_slug, ET_Builder_Element::$uses_module_classname ) ) {
return $output;
}
remove_filter( "{$module_slug}_shortcode_output", array( $this, 'add_border_reset_class' ), 10 );
return preg_replace( "/class=\"(.*?{$module_slug}_\d+.*?)\"/", 'class="$1 et_pb_with_border"', $output, 1 );
}
}
return new ET_Builder_Module_Field_Border();

View File

@ -0,0 +1,667 @@
<?php
class ET_Builder_Module_Field_BoxShadow extends ET_Builder_Module_Field_Base {
private static $classes = array();
/**
* @var ET_Builder_Module_Helper_ResponsiveOptions
*
* @since 3.23
*/
public static $responsive = null;
/**
* Constructor.
*/
public function __construct() {
$this->template = et_pb_option_template();
$this->set_template();
}
/**
* Set option template for Box Shadow
*
* @since 3.28
*
* @return void
*/
public function set_template() {
$template = $this->template;
if ( $template->is_enabled() && ! $template->has( 'box_shadow' ) ) {
$template->add(
'box_shadow',
$this->get_fields(
$template->placeholders(
array(
'suffix' => null,
'label' => null,
'option_category' => null,
'tab_slug' => null,
'toggle_slug' => null,
'sub_toggle' => null,
'depends_show_if_not' => null,
'depends_show_if' => null,
'depends_on' => null,
'default_on_fronts' => null,
'show_if' => null,
'show_if_not' => null,
)
)
)
);
}
}
/**
* Get box shadow fields.
*
* @since 3.23 Add support for responsive settings. Add allowed units for range fields.
*
* @param array $args Box shadow settings args.
* @return array Box shadow fields.
*/
public function get_fields( array $args = array() ) {
static $i18n;
// Cache translations.
if ( ! isset( $i18n ) ) {
$i18n['label'] = esc_html__( 'Box Shadow', 'et_builder' );
}
$arguments = shortcode_atts(
array(
'suffix' => '',
'label' => $i18n['label'],
'option_category' => '',
'tab_slug' => '',
'toggle_slug' => '',
'sub_toggle_slug' => null, // @deprecated Use {@see `sub_toggle`} instead. Keep it here as backward compatibility.
'sub_toggle' => null,
'depends_show_if_not' => null,
'depends_show_if' => null,
'depends_on' => null,
'default_on_fronts' => array(),
'show_if' => null,
'show_if_not' => null,
),
$args
);
// The `sub_toggle_slug` is deprecated in favor of `sub_toggle` which are used by
// other option groups. Keep it here for backward compatibiluty.
if ( ! empty( $arguments['sub_toggle_slug'] ) && empty( $arguments['sub_toggle'] ) ) {
$arguments['sub_toggle'] = $arguments['sub_toggle_slug'];
}
if ( $this->template->is_enabled() && $this->template->has( 'box_shadow' ) ) {
return $this->template->create( 'box_shadow', $arguments );
}
$prefix = 'box_shadow_';
$style = $prefix . 'style' . $arguments['suffix'];
$horizontal = $prefix . 'horizontal' . $arguments['suffix'];
$vertical = $prefix . 'vertical' . $arguments['suffix'];
$blur = $prefix . 'blur' . $arguments['suffix'];
$spread = $prefix . 'spread' . $arguments['suffix'];
$position = $prefix . 'position' . $arguments['suffix'];
$color = $prefix . 'color' . $arguments['suffix'];
$options = array();
$option = array(
'option_category' => $arguments['option_category'],
'tab_slug' => $arguments['tab_slug'],
'toggle_slug' => $arguments['toggle_slug'],
'sub_toggle' => $arguments['sub_toggle'],
'show_if_not' => array(
"{$style}" => 'none',
),
'default_on_child' => true,
);
$range = array_merge(
$option,
array(
'type' => 'range',
'range_settings' => array(
'min' => - 80,
'max' => 80,
'step' => 1,
),
'default' => 0,
'validate_unit' => true,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'px',
'fixed_range' => true,
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
)
);
$presets = array();
foreach ( $this->get_presets() as $id => $preset ) {
if ( 'none' === $id ) {
$presets[] = array(
'value' => $id,
'icon' => $id,
'fields' => $this->fetch_preset( $preset, $arguments['suffix'] ),
);
} else {
$presets[] = array(
'value' => $id,
'content' => sprintf( '<span class="preset %1$s"></span>', esc_attr( $id ) ),
'fields' => $this->fetch_preset( $preset, $arguments['suffix'] ),
);
}
}
$options[ $style ] = array_merge(
$option,
array(
'label' => $arguments['label'],
'type' => 'select_box_shadow',
'default' => 'none',
'className' => 'box_shadow',
'presets' => $presets,
'affects' => array( $horizontal, $vertical, $blur, $spread, $color, $position ),
'copy_with' => array( $horizontal, $vertical, $blur, $spread, $color, $position ),
'depends_show_if' => $arguments['depends_show_if'],
'depends_show_if_not' => $arguments['depends_show_if_not'],
'depends_on' => $arguments['depends_on'],
'show_if' => $arguments['show_if'],
'show_if_not' => $arguments['show_if_not'],
'description' => esc_html__( 'Pick a box shadow style to enable box shadow for this element. Once enabled, you will be able to customize your box shadow style further. To disable custom box shadow style, choose the None option.', 'et_builder' ),
)
);
// Configure dependency for fields via show_if/show_if_not attribute
if ( null === $options[ $style ]['show_if'] ) {
unset( $options[ $style ]['show_if'] );
}
if ( null === $options[ $style ]['show_if_not'] ) {
unset( $options[ $style ]['show_if_not'] );
}
// Field dependency via depends_on, depends_show_if, and depends_show_if_not have been deprecated
// These remain here as backward compatibility for third party modules
if ( null === $options[ $style ]['depends_on'] ) {
unset( $options[ $style ]['depends_on'] );
}
if ( null === $options[ $style ]['depends_show_if'] ) {
unset( $options[ $style ]['depends_show_if'] );
}
if ( null === $options[ $style ]['depends_show_if_not'] ) {
unset( $options[ $style ]['depends_show_if_not'] );
}
if ( isset( $arguments['default_on_fronts']['style'] ) && false !== $arguments['default_on_fronts']['style'] ) {
$options[ $style ]['default_on_front'] = $arguments['default_on_fronts']['style'];
}
$options[ $horizontal ] = array_merge(
$range,
array(
'label' => esc_html__( 'Box Shadow Horizontal Position', 'et_builder' ),
'description' => esc_html__( 'Shadow\'s horizontal distance from the element. A negative value places the shadow to the left of the element.', 'et_builder' ),
)
);
$options[ $vertical ] = array_merge(
$range,
array(
'label' => esc_html__( 'Box Shadow Vertical Position', 'et_builder' ),
'description' => esc_html__( 'Shadow\'s vertical distance from the element. A negative value places the shadow above the element.', 'et_builder' ),
)
);
$options[ $blur ] = array_merge(
$range,
array(
'label' => esc_html__( 'Box Shadow Blur Strength', 'et_builder' ),
'range_settings' => array(
'min' => 0,
'max' => 80,
'step' => 1,
),
'description' => esc_html__( 'The higher the value, the bigger the blur, the shadow becomes wider and lighter.', 'et_builder' ),
)
);
$options[ $spread ] = array_merge(
$range,
array(
'label' => esc_html__( 'Box Shadow Spread Strength', 'et_builder' ),
'description' => esc_html__( 'Increasing the spread strength will increase the density of the box shadow. Higher density results in a more intense shadow.', 'et_builder' ),
)
);
$options[ $color ] = array_merge(
$option,
array(
'label' => esc_html__( 'Shadow Color', 'et_builder' ),
'type' => 'color-alpha',
'hover' => 'tabs',
'default' => 'rgba(0,0,0,0.3)',
'field_template' => 'color',
'mobile_options' => true,
'sticky' => true,
'description' => esc_html__( 'The color of the shadow.', 'et_builder' ),
)
);
if ( isset( $arguments['default_on_fronts']['color'] ) && false !== $arguments['default_on_fronts']['color'] ) {
$options[ $color ]['default_on_front'] = $arguments['default_on_fronts']['color'];
}
$options[ $position ] = array_merge(
$option,
array(
'label' => esc_html__( 'Box Shadow Position', 'et_builder' ),
'description' => esc_html__( 'Choose whether you would like the shadow to appear outside your module, lifting the module up from the page, or inside the module, setting the module downwards within the page.', 'et_builder' ),
'type' => 'select',
'default' => 'outer',
'options' => array(
'outer' => esc_html__( 'Outer Shadow', 'et_builder' ),
'inner' => esc_html__( 'Inner Shadow', 'et_builder' ),
),
'mobile_options' => true,
)
);
if ( isset( $arguments['default_on_fronts']['position'] ) && false !== $arguments['default_on_fronts']['position'] ) {
$options[ $position ]['default_on_front'] = $arguments['default_on_fronts']['position'];
}
$list = array(
'vertical' => $vertical,
'horizontal' => $horizontal,
'blur' => $blur,
'spread' => $spread,
'position' => $position,
);
foreach ( $list as $id => $field ) {
$values = array();
foreach ( array_keys( $this->get_presets() ) as $preset ) {
$values[ $preset ] = $this->get_preset_field( $preset, $id );
}
$options[ $field ]['default'] = array( $style, $values );
}
return $options;
}
/**
* Get box-shadow declaration style.
*
* @since 3.23 Add support for responsive settings.
*
* @param array $atts Module attributes.
* @param array $args Box-shadow arguments.
* @return string Box shadow CSS declaration.
*/
public function get_value( $atts, array $args = array() ) {
$args = shortcode_atts(
array(
'suffix' => '',
'important' => false,
'hover' => false,
'sticky' => false,
'device' => 'desktop',
),
$args
);
$suffix = $args['suffix'];
$important = $args['important'] ? '!important' : '';
$hover = $args['hover'];
$sticky = $args['sticky'];
$device = $args['device'];
$style = $this->get_key_value( "style$suffix", $atts );
if ( empty( $style ) || 'none' === $style ) {
return '';
}
// 1. Get preset styles as default.
$preset = $this->get_preset( $style );
// 2. Get current device properties value.
$atts = array_merge(
array(
"box_shadow_position{$suffix}" => $preset['position'],
"box_shadow_horizontal{$suffix}" => $preset['horizontal'],
"box_shadow_vertical{$suffix}" => $preset['vertical'],
"box_shadow_blur{$suffix}" => $preset['blur'],
"box_shadow_spread{$suffix}" => $preset['spread'],
"box_shadow_color{$suffix}" => 'rgba(0,0,0,0.3)',
),
array_filter( $atts, 'strlen' )
);
// All the values below sometime return null.
$position = $this->get_key_value( "position{$suffix}", $atts, false, $device, $sticky ) === 'inner' ? 'inset' : '';
$horizontal = $this->get_key_value( "horizontal{$suffix}", $atts, $hover, $device, $sticky );
$vertical = $this->get_key_value( "vertical{$suffix}", $atts, $hover, $device, $sticky );
$blur = $this->get_key_value( "blur{$suffix}", $atts, $hover, $device, $sticky );
$strength = $this->get_key_value( "spread{$suffix}", $atts, $hover, $device, $sticky );
$color = $this->get_key_value( "color{$suffix}", $atts, $hover, $device, $sticky );
// CSS declaration.
$value = sprintf(
'box-shadow: %1$s %2$s %3$s %4$s %5$s %6$s %7$s;',
$position,
$horizontal,
$vertical,
$blur,
$strength,
$color,
$important
);
// Do not provider hover style if it is the same as normal style
if ( $hover ) {
$new_args = $args;
$new_args['hover'] = false;
$normal = $this->get_value( $atts, $new_args );
if ( $normal === $value ) {
return '';
}
}
return $value;
}
public function get_presets() {
return array(
'none' => array(
'horizontal' => '',
'vertical' => '',
'blur' => '',
'spread' => '',
'position' => 'outer',
),
'preset1' => array(
'horizontal' => '0px',
'vertical' => '2px',
'blur' => '18px',
'spread' => '0px',
'position' => 'outer',
),
'preset2' => array(
'horizontal' => '6px',
'vertical' => '6px',
'blur' => '18px',
'spread' => '0px',
'position' => 'outer',
),
'preset3' => array(
'horizontal' => '0px',
'vertical' => '12px',
'blur' => '18px',
'spread' => '-6px',
'position' => 'outer',
),
'preset4' => array(
'horizontal' => '10px',
'vertical' => '10px',
'blur' => '0px',
'spread' => '0px',
'position' => 'outer',
),
'preset5' => array(
'horizontal' => '0px',
'vertical' => '6px',
'blur' => '0px',
'spread' => '10px',
'position' => 'outer',
),
'preset6' => array(
'horizontal' => '0px',
'vertical' => '0px',
'blur' => '18px',
'spread' => '0px',
'position' => 'inner',
),
'preset7' => array(
'horizontal' => '10px',
'vertical' => '10px',
'blur' => '0px',
'spread' => '0px',
'position' => 'inner',
),
);
}
public function get_preset( $name ) {
$presets = $this->get_presets();
return isset( $presets[ $name ] )
? $presets[ $name ]
: array(
'horizontal' => 0,
'vertical' => 0,
'blur' => 0,
'spread' => 0,
'position' => 'outer',
);
}
public function get_style( $selector, array $atts = array(), array $args = array() ) {
$value = $this->get_value( $atts, $args );
return array(
'selector' => $selector,
'declaration' => empty( $value ) ? null : $value,
);
}
public function has_overlay( $atts, $args ) {
$overlay = ET_Core_Data_Utils::instance()->array_get( $args, 'overlay', false );
$inset = $this->is_inset( $this->get_value( $atts, $args ) );
return ( $inset && 'inset' === $overlay ) || 'always' === 'overlay';
}
public function get_overlay_selector( $selector ) {
$selectors = array_map( 'trim', explode( ',', $selector ) );
$new_selector = array();
foreach ( $selectors as $selector ) {
$new_selector[] = $selector . '>.box-shadow-overlay, ' . $selector . '.et-box-shadow-no-overlay';
}
return implode( ',', $new_selector );
}
public function get_overlay_style( $function_name, $selector, $atts, array $args = array() ) {
$order_class_name = ET_Builder_Element::get_module_order_class( $function_name );
$reg_selector = str_replace( '%%order_class%%', ".{$order_class_name}", $selector );
$reg_selector = str_replace( '%order_class%', ".{$order_class_name}", $reg_selector );
// %%parent_class%% only works if child module's slug is `parent_slug` + _item suffix. If child module slug
// use different slug structure, %%parent_class%% should not be used
if ( false !== strpos( $reg_selector, '%%parent_class%%' ) ) {
$parent_class = str_replace( '_item', '', $function_name );
$reg_selector = str_replace( '%%parent_class%%', ".{$parent_class}", $reg_selector );
}
$selector = $this->get_overlay_selector( $selector );
$value = $this->get_value( $atts, $args );
if ( empty( $value ) ) {
return array(
'selector' => $selector,
'declaration' => null,
);
}
array_map(
array( get_class( $this ), 'register_element' ),
array_map( 'trim', explode( ',', $reg_selector ) )
);
return array(
'selector' => $selector,
'declaration' => $value,
);
}
public function is_inset( $style ) {
return strpos( $style, 'inset' ) !== false;
}
public static function register_element( $class ) {
self::$classes[] = $class;
}
public static function get_elements() {
return self::$classes;
}
protected function fetch_preset( array $preset, $suffix ) {
return array(
"box_shadow_horizontal{$suffix}" => $preset['horizontal'],
"box_shadow_vertical{$suffix}" => $preset['vertical'],
"box_shadow_blur{$suffix}" => $preset['blur'],
"box_shadow_spread{$suffix}" => $preset['spread'],
"box_shadow_position{$suffix}" => $preset['position'],
);
}
protected function get_preset_field( $name, $field ) {
$preset = $this->get_preset( $name );
return $preset[ $field ];
}
/**
* Get box shadow property value based on current active device.
*
* @since 3.23 Add responsive support. Check last edited value first for tablet/phone.
*
* @param string $key Box shadow property.
* @param array $atts All module attributes.
* @param boolean $hover Hover mode status.
* @param string $device Current device.
* @param boolean $sticky Sticky mode status.
*
* @return string Box shadow property value.
*/
protected function get_key_value( $key, $atts = array(), $hover = false, $device = 'desktop', $sticky = false ) {
$hover_options = et_pb_hover_options();
// Add device name as suffix.
$is_desktop = 'desktop' === $device;
$device_suffix = '';
if ( ! $hover && ! $is_desktop && ! $sticky ) {
$device_suffix = "_{$device}";
}
// Get current active device value.
$attr_value = et_pb_responsive_options()->get_any_value( $atts, "box_shadow_{$key}{$device_suffix}", '', true );
// Bail early if current mode is sticky, hover or desktop mode.
if ( $sticky ) {
return et_pb_sticky_options()->get_value( "box_shadow_{$key}", $atts, $attr_value );
} elseif ( $hover ) {
return $hover_options->get_value( "box_shadow_{$key}", $atts, $attr_value );
} elseif ( $is_desktop ) {
return $attr_value;
}
// Ensure responsive settings is enabled before return tablet/phone value.
$is_responsive = et_pb_responsive_options()->is_responsive_enabled( $atts, "box_shadow_{$key}" );
if ( ! $is_responsive ) {
// To avoid any issue when no box shadow defined on tablet and phone, we should return
// desktop value instead. By doing this, tablet and phone box shadow will be identical
// with desktop box shadow value.
return et_pb_responsive_options()->get_any_value( $atts, "box_shadow_{$key}" );
}
return $attr_value;
}
/**
* Check if box shadow is used.
*
* @since 4.10.0
* @param array $attrs All module attributes.
* @param string $key Box shadow property.
*/
public function is_used( $attrs, $key = '' ) {
foreach ( $attrs as $attr => $value ) {
if ( ! $value ) {
continue;
}
$has_attr = false !== strpos( $attr, 'box_shadow_style' );
if ( ! $has_attr ) {
continue;
}
return ! empty( $attr );
}
}
/**
* Check if module has inset.
*
* @since 4.10.0
* @param array $attrs All module attributes.
* @param array $advanced_options Advanced module options.
*/
public function has_inset( $attrs, $advanced_options, $_ ) {
$has_box_inset = false;
foreach ( $advanced_options as $option_name => $option_settings ) {
if ( true === $has_box_inset ) {
break;
}
// Enable module to explicitly disable box shadow fields (box shadow is automatically)
// added to all module by default.
if ( false === $option_settings ) {
continue;
}
// Prepare attribute for getting box shadow's css declaration.
$declaration_args = array(
'suffix' => 'default' === $option_name ? '' : "_{$option_name}",
'important' => $_->array_get( $option_settings, 'css.important', false ),
);
$overlay = $_->array_get( $option_settings, 'css.overlay', false );
$inset = $this->is_inset( $this->get_value( $attrs, $declaration_args ) );
$inset_hover = $this->is_inset(
$this->get_value(
$attrs,
array_merge( $declaration_args, array( 'hover' => true ) )
)
);
$has_video_bg = ! empty( $atts['background_video_mp4'] ) || ! empty( $atts['background_video_webm'] );
foreach ( et_pb_responsive_options()->get_modes() as $device ) {
// Add device argument.
$device_declaration_args = array_merge( $declaration_args, array( 'device' => $device ) );
if ( ( $inset && 'inset' === $overlay ) || 'always' === $overlay || $has_video_bg ) {
$has_box_inset = true;
break;
}
}
// Get box-shadow styles.
}
return $has_box_inset;
}
}
function _action_et_pb_box_shadow_overlay() {
wp_localize_script(
et_get_combined_script_handle(),
'et_pb_box_shadow_elements',
ET_Builder_Module_Field_BoxShadow::get_elements()
);
}
add_action( 'wp_footer', '_action_et_pb_box_shadow_overlay' );
return new ET_Builder_Module_Field_BoxShadow();

View File

@ -0,0 +1,374 @@
<?php
/**
* Display Conditions logics lies below, Buckle up!
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
if ( ! defined( 'ABSPATH' ) ) {
die( 'Direct access forbidden.' );
}
/**
* Load traits, No autoloader :sad_pepe:
*/
require_once __DIR__ . '/display-conditions/LoggedInStatus.php';
require_once __DIR__ . '/display-conditions/UserRole.php';
require_once __DIR__ . '/display-conditions/DateTime.php';
require_once __DIR__ . '/display-conditions/PostType.php';
require_once __DIR__ . '/display-conditions/Author.php';
require_once __DIR__ . '/display-conditions/Categories.php';
require_once __DIR__ . '/display-conditions/Tags.php';
require_once __DIR__ . '/display-conditions/DateArchive.php';
require_once __DIR__ . '/display-conditions/ProductPurchase.php';
require_once __DIR__ . '/display-conditions/CartContents.php';
require_once __DIR__ . '/display-conditions/SearchResults.php';
require_once __DIR__ . '/display-conditions/OperatingSystem.php';
require_once __DIR__ . '/display-conditions/Browser.php';
require_once __DIR__ . '/display-conditions/PageVisit.php';
require_once __DIR__ . '/display-conditions/DynamicPosts.php';
require_once __DIR__ . '/display-conditions/Cookie.php';
require_once __DIR__ . '/display-conditions/CategoryPage.php';
require_once __DIR__ . '/display-conditions/TagPage.php';
require_once __DIR__ . '/display-conditions/NumberOfViews.php';
/**
* Import class dependencies
*/
use ET_Builder_Module_Field_Base;
/**
* Display Conditions class.
*
* @since 4.11.0
*/
class ET_Builder_Module_Field_DisplayConditions extends ET_Builder_Module_Field_Base {
/**
* Import traits dependencies.
* Keep the code clean and the logic separated, don't be ET_Builder_Element.
*/
use LoggedInStatusCondition;
use UserRoleCondition;
use DateTimeCondition;
use PostTypeCondition;
use AuthorCondition;
use CategoriesCondition;
use TagsCondition;
use DateArchiveCondition;
use ProductPurchaseCondition;
use CartContentsCondition;
use SearchResultsCondition;
use OperatingSystemCondition;
use BrowserCondition;
use PageVisitCondition;
use DynamicPostsCondition;
use CookieCondition;
use CategoryPageCondition;
use TagPageCondition;
use NumberOfViewsCondition;
/**
* Custom current date.
* Useful for testing purposes where we don't want to depend on server's timestamp.
*
* @since 4.11.0
*
* @var string
*/
protected $_custom_current_date = '';
/**
* Retrieves fields for Display Conditions.
* Used in `ET_Builder_ELement` to set Display Conditions fields in Divi Builder.
*
* @since 4.11.0
*
* @param array $args Associative array for settings.
*
* @return array $fields Option settings.
*/
public function get_fields( array $args = array() ) {
$defaults = [
'prefix' => '',
'tab_slug' => 'custom_css',
'toggle_slug' => 'conditions',
'mobile_options' => false,
'default' => '',
];
$settings = array_merge( $defaults, $args );
return array_merge(
$this->get_field( $settings )
);
}
/**
* Retrieves field for Display Conditions.
*
* @since 4.11.0
*
* @param array $args Associative array for settings.
*
* @return array $options Option settings.
*/
public function get_field( $args ) {
static $i18n;
// Cache translations.
if ( ! $i18n ) {
$i18n = [
'Display Conditions' => esc_html__( 'Display Conditions', 'et_builder' ),
'description' => et_get_safe_localization( sprintf( __( 'Choose when to display this element based on a set of conditions. Multiple conditions can be added. Date & Time condition is based on your timezone settings in your <a href="%1$s" target="_blank" title="WordPress General Settings">WordPress General Settings</a>', 'et_builder' ), esc_url( admin_url( 'options-general.php' ) ) ) ),
];
}
$settings = array(
'label' => $i18n['Display Conditions'],
'type' => 'display_conditions',
'mobile_options' => $args['mobile_options'],
'default' => $args['default'],
'tab_slug' => $args['tab_slug'],
'toggle_slug' => $args['toggle_slug'],
'description' => $i18n['description'],
);
$options = array( 'display_conditions' => $settings );
return $options;
}
/**
* Checks all $display_conditions and returns a final boolean output.
*
* @since 4.11.0
*
* @param array $display_conditions Associative array containing conditions.
* @param boolean $only_return_status Whether to return all conditions full status (useful in VB tooltips).
*
* @return boolean Conditions final result.
*/
public function is_displayable( $display_conditions, $only_return_status = false ) {
// Bail out and just display the module if below WordPress 5.3.
if ( version_compare( get_bloginfo( 'version' ), '5.3', '<' ) ) {
return true;
}
// Bail out and just display the module if $display_conditions is not array.
if ( ! is_array( $display_conditions ) ) {
return true;
}
// Holds current condition evaluation.
$should_display = true;
$status = [];
// Reverses condition list, We start from the bottom of the list.
$display_conditions = array_reverse( $display_conditions );
// Holds all the conditions that have been processed, except the ones detected as conflicted.
$processed_conditions = array();
foreach ( $display_conditions as $arr_key => $condition ) {
$condition_id = isset( $condition['id'] ) ? $condition['id'] : '';
$condition_name = isset( $condition['condition'] ) ? $condition['condition'] : '';
$condition_settings = isset( $condition['conditionSettings'] ) ? $condition['conditionSettings'] : [];
$operator = isset( $condition['operator'] ) ? $condition['operator'] : 'OR';
$is_enable_condition_set = isset( $condition_settings['enableCondition'] ) ? true : false;
$is_disabled = $is_enable_condition_set && 'off' === $condition_settings['enableCondition'] ? true : false;
// Skip if condition is disabled.
if ( $is_disabled ) {
$status[] = [
'id' => $condition_id,
'is_conflicted' => false,
];
continue;
}
$is_conflict_detected = $this->_is_condition_conflicted( $condition, $processed_conditions, $operator );
$status[] = [
'id' => $condition_id,
'is_conflicted' => $is_conflict_detected,
];
if ( $is_conflict_detected ) {
continue;
} else {
$should_display = $this->is_condition_true( $condition_id, $condition_name, $condition_settings );
$processed_conditions[] = $condition;
}
// If operator is set to "OR/ANY" break as soon as one condition is true - returning a final true.
// If operator is set to "AND/ALL" break as soon as one condition is false - returning a final false.
if ( 'OR' === $operator && $should_display && ! $only_return_status ) {
break;
} elseif ( 'AND' === $operator && ! $should_display && ! $only_return_status ) {
break;
}
}
return ( $only_return_status ) ? $status : $should_display;
}
/**
* Checks a single condition and returns a boolean result.
*
* @since 4.11.0
*
* @param string $condition_id Condition ID.
* @param string $condition_name Condition name.
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
public function is_condition_true( $condition_id, $condition_name, $condition_settings ) {
switch ( $condition_name ) {
case 'loggedInStatus':
return $this->_process_logged_in_status_condition( $condition_settings );
case 'userRole':
return $this->_process_user_role_condition( $condition_settings );
case 'dateTime':
return $this->_process_date_time_condition( $condition_settings );
case 'postType':
return $this->_process_post_type_condition( $condition_settings );
case 'author':
return $this->_process_author_condition( $condition_settings );
case 'categories':
return $this->_process_categories_condition( $condition_settings );
case 'categoryPage':
return $this->_process_category_page_condition( $condition_settings );
case 'tags':
return $this->_process_tags_condition( $condition_settings );
case 'tagPage':
return $this->_process_tag_page_condition( $condition_settings );
case 'dateArchive':
return $this->_process_date_archive_condition( $condition_settings );
case 'productPurchase':
return $this->_process_product_purchase_condition( $condition_settings );
case 'cartContents':
return $this->_process_cart_contents_condition( $condition_settings );
case 'searchResults':
return $this->_process_search_results_condition( $condition_settings );
case 'operatingSystem':
return $this->_process_operating_system_condition( $condition_settings );
case 'browser':
return $this->_process_browser_condition( $condition_settings );
case 'pageVisit':
return $this->_process_page_visit_condition( $condition_settings );
case 'postVisit':
return $this->_process_page_visit_condition( $condition_settings );
case 'cookie':
return $this->_process_cookie_condition( $condition_settings );
case 'numberOfViews':
return $this->_process_number_of_views_condition( $condition_id, $condition_settings );
default:
if ( isset( $condition_settings['dynamicPosts'] ) ) {
return $this->_process_dynamic_posts_condition( $condition_settings );
}
return true;
}
}
/**
* Checks the $condition against $processed_conditions to determine if the $condition is considered a conflict or not.
*
* When operator 'OR/Any' is selected and we have more than one condition of the same type the priority
* is with the latest condition (located lower in the list).
*
* When operator 'AND/All' is selected no condition is considered a conflict.
*
* @since 4.11.0
*
* @param array $condition Containing all settings of the condition.
* @param array $processed_conditions Containing all settings of previously processed conditions.
* @param array $operator Selected operator for the Display Conditions, Options: 'OR' or 'AND'.
*
* @return boolean Condition output.
*/
protected function _is_condition_conflicted( $condition, $processed_conditions, $operator ) {
if ( 'AND' === $operator ) {
return false;
}
$is_conflicted = false;
// Check condition against all previously processed conditions.
foreach ( $processed_conditions as $processed_condition ) {
// Only check same condition types against each other, Ex. UserRole against UserRole.
if ( $condition['condition'] !== $processed_condition['condition'] ) {
continue;
}
// Exception! "Date Time" Condition can have multiple positive conditions.
$is_datetime = 'dateTime' === $condition['condition'];
$is_prev_cond_datetime_and_negative = $is_datetime && 'isNotOnSpecificDate' === $processed_condition['conditionSettings']['dateTimeDisplay'];
$is_current_cond_datetime_and_negative = $is_datetime && 'isNotOnSpecificDate' === $condition['conditionSettings']['dateTimeDisplay'];
if ( $is_prev_cond_datetime_and_negative || $is_current_cond_datetime_and_negative ) {
$is_conflicted = true;
break;
} elseif ( $is_datetime ) {
$is_conflicted = false;
break;
}
/**
* When operator is set to "OR/ANY" and we have more than one condition, all other conditions
* will be set as conflicted, giving the priority to the latest condition in the list.
*/
if ( count( $processed_conditions ) > 0 ) {
$is_conflicted = true;
break;
}
}
return $is_conflicted;
}
/**
* Overrides current date with specified date.
* Useful for testing purposes where we don't want to depend on server's timestamp.
*
* @since 4.11.0
*
* @param DateTimeImmutable $date The datetime which will overrides current datetime.
*
* @return void
*/
public function override_current_date( $date ) {
$this->_custom_current_date = $date;
}
}
return new ET_Builder_Module_Field_DisplayConditions();

View File

@ -0,0 +1,578 @@
<?php
/**
* Module Divider class.
*/
class ET_Builder_Module_Field_Divider extends ET_Builder_Module_Field_Base {
/**
* List of available dividers for the sections.
*
* @var array
*/
public $dividers = array();
/**
* Markup for the SVG
*
* @var string
*/
public $svg;
/**
* List of classes for using in styling.
*
* @var array
*/
public $classes = array( 'section_has_divider' );
/**
* @var ET_Core_Data_Utils
*/
public static $data_utils = null;
/**
* @var ET_Builder_Module_Helper_ResponsiveOptions
*
* @since 3.23
*/
public static $responsive = null;
/**
* Constructor for the class. This is done so that the divider options could be filtered
* by a child theme or plugin.
*/
public function __construct() {
$section_dividers = array(
'arrow-bottom' => '<path d="M640 139L0 0v140h1280V0L640 139z"/>',
'arrow-top' => '<path d="M640 140L1280 0H0z"/>',
'arrow2-bottom' => '<path d="M640 139L0 0v140h1280V0L640 139z" fill-opacity=".5"/><path d="M640 139L0 42v98h1280V42l-640 97z"/>',
'arrow2-top' => '<path d="M640 140L1280 0H0z" fill-opacity=".5"/><path d="M640 98l640-98H0z"/>',
'arrow3-bottom' => '<path d="M0 140l640-70 640 70V0L640 70 0 0v140z" fill-opacity=".5"/><path d="M0 140h1280L640 70 0 140z"/>',
'arrow3-top' => '<path d="M1280 0L640 70 0 0v140l640-70 640 70V0z" fill-opacity=".5"/><path d="M1280 0H0l640 70 640-70z"/>',
'asymmetric-bottom' => '<path d="M1280 0l-262.1 116.26a73.29 73.29 0 0 1-39.09 6L0 0v140h1280z"/>',
'asymmetric-top' => '<path d="M978.81 122.25L0 0h1280l-262.1 116.26a73.29 73.29 0 0 1-39.09 5.99z"/>',
'asymmetric2-bottom' => '<path d="M1280 0l-266 91.52a72.59 72.59 0 0 1-30.76 3.71L0 0v140h1280z" fill-opacity=".5"/><path d="M1280 0l-262.1 116.26a73.29 73.29 0 0 1-39.09 6L0 0v140h1280z"/>',
'asymmetric2-top' => '<path d="M978.81 122.25L0 0h1280l-262.1 116.26a73.29 73.29 0 0 1-39.09 5.99z" fill-opacity=".5"/><path d="M983.19 95.23L0 0h1280l-266 91.52a72.58 72.58 0 0 1-30.81 3.71z"/>',
'asymmetric3-bottom' => '<path d="M1093.48 131.85L173 94a76.85 76.85 0 0 1-36.79-11.46L0 0v140h1280V0l-131.81 111.68c-16.47 13.96-35.47 20.96-54.71 20.17z"/>',
'asymmetric3-top' => '<path d="M1280 0l-131.81 111.68c-16.47 14-35.47 21-54.71 20.17L173 94a76.85 76.85 0 0 1-36.79-11.46L0 0z"/>',
'asymmetric4-bottom' => '<path d="M1094.44 119L172.7 68.72a74.54 74.54 0 0 1-25.19-5.95L0 0v140h1280V0l-133.85 102c-15.84 12.09-33.7 17.95-51.71 17z" fill-opacity=".5"/><path d="M1093.48 131.85L173 94a76.85 76.85 0 0 1-36.79-11.46L0 0v140h1280V0l-131.81 111.68c-16.47 13.96-35.47 20.96-54.71 20.17z"/>',
'asymmetric4-top' => '<path d="M1093.48 131.85L173 94a76.85 76.85 0 0 1-36.79-11.46L0 0h1280l-131.81 111.68c-16.47 13.96-35.47 20.96-54.71 20.17z" fill-opacity=".5"/><path d="M1094.44 119L172.7 68.72a74.54 74.54 0 0 1-25.19-5.95L0 0h1280l-133.85 102c-15.84 12.09-33.7 17.95-51.71 17z"/>',
'clouds-bottom' => '<path d="M1280 63.1c-3.8 0-7.6.3-11.4.8-18.3-32.6-59.6-44.2-92.2-25.9-3.5 2-6.9 4.3-10 6.9-22.7-41.7-74.9-57.2-116.6-34.5-14.2 7.7-25.9 19.3-33.8 33.3-.2.3-.3.6-.5.8-12.2-1.4-23.7 5.9-27.7 17.5-11.9-6.1-25.9-6.3-37.9-.6-21.7-30.4-64-37.5-94.4-15.8-12.1 8.6-21 21-25.4 35.2-10.8-9.3-24.3-15-38.5-16.2-8.1-24.6-34.6-38-59.2-29.9-14.3 4.7-25.5 16-30 30.3-4.3-1.9-8.9-3.2-13.6-3.8-13.6-45.2-61.5-71.1-107-57.6A86.38 86.38 0 0 0 538.6 33c-8.7-3.6-18.7-1.8-25.4 4.8-23.1-24.8-61.9-26.2-86.7-3.1-7.1 6.6-12.5 14.8-15.9 24-26.7-10.1-56.9-.4-72.8 23.3-2.6-2.7-5.6-5.1-8.9-6.9-.4-.2-.8-.4-1.2-.7-.6-25.9-22-46.4-47.9-45.8-11.5.3-22.5 4.7-30.9 12.5-16.5-33.5-57-47.4-90.5-31-22 10.8-36.4 32.6-37.8 57.1-7-2.3-14.5-2.8-21.8-1.6-14-21.7-43.1-27.9-64.8-13.8-5.6 3.6-10.3 8.4-13.9 14C13.5 64 6.8 63.2 0 63.2-.1 63.2 0 86 0 86h1280V63.1z"/>',
'clouds-bottom2' => '<path d="M1280,63.1a81.42,81.42,0,0,0-11.41.81,67.71,67.71,0,0,0-102.21-19,86,86,0,0,0-150.47-1.2c-.16.28-.29.57-.45.85a26.07,26.07,0,0,0-27.65,17.54,43,43,0,0,0-37.93-.57A67.66,67.66,0,0,0,830.15,81a67.85,67.85,0,0,0-38.51-16.19,46.9,46.9,0,0,0-89.25.45,46.66,46.66,0,0,0-13.56-3.77A86,86,0,0,0,538.67,33.07a23.42,23.42,0,0,0-25.4,4.8A61.36,61.36,0,0,0,410.7,58.74a61.44,61.44,0,0,0-72.79,23.32A38.37,38.37,0,0,0,329,75.15c-.41-.23-.83-.45-1.25-.66a46.88,46.88,0,0,0-78.77-33.31A67.65,67.65,0,0,0,120.71,67.29a46.76,46.76,0,0,0-21.82-1.62,46.91,46.91,0,0,0-78.8.07A79.35,79.35,0,0,0,0,63.17C0,63.17,0,140,0,140H1280Z"/>',
'clouds-top' => '<path d="M1280 0H0v65.2c6.8 0 13.5.9 20.1 2.6 14-21.8 43.1-28 64.8-14 5.6 3.6 10.3 8.3 14 13.9 7.3-1.2 14.8-.6 21.8 1.6 2.1-37.3 34.1-65.8 71.4-63.7 24.3 1.4 46 15.7 56.8 37.6 19-17.6 48.6-16.5 66.3 2.4C323 54 327.4 65 327.7 76.5c.4.2.8.4 1.2.7 3.3 1.9 6.3 4.2 8.9 6.9 15.9-23.8 46.1-33.4 72.8-23.3 11.6-31.9 46.9-48.3 78.8-36.6 9.1 3.3 17.2 8.7 23.8 15.7 6.7-6.6 16.7-8.4 25.4-4.8 29.3-37.4 83.3-44 120.7-14.8 14 11 24.3 26.1 29.4 43.1 4.7.6 9.3 1.8 13.6 3.8 7.8-24.7 34.2-38.3 58.9-30.5 14.4 4.6 25.6 15.7 30.3 30 14.2 1.2 27.7 6.9 38.5 16.2 11.1-35.7 49-55.7 84.7-44.7 14.1 4.4 26.4 13.3 35 25.3 12-5.7 26.1-5.5 37.9.6 3.9-11.6 15.5-18.9 27.7-17.5.2-.3.3-.6.5-.9 23.3-41.4 75.8-56 117.2-32.6 14.1 7.9 25.6 19.7 33.3 33.8 28.8-23.8 71.5-19.8 95.3 9 2.6 3.1 4.9 6.5 6.9 10 3.8-.5 7.6-.8 11.4-.8L1280 0z"/>',
'clouds-top2' => '<path d="M1280,0H0S0,116.17,0,116.17a79.47,79.47,0,0,1,20.07,2.57,46.91,46.91,0,0,1,78.8-.07,46.76,46.76,0,0,1,21.82,1.62A67.67,67.67,0,0,1,248.93,94.17a46.88,46.88,0,0,1,78.77,33.31c.42.22.84.43,1.25.66a38.38,38.38,0,0,1,8.94,6.92,61.44,61.44,0,0,1,72.79-23.32A61.43,61.43,0,0,1,513.26,90.87a23.42,23.42,0,0,1,25.4-4.8,86,86,0,0,1,150.15,28.37,46.65,46.65,0,0,1,13.56,3.77,46.9,46.9,0,0,1,89.25-.45A67.85,67.85,0,0,1,830.13,134a67.7,67.7,0,0,1,119.73-19.38,43,43,0,0,1,37.93.57,26.07,26.07,0,0,1,27.65-17.54c.16-.28.29-.57.45-.85A86,86,0,0,1,1166.37,98a67.71,67.71,0,0,1,102.21,19,81.66,81.66,0,0,1,11.42-.81Z"/>',
'clouds2-bottom' => '<path d="M1280 66.1c-3.8 0-7.6.3-11.4.8-18.3-32.6-59.6-44.2-92.2-25.9-3.5 2-6.9 4.3-10 6.9-22.7-41.7-74.9-57.2-116.6-34.5-14.2 7.7-25.9 19.3-33.8 33.3-.2.3-.3.6-.5.8-12.2-1.4-23.7 5.9-27.7 17.5-11.9-6.1-25.9-6.3-37.9-.6-21.7-30.4-64-37.5-94.4-15.7-12.1 8.6-21 21-25.4 35.2-10.8-9.3-24.3-15-38.5-16.2-8.1-24.6-34.6-38-59.2-29.9-14.3 4.7-25.5 16-30 30.3-4.3-1.9-8.9-3.2-13.6-3.8-13.6-45.5-61.5-71.4-107-57.8a86.38 86.38 0 0 0-43.2 29.4c-8.7-3.6-18.7-1.8-25.4 4.8-23.1-24.8-61.9-26.2-86.7-3.1-7.1 6.6-12.5 14.8-15.9 24-26.7-10.1-56.9-.4-72.8 23.3-2.6-2.7-5.6-5.1-8.9-6.9-.4-.2-.8-.4-1.2-.7-.6-25.9-22-46.4-47.9-45.8-11.5.3-22.5 4.7-30.9 12.5-16.5-33.5-57.1-47.3-90.6-30.8-21.9 11-36.3 32.7-37.6 57.1-7-2.3-14.5-2.8-21.8-1.6C84.8 47 55.7 40.7 34 54.8c-5.6 3.6-10.3 8.4-13.9 14-6.6-1.7-13.3-2.6-20.1-2.6-.1 0 0 19.8 0 19.8h1280V66.1z" fill-opacity=".5"/><path d="M15.6 86H1280V48.5c-3.6 1.1-7.1 2.5-10.4 4.4-6.3 3.6-11.8 8.5-16 14.5-8.1-1.5-16.4-.9-24.2 1.7-3.2-39-37.3-68.1-76.4-64.9-24.8 2-46.8 16.9-57.9 39.3-19.9-18.5-51-17.3-69.4 2.6-8.2 8.8-12.8 20.3-13.1 32.3-.4.2-.9.4-1.3.7-3.5 1.9-6.6 4.4-9.4 7.2-16.6-24.9-48.2-35-76.2-24.4-12.2-33.4-49.1-50.6-82.5-38.4-9.5 3.5-18.1 9.1-25 16.5-7.1-6.9-17.5-8.8-26.6-5-30.4-39.3-87-46.3-126.2-15.8-14.8 11.5-25.6 27.4-31 45.4-4.9.6-9.7 1.9-14.2 3.9-8.2-25.9-35.8-40.2-61.7-32-15 4.8-26.9 16.5-31.8 31.5-14.9 1.3-29 7.2-40.3 17-11.5-37.4-51.2-58.4-88.7-46.8-14.8 4.6-27.7 13.9-36.7 26.5-12.6-6-27.3-5.7-39.7.6-4.1-12.2-16.2-19.8-29-18.4-.2-.3-.3-.6-.5-.9-24.4-43.3-79.4-58.6-122.7-34.2-13.3 7.5-24.4 18.2-32.4 31.2C99.8 18.5 50 28.5 25.4 65.4c-4.3 6.4-7.5 13.3-9.8 20.6z"/>',
'clouds2-bottom2' => '<path d="M1269.61,52.83a48.82,48.82,0,0,0-16,14.48A48.6,48.6,0,0,0,1229.45,69a70.88,70.88,0,0,0-134.21-25.66,49.11,49.11,0,0,0-82.51,34.9c-.44.23-.88.45-1.31.69a40.18,40.18,0,0,0-9.36,7.24,64.35,64.35,0,0,0-76.25-24.43A64.34,64.34,0,0,0,818.36,39.85a24.53,24.53,0,0,0-26.61-5A90,90,0,0,0,634.48,64.55a48.89,48.89,0,0,0-14.21,3.95A49.12,49.12,0,0,0,526.79,68a71.07,71.07,0,0,0-40.34,17A70.91,70.91,0,0,0,361,64.68a45.07,45.07,0,0,0-39.73.6,27.31,27.31,0,0,0-29-18.37c-.16-.29-.31-.59-.47-.89a90.06,90.06,0,0,0-155.12-3A80.23,80.23,0,0,0,12.64,99.75a80.1,80.1,0,0,0-12.64,2V140H1280V48.48A49.22,49.22,0,0,0,1269.61,52.83Z" fill-opacity=".5"/><path d="M1280,66.1a81.63,81.63,0,0,0-11.42.81,67.71,67.71,0,0,0-102.21-19,86,86,0,0,0-150.47-1.2c-.16.28-.29.57-.45.85a26.07,26.07,0,0,0-27.65,17.54,43,43,0,0,0-37.93-.57A67.66,67.66,0,0,0,830.13,84a67.85,67.85,0,0,0-38.51-16.19,46.9,46.9,0,0,0-89.25.45,46.66,46.66,0,0,0-13.56-3.77A86,86,0,0,0,538.66,36.07a23.42,23.42,0,0,0-25.4,4.8A61.36,61.36,0,0,0,410.68,61.74a61.44,61.44,0,0,0-72.79,23.32A38.37,38.37,0,0,0,329,78.15c-.41-.23-.83-.45-1.25-.66a46.88,46.88,0,0,0-78.77-33.31A67.65,67.65,0,0,0,120.69,70.29a46.76,46.76,0,0,0-21.82-1.62,46.91,46.91,0,0,0-78.8.07A79.46,79.46,0,0,0,0,66.17C-.07,66.17,0,140,0,140H1280Z"/>',
'clouds2-top' => '<path d="M833.9 27.5c-5.8 3.2-11 7.3-15.5 12.2-7.1-6.9-17.5-8.8-26.6-5-30.6-39.2-87.3-46.1-126.5-15.5-1.4 1.1-2.8 2.2-4.1 3.4C674.4 33.4 684 48 688.8 64.3c4.7.6 9.3 1.8 13.6 3.8 7.8-24.7 34.2-38.3 58.9-30.5 14.4 4.6 25.6 15.7 30.3 30 14.2 1.2 27.7 6.9 38.5 16.2C840.6 49.6 876 29.5 910.8 38c-20.4-20.3-51.8-24.6-76.9-10.5zM384 43.9c-9 5-16.7 11.9-22.7 20.3 15.4-7.8 33.3-8.7 49.4-2.6 3.7-10.1 9.9-19.1 18.1-26-15.4-2.3-31.2.6-44.8 8.3zm560.2 13.6c2 2.2 3.9 4.5 5.7 6.9 5.6-2.6 11.6-4 17.8-4.1-7.6-2.4-15.6-3.3-23.5-2.8zM178.7 7c29-4.2 57.3 10.8 70.3 37 8.9-8.3 20.7-12.8 32.9-12.5C256.4 1.8 214.7-8.1 178.7 7zm146.5 56.3c1.5 4.5 2.4 9.2 2.5 14 .4.2.8.4 1.2.7 3.3 1.9 6.3 4.2 8.9 6.9 5.8-8.7 13.7-15.7 22.9-20.5-11.1-5.2-23.9-5.6-35.5-1.1zM33.5 54.9c21.6-14.4 50.7-8.5 65 13 .1.2.2.3.3.5 7.3-1.2 14.8-.6 21.8 1.6.6-10.3 3.5-20.4 8.6-29.4.3-.6.7-1.2 1.1-1.8-32.1-17.2-71.9-10.6-96.8 16.1zm1228.9 2.7c2.3 2.9 4.4 5.9 6.2 9.1 3.8-.5 7.6-.8 11.4-.8V48.3c-6.4 1.8-12.4 5-17.6 9.3zM1127.3 11c1.9.9 3.7 1.8 5.6 2.8 14.2 7.9 25.8 19.7 33.5 34 13.9-11.4 31.7-16.9 49.6-15.3-20.5-27.7-57.8-36.8-88.7-21.5z" fill-opacity=".5"/><path d="M0 0v66c6.8 0 13.5.9 20.1 2.6 3.5-5.4 8.1-10.1 13.4-13.6 24.9-26.8 64.7-33.4 96.8-16 10.5-17.4 28.2-29.1 48.3-32 36.1-15.1 77.7-5.2 103.2 24.5 19.7.4 37.1 13.1 43.4 31.8 11.5-4.5 24.4-4.2 35.6 1.1l.4-.2c15.4-21.4 41.5-32.4 67.6-28.6 25-21 62.1-18.8 84.4 5.1 6.7-6.6 16.7-8.4 25.4-4.8 29.2-37.4 83.3-44.1 120.7-14.8l1.8 1.5c37.3-32.9 94.3-29.3 127.2 8 1.2 1.3 2.3 2.7 3.4 4.1 9.1-3.8 19.5-1.9 26.6 5 24.3-26 65-27.3 91-3.1.5.5 1 .9 1.5 1.4 12.8 3.1 24.4 9.9 33.4 19.5 7.9-.5 15.9.4 23.5 2.8 7-.1 13.9 1.5 20.1 4.7 3.9-11.6 15.5-18.9 27.7-17.5.2-.3.3-.6.5-.9 22.1-39.2 70.7-54.7 111.4-35.6 30.8-15.3 68.2-6.2 88.6 21.5 18.3 1.7 35 10.8 46.5 25.1 5.2-4.3 11.1-7.4 17.6-9.3V0H0z"/>',
'clouds2-top2' => '<path d="M833.9,77.67a64.2,64.2,0,0,0-15.53,12.18,24.53,24.53,0,0,0-26.61-5,90.1,90.1,0,0,0-130.57-12.1,85.54,85.54,0,0,1,27.62,41.73,46.66,46.66,0,0,1,13.56,3.77,46.9,46.9,0,0,1,89.25-.45A67.84,67.84,0,0,1,830.13,134,67.61,67.61,0,0,1,910.8,88.2,64.38,64.38,0,0,0,833.9,77.67Z M384,94.11a70.48,70.48,0,0,0-22.73,20.27,61.44,61.44,0,0,1,49.42-2.63,61.19,61.19,0,0,1,18.15-26A70.64,70.64,0,0,0,384,94.11Z M944.2,107.71a67.34,67.34,0,0,1,5.66,6.87,43.3,43.3,0,0,1,17.8-4.1A64.53,64.53,0,0,0,944.2,107.71Z M178.67,57.16a67.63,67.63,0,0,1,70.26,37,47.06,47.06,0,0,1,32.92-12.5A90.18,90.18,0,0,0,178.67,57.16Z M325.24,113.52a46.93,46.93,0,0,1,2.46,14c.42.22.84.43,1.25.66a38.38,38.38,0,0,1,8.94,6.92,61,61,0,0,1,22.94-20.48A45.09,45.09,0,0,0,325.24,113.52Z M33.49,105.13a46.91,46.91,0,0,1,65.38,13.55,46.75,46.75,0,0,1,21.82,1.62,67.13,67.13,0,0,1,8.58-29.39c.34-.6.7-1.19,1.06-1.78a80.19,80.19,0,0,0-96.84,16Z M1262.42,107.77a67.35,67.35,0,0,1,6.16,9.15,81.66,81.66,0,0,1,11.42-.81V98.48a48.83,48.83,0,0,0-17.58,9.29Z M1127.33,61.18c1.88.88,3.74,1.81,5.58,2.84A85.42,85.42,0,0,1,1166.37,98a68,68,0,0,1,49.55-15.27A70.94,70.94,0,0,0,1127.33,61.18Z" fill-opacity=".5"/><path d="M361,114.68l.23-.3-.43.22Z M0,0V120.87c0-3,0-4.69,0-4.69a79.35,79.35,0,0,1,20.06,2.57,46.56,46.56,0,0,1,13.42-13.62,80.19,80.19,0,0,1,96.84-16,67.52,67.52,0,0,1,48.33-32A90.18,90.18,0,0,1,281.84,81.67a46.82,46.82,0,0,1,43.4,31.85,45.09,45.09,0,0,1,35.59,1.07l.43-.22a70.84,70.84,0,0,1,67.57-28.6,61.47,61.47,0,0,1,84.42,5.09,23.42,23.42,0,0,1,25.4-4.8A86,86,0,0,1,661.19,72.72a90.1,90.1,0,0,1,130.57,12.1,24.53,24.53,0,0,1,26.61,5A64.37,64.37,0,0,1,910.8,88.2a67.45,67.45,0,0,1,33.4,19.51,64.53,64.53,0,0,1,23.45,2.77,42.8,42.8,0,0,1,20.14,4.67,26.07,26.07,0,0,1,27.65-17.54c.16-.28.29-.57.45-.85a86,86,0,0,1,111.44-35.58,70.94,70.94,0,0,1,88.59,21.52,67.79,67.79,0,0,1,46.5,25.07A48.83,48.83,0,0,1,1280,98.48V0Z"/>',
'curve-bottom' => '<path d="M1280 140V0S993.46 140 640 139 0 0 0 0v140z"/>',
'curve-top' => '<path d="M640 140C286.54 140 0 0 0 0h1280S993.46 140 640 140z"/>',
'curve2-bottom' => '<path d="M725.29 101.2C325.22 122.48 0 0 0 0v140h1280V0s-154.64 79.92-554.71 101.2z" fill-opacity=".3"/><path d="M556.45 119.74C953.41 140 1280 14 1280 14v126H0V0s159.5 99.48 556.45 119.74z" fill-opacity=".5"/><path d="M640 140c353.46 0 640-140 640-139v140H0V0s286.54 140 640 140z"/>',
'curve2-top' => '<path d="M0 0v.48C18.62 9.38 297.81 140 639.5 140 993.24 140 1280 0 1280 0z" fill-opacity=".3"/><path d="M0 .6c14 8.28 176.54 99.8 555.45 119.14C952.41 140 1280 0 1280 0H0z" fill-opacity=".5"/><path d="M726.29 101.2C1126.36 79.92 1281 0 1281 0H1c.05 0 325.25 122.48 725.29 101.2z"/>',
'graph-bottom' => '<path d="M0 122.138l60.614 9.965 95.644-4.2 86.363-18.654 78.684 13.079L411.442 99.4l94.453 10.303L582.821 93.8l82.664 18.728 76.961-11.39L816.11 71.4l97.601 9.849L997.383 50.4l66.285 14.694 70.793-24.494h79.863L1280 0v140H0z"/>',
'graph-top' => '<path d="M156.258 127.903l86.363-18.654 78.684 13.079L411.441 99.4l94.454 10.303L582.82 93.8l82.664 18.728 76.961-11.39L816.109 71.4l97.602 9.849L997.383 50.4l66.285 14.694 70.793-24.494h79.863L1280 0H0v122.138l60.613 9.965z"/>',
'graph2-bottom' => '<path d="M0 127.899l60.613 4.878 95.645-6.211 86.363-16.074 78.684 9.883 90.136-21.594 94.454 7.574 77.925-17.66 91.664 20.798 76.961-12.649 63.664-21.422 97.602 7.07 83.672-29.617 66.285 11.678 70.793-23.334 74.863-4.641L1280 0v140H0z" fill-opacity=".5"/><path d="M0 126.71l60.613 7.415L156.257 131l86.364-13.879 78.683 9.731 90.137-17.059 94.453 7.666 76.926-11.833 82.664 13.935 76.961-8.475 73.664-22.126 97.601 7.328 83.672-22.952 66.285 10.933 70.794-18.224h79.862L1280 35.838V140H0z"/>',
'graph2-top' => '<path d="M1214.323 66.051h-79.863l-70.793 18.224-66.285-10.933-83.672 22.953-97.601-7.328-73.664 22.125-76.961 8.475-82.664-13.934-76.926 11.832-94.453-7.666-90.137 17.059-78.684-9.731-86.363 13.879-95.644 3.125L0 126.717V0h1280l-.001 35.844z" fill-opacity=".5"/><path d="M0 0h1280v.006l-70.676 36.578-74.863 4.641-70.793 23.334-66.285-11.678-83.672 29.618-97.602-7.07-63.664 21.421-76.961 12.649-91.664-20.798-77.926 17.66-94.453-7.574-90.137 21.595-78.683-9.884-86.363 16.074-95.645 6.211L0 127.905z"/>',
'graph3-bottom' => '<path d="M0 0l64.8 38.69 91.2-3.18 95.45 34.84 120.04.24 71.5 33.35 90.08-3.91 106.91 37.62 102.38-37.17 85.55 10.65 88.11-7.19 75.95-38.66 73.21 5.31 66.78-22.1 77-.42 71-48.07v140H0V0z"/>',
'graph3-top' => '<path d="M156 35.51l95.46 34.84 120.04.24 71.5 33.35 90.09-3.91L640 137.65l102.39-37.17 85.55 10.65 88.11-7.19L992 65.28l73.21 5.31 66.79-22.1 77-.42L1280 0H0l64.8 38.69 91.2-3.18z"/>',
'graph4-bottom' => '<path d="M0 0l64.8 30.95 91.2-2.54 95.46 27.87 120.04.2L443 83.15l90.09-3.12L640 110.12l102.39-29.73 85.55 8.51 88.11-5.75L992 52.22l73.21 4.26L1132 38.79l77-.33L1280 0v140H0V0z" fill-opacity=".5"/><path d="M0 0l64.8 38.69 91.2-3.18 95.46 34.84 120.04.24 71.5 33.35 90.09-3.91L640 137.65l102.39-37.17 85.55 10.65 88.11-7.19L992 65.28l73.21 5.31 66.79-22.1 77-.41L1280 0v140H0V0z"/>',
'graph4-top' => '<path d="M156 35.41l95.46 34.73 120.04.25 71.5 33.24 90.09-3.89L640 137.25l102.39-37.06 85.55 10.61 88.11-7.17L992 65.08l73.21 5.31L1132 48.35l77-.42L1280 0H0l64.8 38.57 91.2-3.16z" fill-opacity=".5"/><path d="M156 28.32l95.46 27.79 120.04.2L443 82.9l90.09-3.11L640 109.8l102.39-29.65 85.55 8.49 88.11-5.74L992 52.07l73.21 4.24L1132 38.68l77-.34L1280 0H0l64.8 30.86 91.2-2.54z"/>',
'mountains-bottom' => '<path d="M0 70.35l320-49.24 640 98.49 320-49.25V140H0V70.35z"/>',
'mountains-top' => '<path d="M1280 69.65l-320 49.24L320 20.4 0 69.65V0h1280v69.65z"/>',
'mountains2-bottom' => '<path d="M0 47.44L170 0l626.48 94.89L1110 87.11l170-39.67V140H0V47.44z" fill-opacity=".5"/><path d="M0 90.72l140-28.28 315.52 24.14L796.48 65.8 1140 104.89l140-14.17V140H0V90.72z"/>',
'mountains2-top' => '<path d="M0 90.72l140-28.28 315.52 24.14L796.48 65.8 1140 104.89l140-14.17V0H0v90.72z" fill-opacity=".5"/><path d="M0 0v47.44L170 0l626.48 94.89L1110 87.11l170-39.67V0H0z"/>',
'ramp-bottom' => '<path d="M0 140h1280C573.08 140 0 0 0 0z"/>',
'ramp-top' => '<path d="M0 0s573.08 140 1280 140V0z"/>',
'ramp2-bottom' => '<path d="M0 140h1280C573.08 140 0 0 0 0z" fill-opacity=".3"/><path d="M0 140h1280C573.08 140 0 30 0 30z" fill-opacity=".5"/><path d="M0 140h1280C573.08 140 0 60 0 60z"/>',
'ramp2-top' => '<path d="M0 0v60s573.09 80 1280 80V0z" fill-opacity=".3"/><path d="M0 0v30s573.09 110 1280 110V0z" fill-opacity=".5"/><path d="M0 0s573.09 140 1280 140V0z"/>',
'slant-bottom' => '<path d="M0 0v140h1280L0 0z"/>',
'slant-top' => '<path d="M1280 140V0H0l1280 140z"/>',
'slant2-bottom' => '<path d="M0 0v140h1280L0 0z" fill-opacity=".5"/><path d="M0 42v98h1280L0 42z"/>',
'slant2-top' => '<path d="M1280 140V0H0l1280 140z" fill-opacity=".5"/><path d="M1280 98V0H0l1280 98z"/>',
'triangle-bottom' => '<path d="M80 0L0 140h160z"/>',
'triangle-bottom2' => '<polygon points="640 0 560 140 720 140 640 0"/>',
'triangle-top' => '<path d="M720 140L640 0l-80 140H0V0h1280v140H720z"/>',
'triangle-top2' => '<path d="M720 140L640 0l-80 140H0V0h1280v140H720z"/>',
'wave-bottom' => '<path d="M320 28c320 0 320 84 640 84 160 0 240-21 320-42v70H0V70c80-21 160-42 320-42z"/>',
'wave-top' => '<path d="M320 28C160 28 80 49 0 70V0h1280v70c-80 21-160 42-320 42-320 0-320-84-640-84z"/>',
'wave2-bottom' => '<path d="M1280 3.4C1050.59 18 1019.4 84.89 734.42 84.89c-320 0-320-84.3-640-84.3C59.4.59 28.2 1.6 0 3.4V140h1280z" fill-opacity=".3"/><path d="M0 24.31c43.46-5.69 94.56-9.25 158.42-9.25 320 0 320 89.24 640 89.24 256.13 0 307.28-57.16 481.58-80V140H0z" fill-opacity=".5"/><path d="M1280 51.76c-201 12.49-242.43 53.4-513.58 53.4-320 0-320-57-640-57-48.85.01-90.21 1.35-126.42 3.6V140h1280z"/>',
'wave2-top' => '<path d="M0 51.76c36.21-2.25 77.57-3.58 126.42-3.58 320 0 320 57 640 57 271.15 0 312.58-40.91 513.58-53.4V0H0z" fill-opacity=".3"/><path d="M0 24.31c43.46-5.69 94.56-9.25 158.42-9.25 320 0 320 89.24 640 89.24 256.13 0 307.28-57.16 481.58-80V0H0z" fill-opacity=".5"/><path d="M0 0v3.4C28.2 1.6 59.4.59 94.42.59c320 0 320 84.3 640 84.3 285 0 316.17-66.85 545.58-81.49V0z"/>',
'waves-bottom' => '<path d="M1280 86c-19.9-17.21-40.08-39.69-79.89-39.69-57.49 0-56.93 46.59-115 46.59-53.61 0-59.76-39.62-115.6-39.62C923.7 53.27 924.26 87 853.89 87c-89.35 0-78.74-87-188.2-87C554 0 543.95 121.8 423.32 121.8c-100.52 0-117.84-54.88-191.56-54.88-77.06 0-100 48.57-151.75 48.57-40 0-60-12.21-80-29.51v54H1280z"/>',
'waves-top' => '<path d="M0 0v100c20 17.3 40 29.51 80 29.51 51.79 0 74.69-48.57 151.75-48.57 73.72 0 91 54.88 191.56 54.88C543.95 135.8 554 14 665.69 14c109.46 0 98.85 87 188.2 87 70.37 0 69.81-33.73 115.6-33.73 55.85 0 62 39.62 115.6 39.62 58.08 0 57.52-46.59 115-46.59 39.8 0 60 22.48 79.89 39.69V0z"/>',
'waves2-bottom' => '<path d="M853.893,86.998c-38.859,0-58.811-16.455-77.956-35.051c18.295-10.536,40.891-18.276,73.378-18.276 c38.685,0,64.132,12.564,85.489,28.347C916.192,72.012,900.8,86.998,853.893,86.998z M526.265,80.945 c-6.517-0.562-13.599-0.879-21.41-0.879c-70.799,0-91.337,27.229-134.433,35.662c14.901,3.72,32.118,6.07,52.898,6.07 C470.171,121.797,500.34,103.421,526.265,80.945z" fill-opacity=".3"/><path d="M663.458,109.671c-67.137,0-80.345-23.824-137.193-28.726C567.086,45.555,597.381,0,665.691,0 c61.857,0,85.369,27.782,110.246,51.947C736.888,74.434,717.459,109.671,663.458,109.671z M217.68,94.163 c55.971,0,62.526,24.026,126.337,24.026c9.858,0,18.508-0.916,26.404-2.461c-57.186-14.278-80.177-48.808-138.659-48.808 c-77.063,0-99.96,48.569-151.751,48.569c-40.006,0-60.008-12.206-80.011-29.506v16.806c20.003,10.891,40.005,21.782,80.011,21.782 C160.014,124.57,158.608,94.163,217.68,94.163z M1200.112,46.292c-57.493,0-56.935,46.595-115.015,46.595 c-53.612,0-59.755-39.618-115.602-39.618c-15.267,0-25.381,3.751-34.69,8.749c36.096,26.675,60.503,62.552,117.342,62.552 c69.249,0,75.951-43.559,147.964-43.559c39.804,0,59.986,10.943,79.888,21.777V85.982 C1260.097,68.771,1239.916,46.292,1200.112,46.292z" fill-opacity=".5"/><path d="M1052.147,124.57c-56.84,0-81.247-35.876-117.342-62.552c-18.613,9.994-34.005,24.98-80.912,24.98 c-38.859,0-58.811-16.455-77.956-35.051c-39.05,22.487-58.479,57.724-112.48,57.724c-67.137,0-80.345-23.824-137.193-28.726 c-25.925,22.475-56.093,40.852-102.946,40.852c-20.779,0-37.996-2.349-52.898-6.07c-7.895,1.545-16.546,2.461-26.404,2.461 c-63.811,0-70.366-24.026-126.337-24.026c-59.072,0-57.665,30.407-137.669,30.407c-40.006,0-60.008-10.891-80.011-21.782V140h1280 v-37.212c-19.903-10.835-40.084-21.777-79.888-21.777C1128.098,81.011,1121.397,124.57,1052.147,124.57z"/>',
'waves2-top' => '<path d="M504.854,80.066c7.812,0,14.893,0.318,21.41,0.879 c-25.925,22.475-56.093,40.852-102.946,40.852c-20.779,0-37.996-2.349-52.898-6.07C413.517,107.295,434.056,80.066,504.854,80.066z M775.938,51.947c19.145,18.596,39.097,35.051,77.956,35.051c46.907,0,62.299-14.986,80.912-24.98 c-21.357-15.783-46.804-28.348-85.489-28.348C816.829,33.671,794.233,41.411,775.938,51.947z" fill-opacity=".3"/><path d="M1200.112,46.292c39.804,0,59.986,22.479,79.888,39.69v16.805 c-19.903-10.835-40.084-21.777-79.888-21.777c-72.014,0-78.715,43.559-147.964,43.559c-56.84,0-81.247-35.876-117.342-62.552 c9.309-4.998,19.423-8.749,34.69-8.749c55.846,0,61.99,39.617,115.602,39.617C1143.177,92.887,1142.618,46.292,1200.112,46.292z M80.011,115.488c-40.006,0-60.008-12.206-80.011-29.506v16.806c20.003,10.891,40.005,21.782,80.011,21.782 c80.004,0,78.597-30.407,137.669-30.407c55.971,0,62.526,24.026,126.337,24.026c9.858,0,18.509-0.916,26.404-2.461 c-57.186-14.278-80.177-48.808-138.66-48.808C154.698,66.919,131.801,115.488,80.011,115.488z M526.265,80.945 c56.848,4.902,70.056,28.726,137.193,28.726c54.001,0,73.43-35.237,112.48-57.724C751.06,27.782,727.548,0,665.691,0 C597.381,0,567.086,45.555,526.265,80.945z" fill-opacity=".5"/><path d="M0,0v85.982c20.003,17.3,40.005,29.506,80.011,29.506c51.791,0,74.688-48.569,151.751-48.569 c58.482,0,81.473,34.531,138.66,48.808c43.096-8.432,63.634-35.662,134.433-35.662c7.812,0,14.893,0.318,21.41,0.879 C567.086,45.555,597.381,0,665.691,0c61.856,0,85.369,27.782,110.246,51.947c18.295-10.536,40.891-18.276,73.378-18.276 c38.685,0,64.132,12.564,85.489,28.348c9.309-4.998,19.423-8.749,34.69-8.749c55.846,0,61.99,39.617,115.602,39.617 c58.08,0,57.521-46.595,115.015-46.595c39.804,0,59.986,22.479,79.888,39.69V0H0z"/>',
);
/**
* Filters the section divider paths.
*
* @param array $dividers Array list of available dividers.
*/
$this->dividers = apply_filters( 'et_section_dividers', $section_dividers );
if ( null === self::$data_utils ) {
self::$data_utils = ET_Core_Data_Utils::instance();
}
}
/**
* Retrieves fields for divider settings.
*
* @since 3.23 Add responsive settings on Divider Style. Add allowed units on some range fields.
*
* @param array $args Associative array for settings.
* @return array Option settings.
*/
public function get_fields( array $args = array() ) {
// Create an array so we don't get an error.
$additional_options = array();
// Create the options by first creating the structure.
$structure = array();
foreach ( array( 'top', 'bottom' ) as $placement ) :
$structure[ "{$placement}_divider" ] = array(
'controls' => array(
"{$placement}_divider_style" => array(
'label' => esc_html__( 'Divider Style', 'et_builder' ),
'description' => esc_html__( 'Select the divider shape that you would like to use. Shapes are represented visually within the list.', 'et_builder' ),
'type' => 'divider',
'options' => array(
'none' => et_builder_i18n( 'None' ),
'slant' => esc_html__( 'Slant', 'et_builder' ),
'slant2' => esc_html__( 'Slant 2', 'et_builder' ),
'arrow' => esc_html__( 'Arrow', 'et_builder' ),
'arrow2' => esc_html__( 'Arrow 2', 'et_builder' ),
'arrow3' => esc_html__( 'Arrow 3', 'et_builder' ),
'ramp' => esc_html__( 'Ramp', 'et_builder' ),
'ramp2' => esc_html__( 'Ramp 2', 'et_builder' ),
'curve' => esc_html__( 'Curve', 'et_builder' ),
'curve2' => esc_html__( 'Curve 2', 'et_builder' ),
'mountains' => esc_html__( 'Mountains', 'et_builder' ),
'mountains2' => esc_html__( 'Mountains 2', 'et_builder' ),
'wave' => esc_html__( 'Wave', 'et_builder' ),
'wave2' => esc_html__( 'Wave 2', 'et_builder' ),
'waves' => esc_html__( 'Waves', 'et_builder' ),
'waves2' => esc_html__( 'Waves 2', 'et_builder' ),
'asymmetric' => esc_html__( 'Asymmetric', 'et_builder' ),
'asymmetric2' => esc_html__( 'Asymmetric 2', 'et_builder' ),
'asymmetric3' => esc_html__( 'Asymmetric 3', 'et_builder' ),
'asymmetric4' => esc_html__( 'Asymmetric 4', 'et_builder' ),
'graph' => esc_html__( 'Graph', 'et_builder' ),
'graph2' => esc_html__( 'Graph 2', 'et_builder' ),
'graph3' => esc_html__( 'Graph 3', 'et_builder' ),
'graph4' => esc_html__( 'Graph 4', 'et_builder' ),
'triangle' => esc_html__( 'Triangle', 'et_builder' ),
'clouds' => esc_html__( 'Clouds', 'et_builder' ),
'clouds2' => esc_html__( 'Clouds 2', 'et_builder' ),
),
'default' => 'none',
'flip' => '',
'mobile_options' => true,
),
"{$placement}_divider_color" => array(
'label' => esc_html__( 'Divider Color', 'et_builder' ),
'description' => esc_html__( 'Pick a color to use for the section divider. By default, it will assume the color of the section above or below this section to ensure a smooth transition.', 'et_builder' ),
'type' => 'color-alpha',
'default' => '',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
'mobile_options' => true,
),
"{$placement}_divider_height" => array(
'label' => esc_html__( 'Divider Height', 'et_builder' ),
'description' => esc_html__( 'Increase or decrease the height of the shape divider.', 'et_builder' ),
'type' => 'range',
'range_settings' => array(
'min' => 0,
'max' => 500,
'step' => 1,
),
'default' => '100px',
'hover' => 'tabs',
'allowed_units' => array( '%', 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'px',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
'mobile_options' => true,
'sticky' => true,
),
"{$placement}_divider_repeat" => array(
'label' => esc_html__( 'Divider Horizontal Repeat', 'et_builder' ),
'description' => esc_html__( 'Choose how many times the shape divider should repeat. Setting to 1x will remove all repetition.', 'et_builder' ),
'type' => 'range',
'range_settings' => array(
'min' => 1,
'max' => 20,
'step' => 1,
'min_limit' => 1, // Changed to 1 from 0 since it's basically the same result for both values.
),
'default' => '1', // Dont use the fixed_unit in default value ( i.e. 1x, just use 1 ), or else input will return undefined.
'fixed_unit' => 'x',
'show_if_not' => array(
"{$placement}_divider_style" => array( 'none', 'clouds', 'clouds2', 'triangle' ),
),
'mobile_options' => true,
),
"{$placement}_divider_flip" => array(
'label' => esc_html__( 'Divider Flip', 'et_builder' ),
'description' => esc_html__( 'Flip the divider horizontally or vertically to change the shape and its direction.', 'et_builder' ),
'type' => 'multiple_buttons',
'options' => array(
'horizontal' => array(
'title' => esc_html__( 'Horizontal', 'et_builder' ),
'icon' => 'flip-horizontally',
),
'vertical' => array(
'title' => esc_html__( 'Vertical', 'et_builder' ),
'icon' => 'flip-vertically',
),
),
'toggleable' => true,
'multi_selection' => true,
'default' => '',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
),
'mobile_options' => true,
),
"{$placement}_divider_arrangement" => array(
'label' => esc_html__( 'Divider Arrangement', 'et_builder' ),
'description' => esc_html__( 'Dividers can be placed either above or below section content. If placed above section content, then modules and rows within the section will be hidden behind the divider when they overlap.', 'et_builder' ),
'type' => 'select',
'options' => array(
'above_content' => esc_html__( 'On Top Of Section Content', 'et_builder' ),
'below_content' => esc_html__( 'Underneath Section Content', 'et_builder' ),
),
'default' => 'below_content',
'show_if_not' => array(
"{$placement}_divider_style" => 'none',
'fullwidth' => 'on',
),
'mobile_options' => true,
),
),
);
// Automatically append responsive field
foreach ( $structure[ "{$placement}_divider" ]['controls'] as $field_name => $field ) {
if ( isset( $field['mobile_options'] ) && $field['mobile_options'] ) {
$responsive_field_default = isset( $field['default'] ) ? $field['default'] : '';
// Tablet field
$structure[ "{$placement}_divider" ]['controls'][ "{$field_name}_tablet" ] = array(
'type' => 'hidden',
'default' => $responsive_field_default,
);
// Phone field
$structure[ "{$placement}_divider" ]['controls'][ "{$field_name}_phone" ] = array(
'type' => 'hidden',
'default' => $responsive_field_default,
);
// Last edited field
$structure[ "{$placement}_divider" ]['controls'][ "{$field_name}_last_edited" ] = array(
'type' => 'hidden',
'default' => 'off|desktop',
);
}
}
endforeach; // End foreach().
// Set our labels.
$structure['bottom_divider']['label'] = et_builder_i18n( 'Bottom' );
$structure['top_divider']['label'] = et_builder_i18n( 'Top' );
$additional_options['divider_settings'] = array(
'label' => esc_html__( 'Dividers', 'et_builder' ),
'description' => esc_html__( 'Section dividers allow you to add creative shape transitions between different sections on your page.', 'et_builder' ),
'tab_slug' => $args['tab_slug'],
'toggle_slug' => $args['toggle_slug'],
'attr_suffix' => '',
'type' => 'composite',
'option_category' => 'layout',
'composite_type' => 'default',
'composite_structure' => $structure,
);
return $additional_options;
}
/**
* Process Section Divider
*
* Adds a CSS class to the section, determines orientaion of the SVG, encodes an SVG to use as data
* for the background-image property.
*
* @since 3.23 Pass values parameter to support responsive settings.
* @since 4.6.0 Add sticky style support.
*
* @param string $placement Whether it is the top or bottom divider.
* @param array $atts Associative array of shortcode and their
* respective values.
* @param string $breakpoint ''|tablet|phone
* @param array $values Existing responsive values.
*/
public function process_svg( $placement, $atts, $breakpoint = '', $values = array() ) {
// add a class to the section.
$this->classes[] = sprintf( 'et_pb_%s_divider', esc_attr( $placement ) );
// set some defaults.
$previous_section = ! empty( $atts['prev_background_color'] ) ? $atts['prev_background_color'] : '#ffffff';
$next_section = ! empty( $atts['next_background_color'] ) ? $atts['next_background_color'] : '#ffffff';
// set a default based on whether it is the top or bottom divider.
$default_color = ( 'top' === $placement ) ? $previous_section : $next_section;
$color = ! empty( $atts[ "{$placement}_divider_color" ] ) ? $atts[ "{$placement}_divider_color" ] : $default_color;
$height = ! empty( $atts[ "{$placement}_divider_height" ] ) ? $atts[ "{$placement}_divider_height" ] : '100px';
$height_hover = et_pb_hover_options()->get_value( "{$placement}_divider_height", $atts, false );
$repeat = ! empty( $atts[ "{$placement}_divider_repeat" ] ) ? floatval( $atts[ "{$placement}_divider_repeat" ] ) : 1;
$flip = ( '' !== $atts[ "{$placement}_divider_flip" ] ) ? explode( '|', $atts[ "{$placement}_divider_flip" ] ) : array();
$arrangement = ! empty( $atts[ "{$placement}_divider_arrangement" ] ) ? $atts[ "{$placement}_divider_arrangement" ] : 'below_content';
$divider_style = et_pb_responsive_options()->get_any_value( $atts, "{$placement}_divider_style", '', true, $breakpoint );
$style = $divider_style . "-{$placement}";
$fullwidth = $atts['fullwidth'];
// Apply adjustment for responsive styling
if ( '' !== $breakpoint ) {
// Get all responsive unique value.
$values = et_pb_responsive_options()->get_any_responsive_values(
$atts,
array(
"{$placement}_divider_color" => '',
"{$placement}_divider_height" => '',
"{$placement}_divider_repeat" => '',
"{$placement}_divider_flip" => '',
"{$placement}_divider_arrangement" => '',
),
true,
$breakpoint
);
// Replace all default values.
$color = ! empty( $values[ "{$placement}_divider_color" ] ) ? $values[ "{$placement}_divider_color" ] : $color;
$height = ! empty( $values[ "{$placement}_divider_height" ] ) ? $values[ "{$placement}_divider_height" ] : $height;
$repeat = ! empty( $values[ "{$placement}_divider_repeat" ] ) ? floatval( $values[ "{$placement}_divider_repeat" ] ) : $repeat;
$flip = ! empty( $values[ "{$placement}_divider_flip" ] ) ? explode( '|', $values[ "{$placement}_divider_flip" ] ) : $flip;
$arrangement = ! empty( $values[ "{$placement}_divider_arrangement" ] ) ? $values[ "{$placement}_divider_arrangement" ] : $arrangement;
if ( ! empty( $values[ "{$placement}_divider_flip" ] ) && 'none' === $values[ "{$placement}_divider_flip" ] ) {
$flip = array();
}
}
// Make sure that we don't divide by zero.
if ( ! $repeat ) {
$repeat = 1;
}
// let's make sure we flip the fight ones, yeah?
// use the opposite SVG
if ( in_array( 'vertical', $flip ) ) {
switch ( $placement ) {
case 'top':
$style = $divider_style . '-bottom';
break;
case 'bottom':
$style = $divider_style . '-top';
break;
}
}
// The SVG markup for the background.
switch ( $style ) {
case 'clouds-top':
case 'clouds2-top':
// we can use the viewBox to move down the image since it has a height of 86px
$svg_markup = '<svg width="100%%" height="%1$s" viewBox="0 0 1280 86" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg"><g fill="%2$s">%3$s</g></svg>';
break;
case 'clouds-bottom':
case 'clouds2-bottom':
// we can use the viewBox to move up the image since it has a height of 86px
$svg_markup = '<svg width="100%%" viewBox="0 0 1280 86" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg"><g fill="%2$s">%3$s</g></svg>';
break;
case 'triangle-top':
$svg_markup = '<svg width="100%%" height="100px" viewBox="0 0 1280 100" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg"><g fill="%2$s">%3$s</g></svg>';
break;
case 'triangle-bottom':
$svg_markup = '<svg width="160px" height="140px" viewBox="0 0 160 140" xmlns="http://www.w3.org/2000/svg"><g fill="%2$s">%3$s</g></svg>';
break;
default:
$svg_markup = '<svg width="100%%" height="%1$s" viewBox="0 0 1280 140" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg"><g fill="%2$s">%3$s</g></svg>';
break;
}
$divider_style = isset( $this->dividers[ $style ] ) ? $this->dividers[ $style ] : '';
$svg = sprintf( $svg_markup, $height, $color, $divider_style );
// encode the SVG so we can use it as data for background-image.
$this->svg = base64_encode( $svg ); // phpcs:ignore
// Build up our declaration.
// bg-image
$declaration['background-image'] = sprintf( 'url( data:image/svg+xml;base64,%s )', $this->svg );
// bg-size. the percent is how many times to repeat the image.
if ( 0 === strpos( $style, 'clouds' ) ) {
$declaration['background-size'] = 'cover';
switch ( $placement ) {
case 'top':
$declaration['background-position'] = ( 'top' === $placement || 'vertical' === $flip ) ? 'center top' : 'center bottom';
break;
case 'bottom':
$declaration['background-position'] = ( 'top' === $placement || 'vertical' !== $flip ) ? 'center top' : 'center bottom';
break;
}
} elseif ( 0 === strpos( $style, 'triangle' ) ) {
$declaration['background-size'] = 'cover';
$declaration['background-position-x'] = 'center';
} else {
// Adjusts for when percentages are being used.
if ( 0 < strpos( $height, '%' ) ) {
$declaration['background-size'] = sprintf( '%1$s%% 100%%', floatval( 100 / $repeat ) );
} else {
$declaration['background-size'] = sprintf( '%1$s%% %2$s', floatval( 100 / $repeat ), $height );
}
}
// position
$declaration[ $placement ] = 0;
// height
$declaration['height'] = $height;
// z-index - determined by arrangement.
$declaration['z-index'] = ( 'on' === $fullwidth || 'above_content' === $arrangement ) ? 10 : 1;
$flip_styles = array();
// flipping the svg x|y
if ( in_array( 'horizontal', $flip ) ) {
$flip_styles[] = 'rotateY(180deg)';
} elseif ( '' !== $breakpoint ) {
$flip_styles[] = 'rotateY(0)';
}
if ( in_array( 'vertical', $flip ) ) {
$flip_styles[] = 'rotateX(180deg)';
} elseif ( '' !== $breakpoint ) {
$flip_styles[] = 'rotateX(0)';
}
if ( ! empty( $flip_styles ) ) {
$declaration['transform'] = implode( ' ', $flip_styles );
}
// finally create our CSS declaration.
$css = '';
foreach ( $declaration as $rule => $value ) {
$css .= esc_html( "{$rule}:{$value};" );
}
// prepare our selector.
$selector = sprintf( '%%order_class%%.section_has_divider.et_pb_%1$s_divider .et_pb_%1$s_inside_divider', esc_attr( $placement ) );
// The styling of our section divider.
$styling = array(
'selector' => $selector,
'declaration' => $css,
);
// Apply media query if needed
if ( in_array( $breakpoint, array( 'tablet', 'phone' ) ) ) {
$query_map = array(
'tablet' => 'max_width_980',
'phone' => 'max_width_767',
);
$styling['media_query'] = ET_Builder_Element::get_media_query( $query_map[ $breakpoint ] );
}
ET_Builder_Element::set_style( 'et_pb_section', $styling );
// if we are on the first section and is the top divider.
if ( 0 === $this->count && 'top' === $placement && '' === $breakpoint ) {
// we will use a transparent bg.
ET_Builder_Element::set_style(
'et_pb_section',
array(
'selector' => $selector,
'declaration' => 'background-color: transparent;',
)
);
}
// Print Hover / Sticky height.
$modes = array( 'hover', 'sticky' );
// sprintf() removes `%` while add_hover* and add_sticky* only recognize %%order_class%%.
// thus append mode selector before $placement is re-added to the selector.
$height_selector_base = '%%order_class%%.section_has_divider.et_pb_%1$s_divider .et_pb_%1$s_inside_divider';
foreach ( $modes as $mode ) {
switch ( $mode ) {
case 'hover':
$helper = et_pb_hover_options();
$height_mode_selector = $helper->add_hover_to_order_class( $height_selector_base );
break;
case 'sticky':
$helper = et_pb_sticky_options();
$height_mode_selector = $helper->add_sticky_to_order_class( $height_selector_base, $helper->is_sticky_module( $atts ) );
break;
}
$height_mode = $helper->get_value( "{$placement}_divider_height", $atts, false );
if ( false === $height_mode ) {
continue;
}
$css = '';
$height = $height_mode;
$selector = sprintf(
$height_mode_selector,
esc_attr( $placement )
);
$declaration = array(
'height' => $height,
);
// Adjusts for when percentages are being used.
if ( 0 < strpos( $height, '%' ) ) {
$declaration['background-size'] = sprintf( '%1$s%% 100%%', floatval( 100 / $repeat ) );
} else {
$declaration['background-size'] = sprintf( '%1$s%% %2$s', floatval( 100 / $repeat ), $height );
}
foreach ( $declaration as $rule => $value ) {
$css .= esc_html( "{$rule}:{$value};" );
}
ET_Builder_Element::set_style(
'et_pb_section',
array(
'selector' => "$selector",
'declaration' => $css,
)
);
}
}
/**
* Returns a placeholder for the section only if it is set to be inside of the section.
*
* @param string $placement Whether it is the top or bottom
* @return string HTML container
*/
public function get_svg( $placement ) {
// we return a div to use for the divider
return sprintf( '<div class="et_pb_%s_inside_divider et-no-transition"></div>', esc_attr( $placement ) );
}
}
return new ET_Builder_Module_Field_Divider();

View File

@ -0,0 +1,23 @@
<?php
class ET_Builder_Module_Fields_Factory {
protected static $fields = array();
/**
* @param $fields_type
*
* @return ET_Builder_Module_Field_Base
*/
public static function get( $fields_type ) {
if ( ! isset( self::$fields[ $fields_type ] ) ) {
$file = implode( DIRECTORY_SEPARATOR, array( ET_BUILDER_DIR, 'module', 'field', "$fields_type.php" ) );
$instance = file_exists( $file ) ? require_once $file : null;
self::$fields[ $fields_type ] = $instance instanceof ET_Builder_Module_Field_Base ? $instance : null;
}
return self::$fields[ $fields_type ];
}
}

View File

@ -0,0 +1,191 @@
<?php
class ET_Builder_Module_Field_Height extends ET_Builder_Module_Field_Base {
/**
* Translations.
*
* @var array
*/
protected $i18n = array();
public function get_defaults() {
return array(
'prefix' => '',
'use_min_height' => true,
'use_height' => true,
'use_max_height' => true,
);
}
public function get_fields( array $args = array() ) {
$settings = array_merge( $this->get_defaults(), $args );
return array_merge(
$this->get_min_height( $settings ),
$this->get_height( $settings ),
$this->get_max_height( $settings )
);
}
private function get_min_height( $settings ) {
if ( ! $settings['use_min_height'] ) {
return array();
}
$helper = et_pb_min_height_options( $settings['prefix'] );
$i18n =& $this->i18n;
if ( ! isset( $i18n['minheight'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['minheight'] = array(
'label' => __( 'Min Height', 'et_builder' ),
'description' => __( 'When a minimum height is set, the element will always have a height of at least the amount defined. This supersedes smaller static height values. Unlike height, minimum height does not result in content overflow and will allow the height of your element to remain dynamic.', 'et_builder' ),
);
// phpcs:enable
}
return array_merge(
array(
$helper->get_field() => array_merge(
array(
'label' => $i18n['minheight']['label'],
'description' => $i18n['minheight']['description'],
'default' => 'auto',
'default_tablet' => 'auto',
'default_phone' => 'auto',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'min-height' ),
'range_settings' => array(
'min' => 100,
'max' => 1000,
'step' => 1,
),
),
$this->get_base_field()
),
),
$this->responsive_fields( $helper->get_field() )
);
}
private function get_height( $settings ) {
if ( ! $settings['use_height'] ) {
return array();
}
$helper = et_pb_height_options( $settings['prefix'] );
$i18n =& $this->i18n;
if ( ! isset( $i18n['height'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['height'] = array(
'label' => __( 'Height', 'et_builder' ),
'description' => __( 'This sets a static height value for your element. Once set, the height of the element will no longer be determined by its inner content. Content that exceeds the static height of the element will overflow the element wrapper.', 'et_builder' ),
);
// phpcs:enable
}
return array_merge(
array(
$helper->get_field() => array_merge(
array(
'label' => $i18n['height']['label'],
'description' => $i18n['height']['description'],
'default' => 'auto',
'default_tablet' => 'auto',
'default_phone' => 'auto',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'height' ),
'range_settings' => array(
'min' => 100,
'max' => 1000,
'step' => 1,
),
),
$this->get_base_field()
),
),
$this->responsive_fields( $helper->get_field() )
);
}
private function get_max_height( $settings ) {
if ( ! $settings['use_max_height'] ) {
return array();
}
$helper = et_pb_max_height_options( $settings['prefix'] );
$i18n =& $this->i18n;
if ( ! isset( $i18n['maxheight'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['maxheight'] = array(
'label' => __( 'Max Height', 'et_builder' ),
'description' => __( 'Setting a maximum height will prevent your element from ever surpassing the defined height value. As your module content increases and surpasses the maximum height, it will overflow the element wrapper.', 'et_builder' ),
);
// phpcs:enable
}
return array_merge(
array(
$helper->get_field() => array_merge(
array(
'label' => $i18n['maxheight']['label'],
'description' => $i18n['maxheight']['description'],
'default' => 'none',
'default_tablet' => 'none',
'default_phone' => 'none',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-height' ),
'range_settings' => array(
'min' => 100,
'max' => 1000,
'step' => 1,
),
),
$this->get_base_field()
),
),
$this->responsive_fields( $helper->get_field() )
);
}
private function get_base_field() {
return array(
'type' => 'range',
'hover' => 'tabs',
'default_on_child' => true,
'mobile_options' => true,
'sticky' => true,
'validate_unit' => true,
'unitless' => false,
'default_unit' => 'px',
'allow_empty' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
);
}
private function responsive_fields( $field ) {
return array(
"{$field}_tablet" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
"{$field}_phone" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
"{$field}_last_edited" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
);
}
}
return new ET_Builder_Module_Field_Height();

View File

@ -0,0 +1,555 @@
<?php
/**
* Module Margin and Padding class.
*
* This is not how main module margin and padding is generated. Mostly used by other custom options
* group such as Button and Field Input. Doesn't support selective padding yet.
*
* Copy of ET_Builder_Element::process_advanced_custom_margin_options().
*
* @since 3.23
* @since 4.6.0 Add sticky style support
*/
class ET_Builder_Module_Field_MarginPadding extends ET_Builder_Module_Field_Base {
/**
* True when Divi plugin is active.
*
* @since 3.23
*
* @var bool
*/
public $is_plugin_active = false;
/**
* Margin padding properties.
*
* @since 3.23
*
* @var array
*/
public $properties;
/**
* Margin padding config.
*
* @since 3.23
*
* @var array
*/
public $config;
/**
* Constructor.
*/
public function __construct() {
$this->is_plugin_active = et_is_builder_plugin_active();
$this->properties = array(
'custom_padding',
'custom_padding_tablet',
'custom_padding_phone',
'custom_padding_last_edited',
'custom_margin',
'custom_margin_tablet',
'custom_margin_phone',
'custom_margin_last_edited',
'padding_1_last_edited',
'padding_2_last_edited',
'padding_3_last_edited',
'padding_4_last_edited',
);
$this->config = array(
'label' => '',
'prefix' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'margin_padding',
'sub_toggle' => null,
'option_category' => 'layout',
'depends_show_if' => '',
'depends_show_if_not' => '',
'use_padding' => true,
'use_margin' => true,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
'custom_padding' => '',
'custom_margin' => '',
'depends_show_if' => 'on',
'priority' => 90,
);
}
/**
* Returns prefixed field names.
*
* @since 3.23
*
* @param string $prefix Prefix.
*
* @return array
*/
public function get_prefixed_field_names( $prefix ) {
$prefix = $prefix ? "{$prefix}_" : '';
return array(
"{$prefix}custom_padding",
"{$prefix}custom_padding_tablet",
"{$prefix}custom_padding_phone",
"{$prefix}custom_padding_last_edited",
"{$prefix}custom_margin",
"{$prefix}custom_margin_tablet",
"{$prefix}custom_margin_phone",
"{$prefix}custom_margin_last_edited",
"{$prefix}padding_1_last_edited",
"{$prefix}padding_2_last_edited",
"{$prefix}padding_3_last_edited",
"{$prefix}padding_4_last_edited",
);
}
/**
* Add selector prefix if needed.
*
* @since 3.23
*
* Custom margin & padding selector for button element. This is custom selector exist on
* ET_Builder_Element. We should do the samething to override hardcoded padding generated
* by button element.
*
* @see ET_Builder_Element::process_advanced_button_options
*/
public function get_prefixed_selector( $css_element, $type = '', $is_divi_builder_plugin = false ) {
// See ET_Builder_Element->process_advanced_button_options() on generating $css_element_processed
// for non Divi Builder Plugin. Explicitly add '.et_pb_section' to the selector so selector
// splitting during prefixing does not incorrectly add third party classes before #et-boc.
if ( 'button' === $type && ! $is_divi_builder_plugin ) {
$css_element = "body #page-container .et_pb_section {$css_element}";
}
return $css_element;
}
/**
* Returns fields definition.
*
* @since 3.23
*
* @param array $args Field configuration.
*
* @return array
*/
public function get_fields( array $args = array() ) {
$fields = array();
$config = wp_parse_args( $args, $this->config );
// Config details.
$tab_slug = $config['tab_slug'];
$toggle_slug = $config['toggle_slug'];
$sub_toggle = $config['sub_toggle'];
list(
$custom_padding,
$custom_padding_tablet,
$custom_padding_phone,
$custom_padding_last_edited,
$custom_margin,
$custom_margin_tablet,
$custom_margin_phone,
$custom_margin_last_edited,
$padding_1_last_edited,
$padding_2_last_edited,
$padding_3_last_edited,
$padding_4_last_edited,
) = $this->get_prefixed_field_names( $config['prefix'] );
// Custom margin.
if ( $config['use_margin'] ) {
$fields[ $custom_margin ] = array(
'label' => sprintf( esc_html__( '%1$s Margin', 'et_builder' ), $config['label'] ),
'description' => esc_html__( 'Margin adds extra space to the outside of the element, increasing the distance between the element and other items on the page.', 'et_builder' ),
'type' => 'custom_margin',
'option_category' => $config['option_category'],
'mobile_options' => $config['mobile_options'],
'hover' => $config['hover'],
'sticky' => $config['sticky'],
'depends_show_if' => $config['depends_show_if'],
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'sub_toggle' => $sub_toggle,
'priority' => $config['priority'],
);
$fields[ $custom_margin_tablet ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
);
$fields[ $custom_margin_phone ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
// Make it possible to override/add options.
if ( ! empty( $config['custom_margin'] ) ) {
$fields[ $custom_margin ] = array_merge( $fields[ $custom_margin ], $config['custom_margin'] );
}
$fields[ $custom_margin_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
$fields[ $padding_1_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
$fields[ $padding_2_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
$fields[ $padding_3_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
$fields[ $padding_4_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
}
// Custom padding.
if ( $config['use_padding'] ) {
$fields[ $custom_padding ] = array(
'label' => sprintf( esc_html__( '%1$s Padding', 'et_builder' ), $config['label'] ),
'description' => esc_html__( 'Padding adds extra space to the inside of the element, increasing the distance between the edge of the element and its inner contents.', 'et_builder' ),
'type' => 'custom_padding',
'option_category' => $config['option_category'],
'mobile_options' => $config['mobile_options'],
'hover' => $config['hover'],
'sticky' => $config['sticky'],
'depends_show_if' => $config['depends_show_if'],
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'sub_toggle' => $sub_toggle,
'priority' => $config['priority'],
);
$fields[ $custom_padding_tablet ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
$fields[ $custom_padding_phone ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
// Make it possible to override/add options.
if ( ! empty( $config['custom_padding'] ) ) {
$fields[ $custom_padding ] = array_merge( $fields[ $custom_padding ], $config['custom_padding'] );
}
$fields[ $custom_padding_last_edited ] = array(
'type' => 'skip',
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
);
}
return $fields;
}
/**
* Adds CSS rule.
*
* @since 3.23
* @since 4.6.0 Add sticky style support
*
* @see ET_Builder_Element->process_advanced_custom_margin_options()
*
* @param ET_Builder_Element $module Module object.
* @param string $prefix Label.
* @param array $options Field settings.
* @param string $function_name Shortcode function.
* @param string $type Margin padding type.
*/
public function update_styles( $module, $prefix, $options, $function_name, $type ) {
$utils = ET_Core_Data_Utils::instance();
$all_values = $module->props;
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$advanced_fields = $module->advanced_fields;
$css = isset( $this->advanced_fields['margin_padding']['css'] ) ? $this->advanced_fields['margin_padding']['css'] : array();
// Conditional status.
$is_divi_builder_plugin = et_is_builder_plugin_active();
$is_important_set = isset( $options['css']['important'] );
$is_global_important = $is_important_set && 'all' === $options['css']['important'];
$is_use_padding = $utils->array_get( $options, 'use_padding', true );
$is_use_margin = $utils->array_get( $options, 'use_margin', true );
$is_sticky_module = $sticky->is_sticky_module( $all_values );
// Selectors.
$main_selector = ! empty( $options['css']['main'] ) ? $options['css']['main'] : $module->main_css_element;
$limited_selector = ! empty( $options['css']['limited_main'] ) ? $options['css']['limited_main'] : '';
$default_selector = $is_divi_builder_plugin && ! empty( $limited_selector ) ? $limited_selector : $main_selector;
// Get important CSS list.
$important_options = array();
if ( $is_important_set && is_array( $options['css']['important'] ) ) {
$important_options = $options['css']['important'];
}
// A. Padding.
if ( $is_use_padding ) {
// Padding Selectors.
$padding_selector = ! empty( $options['css']['padding'] ) ? $options['css']['padding'] : $default_selector;
$padding_selector_processed = $this->get_prefixed_selector( $padding_selector, $type, $is_divi_builder_plugin );
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$padding_selector_processed = $padding_selector;
}
// A.1. Responsive Padding.
$is_padding_responsive = $responsive->is_responsive_enabled( $all_values, "{$prefix}_custom_padding" );
$padding_desktop = $responsive->get_any_value( $all_values, "{$prefix}_custom_padding" );
$padding_tablet = $is_padding_responsive ? $responsive->get_any_value( $all_values, "{$prefix}_custom_padding_tablet" ) : '';
$padding_phone = $is_padding_responsive ? $responsive->get_any_value( $all_values, "{$prefix}_custom_padding_phone" ) : '';
$important = in_array( 'custom_padding', $important_options ) || $is_global_important ? true : false;
$padding_styles = array(
'desktop' => '' !== $padding_desktop ? rtrim( et_builder_get_element_style_css( $padding_desktop, 'padding', $important ) ) : '',
'tablet' => '' !== $padding_tablet ? rtrim( et_builder_get_element_style_css( $padding_tablet, 'padding', $important ) ) : '',
'phone' => '' !== $padding_phone ? rtrim( et_builder_get_element_style_css( $padding_phone, 'padding', $important ) ) : '',
);
$responsive->declare_responsive_css( $padding_styles, $padding_selector_processed, $function_name, $module->get_style_priority() );
// A.2. Hover Padding.
$custom_padding_hover = $hover->get_value( "{$prefix}_custom_padding", $all_values, '' );
if ( '' !== $custom_padding_hover && et_builder_is_hover_enabled( "{$prefix}_custom_padding", $all_values ) ) {
$padding_hover_selector = $utils->array_get( $options, 'css.hover', $hover->add_hover_to_selectors( $padding_selector ) );
$padding_hover_selector_processed = $this->get_prefixed_selector( $padding_hover_selector, $type, $is_divi_builder_plugin );
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$padding_hover_selector_processed = $padding_hover_selector;
}
$el_style = array(
'selector' => $padding_hover_selector_processed,
'declaration' => rtrim( et_builder_get_element_style_css( $custom_padding_hover, 'padding', true ) ),
'priority' => 20,
);
ET_Builder_Element::set_style( $function_name, $el_style );
}
// A.3. Sticky Padding.
$custom_padding_sticky = $sticky->get_value( "{$prefix}_custom_padding", $all_values, '' );
if ( '' !== $custom_padding_sticky && $sticky->is_enabled( "{$prefix}_custom_padding", $all_values ) ) {
$padding_sticky_selector = $sticky->add_sticky_to_order_class(
$padding_selector,
$is_sticky_module
);
$padding_sticky_selector_processed = $this->get_prefixed_selector(
$padding_sticky_selector,
$type,
$is_divi_builder_plugin
);
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$padding_sticky_selector_processed = $padding_sticky_selector;
}
ET_Builder_Element::set_style(
$function_name,
array(
'selector' => $padding_sticky_selector_processed,
'declaration' => rtrim(
et_builder_get_element_style_css(
$custom_padding_sticky,
'padding',
true
)
),
'priority' => 20,
)
);
}
}
// B. Margin.
if ( $is_use_margin ) {
// Margin Selectors.
$margin_selector = ! empty( $options['css']['margin'] ) ? $options['css']['margin'] : $default_selector;
$margin_selector_processed = $this->get_prefixed_selector( $margin_selector, $type, $is_divi_builder_plugin );
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$margin_selector_processed = $margin_selector;
}
// A.1. Responsive margin.
$is_margin_responsive = $responsive->is_responsive_enabled( $all_values, "{$prefix}_custom_margin" );
$margin_desktop = $responsive->get_any_value( $all_values, "{$prefix}_custom_margin" );
$margin_tablet = $is_margin_responsive ? $responsive->get_any_value( $all_values, "{$prefix}_custom_margin_tablet" ) : '';
$margin_phone = $is_margin_responsive ? $responsive->get_any_value( $all_values, "{$prefix}_custom_margin_phone" ) : '';
$important = in_array( 'custom_margin', $important_options ) || $is_global_important ? true : false;
$margin_styles = array(
'desktop' => '' !== $margin_desktop ? rtrim( et_builder_get_element_style_css( $margin_desktop, 'margin', $important ) ) : '',
'tablet' => '' !== $margin_tablet ? rtrim( et_builder_get_element_style_css( $margin_tablet, 'margin', $important ) ) : '',
'phone' => '' !== $margin_phone ? rtrim( et_builder_get_element_style_css( $margin_phone, 'margin', $important ) ) : '',
);
$responsive->declare_responsive_css( $margin_styles, $margin_selector_processed, $function_name, $module->get_style_priority() );
// A.2. Hover margin.
$custom_margin_hover = $hover->get_value( "{$prefix}_custom_margin", $all_values, '' );
if ( '' !== $custom_margin_hover && et_builder_is_hover_enabled( "{$prefix}_custom_margin", $all_values ) ) {
$margin_hover_selector = $utils->array_get( $options, 'css.hover', $hover->add_hover_to_selectors( $margin_selector ) );
$margin_hover_selector_processed = $this->get_prefixed_selector( $margin_hover_selector, $type, $is_divi_builder_plugin );
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$margin_hover_selector_processed = $margin_hover_selector;
}
$el_style = array(
'selector' => $margin_hover_selector_processed,
'declaration' => rtrim( et_builder_get_element_style_css( $custom_margin_hover, 'margin', true ) ),
'priority' => 20,
);
ET_Builder_Element::set_style( $function_name, $el_style );
}
// A.3. Hover margin.
$custom_margin_sticky = $sticky->get_value( "{$prefix}_custom_margin", $all_values, '' );
if ( '' !== $custom_margin_sticky && $sticky->is_enabled( "{$prefix}_custom_margin", $all_values ) ) {
$margin_sticky_selector = $sticky->add_sticky_to_order_class(
$margin_selector,
$is_sticky_module
);
$margin_sticky_selector_processed = $this->get_prefixed_selector(
$margin_sticky_selector,
$type,
$is_divi_builder_plugin
);
if ( $is_divi_builder_plugin && ! empty( $limited_selector ) ) {
$margin_sticky_selector_processed = $margin_sticky_selector;
}
ET_Builder_Element::set_style(
$function_name,
array(
'selector' => $margin_sticky_selector_processed,
'declaration' => rtrim(
et_builder_get_element_style_css(
$custom_margin_sticky,
'margin',
true
)
),
'priority' => 20,
)
);
}
}
}
/**
* Process Margin & Padding options and adds CSS rules.
*
* @since 3.23
*
* @param ET_Builder_Element $module Module object.
* @param string $function_name Shortcode function.
*/
public function process_advanced_css( $module, $function_name ) {
$utils = ET_Core_Data_Utils::instance();
$all_values = $module->props;
$advanced_fields = $module->advanced_fields;
// Disable if module doesn't set advanced_fields property and has no VB support.
if ( ! $module->has_vb_support() && ! $module->has_advanced_fields ) {
return;
}
$allowed_advanced_fields = array( 'form_field', 'button', 'image_icon' );
foreach ( $allowed_advanced_fields as $advanced_field ) {
if ( empty( $advanced_fields[ $advanced_field ] ) ) {
continue;
}
foreach ( $advanced_fields[ $advanced_field ] as $label => $form_field ) {
$margin_key = "{$label}_custom_margin";
$padding_key = "{$label}_custom_padding";
$multi_view = et_pb_multi_view_options( $module );
$has_margin = '' !== $utils->array_get( $all_values, $margin_key, '' );
$has_padding = '' !== $utils->array_get( $all_values, $padding_key, '' );
$has_margin_hover = $multi_view->hover_is_enabled( $margin_key );
$has_padding_hover = $multi_view->hover_is_enabled( $padding_key );
$has_padding_sticky = ! empty( et_pb_sticky_options()->get_value( "{$label}_custom_padding", $all_values, '' ) ) && et_pb_sticky_options()->is_enabled( "{$label}_custom_padding", $all_values );
$has_margin_sticky = ! empty( et_pb_sticky_options()->get_value( "{$label}_custom_margin", $all_values, '' ) ) && et_pb_sticky_options()->is_enabled( "{$label}_custom_margin", $all_values );
if ( $has_margin || $has_padding || $has_margin_hover || $has_padding_hover || $has_padding_sticky || $has_margin_sticky ) {
$settings = $utils->array_get( $form_field, 'margin_padding', array() );
// Ensure main selector exists.
$form_field_margin_padding_css = $utils->array_get( $settings, 'css.main', '' );
if ( empty( $form_field_margin_padding_css ) ) {
$utils->array_set( $settings, 'css.main', $utils->array_get( $form_field, 'css.main', '' ) );
}
$this->update_styles( $module, $label, $settings, $function_name, $advanced_field );
}
}
}
}
/**
* Process Margin & Padding options and adds CSS rules.
*
* @since 4.10.0
* @param array $attrs Module attributes.
*/
public function is_used( $attrs ) {
foreach ( $attrs as $attr => $value ) {
if ( ! $value ) {
continue;
}
$is_attr = false !== strpos( $attr, 'custom_margin' )
|| false !== strpos( $attr, 'custom_padding' );
if ( $is_attr ) {
return true;
}
}
return false;
}
}
return new ET_Builder_Module_Field_MarginPadding();

View File

@ -0,0 +1,214 @@
<?php
class ET_Builder_Module_Field_MaxWidth extends ET_Builder_Module_Field_Base {
/**
* Translations.
*
* @var array
*/
protected $i18n = array();
public function get_defaults() {
return array(
'prefix' => '',
'use_width' => true,
'use_max_width' => true,
'use_module_alignment' => true,
);
}
public function get_fields( array $args = array() ) {
$settings = array_merge( $this->get_defaults(), $args );
return array_merge(
$this->width_fields( $settings ),
$this->max_width_fields( $settings ),
$this->alignment_fields( $settings )
);
}
private function width_fields( $settings ) {
if ( ! $settings['use_width'] ) {
return array();
}
$i18n =& $this->i18n;
if ( ! isset( $i18n['width'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['width'] = array(
'label' => __( 'Width', 'et_builder' ),
'description' => __( 'By default, elements will extend the full width of their parent element. If you would like to set a custom static width, you can do so using this option.', 'et_builder' ),
);
// phpcs:enable
}
$alignment = new ET_Builder_Module_Helper_Alignment( $settings['prefix'] );
$width = new ET_Builder_Module_Helper_Width( $settings['prefix'] );
$field_name = $width->get_field();
$field = array_merge(
array(
$field_name => array_merge(
array(
'label' => $i18n['width']['label'],
'description' => $i18n['width']['description'],
'default' => 'auto',
'default_tablet' => 'auto',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'width' ),
),
$this->get_base_field()
),
),
$this->responsive_fields( $field_name )
);
if ( $settings['use_module_alignment'] ) {
$field[ $field_name ]['responsive_affects'] = array( $alignment->get_field() );
}
return $field;
}
private function max_width_fields( $settings ) {
if ( ! $settings['use_max_width'] ) {
return array();
}
$i18n =& $this->i18n;
if ( ! isset( $i18n['maxwidth'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['maxwidth'] = array(
'label' => __( 'Max Width', 'et_builder' ),
'description' => __( 'Setting a maximum width will prevent your element from ever surpassing the defined width value. Maximum width can be used in combination with the standard width setting. Maximum width supersedes the normal width value.', 'et_builder' ),
);
// phpcs:enable
}
$alignment = new ET_Builder_Module_Helper_Alignment( $settings['prefix'] );
$max_width = new ET_Builder_Module_Helper_Max_Width( $settings['prefix'] );
$field_name = $max_width->get_field();
$field = array_merge(
array(
$field_name => array_merge(
array(
'label' => $i18n['maxwidth']['label'],
'description' => $i18n['maxwidth']['description'],
'default' => 'none',
'default_tablet' => 'none',
'allowed_values' => et_builder_get_acceptable_css_string_values( 'max-width' ),
),
$this->get_base_field()
),
),
$this->responsive_fields( $field_name )
);
if ( $settings['use_module_alignment'] ) {
$field[ $field_name ]['responsive_affects'] = array( $alignment->get_field() );
}
return $field;
}
private function alignment_fields( $settings ) {
if ( ! $settings['use_module_alignment'] ) {
return array();
}
$i18n =& $this->i18n;
if ( ! isset( $i18n['alignment'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['alignment'] = array(
'label' => esc_html__( 'Module Alignment', 'et_builder' ),
'description' => esc_html__( 'Align the module to the left, right or center.', 'et_builder' ),
);
// phpcs:enable
}
$width = new ET_Builder_Module_Helper_Width( $settings['prefix'] );
$max_width = new ET_Builder_Module_Helper_Max_Width( $settings['prefix'] );
$alignment = new ET_Builder_Module_Helper_Alignment( $settings['prefix'] );
$field_name = $alignment->get_field();
$depends = array();
$depends_responsive = array();
$field = array(
'label' => $i18n['alignment']['label'],
'description' => $i18n['alignment']['description'],
'type' => 'align',
'option_category' => 'layout',
'options' => et_builder_get_text_orientation_options( array( 'justified' ) ),
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'mobile_options' => true,
'show_if_not' => array(
'positioning' => array( 'absolute', 'fixed' ),
),
);
if ( $settings['use_width'] ) {
array_push( $depends, $width->get_field() );
array_push( $depends_responsive, $width->get_field() );
}
if ( $settings['use_max_width'] ) {
array_push( $depends, $max_width->get_field() );
array_push( $depends_responsive, $max_width->get_field() );
}
if ( $settings['use_width'] || $settings['use_max_width'] ) {
$field['depends_show_if_not'] = array( '', '100%', 'auto', 'none' );
}
if ( ! empty( $depends ) ) {
$field['depends_on'] = $depends;
$field['depends_on_responsive'] = $depends_responsive;
}
return array( $field_name => $field );
}
private function get_base_field() {
return array(
'type' => 'range',
'hover' => 'tabs',
'default_on_child' => true,
'mobile_options' => true,
'sticky' => true,
'validate_unit' => true,
'default_unit' => '%',
'allow_empty' => true,
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
'range_settings' => array(
'min' => 0,
'max' => 100,
'step' => 1,
),
);
}
private function responsive_fields( $field ) {
return array(
"{$field}_tablet" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
"{$field}_phone" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
"{$field}_last_edited" => array(
'type' => 'skip',
'tab_slug' => 'advanced',
'toggle_slug' => 'width',
),
);
}
}
return new ET_Builder_Module_Field_MaxWidth();

View File

@ -0,0 +1,85 @@
<?php
class ET_Builder_Module_Field_Overflow extends ET_Builder_Module_Field_Base {
public function get_defaults() {
return array(
'prefix' => '',
'tab_slug' => 'custom_css',
'toggle_slug' => 'visibility',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
'default' => ET_Builder_Module_Helper_Overflow::OVERFLOW_DEFAULT,
);
}
public function get_fields( array $args = array() ) {
$settings = array_merge( $this->get_defaults(), $args );
return array_merge(
$this->get_field( 'x', $settings ),
$this->get_field( 'y', $settings )
);
}
protected function get_field( $axis, $args ) {
static $i18n;
if ( ! $i18n ) {
$i18n = array(
'default' => __( 'Default', 'et_builder' ),
'visible' => __( 'Visible', 'et_builder' ),
'scroll' => __( 'Scroll', 'et_builder' ),
'hidden' => __( 'Hidden', 'et_builder' ),
'auto' => __( 'Auto', 'et_builder' ),
'description' => __( 'Here you can control element overflow on the %s axis. If set to scroll, content that overflows static widths or heights will trigger a browser scrollbar. If set to hidden, content overflow will be clipped.', 'et_builder' ),
'horizontal' => __( 'Horizontal Overflow', 'et_builder' ),
'vertical' => __( 'Vertical Overflow', 'et_builder' ),
);
}
$overflow = et_pb_overflow();
$OVERFLOW_DEFAULT = ET_Builder_Module_Helper_Overflow::OVERFLOW_DEFAULT;
$OVERFLOW_VISIBLE = ET_Builder_Module_Helper_Overflow::OVERFLOW_VISIBLE;
$OVERFLOW_SCROLL = ET_Builder_Module_Helper_Overflow::OVERFLOW_SCROLL;
$OVERFLOW_HIDDEN = ET_Builder_Module_Helper_Overflow::OVERFLOW_HIDDEN;
$OVERFLOW_AUTO = ET_Builder_Module_Helper_Overflow::OVERFLOW_AUTO;
switch ( $axis ) {
case 'x':
$field = $overflow->get_field_x( $args['prefix'] );
$label = $i18n['horizontal'];
break;
default:
$field = $overflow->get_field_y( $args['prefix'] );
$label = $i18n['vertical'];
break;
}
$settings = array(
'label' => $label,
'type' => 'select',
'hover' => $args['hover'],
'mobile_options' => $args['mobile_options'],
'sticky' => $args['sticky'],
'default' => $args['default'],
'tab_slug' => $args['tab_slug'],
'toggle_slug' => $args['toggle_slug'],
'options' => array(
$OVERFLOW_DEFAULT => $i18n['default'],
$OVERFLOW_VISIBLE => $i18n['visible'],
$OVERFLOW_SCROLL => $i18n['scroll'],
$OVERFLOW_HIDDEN => $i18n['hidden'],
$OVERFLOW_AUTO => $i18n['auto'],
),
'description' => sprintf( $i18n['description'], strtoupper( $axis ) ),
);
$options = array( $field => $settings );
return $options;
}
}
return new ET_Builder_Module_Field_Overflow();

View File

@ -0,0 +1,718 @@
<?php
class ET_Builder_Module_Field_Position extends ET_Builder_Module_Field_Base {
const TAB_SLUG = 'custom_css';
const TOGGLE_SLUG = 'position_fields';
/**
* @var ET_Builder_Element
*/
private $module;
public function get_fields( array $args = array() ) {
$responsive_options = array();
$additional_options = array();
$skip = array(
'type' => 'skip',
'tab_slug' => self::TAB_SLUG,
'toggle_slug' => self::TOGGLE_SLUG,
);
static $i18n;
if ( ! isset( $i18n ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n = array(
'positioning' => array(
'description' => esc_html__( 'Here you can choose the element\'s position type. Absolutlely positioned elements will float inside their parent elements. Fixed positioned elements will float within the browser viewport. Relatively positioned elements sit statically in their parent container, but can still be offset without disrupting surrounding elements.', 'et_builder' ),
'options' => array(
'relative' => esc_html__( 'Relative', 'et_builder' ),
'absolute' => esc_html__( 'Absolute', 'et_builder' ),
'fixed' => esc_html__( 'Fixed', 'et_builder' ),
),
),
'origin' => array(
'label' => esc_html__( 'Location', 'et_builder' ),
'description' => esc_html__( 'Here you can adjust the element\'s starting location within its parent container. You can further adjust the element\'s position using the offset controls.', 'et_builder' ),
),
'offset' => array(
'label' => esc_html__( 'Offset Origin ', 'et_builder' ),
'description' => esc_html__( 'Here you can choose from which corner this element is offset from. The vertical and horizontal offset adjustments will be affected based on the element\'s offset origin.', 'et_builder' ),
),
'vertical' => array(
'label' => esc_html__( 'Vertical Offset', 'et_builder' ),
'description' => esc_html__( 'Here you can adjust the element\'s position upwards or downwards from its starting location, which may differ based on its offset origin.', 'et_builder' ),
),
'horizontal' => array(
'label' => esc_html__( 'Horizontal Offset', 'et_builder' ),
'description' => esc_html__( 'Here you can adjust the element\'s position left or right from its starting location, which may differ based on its offset origin.', 'et_builder' ),
),
'zindex' => array(
'label' => esc_html__( 'Z Index', 'et_builder' ),
'description' => esc_html__( 'Here you can control element position on the z axis. Elements with higher z-index values will sit atop elements with lower z-index values.', 'et_builder' ),
),
);
// phpcs:enable
}
if ( ! $args['hide_position_fields'] ) {
$corner_options = array(
'top_left' => et_builder_i18n( 'Top Left' ),
'top_right' => et_builder_i18n( 'Top Right' ),
'bottom_left' => et_builder_i18n( 'Bottom Left' ),
'bottom_right' => et_builder_i18n( 'Bottom Right' ),
);
$center_options = array(
'center_left' => et_builder_i18n( 'Center Left' ),
'center_center' => et_builder_i18n( 'Center Center' ),
'center_right' => et_builder_i18n( 'Center Right' ),
'top_center' => et_builder_i18n( 'Top Center' ),
'bottom_center' => et_builder_i18n( 'Bottom Center' ),
);
$additional_options['positioning'] = array(
'label' => et_builder_i18n( 'Position' ),
'description' => $i18n['positioning']['description'],
'type' => 'select',
'options' => array(
'none' => et_builder_i18n( 'Default' ),
'relative' => $i18n['positioning']['options']['relative'],
'absolute' => $i18n['positioning']['options']['absolute'],
'fixed' => $i18n['positioning']['options']['fixed'],
),
'option_category' => 'layout',
'default' => $args['defaults']['positioning'],
'default_on_child' => true,
'tab_slug' => self::TAB_SLUG,
'toggle_slug' => self::TOGGLE_SLUG,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
'bb_support' => false,
'linked_responsive' => array( 'position_origin_a', 'position_origin_f', 'position_origin_r' ),
);
// Position origin/location options
$origin_option = array(
'label' => $i18n['origin']['label'],
'description' => $i18n['origin']['description'],
'type' => 'position',
'options' => $corner_options + $center_options,
'option_category' => 'layout',
'default' => $args['defaults']['position_origin'],
'default_on_child' => true,
'tab_slug' => self::TAB_SLUG,
'toggle_slug' => self::TOGGLE_SLUG,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
'bb_support' => false,
);
// For absolute position
$additional_options['position_origin_a'] = $origin_option;
$additional_options['position_origin_a']['linked_responsive'] = array( 'positioning', 'position_origin_f', 'position_origin_r' );
// For fixed position
$additional_options['position_origin_f'] = $origin_option;
$additional_options['position_origin_f']['linked_responsive'] = array( 'positioning', 'position_origin_a', 'position_origin_r' );
// For relative position
$additional_options['position_origin_r'] = $origin_option;
$additional_options['position_origin_r']['label'] = $i18n['offset']['label'];
$additional_options['position_origin_r']['description'] = $i18n['offset']['description'];
$additional_options['position_origin_r']['options'] = $corner_options;
$additional_options['position_origin_r']['linked_responsive'] = array( 'positioning', 'position_origin_f', 'position_origin_a' );
// Offset options
$offset_option = array(
'type' => 'range',
'range_settings' => array(
'min' => -1000,
'max' => 1000,
'step' => 1,
),
'option_category' => 'layout',
'default_unit' => 'px',
'default_on_child' => true,
'tab_slug' => self::TAB_SLUG,
'toggle_slug' => self::TOGGLE_SLUG,
'responsive' => true,
'mobile_options' => true,
'sticky' => true,
'hover' => 'tabs',
);
$additional_options['vertical_offset'] = $offset_option;
$additional_options['vertical_offset']['default'] = $args['defaults']['vertical_offset'];
$additional_options['vertical_offset']['label'] = $i18n['vertical']['label'];
$additional_options['vertical_offset']['description'] = $i18n['vertical']['description'];
$additional_options['horizontal_offset'] = $offset_option;
$additional_options['horizontal_offset']['default'] = $args['defaults']['horizontal_offset'];
$additional_options['horizontal_offset']['label'] = $i18n['horizontal']['label'];
$additional_options['horizontal_offset']['description'] = $i18n['horizontal']['description'];
$responsive_options += array(
'vertical_offset',
'horizontal_offset',
'position_origin_a',
'position_origin_f',
'position_origin_r',
);
}
if ( ! $args['hide_z_index_fields'] ) {
$additional_options['z_index'] = array(
'label' => $i18n['zindex']['label'],
'description' => $i18n['zindex']['description'],
'type' => 'range',
'range_settings' => array(
'min' => -500,
'max' => 500,
'step' => 1,
),
'option_category' => 'layout',
'default' => $args['defaults']['z_index'],
'default_on_child' => true,
'tab_slug' => self::TAB_SLUG,
'toggle_slug' => self::TOGGLE_SLUG,
'allowed_values' => et_builder_get_acceptable_css_string_values( 'z-index' ),
'unitless' => true,
'hover' => 'tabs',
'sticky' => true,
'responsive' => true,
'mobile_options' => true,
);
$responsive_options += array(
'z_index',
);
}
foreach ( $responsive_options as $option ) {
$additional_options[ "${option}_tablet" ] = $skip;
$additional_options[ "${option}_phone" ] = $skip;
$additional_options[ "${option}_last_edited" ] = $skip;
}
return $additional_options;
}
// Processing functions
/**
* @param object $module Current module to be processed
*/
public function set_module( $module ) {
$this->module = $module;
}
/**
* Interpreter of ET_Builder_Element::get_media_query
*
* @param string $view
*
* @return array
*/
public function get_media_query( $view ) {
$media_query = array();
if ( 'tablet' === $view ) {
$media_query = array(
'media_query' => ET_Builder_Element::get_media_query( 'max_width_980' ),
);
} elseif ( 'phone' === $view ) {
$media_query = array(
'media_query' => ET_Builder_Element::get_media_query( 'max_width_767' ),
);
}
return $media_query;
}
/**
* @param array $attrs
* @param string $name
* @param string $desktopDefault
* @param string $view
*
* @return mixed
*/
private function get_default( $attrs, $name, $desktopDefault = '', $view = 'desktop' ) {
$utils = ET_Core_Data_Utils::instance();
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$suffix = in_array( $view, array( 'tablet', 'phone' ) ) ? "_$view" : '';
if ( 'hover' === $view ) {
return $utils->array_get( $attrs, $name, $desktopDefault );
}
return $responsive->get_default_value( $attrs, "$name$suffix", $desktopDefault );
}
/**
* @param array $attrs
* @param string $name
* @param string $default_value
* @param string $view
* @param bool $force_return
*
* @return mixed
*/
private function get_value( $attrs, $name, $default_value = '', $view = 'desktop', $force_return = false ) {
// Sticky style.
if ( 'sticky' === $view ) {
$sticky = et_pb_sticky_options();
return $sticky->get_value( $name, $attrs, $default_value );
}
$utils = ET_Core_Data_Utils::instance();
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$hover = et_pb_hover_options();
$is_hover = 'hover' === $view;
$field_device = $is_hover ? 'desktop' : $view;
$field_name = $is_hover ? $hover->get_hover_field( $name ) : $name;
$field_default = $is_hover ? $utils->array_get( $attrs, $name, $default_value ) : $default_value;
return $responsive->get_any_value( $attrs, $field_name, $field_default, $force_return, $field_device );
}
/**
* Get exposed module settings for assisting layout block preview rendering
*
* @since 4.3.2
*
* @param string $function_name
*
* @return null|array
*/
public function get_layout_block_settings( $function_name ) {
$position_fields = et_()->array_get( $this->module->advanced_fields, self::TOGGLE_SLUG, array() );
$has_position_fields = is_array( $position_fields );
// Bail if current module has no position fields
if ( ! $has_position_fields ) {
return;
}
$props = $this->module->props;
$responsive = et_pb_responsive_options();
$hover = et_pb_hover_options();
// Position values
$position = $responsive->is_responsive_enabled( $props, 'positioning' ) ?
$responsive->get_property_values( $props, 'positioning', '', true ) :
array(
'desktop' => $responsive->get_desktop_value( 'positioning', $props ),
);
if ( $hover->is_enabled( 'positioning', $props ) ) {
$position['hover'] = $hover->get_value( 'positioning', $props );
}
// Bail if current module is not fixed positioning on any breakpoint/mode
if ( ! in_array( 'fixed', $position ) ) {
return;
}
// Position fixed origin values
$position_fixed_origin = $responsive->is_responsive_enabled( $props, 'position_origin_f' ) ?
$responsive->get_property_values( $props, 'position_origin_f', '', true ) :
array(
'desktop' => $responsive->get_desktop_value( 'position_origin_f', $props ),
);
if ( $hover->is_enabled( 'position_origin_f', $props ) ) {
$position_fixed_origin['hover'] = $hover->get_value( 'position_origin_f', $props );
}
// Vertical offset
$vertical_offset = $responsive->is_responsive_enabled( $props, 'vertical_offset' ) ?
$responsive->get_property_values( $props, 'vertical_offset', '', true ) :
array(
'desktop' => $responsive->get_desktop_value( 'vertical_offset', $props ),
);
if ( $hover->is_enabled( 'vertical_offset', $props ) ) {
$vertical_offset['hover'] = $hover->get_value( 'vertical_offset', $props );
// Offset rendering relies on origin position. Thus if position origin has
// no hover value, set desktop as hover value to trigger adjustment rendering
if ( ! isset( $position_fixed_origin['hover'] ) ) {
$position_fixed_origin['hover'] = $position_fixed_origin['desktop'];
}
}
// Horizontal offset
$horizontal_offset = $responsive->is_responsive_enabled( $props, 'horizontal_offset' ) ?
$responsive->get_property_values( $props, 'horizontal_offset', '', true ) :
array(
'desktop' => $responsive->get_desktop_value( 'horizontal_offset', $props ),
);
if ( $hover->is_enabled( 'horizontal_offset', $props ) ) {
$horizontal_offset['hover'] = $hover->get_value( 'horizontal_offset', $props );
// Offset rendering relies on origin position. Thus if position origin has
// no hover value, set desktop as hover value to trigger adjustment rendering
if ( ! isset( $position_fixed_origin['hover'] ) ) {
$position_fixed_origin['hover'] = $position_fixed_origin['desktop'];
}
}
// Return current module's position and position origin settings
return array(
'position' => $position,
'position_fixed_origin' => $position_fixed_origin,
'vertical_offset' => $vertical_offset,
'horizontal_offset' => $horizontal_offset,
);
}
/**
* @param string $function_name
*
* @since 4.6.0 Add sticky style support.
*/
public function process( $function_name ) {
$utils = ET_Core_Data_Utils::instance();
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$position_config = $utils->array_get( $this->module->advanced_fields, self::TOGGLE_SLUG, array() );
$z_index_config = $utils->array_get( $this->module->advanced_fields, 'z_index', array() );
$props = $this->module->props;
$this->module->set_position_locations( array() );
if ( ! is_array( $z_index_config ) && ! is_array( $position_config ) ) {
return;
}
$has_z_index = false;
$has_position = false;
// z_index processing
if ( is_array( $z_index_config ) ) {
$z_index_selector = $utils->array_get( $z_index_config, 'css.main', '%%order_class%%' );
$z_index_default = $utils->array_get( $z_index_config, 'default', '' );
$z_important = $utils->array_get( $z_index_config, 'important', false ) !== false ? ' !important' : '';
$views = array( 'desktop' );
if ( $hover->is_enabled( 'z_index', $props ) ) {
array_push( $views, 'hover' );
}
if ( $responsive->is_responsive_enabled( $props, 'z_index' ) ) {
array_push( $views, 'tablet', 'phone' );
}
// If the module is sticky or inside a sticky module, we need to add z-index for sticky state
// with an `!important` flag to override sticky's default inline z-index: 10000 value when module enters sticky state.
if ( $sticky->is_sticky_module( $props ) || $sticky->is_inside_sticky_module() ) {
array_push( $views, 'sticky' );
}
foreach ( $views as $type ) {
$value = $this->get_value( $props, 'z_index', $z_index_default, $type, false );
if ( 'sticky' === $type ) {
$desktop_value = $this->get_value( $props, 'z_index', $z_index_default, 'desktop', false );
$value = $sticky->get_value( 'z_index', $props, $desktop_value );
$z_important = ' !important';
}
if ( '' !== $value ) {
$type_selector = $z_index_selector;
if ( 'hover' === $type ) {
$type_selector = $hover->add_hover_to_selectors( $z_index_selector );
}
if ( 'sticky' === $type ) {
$type_selector = $sticky->add_sticky_to_selectors( $z_index_selector, $sticky->is_sticky_module( $props ) );
}
$el_style = array(
'selector' => $type_selector,
'declaration' => "z-index: $value$z_important;",
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
$has_z_index = true;
}
}
}
if ( is_array( $position_config ) ) {
$position_selector = $utils->array_get( $position_config, 'css.main', '%%order_class%%' );
$position_default = $utils->array_get( $position_config, 'default', 'none' );
$position_important = $utils->array_get( $position_config, 'important', false ) !== false ? ' !important' : '';
$desktop_origin_value = 'top_left';
$views = array( 'desktop' );
if ( $hover->is_enabled( 'positioning', $props ) ) {
array_push( $views, 'hover' );
}
if ( $responsive->is_responsive_enabled( $props, 'positioning' ) ) {
array_push( $views, 'tablet', 'phone' );
}
if ( $sticky->is_inside_sticky_module() && $sticky->is_enabled( 'positioning', $props ) ) {
array_push( $views, 'sticky' );
}
$position_origins = array();
foreach ( $views as $type ) {
$value = $this->get_value( $props, 'positioning', $position_default, $type, true );
$default_value = $this->get_default( $props, 'positioning', $position_default, $type );
$important = in_array( $value, array( 'fixed', 'absolute' ) ) || ( 'desktop' != $type ) ? ' !important' : $position_important;
$position_value = $value;
$is_parallax_on = 'on' === $this->get_value( $props, 'parallax' ) ? true : false;
// When parallax is enabled on the element and the position value
// is set to none skip because it should always be relative.
if ( $is_parallax_on && 'none' === $value ) {
continue;
}
if ( 'none' === $value ) {
// none is interpreted as static in FE.
$position_value = 'static';
$important = ' !important';
$position_origins[ $type ] = 'none';
} else {
$suffix = sprintf( '_%s', substr( $value, 0, 1 ) );
$position_origins[ $type ] = $this->get_value( $props, "position_origin$suffix", 'top_left', $type, true );
}
if ( $default_value === $value ) {
$position_origins[ $type ] .= '_is_default';
}
if ( strpos( $position_origins[ $type ], '_is_default' ) === false ) {
$type_selector = 'hover' === $type ? "${position_selector}:hover" : $position_selector;
$el_style = array(
'selector' => $type_selector,
'declaration' => "position: $position_value$important;",
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
$has_position = true;
}
}
$resp_status = array(
'horizontal' => $responsive->get_responsive_status( $utils->array_get( $props, 'horizontal_offset_last_edited', false ) ),
'vertical' => $responsive->get_responsive_status( $utils->array_get( $props, 'vertical_offset_last_edited', false ) ),
);
$hover_status = array(
'horizontal' => $hover->is_enabled( 'horizontal_offset', $props ),
'vertical' => $hover->is_enabled( 'vertical_offset', $props ),
);
$sticky_status = array(
'horizontal' => $sticky->is_inside_sticky_module() ? $sticky->is_enabled( 'horizontal_offset', $props ) : false,
'vertical' => $sticky->is_inside_sticky_module() ? $sticky->is_enabled( 'vertical_offset', $props ) : false,
);
if ( $resp_status['horizontal'] || $resp_status['vertical'] ) {
if ( ! isset( $position_origins['tablet'] ) ) {
$position_origins['tablet'] = $position_origins['desktop'];
}
if ( ! isset( $position_origins['phone'] ) ) {
$position_origins['phone'] = $position_origins['desktop'];
}
}
if ( ( $hover_status['horizontal'] || $hover_status['vertical'] ) && ! isset( $position_origins['hover'] ) ) {
$position_origins['hover'] = $position_origins['desktop'];
}
if ( ( $sticky_status['horizontal'] || $sticky_status['vertical'] ) && ! isset( $position_origins['sticky'] ) ) {
$position_origins['sticky'] = $position_origins['desktop'];
}
$this->module->set_position_locations( $position_origins );
foreach ( $position_origins as $type => $origin ) {
switch ( $type ) {
case 'hover':
$type_selector = $hover->add_hover_to_selectors( $position_selector );
break;
case 'sticky':
$type_selector = $sticky->add_sticky_to_selectors( $position_selector, false );
break;
default:
$type_selector = $position_selector;
break;
}
$active_origin = $origin;
$is_default_position = false;
$default_strpos = strpos( $origin, '_is_default' );
if ( $default_strpos !== false ) {
$is_default_position = true;
$active_origin = substr( $origin, 0, $default_strpos );
}
if ( 'none' === $active_origin ) {
if ( ! $is_default_position ) {
$el_style = array(
'selector' => $type_selector,
'declaration' => 'top:0px; right:auto; bottom:auto; left:0px;',
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
}
continue;
}
$offsets = array( 'vertical', 'horizontal' );
foreach ( $offsets as $offsetSlug ) {
$field_slug = "${offsetSlug}_offset";
$is_hover = 'hover' === $type && $hover_status[ $offsetSlug ];
$is_sticky = 'sticky' === $type;
$is_responsive = in_array( $type, array( 'tablet', 'phone' ) ) && $resp_status[ $offsetSlug ];
$offset_view = $is_hover || $is_sticky || $is_responsive ? $type : 'desktop';
$value = esc_attr( $this->get_value( $props, $field_slug, '0px', $offset_view, true ) );
if (
in_array( $offset_view, array( 'desktop', 'sticky' ), true )
&& $is_default_position
&& 'top_left' === $active_origin
&& '0px' === $value
) {
continue;
}
$origin_array = explode( '_', $active_origin );
$property = 'left';
$inverse_property = 'right';
if ( 'horizontal' === $offsetSlug ) {
if ( 'center' === $origin_array[1] ) {
$value = '50%';
} elseif ( 'right' === $origin_array[1] ) {
$property = 'right';
$inverse_property = 'left';
}
} else {
$property = 'top';
$inverse_property = 'bottom';
if ( 'center' === $origin_array[0] ) {
$value = '50%';
} elseif ( 'bottom' === $origin_array[0] ) {
$property = 'bottom';
$inverse_property = 'top';
}
}
// add the adminbar height offset to avoid overflow of fixed elements.
$active_position = $this->get_value( $props, 'positioning', $position_default, $type, true );
if ( 'top' === $property ) {
$admin_bar_declaration = "$property: $value";
if ( 'fixed' === $active_position ) {
$admin_bar_height = 'phone' === $type ? '46px' : '32px';
$admin_bar_declaration = "$property: calc($value + $admin_bar_height);";
}
if ( 'desktop' !== $type || 'fixed' === $active_position ) {
$el_style = array(
'selector' => "body.logged-in.admin-bar $type_selector",
'declaration' => $admin_bar_declaration,
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
}
}
if ( 'top' === $inverse_property && ( 'desktop' !== $type || 'fixed' === $active_position ) ) {
$el_style = array(
'selector' => "body.logged-in.admin-bar $type_selector",
'declaration' => "$inverse_property: auto",
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
}
$el_style = array(
'selector' => $type_selector,
'declaration' => "$property: $value;",
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
$el_style = array(
'selector' => $type_selector,
'declaration' => "$inverse_property: auto;",
'priority' => $this->module->get_style_priority(),
) + $this->get_media_query( $type );
ET_Builder_Element::set_style( $function_name, $el_style );
}
}
}
if ( $has_z_index && ( ! is_array( $position_config ) || ! $has_position ) ) {
// Backwards compatibility. Before this feature if z-index was set, position got defaulted as relative
$el_style = array(
'selector' => '%%order_class%%',
'declaration' => 'position: relative;',
'priority' => $this->module->get_style_priority(),
);
ET_Builder_Element::set_style( $function_name, $el_style );
}
}
/**
* Determine if Position Options are used.
*
* @since 4.10.0
*
* @param array $attrs Module attributes/props.
*
* @return bool
*/
public function is_used( $attrs ) {
foreach ( $attrs as $attr => $value ) {
if ( ! $value ) {
continue;
}
$is_attr = false !== strpos( $attr, 'z_index' )
|| false !== strpos( $attr, 'positioning' )
|| false !== strpos( $attr, 'position_origin' )
|| 'vertical_offset' === $attr
|| 'horizontal_offset' === $attr;
// Ignore default value.
if ( 'positioning' === $attr && 'relative' === $value ) {
continue;
}
// Ignore default value.
if ( ( 'position_origin_a' === $attr || 'position_origin_f' === $attr || 'position_origin_r' === $attr ) && 'top_left' === $value ) {
continue;
}
// Ignore default value.
if ( 'z_index' === $attr && 'auto' === $value ) {
continue;
}
if ( $is_attr ) {
return true;
}
}
return false;
}
}
return new ET_Builder_Module_Field_Position();

View File

@ -0,0 +1,191 @@
<?php
class ET_Builder_Module_Field_Scroll extends ET_Builder_Module_Field_Base {
/**
* Translations.
*
* @var array
*/
protected $i18n = array();
public function get_defaults() {
$i18n =& $this->i18n;
if ( ! isset( $i18n['defaults'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['defaults'] = array(
'label' => esc_html__( 'Scroll Transform Effects', 'et_builder' ),
'description' => esc_html__( 'Using Scrolling Effects, you can transform elements on your page as you scroll. The animation\'s transition is based on the user\'s scrolling behavior. Once the element enters the browser viewport (top), the animation begins, and it once it leaves the viewport (bottom), the animation ends.', 'et_builder' ),
);
// phpcs:enable
}
return array(
'prefix' => '',
'label' => $i18n['defaults']['label'],
'description' => $i18n['defaults']['description'],
'tab_slug' => 'custom_css',
'toggle_slug' => 'scroll_effects',
'options' => array(),
);
}
public function get_fields( array $args = array() ) {
$settings = array_merge( $this->get_defaults(), $args );
$prefix = $settings['prefix'];
$grid_support = $settings['grid_support'];
$name = et_builder_add_prefix( $prefix, 'scroll_effects' );
$grid_motion_toggle = array();
$i18n =& $this->i18n;
if ( ! isset( $i18n['grid'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['grid'] = array(
'label' => esc_html__( 'Apply Motion Effects To Child Elements', 'et_builder' ),
'description' => esc_html__( 'This applies motion effects to individual elements within the module rather than the module as a whole. For example, to each image within a Gallery, rather than the Gallery container.', 'et_builder' ),
);
$i18n['trigger'] = array(
'label' => esc_html__( 'Motion Effect Trigger', 'et_builder' ),
'description' => esc_html__( 'Here you can choose when motion effects are triggered: When the top of the element enters into view, when the middle of the element enters into view, or when the bottom of the element enters into view.', 'et_builder' ),
'options' => array(
'middle' => esc_html__( 'Middle of Element', 'et_builder' ),
'top' => esc_html__( 'Top of Element', 'et_builder' ),
'bottom' => esc_html__( 'Bottom of Element', 'et_builder' ),
),
);
// phpcs:enable
}
if ( 'yes' === $grid_support ) {
$grid_motion_toggle = array(
'enable_grid_motion' => array(
'label' => $i18n['grid']['label'],
'description' => $i18n['grid']['description'],
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default' => 'off',
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'bb_support' => false,
),
);
}
$motion_triggers = array(
'motion_trigger_start' => array(
'label' => $i18n['trigger']['label'],
'description' => $i18n['trigger']['description'],
'options' => array(
'middle' => $i18n['trigger']['options']['middle'],
'top' => $i18n['trigger']['options']['top'],
'bottom' => $i18n['trigger']['options']['bottom'],
),
'type' => 'select',
'option_category' => 'configuration',
'default' => 'middle',
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'bb_support' => false,
),
);
return array_merge(
$grid_motion_toggle,
array(
$name => array(
'label' => $settings['label'],
'description' => $settings['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'attr_suffix' => '',
'type' => 'composite',
'option_category' => 'layout',
'composite_type' => 'default',
'composite_structure' => $this->get_options( $settings['options'], $settings['tab_slug'], $settings['toggle_slug'], $prefix ),
'bb_support' => false,
),
),
$motion_triggers
);
}
private function get_options( array $options_settings, $tab, $toggle, $prefix = '' ) {
$options = array();
$i18n =& $this->i18n;
if ( ! isset( $i18n['options'] ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n['options'] = array(
'enable' => __( 'Enable %s', 'et_builder' ),
'set' => __( 'Set %s', 'et_builder' ),
'startTitle' => esc_html__( 'Viewport Bottom', 'et_builder' ),
'endTitle' => esc_html__( 'Viewport Top', 'et_builder' ),
'startValueTitle' => esc_html__( 'Starting', 'et_builder' ),
'middleValueTitle' => esc_html__( 'Mid', 'et_builder' ),
'endValueTitle' => esc_html__( 'Ending', 'et_builder' ),
);
// phpcs:enable
}
foreach ( $options_settings as $name => $settings ) {
$option_name = et_builder_add_prefix( $prefix, $name );
$icon = et_()->array_get( $settings, 'icon', '' );
$label = et_()->array_get( $settings, 'label', '' );
$description = et_()->array_get( $settings, 'description' );
$default = et_()->array_get( $settings, 'default' );
$resolver = et_()->array_get( $settings, 'resolver' );
$options[ $option_name ] = array(
'icon' => $icon,
'tooltip' => $label,
'controls' => array(
"{$option_name}_enable" => array(
'label' => et_esc_html_once( $i18n['options']['enable'], $label ),
'description' => et_esc_html_once( $description ),
'type' => 'yes_no_button',
'option_category' => 'configuration',
'options' => array(
'off' => et_builder_i18n( 'No' ),
'on' => et_builder_i18n( 'Yes' ),
),
'default' => 'off',
'tab_slug' => $tab,
'toggle_slug' => $toggle,
'main_tab_setting' => 'on',
),
$option_name => array(
'label' => et_esc_html_once( $i18n['options']['set'], $label ),
'description' => et_esc_html_once( $description ),
'type' => 'motion',
'default' => $default,
'tab_slug' => $tab,
'toggle_slug' => $toggle,
'mobile_options' => true,
'show_if' => array(
"{$option_name}_enable" => 'on',
),
'resolver' => $resolver,
'i10n' => array(
'startTitle' => $i18n['options']['startTitle'],
'endTitle' => $i18n['options']['endTitle'],
'startValueTitle' => et_()->array_get( $settings, 'startValueTitle', $i18n['options']['startValueTitle'] ),
'middleValueTitle' => et_()->array_get( $settings, 'middleValueTitle', $i18n['options']['middleValueTitle'] ),
'endValueTitle' => et_()->array_get( $settings, 'endValueTitle', $i18n['options']['endValueTitle'] ),
),
),
),
);
}
return $options;
}
}
return new ET_Builder_Module_Field_Scroll();

View File

@ -0,0 +1,285 @@
<?php
/**
* Field definition for sticky elements feature.
*
* @package Divi
* @sub-package Builder
* @since 4.6.0
*/
/**
* Sticky field class.
*
* @since 4.6.0
*/
class ET_Builder_Module_Field_Sticky extends ET_Builder_Module_Field_Base {
/**
* Default sticky element field attributes (prefix, tab, and toggle).
*
* @var array Default sticky element field attributes.
*/
protected $defaults = array(
'prefix' => 'sticky',
'tab_slug' => 'custom_css',
'toggle_slug' => 'scroll_effects',
);
/**
* Retrieves default settings for sticky fields.
*
* @since 4.6.0
*
* @return array $settings Default settings.
*/
public function get_defaults() {
return $this->defaults;
}
/**
* Retrieves default value of specific field settings
*
* @since 4.6.0
*
* @param string $name Default name.
* @param string $default Default's default value.
*
* @return mixed
*/
public function get_default( $name = '', $default = '' ) {
return et_()->array_get( $this->defaults, $name, $default );
}
/**
* Retrieves fields for sticky settings.
*
* @since 4.6.0
*
* @param array $args Associative array for settings.
*
* @return array $fields Option settings.
*/
public function get_fields( array $args = array() ) {
static $i18n;
// Cache translations.
if ( ! isset( $i18n ) ) {
$i18n = array(
'position' => array(
'label' => esc_html__( 'Sticky Position', 'et_builder' ),
'description' => esc_html__( 'Choose to have this element remain a fixed distance from the top or bottom edge of the browser window as the user scrolls', 'et_builder' ),
'options' => array(
'do_not_sticky' => esc_html__( 'Do Not Stick', 'et_builder' ),
'sticky_to_top' => esc_html__( 'Stick to Top', 'et_builder' ),
'stick_to_bottom' => esc_html__( 'Stick to Bottom', 'et_builder' ),
'stick_to_top_bottom' => esc_html__( 'Stick to Top and Bottom', 'et_builder' ),
),
),
'offset_top' => array(
'label' => esc_html__( 'Sticky Top Offset', 'et_builder' ),
'description' => esc_html__( 'Define the vertical offset distance from the top edge of the browser window', 'et_builder' ),
),
'offset_bottom' => array(
'label' => esc_html__( 'Sticky Bottom Offset', 'et_builder' ),
'description' => esc_html__( 'Define the vertical offset distance from the bottom edge of the browser window', 'et_builder' ),
),
'limit_top' => array(
'label' => esc_html__( 'Top Sticky Limit', 'et_builder' ),
'description' => esc_html__( 'If defined, this element will stick to the top of this container, overriding its stickiness edge of the browser', 'et_builder' ),
),
'limit_bottom' => array(
'label' => esc_html__( 'Bottom Sticky Limit', 'et_builder' ),
'description' => esc_html__( 'If defined, this element will stick to the bottom of this container, overriding its stickiness to the edge of the browser', 'et_builder' ),
),
'offset_surrounding' => array(
'label' => esc_html__( 'Offset From Surrounding Sticky Elements', 'et_builder' ),
'description' => esc_html__( 'Apply “Sticky Offset” to the nearest Sticky Element above or below this element', 'et_builder' ),
),
'transition' => array(
'label' => esc_html__( 'Transition Default and Sticky Styles', 'et_builder' ),
'description' => esc_html__( 'Enabled animated transitions between default and sticky styles when the element becomes “stuck”', 'et_builder' ),
),
);
}
$settings = array_merge( $this->get_defaults(), $args );
$prefix = $settings['prefix'];
return array(
"{$prefix}_position" => array(
'label' => $i18n['position']['label'],
'description' => $i18n['position']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'select',
'options' => array(
'none' => $i18n['position']['options']['do_not_sticky'],
'top' => $i18n['position']['options']['sticky_to_top'],
'bottom' => $i18n['position']['options']['stick_to_bottom'],
'top_bottom' => $i18n['position']['options']['stick_to_top_bottom'],
),
'default' => 'none',
'option_category' => 'layout',
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_offset_top" => array(
'label' => $i18n['offset_top']['label'],
'description' => $i18n['offset_top']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'range',
'range_settings' => array(
'min' => 0,
'max' => 400,
'step' => 1,
),
'default' => '0px',
'show_if_not' => array(
"{$prefix}_position" => array( 'none', 'bottom' ),
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_offset_bottom" => array(
'label' => $i18n['offset_bottom']['label'],
'description' => $i18n['offset_bottom']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'range',
'range_settings' => array(
'min' => 0,
'max' => 400,
'step' => 1,
),
'default' => '0px',
'show_if_not' => array(
"{$prefix}_position" => array( 'none', 'top' ),
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_limit_top" => array(
'label' => $i18n['limit_top']['label'],
'description' => $i18n['limit_top']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'select',
'options' => $this->get_limit_options( $settings['module_slug'] ),
'default' => 'none',
'depends_show_if_not' => array( 'top', 'none' ),
'depends_on' => array(
"{$prefix}_position",
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_limit_bottom" => array(
'label' => $i18n['limit_bottom']['label'],
'description' => $i18n['limit_bottom']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'select',
'options' => $this->get_limit_options( $settings['module_slug'] ),
'default' => 'none',
'depends_show_if_not' => array( 'bottom', 'none' ),
'depends_on' => array(
"{$prefix}_position",
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_offset_surrounding" => array(
'label' => $i18n['offset_surrounding']['label'],
'description' => $i18n['offset_surrounding']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'yes_no_button',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default' => 'on',
'show_if_not' => array(
"{$prefix}_position" => 'none',
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
"{$prefix}_transition" => array(
'label' => $i18n['transition']['label'],
'description' => $i18n['transition']['description'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'yes_no_button',
'options' => array(
'on' => et_builder_i18n( 'Yes' ),
'off' => et_builder_i18n( 'No' ),
),
'default' => 'on',
'show_if_not' => array(
"{$prefix}_position" => 'none',
),
'responsive' => true,
'mobile_options' => true,
'bb_support' => false,
),
);
}
/**
* Get limit position options based on Element Type.
*
* @since 4.6.0
*
* @param string $module_slug Module Slug.
*
* @return array $options Limit options.
*/
private function get_limit_options( $module_slug ) {
static $i18n;
// Cache translations.
if ( ! isset( $i18n ) ) {
$i18n = array(
'none' => esc_html__( 'None', 'et_builder' ),
'body' => esc_html__( 'Body Area', 'et_builder' ),
'section' => esc_html__( 'Section', 'et_builder' ),
'row' => esc_html__( 'Row', 'et_builder' ),
'column' => esc_html__( 'Column', 'et_builder' ),
);
}
$options = array(
'none' => $i18n['none'],
'body' => $i18n['body'],
'section' => $i18n['section'],
'row' => $i18n['row'],
'column' => $i18n['column'],
);
if ( 'et_pb_column' === $module_slug ) {
unset( $options['column'] );
}
if ( 'et_pb_row' === $module_slug ) {
unset( $options['column'] );
unset( $options['row'] );
}
if ( 'et_pb_section' === $module_slug ) {
unset( $options['column'] );
unset( $options['row'] );
unset( $options['section'] );
}
return $options;
}
}
return new ET_Builder_Module_Field_Sticky();

View File

@ -0,0 +1,777 @@
<?php
class ET_Builder_Module_Field_TextShadow extends ET_Builder_Module_Field_Base {
/**
* True when Divi plugin is active.
*
* @var bool
*/
public $is_plugin_active = false;
/**
* Text shadow properties.
*
* @var array
*/
public $properties;
protected $template;
/**
* Constructor.
*/
public function __construct() {
$this->template = et_pb_option_template();
$this->is_plugin_active = et_is_builder_plugin_active();
$this->properties = array(
'horizontal_length',
'vertical_length',
'blur_strength',
'color',
);
$this->set_template();
}//end __construct()
/**
* Returns prefixed field names.
*
* @param string $prefix Prefix.
*
* @return array
*/
public function get_prefixed_field_names( $prefix ) {
$prefix = $prefix ? "{$prefix}_" : '';
return array(
"{$prefix}text_shadow_style",
"{$prefix}text_shadow_horizontal_length",
"{$prefix}text_shadow_vertical_length",
"{$prefix}text_shadow_blur_strength",
"{$prefix}text_shadow_color",
);
}//end get_prefixed_field_names()
/**
* Returns Text Shadow presets.
*
* @param string $prefix Prefix.
*
* @return array
*/
public function get_presets( $prefix, $suffix = '' ) {
list(
$text_shadow_style,
$text_shadow_horizontal_length,
$text_shadow_vertical_length,
$text_shadow_blur_strength,
$text_shadow_color
) = $this->get_prefixed_field_names( $prefix );
return array(
array(
'icon' => 'none',
'value' => 'none',
),
array(
'value' => 'preset1',
'content' => array(
'content' => 'aA',
'class' => 'preset preset1',
),
'fields' => array(
$text_shadow_horizontal_length => '0em',
$text_shadow_vertical_length => '0.1em',
$text_shadow_blur_strength => '0.1em',
),
),
array(
'value' => 'preset2',
'content' => array(
'content' => 'aA',
'class' => 'preset preset2',
),
'fields' => array(
$text_shadow_horizontal_length => '0.08em',
$text_shadow_vertical_length => '0.08em',
$text_shadow_blur_strength => '0.08em',
),
),
array(
'value' => 'preset3',
'content' => array(
'content' => 'aA',
'class' => 'preset preset3',
),
'fields' => array(
$text_shadow_horizontal_length => '0em',
$text_shadow_vertical_length => '0em',
$text_shadow_blur_strength => '0.3em',
),
),
array(
'value' => 'preset4',
'content' => array(
'content' => 'aA',
'class' => 'preset preset4',
),
'fields' => array(
$text_shadow_horizontal_length => '0em',
$text_shadow_vertical_length => '0.08em',
$text_shadow_blur_strength => '0em',
),
),
array(
'value' => 'preset5',
'content' => array(
'content' => 'aA',
'class' => 'preset preset5',
),
'fields' => array(
$text_shadow_horizontal_length => '0.08em',
$text_shadow_vertical_length => '0.08em',
$text_shadow_blur_strength => '0em',
),
),
);
}//end get_presets()
/**
* Returns conditional defaults array.
*
* @param string $prefix Prefix.
* @param string $depend Field whose value controls which default should be used.
* @param string $field Field for which we're generating the defaults array.
* @param string $default Default value to be used when a Preset doesn't include a value for $field.
*
* @return array
*/
public function get_defaults( $prefix, $depend, $field, $default ) {
$presets = $this->get_presets( $prefix );
$defaults = array();
foreach ( $presets as $preset ) {
$value = $preset['value'];
$defaults[ $value ] = isset( $preset['fields'][ $field ] ) ? $preset['fields'][ $field ] : $default;
}
return array(
$depend,
$defaults,
);
}//end get_defaults()
/**
* Set option template for Text Shadow
*
* @since 3.28
*
* @return void
*/
public function set_template() {
$template = $this->template;
if ( $template->is_enabled() && ! $template->has( 'text_shadow' ) ) {
$template_placeholder = $template->placeholders(
array(
'label' => null,
'prefix' => null,
'tab_slug' => null,
'toggle_slug' => null,
'sub_toggle' => null,
'option_category' => null,
'depends_show_if' => null,
'depends_show_if_not' => null,
'show_if' => null,
'show_if_not' => null,
)
);
$template->add( 'text_shadow', $this->get_fields( $template_placeholder ) );
}
}
/**
* Returns fields definition.
*
* @since 3.23 Add mobile_options attributes for all fields to support responsive settings, except
* text_shadow_style. Add allowed units for some fields with range type.
*
* @param array $args Field configuration.
*
* @return array
*/
public function get_fields( array $args = array() ) {
$config = shortcode_atts(
array(
'label' => '',
'prefix' => '',
'tab_slug' => 'advanced',
'toggle_slug' => 'text',
'sub_toggle' => false,
'option_category' => 'configuration',
'depends_show_if' => '',
'depends_show_if_not' => '',
'show_if' => '',
'show_if_not' => '',
),
$args
);
if ( $this->template->is_enabled() && $this->template->has( 'text_shadow' ) ) {
return $this->template->create( 'text_shadow', $config );
}
$prefix = $config['prefix'];
list(
$text_shadow_style,
$text_shadow_horizontal_length,
$text_shadow_vertical_length,
$text_shadow_blur_strength,
$text_shadow_color
) = $this->get_prefixed_field_names( $prefix );
$tab_slug = $config['tab_slug'];
$toggle_slug = $config['toggle_slug'];
$sub_toggle = $config['sub_toggle'];
$option_category = $config['option_category'];
// Some option categories (like font) have custom logic that involves changing default values and we don't want that to interfere with conditional defaults. This might change in future so, for now, I'm just overriding the value while leaving the possibility to remove this line afterwards and provide custom option_category via $config.
$option_category = 'configuration';
$label = $config['label'];
if ( $label ) {
$labels = array(
// translators: text shadow group label
sprintf( esc_html__( '%1$s Text Shadow', 'et_builder' ), $label ),
// translators: text shadow group label
sprintf( esc_html__( '%1$s Text Shadow Horizontal Length', 'et_builder' ), $label ),
// translators: text shadow group label
sprintf( esc_html__( '%1$s Text Shadow Vertical Length', 'et_builder' ), $label ),
// translators: text shadow group label
sprintf( esc_html__( '%1$s Text Shadow Blur Strength', 'et_builder' ), $label ),
// translators: text shadow group label
sprintf( esc_html__( '%1$s Text Shadow Color', 'et_builder' ), $label ),
);
} else {
$labels = array(
esc_html__( 'Text Shadow', 'et_builder' ),
esc_html__( 'Text Shadow Horizontal Length', 'et_builder' ),
esc_html__( 'Text Shadow Vertical Length', 'et_builder' ),
esc_html__( 'Text Shadow Blur Strength', 'et_builder' ),
esc_html__( 'Text Shadow Color', 'et_builder' ),
);
}
$fields = array(
$text_shadow_style => array(
'label' => $labels[0],
'description' => esc_html__( 'Pick a text shadow style to enable text shadow for this element. Once enabled, you will be able to customize your text shadow style further. To disable custom text shadow style, choose the None option.', 'et_builder' ),
'type' => 'presets_shadow',
'option_category' => $option_category,
'default' => 'none',
'default_on_child' => true,
'presets' => $this->get_presets( $prefix ),
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'sync_affects' => array(
$text_shadow_horizontal_length,
$text_shadow_vertical_length,
$text_shadow_blur_strength,
$text_shadow_color,
),
'affects' => array(
$text_shadow_horizontal_length,
$text_shadow_vertical_length,
$text_shadow_blur_strength,
$text_shadow_color,
),
'copy_with' => array(
$text_shadow_horizontal_length,
$text_shadow_vertical_length,
$text_shadow_blur_strength,
$text_shadow_color,
),
),
$text_shadow_horizontal_length => array(
'label' => $labels[1],
'description' => esc_html__( 'Shadow\'s horizontal distance from the text. A negative value places the shadow to the left of the text.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'option_category' => $option_category,
'range_settings' => array(
'min' => -2,
'max' => 2,
'step' => 0.01,
),
'default' => $this->get_defaults( $prefix, $text_shadow_style, $text_shadow_horizontal_length, '0em' ),
'default_on_child' => true,
'hide_sync' => true,
'validate_unit' => true,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'em',
'fixed_range' => true,
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'depends_show_if_not' => 'none',
'mobile_options' => true,
'sticky' => true,
),
$text_shadow_vertical_length => array(
'label' => $labels[2],
'description' => esc_html__( 'Shadow\'s vertical distance from the text. A negative value places the shadow above the text.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'option_category' => $option_category,
'range_settings' => array(
'min' => -2,
'max' => 2,
'step' => 0.01,
),
'default' => $this->get_defaults( $prefix, $text_shadow_style, $text_shadow_vertical_length, '0em' ),
'default_on_child' => true,
'hide_sync' => true,
'validate_unit' => true,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'em',
'fixed_range' => true,
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'depends_show_if_not' => 'none',
'mobile_options' => true,
'sticky' => true,
),
$text_shadow_blur_strength => array(
'label' => $labels[3],
'description' => esc_html__( 'The higher the value, the bigger the blur, the shadow becomes wider and lighter.', 'et_builder' ),
'type' => 'range',
'hover' => 'tabs',
'option_category' => $option_category,
'range_settings' => array(
'min' => 0,
'max' => 2,
'step' => 0.01,
),
'default' => $this->get_defaults( $prefix, $text_shadow_style, $text_shadow_blur_strength, '0em' ),
'default_on_child' => true,
'hide_sync' => true,
'validate_unit' => true,
'allowed_units' => array( 'em', 'rem', 'px', 'cm', 'mm', 'in', 'pt', 'pc', 'ex', 'vh', 'vw' ),
'default_unit' => 'em',
'fixed_range' => true,
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'depends_show_if_not' => 'none',
'mobile_options' => true,
'sticky' => true,
),
$text_shadow_color => array(
'label' => $labels[4],
'description' => esc_html__( 'The color of the shadow.', 'et_builder' ),
'type' => 'color-alpha',
'hover' => 'tabs',
'option_category' => $option_category,
'default' => 'rgba(0,0,0,0.4)',
'default_on_child' => true,
'hide_sync' => true,
'tab_slug' => $tab_slug,
'toggle_slug' => $toggle_slug,
'depends_show_if_not' => 'none',
'mobile_options' => true,
'sticky' => true,
),
);
// Only add sub_toggle to fields if defined
if ( false !== $sub_toggle ) {
$fields[ $text_shadow_style ]['sub_toggle'] = $sub_toggle;
$fields[ $text_shadow_vertical_length ]['sub_toggle'] = $sub_toggle;
$fields[ $text_shadow_horizontal_length ]['sub_toggle'] = $sub_toggle;
$fields[ $text_shadow_blur_strength ]['sub_toggle'] = $sub_toggle;
$fields[ $text_shadow_color ]['sub_toggle'] = $sub_toggle;
}
// add conditional settings if defined
if ( '' !== $config['show_if'] ) {
$fields[ $text_shadow_style ]['show_if'] = $config['show_if'];
}
if ( '' !== $config['show_if_not'] ) {
$fields[ $text_shadow_style ]['show_if_not'] = $config['show_if_not'];
}
if ( '' !== $config['depends_show_if'] ) {
$fields[ $text_shadow_style ]['depends_show_if'] = $config['depends_show_if'];
}
if ( '' !== $config['depends_show_if_not'] ) {
$fields[ $text_shadow_style ]['depends_show_if_not'] = $config['depends_show_if_not'];
}
return $fields;
}//end get_fields()
/**
* Returns whether a declaration should be added !important or not.
*
* @param array $options Field definition.
* @param string $key Property name.
*
* @return bool
*/
public function get_important( $options, $key = false ) {
if ( ! isset( $options['css']['important'] ) ) {
// nothing to do, bye
return false;
}
$important = $options['css']['important'];
if ( 'all' === $important || ( $this->is_plugin_active && 'plugin_only' === $important ) ) {
return true;
}
if ( is_array( $important ) ) {
if ( $this->is_plugin_active && in_array( 'plugin_all', $important ) ) {
return true;
}
if ( false !== $key && in_array( $key, $important ) ) {
return true;
}
}
return false;
}//end get_important()
/**
* Returns the text-shadow declaration
*
* @since 3.23 Add responsive settings support to get the correct tablet and phone values.
*
* @param string $label Prefix.
* @param bool $important Whether to add !important or not.
* @param array $all_values All shortcode values.
* @param bool $is_hover Hover status.
* @param string $device Current active device.
*
* @return string
*/
public function get_declaration( $label, $important, $all_values, $is_hover = false, $device = 'desktop' ) {
$prefix = $label ? "{$label}_" : '';
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
$utils = ET_Core_Data_Utils::instance();
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$is_desktop = 'desktop' === $device;
$is_sticky = $sticky->get_suffix() === $device;
$suffix = '';
// Responsive styles. Ensure to render when at least one of the fields activate responsive
// settings to avoid unnecessary CSS styles rendered.
$is_any_shadow_responsive = false;
if ( ! $is_desktop && ! $is_hover && ! $is_sticky ) {
$is_any_shadow_responsive = $responsive->is_any_responsive_enabled(
$all_values,
array(
"{$prefix}text_shadow_horizontal_length",
"{$prefix}text_shadow_vertical_length",
"{$prefix}text_shadow_blur_strength",
"{$prefix}text_shadow_color",
)
);
// Bail early
if ( ! $is_any_shadow_responsive ) {
return '';
}
$suffix = "_{$device}";
}
$text_shadow = array();
foreach ( $this->properties as $property ) {
// As default, we will return desktop value.
$prop = "{$prefix}text_shadow_{$property}";
$value = et_()->array_get( $all_values, $prop, '' );
if ( $is_any_shadow_responsive ) {
// If current device is mobile (responsive settings is enabled already checked above),
// return any value exist.
$value = $responsive->is_responsive_enabled( $all_values, $prop ) ? $responsive->get_any_value( $all_values, "{$prop}{$suffix}", '', true ) : $value;
} elseif ( $is_hover ) {
$value = $hover->get_value( $prop, $all_values, $value );
} elseif ( $is_sticky ) {
$value = $sticky->get_value( $prop, $all_values, $value );
}
$text_shadow[] = $value;
}
return sprintf(
'text-shadow: %s%s;',
et_core_esc_previously( join( ' ', array_filter( $text_shadow ) ) ),
$important ? '!important' : ''
);
}//end get_declaration()
/**
* Adds CSS rule.
*
* @since 3.23 Add responsive settings support to render tablet and phone styles.
*
* @param ET_Builder_Element $module Module object.
* @param string $label Label.
* @param array $font Field definition.
* @param string $function_name Shortcode function.
* @param bool $is_hover Hover status.
* @param string $device Current active device.
*
* @return void
*/
public function update_styles( $module, $label, $font, $function_name, $is_hover = false, $device = 'desktop' ) {
$all_values = $module->props;
$main_element_selector = $module->main_css_element;
$device = '' === $device ? 'desktop' : $device;
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
$is_sticky = $device === $sticky->get_suffix();
// Use a different selector for plugin
$css_element = $this->is_plugin_active && isset( $font['css']['limited_main'] ) ? 'css.limited_main' : 'css.main';
// Use 'text_shadow' selector if defined, fallback to $css_element or default selector
$selector = et_()->array_get(
$font,
'css.text_shadow',
et_()->array_get( $font, $css_element, $main_element_selector )
);
$responsive_selector = $selector;
if ( $is_hover ) {
if ( is_array( $selector ) ) {
$selector = array_map( array( $this, 'add_hover_to_selectors' ), $selector );
} else {
$selector = $hover->add_hover_to_selectors( $selector );
}
$selector = et_()->array_get( $font, 'css.text_shadow_hover', et_()->array_get( $font, 'css.hover', $selector ) );
}
if ( $is_sticky ) {
$has_wrapper = et_()->array_get( $module->wrapper_settings, 'order_class_wrapper', false );
$is_sticky_module_without_wrapper = $has_wrapper ? false : $sticky->is_sticky_module( $all_values );
$selector = $sticky->add_sticky_to_selectors( $selector, $is_sticky_module_without_wrapper, is_string( $selector ) );
$selector = et_()->array_get( $font, 'css.text_shadow_sticky', et_()->array_get( $font, 'css.sticky', $selector ) );
}
// Get the text-shadow declaration (horizontal vertical blur color).
$declaration = $this->get_declaration(
$label,
$this->get_important( $font, 'text-shadow' ),
$all_values,
$is_hover,
$device
);
// Do not provide hover or sticky style if it is the same as normal style.
if ( $is_hover || $is_sticky ) {
$normal = $this->get_declaration(
$label,
$this->get_important( $font, 'text-shadow' ),
$all_values,
false
);
if ( $declaration === $normal ) {
return;
}
}
// Media query.
$media_query = array();
if ( 'desktop' !== $device && ! $is_hover && ! $is_sticky ) {
$breakpoint = 'tablet' === $device ? 'max_width_980' : 'max_width_767';
$media_query = array( 'media_query' => ET_Builder_Element::get_media_query( $breakpoint ) );
}
if ( is_array( $selector ) ) {
foreach ( $selector as $single_selector ) {
ET_Builder_Element::set_style(
$function_name,
array_merge(
array(
'selector' => $single_selector,
'declaration' => $declaration,
'priority' => $module->get_style_priority(),
),
$media_query
)
);
}
} else {
ET_Builder_Element::set_style(
$function_name,
array_merge(
array(
'selector' => $selector,
'declaration' => $declaration,
'priority' => $module->get_style_priority(),
),
$media_query
)
);
}
}//end update_styles()
/**
* Added to fix array_map can't access static class of Hover Options.
*
* @since 3.23
*
* @param string $selector Current selector.
*
* @return string Updated selector with hover suffix.
*/
private function add_hover_to_selectors( $selector ) {
return et_pb_hover_options()->add_hover_to_selectors( $selector );
}
/**
* Process Text Shadow options and adds CSS rules.
*
* @since 4.6.0 Add sticky style support
*
* @param ET_Builder_Element $module Module object.
* @param string $function_name Shortcode function.
*
* @return void
*/
public function process_advanced_css( $module, $function_name ) {
$all_values = $module->props;
$advanced_fields = $module->advanced_fields;
$hover = et_pb_hover_options();
$sticky = et_pb_sticky_options();
// Disable if module doesn't set advanced_fields property and has no VB support
if ( ! $module->has_vb_support() && ! $module->has_advanced_fields ) {
return;
}
$suffixes = array( '', 'tablet', 'phone', $hover->get_suffix(), $sticky->get_suffix() );
foreach ( $suffixes as $suffix ) {
$is_hover = $hover->get_suffix() === $suffix;
$is_sticky = $sticky->get_suffix() === $suffix;
// Check for text shadow settings in font-options
if ( ! empty( $advanced_fields['fonts'] ) ) {
// We have a 'fonts' section, fetch its values
foreach ( $advanced_fields['fonts'] as $label => $font ) {
// label can be header / body / toggle / etc
$shadow_style = "{$label}_text_shadow_style";
if ( 'none' !== et_()->array_get( $all_values, $shadow_style, 'none' ) ) {
// We have a preset selected which isn't none, need to add text-shadow style
$this->update_styles( $module, $label, $font, $function_name, $is_hover, $suffix );
}
}
}
// Check for text shadow settings in Advanced/Text toggle
if ( isset( $advanced_fields['text'] ) && 'none' !== et_()->array_get( $all_values, 'text_shadow_style', 'none' ) ) {
// We have a preset selected which isn't none, need to add text-shadow style
$text = $advanced_fields['text'];
$this->update_styles( $module, '', $text, $function_name, $is_hover, $suffix );
}
// Check for text shadow settings in Advanced/Fields toggle
if ( isset( $advanced_fields['fields'] ) && 'none' !== et_()->array_get( $all_values, 'fields_text_shadow_style', 'none' ) ) {
// We have a preset selected which isn't none, need to add text-shadow style
$fields = $advanced_fields['fields'];
$this->update_styles( $module, 'fields', $fields, $function_name, $is_hover, $suffix );
}
// Check for text shadow settings in Advanced/Button toggle
if ( ! empty( $advanced_fields['button'] ) ) {
// We have a 'button' section, fetch its values
foreach ( $advanced_fields['button'] as $label => $button ) {
// label can be header / body / toggle / etc
$shadow_style = "{$label}_text_shadow_style";
if ( 'none' !== et_()->array_get( $all_values, $shadow_style, 'none' ) ) {
// We have a preset selected which isn't none, need to add text-shadow style
// Build a selector to only target the button
$css_element = et_()->array_get( $button, 'css.main', "{$module->main_css_element} .et_pb_button" );
// Make sure it has highest priority
et_()->array_set( $button, 'css.text_shadow', $css_element );
if ( ! isset( $button['css.hover'] ) ) {
et_()->array_set( $button, 'css.hover', $hover->add_hover_to_selectors( $css_element ) );
}
$this->update_styles( $module, $label, $button, $function_name, $is_hover, $suffix );
}
}
}
// Check for text shadow settings in Advanced/Fields Input toggle
if ( ! empty( $advanced_fields['form_field'] ) ) {
// There are possibilities to have more than one field inputs.
foreach ( $advanced_fields['form_field'] as $label => $form_field ) {
// Ensure the text shadow style is selected before updating the styles.
if ( 'none' !== et_()->array_get( $all_values, $label . '_text_shadow_style', 'none' ) ) {
// Build a selector to only target the field input.
$main_selector = isset( $form_field['css']['main'] ) ? $form_field['css']['main'] : "{$module->main_css_element} .input";
$text_shadow_selector = isset( $form_field['css']['text_shadow'] ) ? $form_field['css']['text_shadow'] : $main_selector;
$text_shadow_hover_selector = isset( $form_field['css']['text_shadow_hover'] ) ? $form_field['css']['text_shadow_hover'] : $hover->add_hover_to_selectors( $text_shadow_selector );
// Make sure it has highest priority.
$form_field['css']['text_shadow'] = $text_shadow_selector;
$form_field['css']['text_shadow_hover'] = $text_shadow_hover_selector;
// Check and override important status.
if ( ! empty( $form_field['css']['important'] ) ) {
$form_field_important = $form_field['css']['important'];
if ( ! empty( $form_field_important['font'] ) ) {
$form_field['css']['important'] = $form_field_important['font'];
}
if ( ! empty( $form_field_important['text_shadow'] ) ) {
$form_field['css']['important'] = $form_field_important['text_shadow'];
}
}
$this->update_styles( $module, $label, $form_field, $function_name, $is_hover, $suffix );
}
}
}
}
}//end process_advanced_css()
/**
* Determine if Text Shadow is used.
*
* @since 4.10.0
*
* @param array $attrs Module attributes/props.
*
* @return bool
*/
public function is_used( $attrs ) {
foreach ( $attrs as $attr => $value ) {
if ( ! $value ) {
continue;
}
$is_attr = false !== strpos( $attr, 'text_shadow_' );
if ( $is_attr ) {
return true;
}
}
return false;
}
}
return new ET_Builder_Module_Field_TextShadow();

View File

@ -0,0 +1,651 @@
<?php
class ET_Builder_Module_Field_Transform extends ET_Builder_Module_Field_Base {
private $processing_props = array();
public $defaults = array(
'scale' => '100%',
'translate' => '0px',
'rotate' => '0deg',
'skew' => '0deg',
'origin' => '50%',
);
public $allTransforms = array(
'scaleX',
'scaleY',
'translateX',
'translateY',
'rotateX',
'rotateY',
'rotateZ',
'skewX',
'skewY',
'originX',
'originY',
);
public function get_fields( array $args = array() ) {
static $i18n;
if ( ! isset( $i18n ) ) {
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
$i18n = array(
'scale' => array(
'label' => esc_html__( 'Transform Scale', 'et_builder' ),
),
'translate' => array(
'label' => esc_html__( 'Transform Translate', 'et_builder' ),
),
'rotate' => array(
'label' => esc_html__( 'Transform Rotate', 'et_builder' ),
),
'skew' => array(
'label' => esc_html__( 'Transform Skew', 'et_builder' ),
),
'origin' => array(
'label' => esc_html__( 'Transform Origin', 'et_builder' ),
),
'styles' => array(
'label' => esc_html__( 'Transform', 'et_builder' ),
'description' => esc_html__( 'Using the transform controls, you can performance visual adjustments to any element using a combination of Scale, Translation, Rotation and Skew settings. This allows you to create advanced design effects without the need of a separate graphic design program.', 'et_builder' ),
),
);
// phpcs:enable
}
$settings_args = array(
'option_category' => 'layout',
'tab_slug' => 'advanced',
'toggle_slug' => 'transform',
'depends_on' => null,
'depends_show_if' => null,
'defaults' => $this->defaults,
);
$settings = wp_parse_args( $settings_args, $args );
$additional_options = array();
$defaults = $settings['defaults'];
$tabs = array(
'scale' => array(
'icon' => 'resize',
'controls' => array(
'transform_scale' => array(
'type' => 'transform',
'label' => $i18n['scale']['label'],
'default' => "${defaults['scale']}|${defaults['scale']}",
'default_unit' => '%',
'range_settings' => array(
'min' => -100,
'max' => 300,
'step' => 1,
),
'context' => 'transform_styles',
'mobile_options' => true,
'sticky' => true,
),
),
),
'translate' => array(
'icon' => 'move',
'controls' => array(
'transform_translate' => array(
'type' => 'transform',
'label' => $i18n['translate']['label'],
'default' => "${defaults['translate']}|${defaults['translate']}",
'default_unit' => 'px',
'range_settings' => array(
'min' => -300,
'max' => 300,
'step' => 1,
),
'context' => 'transform_styles',
'mobile_options' => true,
'sticky' => true,
),
),
),
'rotate' => array(
'icon' => 'rotate',
'controls' => array(
'transform_rotate' => array(
'type' => 'transform',
'label' => $i18n['rotate']['label'],
'default' => "${defaults['rotate']}|${defaults['rotate']}|${defaults['rotate']}",
'default_unit' => 'deg',
'range_settings' => array(
'min' => 0,
'max' => 360,
'step' => 1,
),
'context' => 'transform_styles',
'mobile_options' => true,
'sticky' => true,
),
),
),
'skew' => array(
'icon' => 'skew',
'controls' => array(
'transform_skew' => array(
'type' => 'transform',
'label' => $i18n['skew']['label'],
'default' => "${defaults['skew']}|${defaults['skew']}",
'default_unit' => 'deg',
'range_settings' => array(
'min' => -180,
'max' => 180,
'min_limit' => -180,
'max_limit' => 180,
'step' => 1,
),
'context' => 'transform_styles',
'mobile_options' => true,
'sticky' => true,
),
),
),
'origin' => array(
'icon' => 'transform-origin',
'controls' => array(
'transform_origin' => array(
'type' => 'transform',
'label' => $i18n['origin']['label'],
'default' => "${defaults['origin']}|${defaults['origin']}",
'default_unit' => '%',
'range_settings' => array(
'min' => -50,
'max' => 150,
'step' => 1,
),
'context' => 'transform_styles',
'mobile_options' => true,
'sticky' => true,
),
),
),
);
$additional_options['transform_styles'] = array(
'label' => $i18n['styles']['label'],
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
'type' => 'composite',
'attr_suffix' => '',
'composite_type' => 'transforms',
'hover' => 'tabs',
'mobile_options' => true,
'sticky' => true,
'responsive' => true,
'bb_support' => false,
'description' => $i18n['styles']['description'],
'composite_structure' => $tabs,
);
// Register responsive options
$skip = array(
'type' => 'skip',
'tab_slug' => $settings['tab_slug'],
'toggle_slug' => $settings['toggle_slug'],
);
$linked_skip = $skip + array( 'default' => 'on' );
foreach ( $additional_options['transform_styles']['composite_structure'] as $tab_name => $tab ) {
foreach ( $tab['controls'] as $field_name => $field_options ) {
$controls = $additional_options['transform_styles']['composite_structure'][ $tab_name ]['controls'];
$controls[ "${field_name}_tablet" ] = $skip;
$controls[ "${field_name}_phone" ] = $skip;
$controls[ "${field_name}_last_edited" ] = $skip;
if ( in_array( $field_name, array( 'transform_scale', 'transform_translate', 'transform_skew' ) ) ) {
$controls[ "${field_name}_linked" ] = $linked_skip;
$controls[ "${field_name}_linked_tablet" ] = $linked_skip;
$controls[ "${field_name}_linked_phone" ] = $linked_skip;
$controls[ "${field_name}_linked__hover" ] = $linked_skip;
$controls[ "${field_name}_linked__sticky" ] = $linked_skip;
}
$additional_options['transform_styles']['composite_structure'][ $tab_name ]['controls'] = $controls;
}
}
$additional_options['transform_styles_last_edited'] = $skip;
return $additional_options;
}
// Processing functions
public function percent_to_unit( $percent = 0 ) {
if ( strpos( $percent, '%' ) === false ) {
return $percent;
}
$value = (float) trim( str_replace( '%', '', $percent ) );
return $value / 100;
}
public function set_props( $props ) {
$this->processing_props = $props;
}
public function get_setting( $value, $default ) {
if ( ! empty( $this->processing_props[ $value ] ) ) {
return $this->processing_props[ $value ];
} else {
return $default;
}
}
public function get_option( $typeAxis, $type = 'desktop' ) {
$setting = "transform_$typeAxis[0]";
$interpreter = array(
'X' => 0,
'Y' => 1,
'Z' => 2,
);
$index = $interpreter[ $typeAxis[1] ];
$default_value = false;
$option_value = $this->get_setting( $setting, false );
if ( 'hover' === $type ) {
$default_value = $this->get_setting( $setting, false );
$option_value = $this->get_setting( $setting . '__hover', false );
} elseif ( 'sticky' === $type ) {
$default_value = $this->get_setting( $setting, false );
$option_value = $this->get_setting( $setting . '__sticky', false );
} elseif ( 'tablet' === $type ) {
$default_value = $this->get_setting( $setting, false );
$option_value = $this->get_setting( $setting . '_tablet', false );
} elseif ( 'phone' === $type ) {
$default_value = $this->get_setting( $setting . '_tablet', false );
$option_value = $this->get_setting( $setting . '_phone', false );
if ( false === $default_value ) {
$default_value = $this->get_setting( $setting, false );
}
}
if ( false === $option_value ) {
if ( false !== $default_value ) {
$option_value = $default_value;
}
}
if ( false === $option_value ) {
return '';
}
$value_array = explode( '|', $option_value );
$value = $value_array[ $index ];
if ( 'scale' === $typeAxis[0] ) {
return $this->percent_to_unit( $value );
}
return $value;
}
public function get_elements( $type ) {
if ( empty( $this->processing_props ) ) {
wp_die( new WP_Error( '666', 'Run set_props first' ) );
}
$transformElements = array();
$originArray = array();
foreach ( $this->allTransforms as $option ) {
$typeAxis = array();
$typeAxis[0] = substr( $option, 0, -1 );
$typeAxis[1] = substr( $option, -1 );
$value = esc_attr( $this->get_option( $typeAxis, $type ) );
if ( ! empty( $value ) ) {
if ( 'origin' === $typeAxis[0] ) {
if ( 'originY' === $option && empty( $originArray ) ) {
// default value of originX
array_push( $originArray, '50%' );
}
array_push( $originArray, $value );
} else {
$transformElements[ $option ] = $value;
}
}
}
return array(
'transform' => $transformElements,
'origin' => $originArray,
);
}
public function getTransformDeclaration( $transformElements, $view = 'desktop' ) {
$declaration = array();
unset( $transformElements['originX'], $transformElements['originY'] );
// Perspective is included on when combining with some animations
if ( ! empty( $transformElements['perspective'] ) ) {
array_push( $declaration, sprintf( 'perspective(%s)', $transformElements['perspective'] ) );
}
// Transforms must maintain this order to blend correctly with animation rules
foreach ( $this->allTransforms as $option ) {
if ( ! empty( $transformElements[ $option ] ) ) {
array_push( $declaration, sprintf( '%s(%s)', $option, $transformElements[ $option ] ) );
}
}
if ( ! empty( $declaration ) ) {
if ( $this->processing_props['transforms_important'] || 'hover' === $view || 'sticky' === $view ) {
array_push( $declaration, '!important' );
}
return sprintf( 'transform: %s;', implode( ' ', $declaration ) );
}
return '';
}
/**
* @param $animationType
* @param $elements
* @param $function_name
* @param $device
*
* @return array
*/
public function transformedAnimation( $animationType, $elements, $function_name, $device ) {
if ( 'hover' === $device || 'sticky' === $device ) {
return array();
}
$utils = ET_Core_Data_Utils::instance();
$startElements = $elements['transform'];
$responsive = ET_Builder_Module_Helper_ResponsiveOptions::instance();
$direction = $responsive->get_any_value( $this->processing_props, 'animation_direction', 'center', true, $device );
$animation_intensity = $utils->array_get( $this->processing_props, "animation_intensity_$animationType", 50 );
$module_class = ET_Builder_Element::get_module_order_class( $function_name );
$animationName = "et_pb_${animationType}_${direction}_$module_class";
$newKeyframe = "@keyframes $animationName";
$newAnimationSelector = ".$module_class.et_animated.transformAnim";
$newAnimationRules = "animation-name: $animationName;";
$newKeyframeRules = '';
$transformDeclaration = $this->getTransformDeclaration( $elements['transform'] );
$originDeclaration = sprintf( 'transform-origin:%s;', implode( ' ', $elements['origin'] ) );
$intensity = ! is_numeric( str_replace( '%', '', $animation_intensity ) )
? 50
: (int) str_replace( '%', '', $animation_intensity );
// slide animation direction center is the same animation as zoom center
if ( 'slide' === $animationType && 'center' === $direction ) {
$animationType = 'zoom';
}
// animation transform gets combined with transform settings as described on et-builder-custom-output.jsx processTransform method
switch ( $animationType ) {
case 'zoom':
$scale = ( 100 - $intensity ) * 0.01;
$startElements['scaleX'] = $scale * $utils->array_get( $elements['transform'], 'scaleX', 1 );
$startElements['scaleY'] = $scale * $utils->array_get( $elements['transform'], 'scaleY', 1 );
$startDeclaration = $this->getTransformDeclaration( $startElements );
// replace origin declaration to preserve animation direction setting only if transform origin is not set
if ( empty( $elements['origin'] ) ) {
$originDeclaration = "transform-origin: $direction;";
} else {
$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
}
$newKeyframeRules = "0%{ $startDeclaration }";
$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
$newAnimationRules .= $originDeclaration;
break;
case 'slide':
$translateY = $utils->array_get( $elements['transform'], 'translateY', '0%' );
$translateX = $utils->array_get( $elements['transform'], 'translateX', '0%' );
switch ( $direction ) {
case 'top':
$startElements['translateY'] = sprintf( 'calc(%s%% + %s)', $intensity * -2, $translateY );
$startElements['translateX'] = $translateX;
break;
case 'bottom':
$startElements['translateY'] = sprintf( 'calc(%s%% + %s)', $intensity * 2, $translateY );
$startElements['translateX'] = $translateX;
break;
case 'left':
$startElements['translateX'] = sprintf( 'calc(%s%% + %s)', $intensity * -2, $translateX );
$startElements['translateY'] = $translateY;
break;
case 'right':
$startElements['translateX'] = sprintf( 'calc(%s%% + %s)', $intensity * 2, $translateX );
$startElements['translateY'] = $translateY;
break;
}
$startDeclaration = $this->getTransformDeclaration( $startElements );
$newKeyframeRules = "0%{ $startDeclaration }";
$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
break;
case 'bounce':
$translateX = $utils->array_get( $elements['transform'], 'translateX', '0px' );
$translateY = $utils->array_get( $elements['transform'], 'translateY', '0px' );
switch ( $direction ) {
case 'center':
$scaleX = (float) $utils->array_get( $elements['transform'], 'scaleX', 1 );
$scaleY = (float) $utils->array_get( $elements['transform'], 'scaleY', 1 );
$newKeyframeRules = 'from, 20%, 40%, 60%, 80%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
$startElements['scaleX'] = 0.3 * $scaleX;
$startElements['scaleY'] = 0.3 * $scaleY;
$newKeyframeRules .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['scaleX'] = 1.1 * $scaleX;
$startElements['scaleY'] = 1.1 * $scaleY;
$newKeyframeRules .= sprintf( '20%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['scaleX'] = 0.9 * $scaleX;
$startElements['scaleY'] = 0.9 * $scaleY;
$newKeyframeRules .= sprintf( '40%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['scaleX'] = 1.03 * $scaleX;
$startElements['scaleY'] = 1.03 * $scaleY;
$newKeyframeRules .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['scaleX'] = 0.97 * $scaleX;
$startElements['scaleY'] = 0.97 * $scaleY;
$newKeyframeRules .= sprintf( '80%%{%s}', $this->getTransformDeclaration( $startElements ) );
$newKeyframeRules .= "100%{opacity: 1;$transformDeclaration}";
break;
case 'top':
$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
$startElements['translateY'] = "calc(-200px + $translateY)";
$newKeyframeRules .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(25px + $translateY)";
$newKeyframeRules .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(-10px + $translateY)";
$newKeyframeRules .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(5px + $translateY)";
$newKeyframeRules .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
$newKeyframeRules .= "100%{opacity: 1;$transformDeclaration}";
break;
case 'bottom':
$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
$startElements['translateY'] = "calc(200px + $translateY)";
$newKeyframeRules .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(-25px + $translateY)";
$newKeyframeRules .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(10px + $translateY)";
$newKeyframeRules .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateY'] = "calc(-5px + $translateY)";
$newKeyframeRules .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
$newKeyframeRules .= "100%{opacity: 1;$transformDeclaration}";
break;
case 'left':
$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
$startElements['translateX'] = "calc(-200px + $translateX)";
$newKeyframeRules .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(25px + $translateX)";
$newKeyframeRules .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(-10px + $translateX)";
$newKeyframeRules .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(5px + $translateX)";
$newKeyframeRules .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
$newKeyframeRules .= "100%{opacity: 1;$transformDeclaration}";
break;
case 'right':
$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
$startElements['translateX'] = "calc(200px + $translateX)";
$newKeyframeRules .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(-25px + $translateX)";
$newKeyframeRules .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(10px + $translateX)";
$newKeyframeRules .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
$startElements['translateX'] = "calc(-5px + $translateX)";
$newKeyframeRules .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
$newKeyframeRules .= "100%{opacity: 1;$transformDeclaration}";
break;
}
break;
case 'flip':
$intensityAngle = ceil( ( 90 / 100 ) * $intensity );
$startElements['perspective'] = '2000px';
$rotateX = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateX', '0' ) );
$rotateY = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateY', '0' ) );
switch ( $direction ) {
default:
case 'top':
$intensityAngle += $rotateX;
$startElement['rotateX'] = "{$intensityAngle}deg";
break;
case 'bottom':
$intensityAngle *= -1;
$intensityAngle += $rotateX;
$startElement['rotateX'] = "{$intensityAngle}deg";
break;
case 'left':
$intensityAngle *= -1;
$intensityAngle += $rotateY;
$startElement['rotateY'] = "{$intensityAngle}deg";
break;
case 'right':
$intensityAngle += $rotateY;
$startElement['rotateY'] = "{$intensityAngle}deg";
break;
}
$startDeclaration = $this->getTransformDeclaration( $startElement );
$newKeyframeRules = "0%{ $startDeclaration }";
$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
break;
case 'fold':
$intensityAngle = ceil( ( 90 / 100 ) * $intensity );
$startElements['perspective'] = '2000px';
$rotateX = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateX', '0' ) );
$rotateY = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateY', '0' ) );
switch ( $direction ) {
case 'top':
$intensityAngle *= -1;
$intensityAngle += $rotateX;
$startElements['rotateX'] = "{$intensityAngle}deg";
break;
case 'bottom':
$intensityAngle += $rotateX;
$startElements['rotateX'] = "{$intensityAngle}deg";
break;
case 'left':
$intensityAngle += $rotateY;
$startElements['rotateY'] = "{$intensityAngle}deg";
break;
default:
case 'right':
$intensityAngle *= -1;
$intensityAngle += $rotateY;
$startElements['rotateY'] = "{$intensityAngle}deg";
break;
}
$startDeclaration = $this->getTransformDeclaration( $startElements );
$newKeyframeRules = "0%{{$startDeclaration}}";
$newKeyframeRules .= "100%{opacity:1;${transformDeclaration}}";
// replace origin declaration to preserve animation direction setting only if transform origin is not set
if ( empty( $elements['origin'] ) ) {
$originDeclaration = "transform-origin: $direction;";
} else {
$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
}
$newAnimationRules .= $originDeclaration;
break;
case 'roll':
$rotateZ = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateZ', '0' ) );
$intensityAngle = ceil( ( 360 / 100 ) * $intensity );
if ( 'bottom' === $direction || 'right' === $direction ) {
$startElements['rotateZ'] = sprintf( '%sdeg', ( $intensityAngle * -1 ) + $rotateZ );
} else {
$startElements['rotateZ'] = sprintf( '%sdeg', $intensityAngle + $rotateZ );
}
$startDeclaration = $this->getTransformDeclaration( $startElements );
$newKeyframeRules = "0%{ $startDeclaration }";
$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
// replace origin declaration to preserve animation direction setting only if transform origin is not set
if ( empty( $elements['origin'] ) ) {
$originDeclaration = "transform-origin: $direction;";
} else {
$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
}
$newAnimationRules .= $originDeclaration;
break;
}
if ( ! empty( $newKeyframeRules ) ) {
return array(
'keyframe' => array(
'selector' => $newKeyframe,
'declaration' => $newKeyframeRules,
),
'animationRules' => array(
'selector' => $newAnimationSelector,
'declaration' => $newAnimationRules,
),
'declaration' => $transformDeclaration . $originDeclaration,
);
}
return array();
}
/**
* Check if we need to process transform.
* Here we also check positions since some of it
* requires transform css.
*
* @param array $attrs Module attributes.
* @param array $positions Position locations.
*
* @return bool
*/
public function is_used( $attrs, $positions ) {
// Check for transform attrs first.
foreach ( $attrs as $attr => $value ) {
if ( ! $value ) {
continue;
}
$is_attr = 0 === strpos( $attr, 'transform_' );
if ( $is_attr ) {
return true;
}
}
// Then check the current positions.
foreach ( $positions as $pos => $value ) {
$default_strpos = strpos( $value, '_is_default' );
if ( false === $default_strpos ) {
return true;
}
}
return false;
}
}
return new ET_Builder_Module_Field_Transform();

View File

@ -0,0 +1,21 @@
<?php
/**
* Parser of additional composite type attributes
*/
class ET_Builder_Module_Field_Attribute_Composite_Parser {
/**
* @param string $type type of composite attribute
* @param array $structure attribute structure, depends on type
*
* @return array Additional attributes for merging with rest of module attributes
*/
public static function parse( $type, $structure ) {
switch ( $type ) {
case 'tabbed':
default:
require_once ET_BUILDER_DIR . 'module/field/attribute/composite/type/Tabbed.php';
return ET_Builder_Module_Field_Attribute_Composite_Type_Tabbed::parse( $structure );
}
}
}

View File

@ -0,0 +1,64 @@
<?php
/**
* Class for parsing shortcode attributes for tabbed controls.
* The tabbed composite structure as follows
* 'composite_structure' => array(
* //tab
* 'border_all' => array(
* //tab icon
* 'icon' => 'border-all',
* //list of standard controls which will be placed within the tab
* 'controls' => array(
* 'border_width_all' => array(
* 'label' => esc_html__( 'Border Width', 'et_builder' ),
* 'type' => 'range',
* 'default' => '0',
* 'range_settings' => array(
* 'min' => 0,
* 'max' => 50,
* 'step' => 1,
* ),
* ),
* 'border_color_all' => array(
* 'label' => esc_html__( 'Border Color', 'et_builder' ),
* 'type' => $color_type,
* 'default' => '#333333',
* ),
* ),
* ),
* )
*/
class ET_Builder_Module_Field_Attribute_Composite_Type_Tabbed {
/**
* @var ET_Core_Data_Utils
*/
protected static $_;
public static function parse( $structure ) {
$result = array();
if ( ! is_array( $structure ) ) {
return $result;
}
if ( is_null( self::$_ ) ) {
self::$_ = ET_Core_Data_Utils::instance();
}
foreach ( $structure as $tab ) {
if ( ! isset( $tab['controls'] ) || ! is_array( $tab['controls'] ) ) {
continue;
}
foreach ( $tab['controls'] as $control => $control_settings ) {
// We don't want to set defaults right now as doing so makes it virtually impossible
// to generate accurate border css styles later on.
$result[ $control ] = '';
}
}
return $result;
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Author Condition's logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Author Condition Trait
*/
trait AuthorCondition {
/**
* Processes "Author" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all condition settings.
*
* @return boolean Condition output.
*/
protected function _process_author_condition( $condition_settings ) {
// Only check for Posts.
if ( ! is_singular() ) {
return false;
}
$display_rule = isset( $condition_settings['authorDisplay'] ) ? $condition_settings['authorDisplay'] : '';
$authors_raw = isset( $condition_settings['authors'] ) ? $condition_settings['authors'] : [];
$authors_ids = array_map(
function( $item ) {
return $item['value'];
},
$authors_raw
);
$is_on_shop_page = class_exists( 'WooCommerce' ) && is_shop();
$queried_object_id = $is_on_shop_page ? wc_get_page_id( 'shop' ) : get_queried_object_id();
$current_post_author_id = get_post_field( 'post_author', (int) $queried_object_id );
$should_display = array_intersect( $authors_ids, (array) $current_post_author_id ) ? true : false;
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
}

View File

@ -0,0 +1,76 @@
<?php
/**
* Browser condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Browser Condition Trait.
*/
trait BrowserCondition {
/**
* Processes "Operating System" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_browser_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['browserDisplay'] ) ? $condition_settings['browserDisplay'] : 'is';
$browsers_raw = isset( $condition_settings['browsers'] ) ? $condition_settings['browsers'] : '';
$browsers = explode( '|', $browsers_raw );
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput -- User Agent is not stored or displayed therefore XSS safe.
$useragent = ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) ? $_SERVER['HTTP_USER_AGENT'] : '';
$is_old_edge = preg_match( '/edge\//i', $useragent );
$is_checking_for_chrome = array_search( 'chrome', $browsers, true ) !== false;
$current_browser = $this->_get_browser( $useragent );
// Exception: When checking "Chrome" condition we should treat New Edge as Chrome.
if ( 'edge' === $current_browser && ! $is_old_edge && $is_checking_for_chrome ) {
$current_browser = 'chrome';
}
$should_display = array_intersect( $browsers, (array) $current_browser ) ? true : false;
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
/**
* Returns the Browser name based on user agent.
*
* @since 4.11.0
*
* @param string $useragent The useragent of the berowser.
*
* @return string Detected browser.
*/
protected function _get_browser( $useragent ) {
$browser = 'unknown';
$browser_array = array(
'/safari/i' => 'safari',
'/chrome|CriOS/i' => 'chrome',
'/firefox|FxiOS/i' => 'firefox',
'/msie|Trident/i' => 'ie',
'/edg/i' => 'edge',
'/opr|Opera|Presto/i' => 'opera',
'/maxthon/i' => 'maxthon',
'/ucbrowser/i' => 'ucbrowser',
);
foreach ( $browser_array as $regex => $value ) {
if ( preg_match( $regex, $useragent ) ) {
$browser = $value;
}
}
return $browser;
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
* Cart Contents condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Cart Contents Condition Trait.
*/
trait CartContentsCondition {
/**
* Processes "Cart Contents" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_cart_contents_condition( $condition_settings ) {
if ( ! class_exists( 'WooCommerce' ) ) {
return false;
}
$display_rule = isset( $condition_settings['cartContentsDisplay'] ) ? $condition_settings['cartContentsDisplay'] : 'hasProducts';
$products_raw = isset( $condition_settings['products'] ) ? $condition_settings['products'] : [];
$products_ids = array_map(
function( $item ) {
return isset( $item['value'] ) ? $item['value'] : '';
},
$products_raw
);
$is_cart_empty = WC()->cart->is_empty();
switch ( $display_rule ) {
case 'hasProducts':
return ! $is_cart_empty;
case 'isEmpty':
return $is_cart_empty;
case 'hasSpecificProduct':
return $this->_has_specific_product_in_cart( $products_ids );
case 'doesNotHaveSpecificProduct':
return ! $this->_has_specific_product_in_cart( $products_ids );
default:
return false;
}
}
/**
* Checks presence of specified products in the Cart.
*
* @param Array $products_ids Array of products IDs to check against the Cart's products.
* @return boolean Indicating the presence of specified products in the Cart.
*/
protected function _has_specific_product_in_cart( $products_ids ) {
$has_specific_product = false;
if ( ! WC()->cart->is_empty() ) {
foreach ( WC()->cart->get_cart() as $cart_item ) {
$cart_item_ids = [ $cart_item['product_id'], $cart_item['variation_id'] ];
if ( array_intersect( $products_ids, $cart_item_ids ) ) {
$has_specific_product = true;
break;
}
}
}
return $has_specific_product;
}
}

View File

@ -0,0 +1,85 @@
<?php
/**
* Categories condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Categories Condition Trait.
*/
trait CategoriesCondition {
/**
* Processes "Categories" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all condition settings.
*
* @return boolean Condition output.
*/
protected function _process_categories_condition( $condition_settings ) {
// Only check for Posts.
if ( ! is_singular() ) {
return false;
}
// Get condition's settings.
$display_rule = isset( $condition_settings['categoriesDisplay'] ) ? $condition_settings['categoriesDisplay'] : 'is';
$categories_raw = isset( $condition_settings['categories'] ) ? $condition_settings['categories'] : [];
$categories = array_map(
function( $item ) {
return (object) [
'id' => $item['value'],
'taxonomy_slug' => $item['groupSlug'],
];
},
$categories_raw
);
$current_queried_id = get_queried_object_id();
$has_post_specified_term = false;
$tax_slugs_of_catch_all_items = [];
$is_any_catch_all_selected = false;
$has_post_specified_taxonomy = false;
// Logic evaluation.
foreach ( $categories_raw as $item ) {
if ( true === $item['isCatchAll'] ) {
$tax_slugs_of_catch_all_items[] = $item['groupSlug'];
$is_any_catch_all_selected = true;
}
}
foreach ( $categories as $cat ) {
if ( has_term( $cat->id, $cat->taxonomy_slug, $current_queried_id ) ) {
$has_post_specified_term = true;
break;
}
}
$is_displayable = $has_post_specified_term ? true : false;
if ( ! $is_displayable && $is_any_catch_all_selected ) {
foreach ( $tax_slugs_of_catch_all_items as $tax_slug ) {
$has_post_specified_taxonomy = has_term( '', $tax_slug, $current_queried_id );
if ( $has_post_specified_taxonomy ) {
break;
}
}
$is_displayable = $has_post_specified_taxonomy ? true : false;
}
// Evaluation output.
return ( 'is' === $display_rule ) ? $is_displayable : ! $is_displayable;
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* Category Page condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Category Page Condition Trait.
*/
trait CategoryPageCondition {
/**
* Processes "Category Page" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_category_page_condition( $condition_settings ) {
// Only check for Archive pages.
if ( ! is_archive() ) {
return false;
}
// Get condition's settings.
$display_rule = isset( $condition_settings['categoryPageDisplay'] ) ? $condition_settings['categoryPageDisplay'] : 'is';
$categories_raw = isset( $condition_settings['categories'] ) ? $condition_settings['categories'] : [];
$queried_object = get_queried_object();
$is_queried_object_valid = $queried_object instanceof \WP_Term && property_exists( $queried_object, 'taxonomy' );
if ( ! $is_queried_object_valid ) {
return false;
}
$queried_taxonomy = $queried_object->taxonomy;
$categories_ids = array_map(
function( $item ) {
return $item['value'];
},
$categories_raw
);
$tax_slugs_of_catch_all_items = [];
$is_any_catch_all_selected = false;
foreach ( $categories_raw as $item ) {
if ( true === $item['isCatchAll'] ) {
$tax_slugs_of_catch_all_items[] = $item['groupSlug'];
$is_any_catch_all_selected = true;
}
}
// Logic evaluation.
$current_category_id = get_queried_object_id();
$is_displayable = array_intersect( $categories_ids, (array) $current_category_id ) ? true : false;
if ( ! $is_displayable && $is_any_catch_all_selected ) {
$is_displayable = array_intersect( $tax_slugs_of_catch_all_items, (array) $queried_taxonomy ) ? true : false;
}
// Evaluation output.
return ( 'is' === $display_rule ) ? $is_displayable : ! $is_displayable;
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Cookie condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Cookie Condition Trait.
*/
trait CookieCondition {
/**
* Processes "Cookie" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_cookie_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['cookieDisplay'] ) ? $condition_settings['cookieDisplay'] : 'cookieExists';
$cookie_name = isset( $condition_settings['cookieName'] ) ? $condition_settings['cookieName'] : '';
$cookie_value = isset( $condition_settings['cookieValue'] ) ? $condition_settings['cookieValue'] : '';
$is_cookie_set = ( isset( $_COOKIE[ $cookie_name ] ) ) ? true : false;
$is_cookie_value_equals = ( isset( $_COOKIE[ $cookie_name ] ) ) ? $cookie_value === $_COOKIE[ $cookie_name ] : false;
switch ( $display_rule ) {
case 'cookieExists':
return $is_cookie_set;
case 'cookieDoesNotExist':
return ! $is_cookie_set;
case 'cookieValueEquals':
return $is_cookie_value_equals;
case 'cookieValueDoesNotEqual':
return ! $is_cookie_value_equals;
default:
return false;
}
}
}

View File

@ -0,0 +1,57 @@
<?php
/**
* Date Archive condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
use DateTimeImmutable;
/**
* Date Archive Condition Trait.
*/
trait DateArchiveCondition {
/**
* Processes "Date Archive" condition.
*
* @since 4.11.0
*
* @param array $all_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_date_archive_condition( $all_settings ) {
if ( ! is_date() ) {
return false;
}
$display_rule = isset( $all_settings['dateArchiveDisplay'] ) ? $all_settings['dateArchiveDisplay'] : 'isAfter';
$date = isset( $all_settings['dateArchive'] ) ? $all_settings['dateArchive'] : '';
$year = get_query_var( 'year' );
$monthnum = get_query_var( 'monthnum' ) === 0 ? 1 : get_query_var( 'monthnum' );
$day = get_query_var( 'day' ) === 0 ? 1 : get_query_var( 'day' );
$archive_date = sprintf( '%s-%s-%s', $year, $monthnum, $day );
$target_date = new DateTimeImmutable( $date, wp_timezone() );
$current_arhive_date = new DateTimeImmutable( $archive_date, wp_timezone() );
switch ( $display_rule ) {
case 'isAfter':
return ( $current_arhive_date > $target_date );
case 'isBefore':
return ( $current_arhive_date < $target_date );
default:
return ( $current_arhive_date > $target_date );
}
}
}

View File

@ -0,0 +1,251 @@
<?php
/**
* Date Time condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
use DateTimeImmutable;
/**
* Date Time Condition Trait.
*/
trait DateTimeCondition {
/**
* Processes "Date & Time" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_date_time_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['dateTimeDisplay'] ) ? $condition_settings['dateTimeDisplay'] : 'isAfter';
$date = isset( $condition_settings['date'] ) ? $condition_settings['date'] : '';
$time = isset( $condition_settings['time'] ) ? $condition_settings['time'] : '';
$all_day = isset( $condition_settings['allDay'] ) ? $condition_settings['allDay'] : '';
$from_time = isset( $condition_settings['fromTime'] ) ? $condition_settings['fromTime'] : '';
$until_time = isset( $condition_settings['untilTime'] ) ? $condition_settings['untilTime'] : '';
$weekdays = isset( $condition_settings['weekdays'] ) ? array_filter( explode( '|', $condition_settings['weekdays'] ) ) : array();
$repeat_frequency = isset( $condition_settings['repeatFrequency'] ) ? $condition_settings['repeatFrequency'] : '';
$repeat_frequency_specific_days = isset( $condition_settings['repeatFrequencySpecificDays'] ) ? $condition_settings['repeatFrequencySpecificDays'] : '';
$date_from_time = $date . ' ' . $from_time;
$date_until_time = $date . ' ' . $until_time;
$date_time = $date . ' ' . $time;
$target_date = new DateTimeImmutable( $date, wp_timezone() );
$target_datetime = new DateTimeImmutable( $date_time, wp_timezone() );
$target_from_datetime = new DateTimeImmutable( $date_from_time, wp_timezone() );
$target_until_datetime = new DateTimeImmutable( $date_until_time, wp_timezone() );
$current_datetime = ! empty( $this->_custom_current_date ) ? $this->_custom_current_date : current_datetime();
$current_datetime_from = $current_datetime->modify( $from_time );
$current_datetime_until = $current_datetime->modify( $until_time );
switch ( $display_rule ) {
case 'isAfter':
return ( $current_datetime > $target_datetime );
case 'isBefore':
return ( $current_datetime < $target_datetime );
case 'isOnSpecificDate':
$has_reached_target_datetime = $current_datetime >= $target_date;
$has_time_until_tomorrow = $current_datetime < $target_date->modify( 'tomorrow' );
if ( 'off' === $all_day ) {
$has_reached_target_datetime = $current_datetime >= $target_from_datetime;
$has_time_until_tomorrow = $current_datetime < $target_until_datetime;
}
$is_on_specific_date = ( $has_reached_target_datetime && $has_time_until_tomorrow );
$is_repeated = $this->_is_datetime_condition_repeated( $condition_settings, $is_on_specific_date, $current_datetime, $target_datetime );
return ( $is_on_specific_date || $is_repeated );
case 'isNotOnSpecificDate':
$has_reached_target_datetime = $current_datetime >= $target_date;
$has_time_until_tomorrow = $current_datetime < $target_date->modify( 'tomorrow' );
if ( 'off' === $all_day ) {
$has_reached_target_datetime = $current_datetime >= $target_from_datetime;
$has_time_until_tomorrow = $current_datetime < $target_until_datetime;
}
return ! ( $has_reached_target_datetime && $has_time_until_tomorrow );
case 'isOnSpecificDays':
$current_day = strtolower( $current_datetime->format( 'l' ) );
$is_on_selected_day = array_intersect( (array) $current_day, $weekdays ) ? true : false;
$has_reached_target_datetime = true;
$has_time_until_tomorrow = true;
if ( 'off' === $all_day ) {
$has_reached_target_datetime = $current_datetime >= $current_datetime_from;
$has_time_until_tomorrow = $current_datetime < $current_datetime_until;
}
$is_repeated = $this->_is_datetime_condition_repeated( $condition_settings, $is_on_selected_day, $current_datetime, $target_datetime );
$is_on_specific_days = $is_on_selected_day && $has_reached_target_datetime && $has_time_until_tomorrow;
return ( 'weekly' === $repeat_frequency_specific_days ) ? $is_on_specific_days : $is_repeated;
case 'isFirstDayOfMonth':
$is_first_day_of_month = $current_datetime->format( 'd' ) === '01';
$has_reached_target_datetime = true;
$has_time_until_tomorrow = true;
if ( 'off' === $all_day ) {
$has_reached_target_datetime = $current_datetime >= $current_datetime_from;
$has_time_until_tomorrow = $current_datetime < $current_datetime_until;
}
return ( $is_first_day_of_month && $has_reached_target_datetime && $has_time_until_tomorrow );
case 'isLastDayOfMonth':
$last_day_of_month = new DateTimeImmutable( 'last day of this month', wp_timezone() );
$is_last_day_of_month = $current_datetime->format( 'd' ) === $last_day_of_month->format( 'd' );
$has_reached_target_datetime = true;
$has_time_until_tomorrow = true;
if ( 'off' === $all_day ) {
$has_reached_target_datetime = $current_datetime >= $current_datetime_from;
$has_time_until_tomorrow = $current_datetime < $current_datetime_until;
}
return ( $is_last_day_of_month && $has_reached_target_datetime && $has_time_until_tomorrow );
default:
return ( $current_datetime >= $target_datetime );
}
}
/**
* Checks whether a condition should be repeated or not.
*
* @since 4.11.0
*
* @param array $condition_settings Contains all settings of the condition.
* @param boolean $is_on_specific_date Specifies if "Is On Specific Date" condition has already
* reached that specific date or not.
* Useful to avoid repetition checking if condition is already
* true and also for "Every Other" repeat frequency.
* @param DateTimeImmutable $current_datetime The current date and time to use.
* @param DateTimeImmutable $target_datetime To detect Monthly/Annually repetition and "After Number of times".
*
* @return boolean Condition repetition result.
*/
protected function _is_datetime_condition_repeated( $condition_settings, $is_on_specific_date, $current_datetime, $target_datetime ) {
$repeat = isset( $condition_settings['repeat'] ) ? $condition_settings['repeat'] : '';
$repeat_frequency = isset( $condition_settings['repeatFrequency'] ) ? $condition_settings['repeatFrequency'] : '';
$repeat_frequency_specific_days = isset( $condition_settings['repeatFrequencySpecificDays'] ) ? $condition_settings['repeatFrequencySpecificDays'] : '';
$repeat_end = isset( $condition_settings['repeatEnd'] ) ? $condition_settings['repeatEnd'] : '';
$repeat_until = isset( $condition_settings['repeatUntilDate'] ) ? $condition_settings['repeatUntilDate'] : '';
$repeat_times = isset( $condition_settings['repeatTimes'] ) ? $condition_settings['repeatTimes'] : '';
$all_day = isset( $condition_settings['allDay'] ) ? $condition_settings['allDay'] : '';
$from_time = isset( $condition_settings['fromTime'] ) ? $condition_settings['fromTime'] : '';
$until_time = isset( $condition_settings['untilTime'] ) ? $condition_settings['untilTime'] : '';
$is_repeated = false;
$is_on_specific_days = 'isOnSpecificDays' === $condition_settings['dateTimeDisplay'];
if ( $is_on_specific_days || ( 'on' === $repeat && ! $is_on_specific_date ) ) {
if ( $is_on_specific_days ) {
$is_day_repeated = $this->_is_day_repeated( $repeat_frequency_specific_days, $is_on_specific_date, $current_datetime, $target_datetime );
} else {
$is_day_repeated = $this->_is_day_repeated( $repeat_frequency, $is_on_specific_date, $current_datetime, $target_datetime );
}
$is_repeat_valid = false;
switch ( $repeat_end ) {
case 'untilDate':
$is_repeat_valid = $current_datetime <= new DateTimeImmutable( $repeat_until, wp_timezone() );
break;
case 'afterNumberOfTimes':
$target_date_after_number_of_times = $target_datetime->modify( '+' . $repeat_times . ' month' );
if ( 'annually' === $repeat_frequency ) {
$target_date_after_number_of_times = $target_datetime->modify( '+' . $repeat_times . ' year' );
}
if ( 'off' === $all_day ) {
$target_date_after_number_of_times = $target_date_after_number_of_times->modify( $until_time );
}
$is_repeat_valid = $current_datetime <= $target_date_after_number_of_times;
break;
case 'never':
$is_repeat_valid = true;
break;
default:
$is_repeat_valid = true;
break;
}
// We assume "All Day" switch is "On".
$has_reached_from_time = $is_day_repeated;
$has_reached_until_time = $current_datetime < $current_datetime->modify( 'tomorrow' );
// Calculate from time/until time if "All Day" switch is "Off".
if ( 'off' === $all_day ) {
$has_reached_from_time = $current_datetime >= $current_datetime->modify( $from_time );
$has_reached_until_time = $current_datetime < $current_datetime->modify( $until_time );
}
$is_repeated = $is_day_repeated && $has_reached_from_time && $has_reached_until_time && $is_repeat_valid;
}
return $is_repeated;
}
/**
* Checks whether a day is repeated or not.
*
* @since 4.11.0
*
* @param string $repeat_frequency Frequency of repeat Ex. monthly, annually, everyOther...
* @param boolean $is_on_specific_date Useful for "Every Other" repeat frequency.
* @param DateTimeImmutable $current_datetime The current date and time to use.
* @param DateTimeImmutable $target_datetime Checks monthly/annually repetition against this Date and Time.
*
* @return boolean Day repetition result.
*/
protected function _is_day_repeated( $repeat_frequency, $is_on_specific_date, $current_datetime, $target_datetime ) {
switch ( $repeat_frequency ) {
case 'monthly':
return ( $current_datetime->format( 'd' ) === $target_datetime->format( 'd' ) );
case 'annually':
return ( $current_datetime->format( 'm d' ) === $target_datetime->format( 'm d' ) );
case 'everyOther':
return ! $is_on_specific_date;
case 'firstInstanceOfMonth':
return ( $current_datetime->format( 'Y-m-d' ) === $current_datetime->modify( 'first ' . $current_datetime->format( 'l' ) . ' of this month' )->format( 'Y-m-d' ) );
case 'lastInstanceOfMonth':
return ( $current_datetime->format( 'Y-m-d' ) === $current_datetime->modify( 'last ' . $current_datetime->format( 'l' ) . ' of this month' )->format( 'Y-m-d' ) );
default:
return false;
}
}
/**
* Checks date and time for possible conflicts.
*
* @since 4.11.0
*
* @param string $current_display_rule Value of currently processing condition's display rule Ex. is,isNot...
* @param string $prev_display_rule Value of previously processed condition's display rule Ex. is,isNot...
* @param array $conflicting_display_rule_vals Array of values containing the conflicting display rules as defined in $this->conflicts.
*
* @return boolean Conflict evaluation result.
*/
protected function _is_date_time_conflicted( $current_display_rule, $prev_display_rule, $conflicting_display_rule_vals ) {
$is_current_display_rule_conflicted = $this->_in_array_conflict( $current_display_rule, $conflicting_display_rule_vals );
$is_prev_display_rule_conflicted = $this->_in_array_conflict( $prev_display_rule, $conflicting_display_rule_vals );
$is_from_same_group = $is_current_display_rule_conflicted['index'] === $is_prev_display_rule_conflicted['index'];
if ( $is_current_display_rule_conflicted['value'] && $is_prev_display_rule_conflicted['value'] && ! $is_from_same_group ) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* Dynamic Posts Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Dynamic Posts Condition Trait.
*/
trait DynamicPostsCondition {
/**
* Processes "Dynamic Posts" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_dynamic_posts_condition( $condition_settings ) {
// Only check for Posts.
if ( ! is_singular() ) {
return false;
}
$display_rule = isset( $condition_settings['dynamicPostsDisplay'] ) ? $condition_settings['dynamicPostsDisplay'] : '';
$dynamic_posts_raw = isset( $condition_settings['dynamicPosts'] ) ? $condition_settings['dynamicPosts'] : [];
$dynamic_posts_ids = array_map(
function( $item ) {
return isset( $item['value'] ) ? $item['value'] : '';
},
$dynamic_posts_raw
);
$is_on_shop_page = class_exists( 'WooCommerce' ) && is_shop();
$current_page_id = $is_on_shop_page ? wc_get_page_id( 'shop' ) : get_queried_object_id();
$should_display = array_intersect( $dynamic_posts_ids, (array) $current_page_id ) ? true : false;
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Logged In Status Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Logged In Status Condition Trait.
*/
trait LoggedInStatusCondition {
/**
* Processes "Logged In Status" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_logged_in_status_condition( $condition_settings ) {
$logged_in_status = isset( $condition_settings['loggedInStatus'] ) ? $condition_settings['loggedInStatus'] : 'loggedIn';
$should_display = ( is_user_logged_in() ) ? true : false;
return ( 'loggedIn' === $logged_in_status ) ? $should_display : ! $should_display;
}
/**
* Checks logged in status for possible conflicts.
*
* @param string $current_value Curent setting value.
* @param string $prev_value Previous setting value.
* @param array $conflicting_value Defined conflicting value.
* @return boolean
*/
protected function _is_logged_in_status_conflicted( $current_value, $prev_value, $conflicting_value ) {
$is_current_value_conflicted = in_array( $current_value, $conflicting_value, true );
$is_prev_value_conflicted = in_array( $prev_value, $conflicting_value, true );
if ( $is_current_value_conflicted && $is_prev_value_conflicted ) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
* Number of Views condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Number of Views Condition Trait.
*/
trait NumberOfViewsCondition {
/**
* Processes "Number of Views" condition.
*
* @since 4.11.0
*
* @param array $condition_id Condition ID.
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_number_of_views_condition( $condition_id, $condition_settings ) {
if ( ! isset( $_COOKIE['divi_module_views'] ) ) {
return true;
}
// Get condition's settings.
$number_of_views = isset( $condition_settings['numberOfViews'] ) ? $condition_settings['numberOfViews'] : '0';
$cookie_array = [];
$visit_count = 0;
$current_datetime = current_datetime();
$cookie_array = json_decode( base64_decode( $_COOKIE['divi_module_views'] ), true ); // phpcs:ignore ET.Sniffs.ValidatedSanitizedInput, WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Cookie is not stored or displayed therefore XSS safe, The returned data is an array and necessary validation checks are performed.
if ( ! is_array( $cookie_array ) ) {
return true;
}
// Logic evaluation.
$col = array_column( $cookie_array, 'id' );
$is_condition_set_in_cookie = array_search( $condition_id, $col, true ) !== false;
if ( ! $is_condition_set_in_cookie ) {
// Display module if condition is not set in Cookie yet.
return true;
}
$is_reset_after_duration_on = 'on' === $condition_settings['resetAfterDuration'] ? true : false;
if ( $is_reset_after_duration_on ) {
$first_visit_timestamp = $cookie_array[ $condition_id ]['first_visit_timestamp'];
$display_again_after = $condition_settings['displayAgainAfter'] . ' ' . $condition_settings['displayAgainAfterUnit'];
$first_visit_datetime = $current_datetime->setTimestamp( $first_visit_timestamp );
$display_again_datetime = $first_visit_datetime->modify( $display_again_after );
if ( $current_datetime > $display_again_datetime ) {
return true;
}
}
$visit_count = $cookie_array[ $condition_id ]['visit_count'];
if ( (int) $visit_count >= (int) $number_of_views ) {
$is_displayable = false;
} else {
$is_displayable = true;
}
// Evaluation output.
return $is_displayable;
}
}

View File

@ -0,0 +1,72 @@
<?php
/**
* Operating System Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Operating System Condition Trait.
*/
trait OperatingSystemCondition {
/**
* Processes "Operating System" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_operating_system_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['operatingSystemDisplay'] ) ? $condition_settings['operatingSystemDisplay'] : 'is';
$operating_systems_raw = isset( $condition_settings['operatingSystems'] ) ? $condition_settings['operatingSystems'] : '';
$operating_systems = explode( '|', $operating_systems_raw );
$current_os = $this->_get_os();
$should_display = array_intersect( $operating_systems, (array) $current_os ) ? true : false;
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
/**
* Returns the Operating System name based on user agent.
*
* @since 4.11.0
*
* @return string
*/
protected function _get_os() {
$os_platform = 'unknown';
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput -- User Agent is not stored or displayed therefore XSS safe.
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$os_array = array(
'/windows nt/i' => 'windows',
'/macintosh|mac os x/i' => 'macos',
'/linux/i' => 'linux',
'/android/i' => 'android',
'/iphone/i' => 'iphone',
'/ipad/i' => 'ipad',
'/ipod/i' => 'ipod',
'/appletv/i' => 'appletv',
'/playstation/i' => 'playstation',
'/xbox/i' => 'xbox',
'/nintendo/i' => 'nintendo',
'/webos|hpwOS/i' => 'webos',
);
foreach ( $os_array as $regex => $value ) {
if ( preg_match( $regex, $user_agent ) ) {
$os_platform = $value;
}
}
return $os_platform;
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* Page Visit Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Page Visit Condition Trait.
*/
trait PageVisitCondition {
/**
* Processes "Page Visit" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_page_visit_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['pageVisitDisplay'] ) ? $condition_settings['pageVisitDisplay'] : 'hasVisitedSpecificPage';
$pages_raw = isset( $condition_settings['pages'] ) ? $condition_settings['pages'] : [];
$pages_ids = array_map(
function( $item ) {
return isset( $item['value'] ) ? (int) $item['value'] : '';
},
$pages_raw
);
$has_visited_specific_page = false;
if ( isset( $_COOKIE['divi_post_visit'] ) ) {
// phpcs:ignore ET.Sniffs.ValidatedSanitizedInput, WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Cookie is not stored or displayed therefore XSS safe, base64_decode returned data is an array and necessary validation checks are performed.
$cookie = json_decode( base64_decode( $_COOKIE['divi_post_visit'] ), true );
$col = array_column( $cookie, 'id' );
$has_visited_specific_page = array_intersect( $pages_ids, $col ) ? true : false;
}
$should_display = $has_visited_specific_page;
return ( 'hasVisitedSpecificPage' === $display_rule ) ? $should_display : ! $should_display;
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Page Type Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Post Type Condition Trait.
*/
trait PostTypeCondition {
/**
* Processes "Post Types" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_post_type_condition( $condition_settings ) {
// Only check for Posts.
if ( ! is_singular() ) {
return false;
}
$display_rule = isset( $condition_settings['postTypeDisplay'] ) ? $condition_settings['postTypeDisplay'] : '';
$post_types_raw = isset( $condition_settings['postTypes'] ) ? $condition_settings['postTypes'] : [];
$post_types_values = array_map(
function( $item ) {
return $item['value'];
},
$post_types_raw
);
$is_on_shop_page = class_exists( 'WooCommerce' ) && is_shop();
$current_queried_id = $is_on_shop_page ? wc_get_page_id( 'shop' ) : get_queried_object_id();
$post_type = get_post_type( $current_queried_id );
$should_display = array_intersect( $post_types_values, (array) $post_type ) ? true : false;
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
}

View File

@ -0,0 +1,109 @@
<?php
/**
* Product Purchase Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Product Purchase Condition Trait.
*/
trait ProductPurchaseCondition {
/**
* Processes "Product Purchase" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_product_purchase_condition( $condition_settings ) {
if ( ! class_exists( 'WooCommerce' ) || ! is_user_logged_in() ) {
return false;
}
$display_rule = isset( $condition_settings['productPurchaseDisplay'] ) ? $condition_settings['productPurchaseDisplay'] : 'hasBoughtProduct';
$products_raw = isset( $condition_settings['products'] ) ? $condition_settings['products'] : [];
$current_user = wp_get_current_user();
$products_ids = array_map(
function( $item ) {
return isset( $item['value'] ) ? $item['value'] : '';
},
$products_raw
);
switch ( $display_rule ) {
case 'hasBoughtProduct':
$has_bought_product = $this->_has_user_bought_any_product( $current_user->ID );
return $has_bought_product;
case 'hasNotBoughtProduct':
$has_bought_product = $this->_has_user_bought_any_product( $current_user->ID );
return ! $has_bought_product;
case 'hasBoughtSpecificProduct':
return $this->_has_user_bought_specific_product( $current_user, $products_ids );
case 'hasNotBoughtSpecificProduct':
return ! $this->_has_user_bought_specific_product( $current_user, $products_ids );
default:
return false;
}
}
/**
* Checks whether `$current_user` has bought any specified products.
*
* @param WP_User $current_user Current user object.
* @param array $products_ids List of specefied product IDs.
*
* @return boolean Returns true if `$current_user` has bought any specified products, False otherwise.
*/
protected function _has_user_bought_specific_product( $current_user, $products_ids ) {
$has_bought_specific_product = false;
foreach ( $products_ids as $product_id ) {
$has_bought_specific_product = wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id );
if ( $has_bought_specific_product ) {
break;
}
}
return $has_bought_specific_product;
}
/**
* Checks if `$user_id` has bought any product in WooCommerce.
*
* @param integer $user_id WordPress User ID.
*
* @return boolean Returns true if `$user_id` has any paid order, False otherwise.
*/
protected function _has_user_bought_any_product( $user_id = 0 ) {
if ( ! class_exists( 'WooCommerce' ) || ! $user_id || ! is_numeric( $user_id ) ) {
return false;
}
$paid_statuses = wc_get_is_paid_statuses();
$orders = wc_get_orders(
[
'limit' => 1,
'status' => $paid_statuses,
'customer_id' => (int) $user_id,
'return' => 'ids',
]
);
return count( $orders ) > 0 ? true : false;
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* Search Results Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Search Results Condition Trait.
*/
trait SearchResultsCondition {
/**
* Processes "Search Results" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_search_results_condition( $condition_settings ) {
// Only check for Search.
if ( ! is_search() ) {
return false;
}
$display_rule = isset( $condition_settings['searchResultsDisplay'] ) ? $condition_settings['searchResultsDisplay'] : 'is';
$specific_search_queries_raw = isset( $condition_settings['specificSearchQueries'] ) ? $condition_settings['specificSearchQueries'] : '';
$excluded_search_queries_raw = isset( $condition_settings['excludedSearchQueries'] ) ? $condition_settings['excludedSearchQueries'] : '';
$specific_search_queries = explode( ',', $specific_search_queries_raw );
$excluded_search_queries = explode( ',', $excluded_search_queries_raw );
switch ( $display_rule ) {
case 'specificSearchQueries':
return $this->_is_specific_search_query( $specific_search_queries );
case 'excludedSearchQueries':
return ! $this->_is_specific_search_query( $excluded_search_queries );
default:
return false;
}
}
/**
* "is specirfic serach query" Condition logic.
*
* @param array $specific_search_queries Array of search queries.
* @return boolean Indicating whether "is specirfic serach query" Condition is true or false.
*/
protected function _is_specific_search_query( $specific_search_queries ) {
$is_specific_search_query = false;
foreach ( $specific_search_queries as $search_query ) {
$is_specific_search_query = get_search_query() === $search_query;
if ( $is_specific_search_query ) {
break;
}
}
return $is_specific_search_query;
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* Tag Page condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Tag Page Condition Trait.
*/
trait TagPageCondition {
/**
* Processes "Tag Page" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_tag_page_condition( $condition_settings ) {
// Only check for Archive pages.
if ( ! is_archive() ) {
return false;
}
// Get condition's settings.
$display_rule = isset( $condition_settings['tagPageDisplay'] ) ? $condition_settings['tagPageDisplay'] : 'is';
$tags_raw = isset( $condition_settings['tags'] ) ? $condition_settings['tags'] : [];
$queried_object = get_queried_object();
$is_queried_object_valid = $queried_object instanceof \WP_Term && property_exists( $queried_object, 'taxonomy' );
if ( ! $is_queried_object_valid ) {
return false;
}
$queried_taxonomy = $queried_object->taxonomy;
$tags_raw_ids = array_map(
function( $item ) {
return $item['value'];
},
$tags_raw
);
$tax_slugs_of_catch_all_items = [];
$is_any_catch_all_selected = false;
foreach ( $tags_raw as $item ) {
if ( true === $item['isCatchAll'] ) {
$tax_slugs_of_catch_all_items[] = $item['groupSlug'];
$is_any_catch_all_selected = true;
}
}
// Logic evaluation.
$current_tag_id = get_queried_object_id();
$is_displayable = array_intersect( $tags_raw_ids, (array) $current_tag_id ) ? true : false;
if ( ! $is_displayable && $is_any_catch_all_selected ) {
$is_displayable = array_intersect( $tax_slugs_of_catch_all_items, (array) $queried_taxonomy ) ? true : false;
}
// Evaluation output.
return ( 'is' === $display_rule ) ? $is_displayable : ! $is_displayable;
}
}

View File

@ -0,0 +1,85 @@
<?php
/**
* Tags Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* Tags Condition Trait.
*/
trait TagsCondition {
/**
* Processes "Tags" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_tags_condition( $condition_settings ) {
// Only check for Posts.
if ( ! is_singular() ) {
return false;
}
// Get condition's settings.
$display_rule = isset( $condition_settings['tagsDisplay'] ) ? $condition_settings['tagsDisplay'] : 'is';
$tags_raw = isset( $condition_settings['tags'] ) ? $condition_settings['tags'] : [];
$tags = array_map(
function( $item ) {
return (object) [
'id' => $item['value'],
'taxonomy_slug' => $item['groupSlug'],
];
},
$tags_raw
);
$current_queried_id = get_queried_object_id();
$has_post_specified_term = false;
$tax_slugs_of_catch_all_items = [];
$is_any_catch_all_selected = false;
$has_post_specified_taxonomy = false;
// Logic evaluation.
foreach ( $tags_raw as $item ) {
if ( true === $item['isCatchAll'] ) {
$tax_slugs_of_catch_all_items[] = $item['groupSlug'];
$is_any_catch_all_selected = true;
}
}
foreach ( $tags as $tag ) {
if ( has_term( $tag->id, $tag->taxonomy_slug, $current_queried_id ) ) {
$has_post_specified_term = true;
break;
}
}
$is_displayable = $has_post_specified_term ? true : false;
if ( ! $is_displayable && $is_any_catch_all_selected ) {
foreach ( $tax_slugs_of_catch_all_items as $tax_slug ) {
$has_post_specified_taxonomy = has_term( '', $tax_slug, $current_queried_id );
if ( $has_post_specified_taxonomy ) {
break;
}
}
$is_displayable = $has_post_specified_taxonomy ? true : false;
}
// Evaluation output.
return ( 'is' === $display_rule ) ? $is_displayable : ! $is_displayable;
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* User Role Condition logic swiftly crafted.
*
* @since 4.11.0
*
* @package Divi
* @sub-package Builder
*/
namespace Module\Field\DisplayConditions;
/**
* User Role Condition Trait.
*/
trait UserRoleCondition {
/**
* Processes "User Role" condition.
*
* @since 4.11.0
*
* @param array $condition_settings Containing all settings of the condition.
*
* @return boolean Condition output.
*/
protected function _process_user_role_condition( $condition_settings ) {
$display_rule = isset( $condition_settings['userRoleDisplay'] ) ? $condition_settings['userRoleDisplay'] : 'is';
$roles_raw = isset( $condition_settings['userRoles'] ) ? $condition_settings['userRoles'] : [];
$ids_raw = isset( $condition_settings['userIds'] ) ? $condition_settings['userIds'] : '';
$roles = array_map(
function( $item ) {
return $item['value'];
},
$roles_raw
);
$ids = isset( $ids_raw ) ? array_map( 'trim', array_filter( explode( ',', $ids_raw ) ) ) : array();
$user = wp_get_current_user();
$should_display_based_on_roles = array_intersect( $roles, (array) $user->roles ) ? true : false;
$should_display_based_on_ids = array_intersect( $ids, (array) $user->ID ) ? true : false;
$should_display = ( $should_display_based_on_roles || $should_display_based_on_ids );
return ( 'is' === $display_rule ) ? $should_display : ! $should_display;
}
/**
* Checks user role for possible conflicts.
*
* @since 4.11.0
*
* @param string $current_value Currently processing condition's conflicting value.
* @param string $prev_value Previously processed condition's conflicting value.
* @param array $conflicting_value Array of values containing the conflicting values as defined in $this->conflicts.
* @param string $current_display_rule Currently processing condition's display rule Ex. is,isNot...
* @param string $prev_display_rule Previously processed condition's display rule Ex. is,isNot...
* @param array $conflicting_display_rule_vals Array of values containing the conflicting display rules as defined in $this->conflicts.
*
* @return boolean Conflict evaluation result.
*/
protected function _is_user_role_conflicted( $current_value, $prev_value, $conflicting_value, $current_display_rule, $prev_display_rule, $conflicting_display_rule_vals ) {
$current_value = explode( '|', $current_value );
$prev_value = explode( '|', $prev_value );
$is_current_value_conflicted = ! empty( array_intersect( $current_value, $conflicting_value ) );
$is_prev_value_conflicted = ! empty( array_intersect( $prev_value, $conflicting_value ) );
$is_current_display_rule_conflicted = in_array( $current_display_rule, $conflicting_display_rule_vals, true );
$is_prev_display_rule_conflicted = in_array( $prev_display_rule, $conflicting_display_rule_vals, true );
if ( $is_current_value_conflicted && $is_prev_value_conflicted && $is_current_display_rule_conflicted && $is_prev_display_rule_conflicted ) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Class ET_Builder_Module_Field_Template_Base
* Base class for field renderers in BB
*/
abstract class ET_Builder_Module_Field_Template_Base {
/**
* @param $field
* @param $render_helper
*
* @return template
*/
abstract public function render( $field, $render_helper );
protected function _render_icon( $icon_name ) {
return '<div class="et-pb-icon">
<svg viewBox="0 0 28 28" preserveAspectRatio="xMidYMid meet" shapeRendering="geometricPrecision"><%= et_builder_template_options.options_icons[ "' . esc_attr( $icon_name ) . '" ] %></svg>
</div>';
}
protected function _wrap_field_name( $name ) {
// Don't add 'et_pb_' prefix to the "Admin Label" field
if ( 'admin_label' === $name ) {
return $name;
}
return 'et_pb_' . $name;
}
}

View File

@ -0,0 +1,76 @@
<?php
require_once ET_BUILDER_DIR . 'module/field/template/Base.php';
class ET_Builder_Module_Field_Template_Tabbed extends ET_Builder_Module_Field_Template_Base {
/**
* @param $field array Field settings
* @param $render_helper ET_Builder_Element
*
* @return string Control rendered html
*/
public function render( $field, $render_helper ) {
ob_start();
if ( ! empty( $field['composite_structure'] ) && is_array( $field['composite_structure'] ) ) {
?>
<div class="et-pb-composite-tabbed-wrapper">
<div id="<?php echo esc_attr( $this->_wrap_field_name( $field['name'] ) ); ?>" class="<?php echo esc_attr( $this->_get_control_class() ); ?>" data-attr-suffix="<?php echo esc_attr( $field['attr_suffix'] ); ?>">
<div class="et-pb-outside-preview-container">
<?php echo et_core_esc_previously( $this->_render_outside_preview() ); ?>
</div>
<ul class="et-pb-settings-tabs">
<?php foreach ( $field['composite_structure'] as $tab => $structure ) : ?>
<li class="et-pb-settings-tab">
<a href="#" class="et-pb-settings-tab-title" data-tab="<?php echo esc_attr( $tab ); ?>">
<?php
if ( isset( $structure['label'] ) && ! empty( $structure['label'] ) ) {
echo esc_html( $structure['label'] );
}
// render the icon if there is one defined.
if ( isset( $structure['icon'] ) && ! empty( $structure['icon'] ) ) {
echo et_core_esc_previously( $this->_render_icon( esc_html( $structure['icon'] ) ) );
}
?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php foreach ( $field['composite_structure'] as $tab => $structure ) : ?>
<div class="et-pb-settings-tab-content" data-tab="<?php echo esc_attr( $tab ); ?>">
<div class="et-pb-tab-preview-container" data-tab="<?php echo esc_attr( $tab ); ?>">
<?php echo et_core_esc_previously( $this->_render_tab_preview( $tab ) ); ?>
</div>
<?php if ( ! empty( $structure['controls'] ) && is_array( $structure['controls'] ) ) : ?>
<?php foreach ( $structure['controls'] as $name => $control ) : ?>
<?php $control['name'] = $name; ?>
<?php $control['tab_slug'] = $field['tab_slug']; ?>
<?php $hidden = 'hidden' === $control['type'] ? ' et_pb_hidden' : ''; ?>
<div class="et-pb-composite-option et-pb-composite-tabbed-option et-pb-option<?php echo et_core_intentionally_unescaped( $hidden, 'fixed_string' ); ?>" data-control-index="<?php echo esc_attr( $name ); ?>" data-option_name="<?php echo esc_attr( $name ); ?>">
<?php echo et_core_esc_previously( $render_helper->wrap_settings_option_label( $control ) ); ?>
<?php echo et_core_esc_previously( $render_helper->wrap_settings_option_field( $control, $name ) ); ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
</div>
<span class="et-pb-reset-setting et-pb-reset-skip et-pb-composite-tabbed-reset-setting"></span>
<?php
}
return ob_get_clean();
}
protected function _render_outside_preview() {
return '';
}
protected function _render_tab_preview( $tab ) {
return '';
}
protected function _get_control_class() {
return 'et-pb-composite-tabbed';
}
}

View File

@ -0,0 +1,73 @@
<?php
require_once ET_BUILDER_DIR . 'module/field/template/Base.php';
class ET_Builder_Module_Field_Template_Border_Radius extends ET_Builder_Module_Field_Template_Base {
public function render( $field, $render_helper ) {
ob_start();
?>
<div class="et-pb-border-radius-wrap">
<div class="et-pb-border-radius-wrap-column">
<div class="et-pb-border-radius-top-left">
<input class="et-pb-border-radius-option-input"
type="text"
value=""
data-corner="top-left"
/>
</div>
<div class="et-pb-border-radius-bottom-left">
<input class="et-pb-border-radius-option-input"
type="text"
value=""
data-corner="bottom-left"
/>
</div>
</div>
<div class="et-pb-border-radius-wrap-column">
<div class="et-pb-border-radius-preview">
<div class="et-pb-border-radius-wrap-link-button">
<a href="#" class="">
<?php echo et_core_esc_previously( $this->_render_icon( 'border-link' ) ); ?>
</a>
</div>
</div>
</div>
<div class="et-pb-border-radius-wrap-column">
<div class="et-pb-border-radius-top-right">
<input class="et-pb-border-radius-option-input"
type="text"
value=""
data-corner="top-right"
/>
</div>
<div class="et-pb-border-radius-bottom-right">
<input class="et-pb-border-radius-option-input"
type="text"
value=""
data-corner="bottom-right"
/>
</div>
</div>
</div>
<span class="et-pb-reset-setting"></span>
<?php
$name = $render_helper->get_field_name( $field );
// Avoid underscore's _.template() being treated as PHP tags when PHP server's asp_tags is enabled
$value_open_tag = '<%-';
$value_close_tag = '%>';
?>
<?php $attr_name = $render_helper->get_type() === 'child' ? 'data.' . esc_attr( $name ) : esc_attr( $name ); ?>
<?php $default = isset( $field['default'] ) ? $field['default'] : 'on||||'; ?>
<input id="<?php echo esc_attr( $name ); ?>"
type="hidden"
name="<?php echo esc_attr( $name ); ?>"
data-default="<?php echo esc_attr( $default ); ?>"
value="<?php echo et_core_intentionally_unescaped( $value_open_tag, 'fixed_string' ); ?> typeof( <?php echo esc_attr( $attr_name ); ?> ) !== 'undefined' ? <?php echo esc_attr( $attr_name ) . '.replace(/%91/g, "[").replace(/%93/g, "]").replace(/%22/g, "\"")'; ?> : '' <?php echo et_core_intentionally_unescaped( $value_close_tag, 'fixed_string' ); ?>"
class="et-pb-main-setting"
/>
<?php
return ob_get_clean();
}
}

View File

@ -0,0 +1,20 @@
<?php
require_once ET_BUILDER_DIR . 'module/field/template/Tabbed.php';
class ET_Builder_Module_Field_Template_Border_Styles extends ET_Builder_Module_Field_Template_Tabbed {
protected function _get_control_class() {
return 'et-pb-composite-tabbed-border-style';
}
protected function _render_tab_preview( $tab ) {
ob_start();
?>
<div class="et-pb-tab-preview-container-column">
<div class="et-pb-tab-preview-container-preview"></div>
</div>
<?php
return ob_get_clean();
}
}

Some files were not shown because too many files have changed in this diff Show More