itself. $this->add_control( $prefix . $breakpoint_key, $control_config ); } } } start_controls_section( 'section_' . $this->get_id(), [ 'label' => $this->get_title(), 'tab' => $this->get_id(), ] ); $this->add_control( 'global_image_lightbox', [ 'label' => esc_html__( 'Image Lightbox', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'description' => esc_html__( 'Open all image links in a lightbox popup window. The lightbox will automatically work on any link that leads to an image file.', 'elementor' ), 'frontend_available' => true, ] ); $this->add_control( 'lightbox_enable_counter', [ 'label' => esc_html__( 'Counter', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_enable_fullscreen', [ 'label' => esc_html__( 'Fullscreen', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_enable_zoom', [ 'label' => esc_html__( 'Zoom', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_enable_share', [ 'label' => esc_html__( 'Share', 'elementor' ), 'type' => Controls_Manager::SWITCHER, 'default' => 'yes', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_title_src', [ 'label' => esc_html__( 'Title', 'elementor' ), 'type' => Controls_Manager::SELECT, 'options' => [ '' => esc_html__( 'None', 'elementor' ), 'title' => esc_html__( 'Title', 'elementor' ), 'caption' => esc_html__( 'Caption', 'elementor' ), 'alt' => esc_html__( 'Alt', 'elementor' ), 'description' => esc_html__( 'Description', 'elementor' ), ], 'default' => 'title', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_description_src', [ 'label' => esc_html__( 'Description', 'elementor' ), 'type' => Controls_Manager::SELECT, 'options' => [ '' => esc_html__( 'None', 'elementor' ), 'title' => esc_html__( 'Title', 'elementor' ), 'caption' => esc_html__( 'Caption', 'elementor' ), 'alt' => esc_html__( 'Alt', 'elementor' ), 'description' => esc_html__( 'Description', 'elementor' ), ], 'default' => 'description', 'frontend_available' => true, ] ); $this->add_control( 'lightbox_color', [ 'label' => esc_html__( 'Background Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => 'background-color: {{VALUE}}', ], ] ); $this->add_control( 'lightbox_ui_color', [ 'label' => esc_html__( 'UI Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-ui-color: {{VALUE}}', ], ] ); $this->add_control( 'lightbox_ui_color_hover', [ 'label' => esc_html__( 'UI Hover Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-ui-color-hover: {{VALUE}}', ], ] ); $this->add_control( 'lightbox_text_color', [ 'label' => esc_html__( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '.elementor-lightbox' => '--lightbox-text-color: {{VALUE}}', ], ] ); $this->add_control( 'lightbox_icons_size', [ 'label' => esc_html__( 'Toolbar Icons Size', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], 'selectors' => [ '.elementor-lightbox' => '--lightbox-header-icons-size: {{SIZE}}{{UNIT}}', ], 'separator' => 'before', ] ); $this->add_control( 'lightbox_slider_icons_size', [ 'label' => esc_html__( 'Navigation Icons Size', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'vw', 'custom' ], 'selectors' => [ '.elementor-lightbox' => '--lightbox-navigation-icons-size: {{SIZE}}{{UNIT}}', ], 'separator' => 'before', ] ); $this->end_controls_section(); } } controls_manager->add_page_transitions_controls( $this->parent, $this->get_id() ); } } start_controls_section( 'section_' . $this->get_id(), [ 'label' => $this->get_title(), 'tab' => $this->get_id(), ] ); $this->add_control( $this->get_id() . '_refresh_notice', [ 'type' => Controls_Manager::RAW_HTML, 'raw' => sprintf( /* translators: 1: Link open tag, 2: Link open tag, 3: Link close tag. */ esc_html__( 'Changes will be reflected only after %1$s saving %3$s and %2$s reloading %3$s preview.', 'elementor' ), '', '', '' ), 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info', ] ); $this->add_control( 'site_name', [ 'label' => esc_html__( 'Site Name', 'elementor' ), 'default' => get_option( 'blogname' ), 'placeholder' => esc_html__( 'Choose name', 'elementor' ), 'label_block' => true, 'export' => false, ] ); $this->add_control( 'site_description', [ 'label' => esc_html__( 'Site Description', 'elementor' ), 'default' => get_option( 'blogdescription' ), 'placeholder' => esc_html__( 'Choose description', 'elementor' ), 'label_block' => true, 'export' => false, ] ); $this->add_control( 'site_logo', [ 'label' => esc_html__( 'Site Logo', 'elementor' ), 'type' => Controls_Manager::MEDIA, 'should_include_svg_inline_option' => $should_include_svg_inline_option, 'default' => [ 'id' => $custom_logo_id, 'url' => $custom_logo_src ? $custom_logo_src[0] : '', ], 'description' => sprintf( /* translators: 1: Width number pixel, 2: Height number pixel. */ esc_html__( 'Suggested image dimensions: %1$s × %2$s pixels.', 'elementor' ), '350', '100' ), 'export' => false, ] ); $this->add_control( 'site_favicon', [ 'label' => esc_html__( 'Site Favicon', 'elementor' ), 'type' => Controls_Manager::MEDIA, 'should_include_svg_inline_option' => $should_include_svg_inline_option, 'default' => [ 'id' => $site_icon_id, 'url' => $site_icon_src ? $site_icon_src[0] : '', ], 'description' => esc_html__( 'Suggested favicon dimensions: 512 × 512 pixels.', 'elementor' ), 'export' => false, ] ); $this->end_controls_section(); } public function on_save( $data ) { if ( ! isset( $data['settings']['post_status'] ) || Document::STATUS_PUBLISH !== $data['settings']['post_status'] || // Should check for the current action to avoid infinite loop // when updating options like: "blogname" and "blogdescription". strpos( current_action(), 'update_option_' ) === 0 ) { return; } if ( isset( $data['settings']['site_name'] ) ) { update_option( 'blogname', $data['settings']['site_name'] ); } if ( isset( $data['settings']['site_description'] ) ) { update_option( 'blogdescription', $data['settings']['site_description'] ); } if ( isset( $data['settings']['site_logo'] ) ) { set_theme_mod( 'custom_logo', $data['settings']['site_logo']['id'] ); } if ( isset( $data['settings']['site_favicon'] ) ) { update_option( 'site_icon', $data['settings']['site_favicon']['id'] ); } } } register_tab(); $this->register_tab_controls(); } public function on_save( $data ) {} /** * Before Save * * Allows for modifying the kit data before it is saved to the database. * * @param array $data * @return array */ public function before_save( array $data ) { return $data; } protected function register_tab() { Controls_Manager::add_tab( $this->get_id(), $this->get_title() ); } protected function add_default_globals_notice() { // Get the current section config (array - section id and tab) to use for creating a unique control ID and name $current_section = $this->parent->get_current_section(); /** @var Manager $module */ $kits_manager = Plugin::$instance->kits_manager; if ( $kits_manager->is_custom_colors_enabled() || $kits_manager->is_custom_typography_enabled() ) { $this->add_control( $current_section['section'] . '_schemes_notice', [ 'name' => $current_section['section'] . '_schemes_notice', 'type' => Controls_Manager::RAW_HTML, 'raw' => sprintf( /* translators: 1: Link open tag, 2: Link close tag. */ esc_html__( 'In order for Theme Style to affect all relevant Elementor elements, please disable Default Colors and Fonts from the %1$sSettings Page%2$s.', 'elementor' ), '', '' ), 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning', 'render_type' => 'ui', ] ); } } } start_controls_section( 'section_buttons', [ 'label' => esc_html__( 'Buttons', 'elementor' ), 'tab' => $this->get_id(), ] ); $this->add_default_globals_notice(); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'button_typography', 'selector' => $button_selector, ] ); $this->add_group_control( Group_Control_Text_Shadow::get_type(), [ 'name' => 'button_text_shadow', 'selector' => $button_selector, ] ); $this->start_controls_tabs( 'tabs_button_style' ); $this->start_controls_tab( 'tab_button_normal', [ 'label' => esc_html__( 'Normal', 'elementor' ), ] ); $this->add_control( 'button_text_color', [ 'label' => esc_html__( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $button_selector => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Background::get_type(), [ 'name' => 'button_background', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], 'selector' => $button_selector, 'fields_options' => [ 'background' => [ 'default' => 'classic', ], 'color' => [ 'dynamic' => [], ], 'color_b' => [ 'dynamic' => [], ], ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'button_box_shadow', 'selector' => $button_selector, ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'button_border', 'selector' => $button_selector, 'fields_options' => [ 'color' => [ 'dynamic' => [], ], ], ] ); $this->add_control( 'button_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ $button_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->end_controls_tab(); $this->start_controls_tab( 'tab_button_hover', [ 'label' => esc_html__( 'Hover', 'elementor' ), ] ); $this->add_control( 'button_hover_text_color', [ 'label' => esc_html__( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $button_hover_selector => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Background::get_type(), [ 'name' => 'button_hover_background', 'types' => [ 'classic', 'gradient' ], 'exclude' => [ 'image' ], 'selector' => $button_hover_selector, 'fields_options' => [ 'background' => [ 'default' => 'classic', ], 'color' => [ 'dynamic' => [], ], 'color_b' => [ 'dynamic' => [], ], ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'button_hover_box_shadow', 'selector' => $button_hover_selector, ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'button_hover_border', 'selector' => $button_hover_selector, 'fields_options' => [ 'color' => [ 'dynamic' => [], ], ], ] ); $this->add_control( 'button_hover_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ $button_hover_selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_responsive_control( 'button_padding', [ 'label' => esc_html__( 'Padding', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], 'selectors' => [ $button_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], 'separator' => 'before', ] ); $this->end_controls_section(); } } start_controls_section( 'section_form_fields', [ 'label' => esc_html__( 'Form Fields', 'elementor' ), 'tab' => $this->get_id(), ] ); $this->add_default_globals_notice(); $this->add_control( 'form_label_heading', [ 'type' => Controls_Manager::HEADING, 'label' => esc_html__( 'Label', 'elementor' ), ] ); $this->add_control( 'form_label_color', [ 'label' => esc_html__( 'Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $label_selector => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'form_label_typography', 'selector' => $label_selector, ] ); $this->add_control( 'form_field_heading', [ 'type' => Controls_Manager::HEADING, 'label' => esc_html__( 'Field', 'elementor' ), 'separator' => 'before', ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'form_field_typography', 'selector' => $input_selector, ] ); $this->start_controls_tabs( 'tabs_form_field_style' ); $this->start_controls_tab( 'tab_form_field_normal', [ 'label' => esc_html__( 'Normal', 'elementor' ), ] ); $this->add_form_field_state_tab_controls( 'form_field', $input_selector ); $this->end_controls_tab(); $this->start_controls_tab( 'tab_form_field_focus', [ 'label' => esc_html__( 'Focus', 'elementor' ), ] ); $this->add_form_field_state_tab_controls( 'form_field_focus', $input_focus_selector ); $this->add_control( 'form_field_focus_transition_duration', [ 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (ms)', 'type' => Controls_Manager::SLIDER, 'selectors' => [ $input_selector => 'transition: {{SIZE}}ms', ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 3000, 'step' => 100, ], ], ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->add_responsive_control( 'form_field_padding', [ 'label' => esc_html__( 'Padding', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ], 'selectors' => [ $input_selector => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], 'separator' => 'before', ] ); $this->end_controls_section(); } private function add_form_field_state_tab_controls( $prefix, $selector ) { $this->add_control( $prefix . '_text_color', [ 'label' => esc_html__( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $selector => 'color: {{VALUE}};', ], ] ); $this->add_control( $prefix . '_accent_color', [ 'label' => esc_html__( 'Accent Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $selector => 'accent-color: {{VALUE}};', ], ] ); $this->add_control( $prefix . '_background_color', [ 'label' => esc_html__( 'Background Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $selector => 'background-color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => $prefix . '_box_shadow', 'selector' => $selector, ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => $prefix . '_border', 'selector' => $selector, 'fields_options' => [ 'color' => [ 'dynamic' => [], ], ], ] ); $this->add_control( $prefix . '_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ $selector => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); } } start_controls_section( 'section_images', [ 'label' => esc_html__( 'Images', 'elementor' ), 'tab' => $this->get_id(), ] ); $this->add_default_globals_notice(); $this->start_controls_tabs( 'tabs_image_style' ); $this->start_controls_tab( 'tab_image_normal', [ 'label' => esc_html__( 'Normal', 'elementor' ), ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'image_border', 'selector' => $image_selectors, 'fields_options' => [ 'color' => [ 'dynamic' => [], ], ], ] ); $this->add_responsive_control( 'image_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ $image_selectors => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_control( 'image_opacity', [ 'label' => esc_html__( 'Opacity', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'max' => 1, 'min' => 0.10, 'step' => 0.01, ], ], 'selectors' => [ $image_selectors => 'opacity: {{SIZE}};', ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'image_box_shadow', 'exclude' => [ 'box_shadow_position', ], 'selector' => $image_selectors, ] ); $this->add_group_control( Group_Control_Css_Filter::get_type(), [ 'name' => 'image_css_filters', 'selector' => '{{WRAPPER}} img', ] ); $this->end_controls_tab(); $this->start_controls_tab( 'tab_image_hover', [ 'label' => esc_html__( 'Hover', 'elementor' ), ] ); $this->add_group_control( Group_Control_Border::get_type(), [ 'name' => 'image_hover_border', 'selector' => '{{WRAPPER}} img:hover', 'fields_options' => [ 'color' => [ 'dynamic' => [], ], ], ] ); $this->add_responsive_control( 'image_hover_border_radius', [ 'label' => esc_html__( 'Border Radius', 'elementor' ), 'type' => Controls_Manager::DIMENSIONS, 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ], 'selectors' => [ $image_hover_selectors => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', ], ] ); $this->add_control( 'image_hover_opacity', [ 'label' => esc_html__( 'Opacity', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'max' => 1, 'min' => 0.10, 'step' => 0.01, ], ], 'selectors' => [ $image_hover_selectors => 'opacity: {{SIZE}};', ], ] ); $this->add_group_control( Group_Control_Box_Shadow::get_type(), [ 'name' => 'image_hover_box_shadow', 'exclude' => [ 'box_shadow_position', ], 'selector' => $image_hover_selectors, ] ); $this->add_group_control( Group_Control_Css_Filter::get_type(), [ 'name' => 'image_hover_css_filters', 'selector' => $image_hover_selectors, ] ); $this->add_control( 'image_hover_transition', [ 'label' => esc_html__( 'Transition Duration', 'elementor' ) . ' (s)', 'type' => Controls_Manager::SLIDER, 'range' => [ 'px' => [ 'min' => 0, 'max' => 3, 'step' => 0.1, ], ], 'selectors' => [ $image_selectors => 'transition-duration: {{SIZE}}s', ], ] ); $this->end_controls_tab(); $this->end_controls_tabs(); $this->end_controls_section(); } } start_controls_section( 'section_typography', [ 'label' => esc_html__( 'Typography', 'elementor' ), 'tab' => $this->get_id(), ] ); $this->add_default_globals_notice(); $this->add_control( 'body_heading', [ 'type' => Controls_Manager::HEADING, 'label' => esc_html__( 'Body', 'elementor' ), ] ); $this->add_control( 'body_color', [ 'label' => esc_html__( 'Text Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ '{{WRAPPER}}' => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'body_typography', 'selector' => '{{WRAPPER}}', ] ); $this->add_responsive_control( 'paragraph_spacing', [ 'label' => esc_html__( 'Paragraph Spacing', 'elementor' ), 'type' => Controls_Manager::SLIDER, 'selectors' => [ '{{WRAPPER}} p' => 'margin-bottom: {{SIZE}}{{UNIT}}', ], 'range' => [ 'px' => [ 'max' => 100, ], 'em' => [ 'min' => 0.1, 'max' => 20, ], ], 'size_units' => [ 'px', 'em', 'rem', 'vh', 'custom' ], ] ); //Link Selectors $link_selectors = [ '{{WRAPPER}} a', ]; $link_hover_selectors = [ '{{WRAPPER}} a:hover', ]; $link_selectors = implode( ',', $link_selectors ); $link_hover_selectors = implode( ',', $link_hover_selectors ); $this->add_control( 'link_heading', [ 'type' => Controls_Manager::HEADING, 'label' => esc_html__( 'Link', 'elementor' ), 'separator' => 'before', ] ); $this->start_controls_tabs( 'tabs_link_style' ); $this->start_controls_tab( 'tab_link_normal', [ 'label' => esc_html__( 'Normal', 'elementor' ), ] ); $this->add_control( 'link_normal_color', [ 'label' => esc_html__( 'Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $link_selectors => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'link_normal_typography', 'selector' => $link_selectors, ] ); $this->end_controls_tab(); $this->start_controls_tab( 'tab_link_hover', [ 'label' => esc_html__( 'Hover', 'elementor' ), ] ); $this->add_control( 'link_hover_color', [ 'label' => esc_html__( 'Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $link_hover_selectors => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => 'link_hover_typography', 'selector' => $link_hover_selectors, ] ); $this->end_controls_tab(); $this->end_controls_tabs(); // Headings. $this->add_element_controls( esc_html__( 'H1', 'elementor' ), 'h1', '{{WRAPPER}} h1' ); $this->add_element_controls( esc_html__( 'H2', 'elementor' ), 'h2', '{{WRAPPER}} h2' ); $this->add_element_controls( esc_html__( 'H3', 'elementor' ), 'h3', '{{WRAPPER}} h3' ); $this->add_element_controls( esc_html__( 'H4', 'elementor' ), 'h4', '{{WRAPPER}} h4' ); $this->add_element_controls( esc_html__( 'H5', 'elementor' ), 'h5', '{{WRAPPER}} h5' ); $this->add_element_controls( esc_html__( 'H6', 'elementor' ), 'h6', '{{WRAPPER}} h6' ); $this->end_controls_section(); } private function add_element_controls( $label, $prefix, $selector ) { $this->add_control( $prefix . '_heading', [ 'type' => Controls_Manager::HEADING, 'label' => $label, 'separator' => 'before', ] ); $this->add_control( $prefix . '_color', [ 'label' => esc_html__( 'Color', 'elementor' ), 'type' => Controls_Manager::COLOR, 'dynamic' => [], 'selectors' => [ $selector => 'color: {{VALUE}};', ], ] ); $this->add_group_control( Group_Control_Typography::get_type(), [ 'name' => $prefix . '_typography', 'selector' => $selector, ] ); } } documents->get( $kit_id ); if ( ! $this->is_valid_kit( $kit ) ) { return $this->get_empty_kit_instance(); } return $kit; } public function get_active_kit() { return $this->get_kit( $this->get_active_id() ); } public function get_active_kit_for_frontend() { $kit = Plugin::$instance->documents->get_doc_for_frontend( $this->get_active_id() ); if ( ! $this->is_valid_kit( $kit ) ) { return $this->get_empty_kit_instance(); } return $kit; } /** * @param $kit * * @return bool */ private function is_valid_kit( $kit ) { return $kit && $kit instanceof Kit && 'trash' !== $kit->get_main_post()->post_status; } /** * Returns an empty kit for situation when there is no kit in the site. * * @return Kit * @throws \Exception */ private function get_empty_kit_instance() { return new Kit( [ 'settings' => [], 'post_id' => 0, ] ); } /** * Checks if specific post is a kit. * * @param $post_id * * @return bool */ public function is_kit( $post_id ) { $document = Plugin::$instance->documents->get( $post_id ); return $document && $document instanceof Kit && ! $document->is_revision(); } /** * Init kit controls. * * A temp solution in order to avoid init kit group control from within another group control. * * After moving the `default_font` to the kit, the Typography group control cause initialize the kit controls at: https://github.com/elementor/elementor/blob/e6e1db9eddef7e3c1a5b2ba0c2338e2af2a3bfe3/includes/controls/groups/typography.php#L91 * and because the group control is a singleton, its args are changed to the last kit group control. */ public function init_kit_controls() { $this->get_active_kit_for_frontend()->get_settings(); } public function get_current_settings( $setting = null ) { $kit = $this->get_active_kit_for_frontend(); if ( ! $kit ) { return ''; } return $kit->get_settings( $setting ); } public function create( array $kit_data = [], array $kit_meta_data = [] ) { $default_kit_data = [ 'post_status' => 'publish', ]; $kit_data = array_merge( $default_kit_data, $kit_data ); $kit_data['post_type'] = Source_Local::CPT; $kit = Plugin::$instance->documents->create( 'kit', $kit_data, $kit_meta_data ); if ( isset( $kit_data['settings'] ) ) { $kit->save( [ 'settings' => $kit_data['settings'] ] ); } return $kit->get_id(); } public function create_new_kit( $kit_name = '', $settings = [], $active = true ) { $kit_name = $kit_name ? $kit_name : esc_html__( 'Custom', 'elementor' ); $id = $this->create( [ 'post_title' => $kit_name, 'settings' => $settings, ] ); if ( $active ) { update_option( self::OPTION_PREVIOUS, $this->get_active_id() ); update_option( self::OPTION_ACTIVE, $id ); } return $id; } public function create_default() { return $this->create( [ 'post_title' => esc_html__( 'Default Kit', 'elementor' ), ] ); } /** * Create a default kit if needed. * * This action runs on activation hook, all the Plugin components do not exists and * the Document manager and Kits manager instances cannot be used. * * @return int|void|\WP_Error */ public static function create_default_kit() { if ( get_option( self::OPTION_ACTIVE ) ) { return; } $id = wp_insert_post( [ 'post_title' => esc_html__( 'Default Kit', 'elementor' ), 'post_type' => Source_Local::CPT, 'post_status' => 'publish', 'meta_input' => [ '_elementor_edit_mode' => 'builder', Document::TYPE_META_KEY => 'kit', ], ] ); update_option( self::OPTION_ACTIVE, $id ); return $id; } /** * @param $imported_kit_id int The id of the imported kit that should be deleted. * @param $active_kit_id int The id of the kit that should set as 'active_kit' after the deletion. * @param $previous_kit_id int The id of the kit that should set as 'previous_kit' after the deletion. * @return void */ public function revert( int $imported_kit_id, int $active_kit_id, int $previous_kit_id ) { // If the kit that should set as active is not a valid kit then abort the revert. if ( ! $this->is_kit( $active_kit_id ) ) { return; } // This a hacky solution to avoid from the revert process to be interrupted by the `trash_kit_confirmation`. $this->should_skip_trash_kit_confirmation = true; $kit = $this->get_kit( $imported_kit_id ); $kit->force_delete(); $this->should_skip_trash_kit_confirmation = false; update_option( self::OPTION_ACTIVE, $active_kit_id ); if ( $this->is_kit( $previous_kit_id ) ) { update_option( self::OPTION_PREVIOUS, $previous_kit_id ); } } /** * @param Documents_Manager $documents_manager */ public function register_document( $documents_manager ) { $documents_manager->register_document_type( 'kit', Kit::get_class_full_name() ); } public function localize_settings( $settings ) { $kit = $this->get_active_kit(); $kit_controls = $kit->get_controls(); $design_system_controls = [ 'colors' => $kit_controls['system_colors']['fields'], 'typography' => $kit_controls['system_typography']['fields'], ]; $settings = array_replace_recursive( $settings, [ 'kit_id' => $kit->get_main_id(), 'kit_config' => [ 'typography_prefix' => Global_Typography::TYPOGRAPHY_GROUP_PREFIX, 'design_system_controls' => $design_system_controls, ], 'user' => [ 'can_edit_kit' => $kit->is_editable_by_current_user(), ], ] ); return $settings; } public function preview_enqueue_styles() { $kit = $this->get_kit_for_frontend(); if ( $kit ) { // On preview, the global style is not enqueued. $this->frontend_before_enqueue_styles(); Plugin::$instance->frontend->print_fonts_links(); } } public function frontend_before_enqueue_styles() { $kit = $this->get_kit_for_frontend(); if ( $kit ) { if ( $kit->is_autosave() ) { $css_file = Post_Preview::create( $kit->get_id() ); } else { $css_file = Post_CSS::create( $kit->get_id() ); } $css_file->enqueue(); } } public function render_panel_html() { require __DIR__ . '/views/panel.php'; } public function get_kit_for_frontend() { $kit = false; $active_kit = $this->get_active_kit(); $is_kit_preview = is_preview() && isset( $_GET['preview_id'] ) && $active_kit->get_main_id() === (int) $_GET['preview_id']; if ( $is_kit_preview ) { $kit = Plugin::$instance->documents->get_doc_or_auto_save( $active_kit->get_main_id(), get_current_user_id() ); } elseif ( 'publish' === $active_kit->get_main_post()->post_status ) { $kit = $active_kit; } return $kit; } public function update_kit_settings_based_on_option( $key, $value ) { /** @var Kit $active_kit */ $active_kit = $this->get_active_kit(); if ( $active_kit->is_saving() ) { return; } $active_kit->update_settings( [ $key => $value ] ); } /** * Map Scheme To Global * * Convert a given scheme value to its corresponding default global value * * @param string $type 'color'/'typography' * @param $value * @return mixed */ private function map_scheme_to_global( $type, $value ) { $schemes_to_globals_map = [ 'color' => [ '1' => Global_Colors::COLOR_PRIMARY, '2' => Global_Colors::COLOR_SECONDARY, '3' => Global_Colors::COLOR_TEXT, '4' => Global_Colors::COLOR_ACCENT, ], 'typography' => [ '1' => Global_Typography::TYPOGRAPHY_PRIMARY, '2' => Global_Typography::TYPOGRAPHY_SECONDARY, '3' => Global_Typography::TYPOGRAPHY_TEXT, '4' => Global_Typography::TYPOGRAPHY_ACCENT, ], ]; return $schemes_to_globals_map[ $type ][ $value ]; } /** * Convert Scheme to Default Global * * If a control has a scheme property, convert it to a default Global. * * @param $scheme - Control scheme property * @return array - Control/group control args * @since 3.0.0 * @access public */ public function convert_scheme_to_global( $scheme ) { if ( isset( $scheme['type'] ) && isset( $scheme['value'] ) ) { //_deprecated_argument( $args['scheme'], '3.0.0', 'Schemes are now deprecated - use $args[\'global\'] instead.' ); return $this->map_scheme_to_global( $scheme['type'], $scheme['value'] ); } // Typography control 'scheme' properties usually only include the string with the typography value ('1'-'4'). return $this->map_scheme_to_global( 'typography', $scheme ); } public function register_controls() { $controls_manager = Plugin::$instance->controls_manager; $controls_manager->register( new Repeater() ); } public function is_custom_colors_enabled() { return ! get_option( 'elementor_disable_color_schemes' ); } public function is_custom_typography_enabled() { return ! get_option( 'elementor_disable_typography_schemes' ); } /** * Add kit wrapper body class. * * It should be added even for non Elementor pages, * in order to support embedded templates. */ private function add_body_class() { $kit = $this->get_kit_for_frontend(); if ( $kit ) { Plugin::$instance->frontend->add_body_class( 'elementor-kit-' . $kit->get_main_id() ); } } /** * Send a confirm message before move a kit to trash, or if delete permanently not for trash. * * @param $post_id * @param false $is_permanently_delete */ private function before_delete_kit( $post_id, $is_permanently_delete = false ) { if ( $this->should_skip_trash_kit_confirmation ) { return; } $document = Plugin::$instance->documents->get( $post_id ); if ( ! $document || ! $this->is_kit( $post_id ) || isset( $_GET['force_delete_kit'] ) || // phpcs:ignore -- nonce validation is not require here. ( $is_permanently_delete && $document->is_trash() ) ) { return; } ob_start(); require __DIR__ . '/views/trash-kit-confirmation.php'; $confirmation_content = ob_get_clean(); // PHPCS - the content does not contain user input value. wp_die( new \WP_Error( 'cant_delete_kit', $confirmation_content ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } /** * Add 'Edit with elementor -> Site Settings' in admin bar. * * @param [] $admin_bar_config * * @return array $admin_bar_config */ private function add_menu_in_admin_bar( $admin_bar_config ) { $document = Plugin::$instance->documents->get( get_the_ID() ); if ( ! $document || ! $document->is_built_with_elementor() ) { $recent_edited_post = Utils::get_recently_edited_posts_query( [ 'posts_per_page' => 1, ] ); if ( $recent_edited_post->post_count ) { $posts = $recent_edited_post->get_posts(); $document = Plugin::$instance->documents->get( reset( $posts )->ID ); } } if ( $document ) { $document_edit_url = add_query_arg( [ 'active-document' => $this->get_active_id(), ], $document->get_edit_url() ); $admin_bar_config['elementor_edit_page']['children'][] = [ 'id' => 'elementor_site_settings', 'title' => esc_html__( 'Site Settings', 'elementor' ), 'sub_title' => esc_html__( 'Site', 'elementor' ), 'href' => $document_edit_url, 'class' => 'elementor-site-settings', 'parent_class' => 'elementor-second-section', ]; } return $admin_bar_config; } public function __construct() { add_action( 'elementor/documents/register', [ $this, 'register_document' ] ); add_filter( 'elementor/editor/localize_settings', [ $this, 'localize_settings' ] ); add_filter( 'elementor/editor/footer', [ $this, 'render_panel_html' ] ); add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'frontend_before_enqueue_styles' ], 0 ); add_action( 'elementor/preview/enqueue_styles', [ $this, 'preview_enqueue_styles' ], 0 ); add_action( 'elementor/controls/register', [ $this, 'register_controls' ] ); add_action( 'wp_trash_post', function ( $post_id ) { $this->before_delete_kit( $post_id ); } ); add_action( 'before_delete_post', function ( $post_id ) { $this->before_delete_kit( $post_id, true ); } ); add_action( 'update_option_blogname', function ( $old_value, $value ) { $this->update_kit_settings_based_on_option( 'site_name', $value ); }, 10, 2 ); add_action( 'update_option_blogdescription', function ( $old_value, $value ) { $this->update_kit_settings_based_on_option( 'site_description', $value ); }, 10, 2 ); add_action( 'wp_head', function() { $this->add_body_class(); } ); add_filter( 'elementor/frontend/admin_bar/settings', function ( $admin_bar_config ) { return $this->add_menu_in_admin_bar( $admin_bar_config ); }, 9 /* Before site-editor (theme-builder) */ ); } } '1' ], get_delete_post_link( $post_id, '', $is_permanently_delete ) ); ?>


date = current_time( 'mysql' ); $this->message = ! empty( $args['message'] ) ? esc_html( $args['message'] ) : ''; $this->type = ! empty( $args['type'] ) ? $args['type'] : 'info'; $this->meta = ! empty( $args['meta'] ) ? $args['meta'] : []; $this->args = $args; $this->set_trace(); } public function __get( $name ) { if ( property_exists( $this, $name ) ) { return $this->{$name}; } return ''; } public function __toString() { $vars = get_object_vars( $this ); return strtr( static::FORMAT, $vars ); } #[\ReturnTypeWillChange] public function jsonSerialize() { return [ 'class' => get_class( $this ), 'item' => [ 'date' => $this->date, 'message' => $this->message, 'type' => $this->type, 'meta' => $this->meta, 'times' => $this->times, 'times_dates' => $this->times_dates, 'args' => $this->args, ], ]; } public function deserialize( $properties ) { $this->date = ! empty( $properties['date'] ) && is_string( $properties['date'] ) ? $properties['date'] : ''; $this->message = ! empty( $properties['message'] ) && is_string( $properties['message'] ) ? $properties['message'] : ''; $this->type = ! empty( $properties['type'] ) && is_string( $properties['type'] ) ? $properties['type'] : ''; $this->meta = ! empty( $properties['meta'] ) && is_array( $properties['meta'] ) ? $properties['meta'] : []; $this->times = ! empty( $properties['times'] ) && is_string( $properties['times'] ) ? $properties['times'] : ''; $this->times_dates = ! empty( $properties['times_dates'] ) && is_array( $properties['times_dates'] ) ? $properties['times_dates'] : []; $this->args = ! empty( $properties['args'] ) && is_array( $properties['args'] ) ? $properties['args'] : []; } /** * @return Log_Item_Interface | null */ public static function from_json( $str ) { $obj = json_decode( $str, true ); if ( ! array_key_exists( 'class', $obj ) ) { return null; } $class = $obj['class']; if ( class_exists( $class ) ) { /** @var Base $item */ $item = new $class( $obj['item']['message'] ); $item->deserialize( $obj['item'] ); return $item; } return null; } public function to_formatted_string( $output_format = 'html' ) { $vars = get_object_vars( $this ); $format = static::FORMAT; if ( 'html' === $output_format ) { $format = str_replace( 'message', 'message', static::FORMAT ); } if ( empty( $vars['meta'] ) ) { $format = str_replace( '[meta]', '', $format ); } else { $vars['meta'] = stripslashes( var_export( $vars['meta'], true ) ); // @codingStandardsIgnoreLine } return strtr( $format, $vars ); } public function get_fingerprint() { $unique_key = $this->type . $this->message . var_export( $this->meta, true ); // @codingStandardsIgnoreLine //info messages are not be aggregated: if ( 'info' === $this->type ) { $unique_key .= $this->date; } return md5( $unique_key ); } public function increase_times( $item, $truncate = true ) { $this->times++; $this->times_dates[] = $item->date; if ( $truncate && ( self::MAX_LOG_ENTRIES < count( $this->times_dates ) ) ) { $this->times_dates = array_slice( $this->times_dates, -self::MAX_LOG_ENTRIES ); } } public function format( $format = 'html' ) { $trace = $this->format_trace(); if ( empty( $trace ) ) { return $this->to_formatted_string( $format ); } $copy = clone $this; $copy->meta['trace'] = $trace; return $copy->to_formatted_string( $format ); } public function get_name() { return 'Log'; } private function format_trace() { $trace = empty( $this->meta['trace'] ) ? '' : $this->meta['trace']; if ( is_string( $trace ) ) { return $trace; } $trace_str = ''; foreach ( $trace as $key => $trace_line ) { $format = static::TRACE_FORMAT; $trace_line['key'] = $key; if ( empty( $trace_line['file'] ) ) { $format = str_replace( 'file(line): ', '', $format ); } $trace_str .= PHP_EOL . strtr( $format, $trace_line ); $trace_str .= empty( $trace_line['args'] ) ? '' : var_export( $trace_line['args'], true ); // @codingStandardsIgnoreLine } return $trace_str . PHP_EOL; } private function set_trace() { if ( ! empty( $this->args['trace'] ) && true === $this->args['trace'] ) { $limit = empty( $this->args['trace_limit'] ) ? static::TRACE_LIMIT : $this->args['trace_limit']; $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // @codingStandardsIgnoreLine while ( ! empty( $stack ) && ! empty( $stack[0]['file'] ) && ( false !== strpos( $stack[0]['file'], 'core' . DIRECTORY_SEPARATOR . 'logger' ) ) ) { array_shift( $stack ); } $this->meta['trace'] = array_slice( $stack, 0, $limit ); return; } if ( is_array( $this->args ) ) { unset( $this->args['trace'] ); } } } file = empty( $args['file'] ) ? '' : $args['file']; $this->line = empty( $args['line'] ) ? '' : $args['line']; } #[\ReturnTypeWillChange] public function jsonSerialize() { $json_arr = parent::jsonSerialize(); $json_arr['file'] = $this->file; $json_arr['line'] = $this->line; return $json_arr; } public function deserialize( $properties ) { parent::deserialize( $properties ); $this->file = ! empty( $properties['file'] ) && is_string( $properties['file'] ) ? $properties['file'] : ''; $this->line = ! empty( $properties['line'] ) && is_string( $properties['line'] ) ? $properties['line'] : ''; } public function get_name() { return 'File'; } } column = $args['column']; $this->file = $args['url']; $this->date = gmdate( 'Y-m-d H:i:s', $args['timestamp'] ); } #[\ReturnTypeWillChange] public function jsonSerialize() { $json_arr = parent::jsonSerialize(); $json_arr['column'] = $this->column; return $json_arr; } public function deserialize( $properties ) { parent::deserialize( $properties ); $this->column = ! empty( $properties['column'] ) && is_string( $properties['column'] ) ? $properties['column'] : ''; } public function get_name() { return 'JS'; } }