/home/moonrcjl/www/wp-content/themes/astra/inc/metabox/class-astra-elementor-editor-settings.php
<?php
/**
* Elementor Editor Settings Integration.
*
* Adds custom React-based settings to the Elementor editor page settings panel.
*
* @package Astra
* @link https://wpastra.com/
* @since 4.11.3
*/
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
/**
* Elementor Editor Settings integration class.
*
* @since 4.11.3
*/
if ( ! class_exists( 'Astra_Elementor_Editor_Settings' ) ) {
/**
* Elementor Editor Settings integration class.
*
* @since 4.11.3
*/
class Astra_Elementor_Editor_Settings {
/**
* Class instance.
*
* @var self|null
* @since 4.11.3
*/
private static $instance = null;
/**
* Get instance.
*
* @since 4.11.3
* @return self
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*
* @since 4.11.3
*/
private function __construct() {
// Bail if Elementor is not active.
if ( ! did_action( 'elementor/loaded' ) ) {
return;
}
// Get post ID.
$post_id = 0;
if ( isset( $_REQUEST['post'] ) ) {
$post_id = absint( $_REQUEST['post'] );
}
if ( isset( $_REQUEST['editor_post_id'] ) ) {
$post_id = absint( $_REQUEST['editor_post_id'] );
}
$post_type = get_post_type( $post_id );
// Bail if post type is excluded.
if ( ! $post_id || in_array( $post_type, self::get_excluded_post_types(), true ) ) {
return;
}
$this->init_hooks();
}
/**
* Initialize WordPress hooks.
*
* @since 4.11.3
*/
private function init_hooks() {
// Registering actions for Elementor editor assets, document controls, and custom control styles.
add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'enqueue_editor_assets' ) );
add_action( 'elementor/documents/register_controls', array( $this, 'register_document_controls' ), 20 );
add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'add_custom_control_style' ) );
// Hook into Elementor's document saving process to persist Astra-specific settings.
add_action( 'elementor/document/after_save', array( $this, 'sync_save_settings' ) );
// Hook into the template redirect action to handle Elementor preview.
add_action( 'template_redirect', array( $this, 'handle_preview' ) );
// Hook into wp_after_insert_post to sync site-post-title with Elementor hide_title.
add_action( 'wp_after_insert_post', array( $this, 'sync_site_post_title_to_elementor' ) );
}
/**
* Check if in Elementor editor mode.
*
* @since 4.11.9
* @return bool
*/
public static function is_elementor_editor() {
// Check if in Elementor editor mode.
/** @psalm-suppress UndefinedClass */
if ( ! class_exists( '\Elementor\Plugin' ) || ! \Elementor\Plugin::$instance->editor || ! \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
return false;
}
return true;
}
/**
* Get array of setting keys for Astra Elementor settings.
*
* @since 4.11.3
*
* @return array Array of setting keys.
*/
public static function get_astra_elementor_setting_keys() {
$settings = array(
'site-post-title', // Astra Disable Title.
'ast-site-content-layout', // Container Layout.
'site-content-style', // Container Style.
'site-sidebar-layout', // Sidebar Layout.
'site-sidebar-style', // Sidebar Style.
'ast-global-header-display', // Disable Header.
'footer-sml-layout', // Disable Footer.
'ast-banner-title-visibility', // Disable Banner Area.
'ast-breadcrumbs-content', // Disable breadcrumb.
'ast-hfb-above-header-display', // Disable Above Header.
'ast-main-header-display', // Disable Primary Header.
'ast-hfb-below-header-display', // Disable Below Header.
'ast-hfb-mobile-header-display', // Disable Mobile Header.
'theme-transparent-header-meta', // Transparent Header.
'stick-header-meta', // Sticky Header (Pro Option).
'header-above-stick-meta', // Stick Above Header (Pro Option).
'header-main-stick-meta', // Stick Primary Header (Pro Option).
'header-below-stick-meta', // Stick Below Header (Pro Option).
);
/**
* Filter to modify the Astra Elementor setting keys.
*
* @since 4.11.3
*
* @param array $keys Array of Astra Elementor setting keys.
*/
return apply_filters( 'astra_elementor_page_setting_keys', $settings );
}
/**
* Enqueue scripts for Elementor editor settings React app.
*
* @since 4.11.3
*/
public function enqueue_editor_assets() {
// Check if in Elementor editor mode.
if ( ! self::is_elementor_editor() ) {
return;
}
$handle = 'astra-elementor-meta-settings';
$path = ASTRA_THEME_URI . '/inc/metabox/extend-metabox/build/elementor.js';
// Get the script dependencies from the asset file.
$dependencies = array();
if ( file_exists( ASTRA_THEME_DIR . 'inc/metabox/extend-metabox/build/elementor.asset.php' ) ) {
$assets = require ASTRA_THEME_DIR . 'inc/metabox/extend-metabox/build/elementor.asset.php';
if ( isset( $assets['dependencies'] ) ) {
$dependencies = $assets['dependencies'];
}
}
wp_enqueue_script(
$handle,
$path,
$dependencies,
ASTRA_THEME_VERSION,
true
);
/**
* Filter to modify the localized data for Astra astraElementor editor settings.
*
* @since 4.11.3
* @param array $localize_data Localized data for astraElementor editor settings.
*/
$localize_data = apply_filters(
'astra_elementor_editor_localize_data',
array(
'themeName' => astra_get_theme_name(),
'themeIconUrl' => esc_url( apply_filters( 'astra_admin_menu_icon', ASTRA_THEME_URI . 'inc/assets/images/astra-logo.svg' ) ),
'postTitle' => get_post_meta( intval( get_the_ID() ), 'site-post-title', true ),
)
);
wp_localize_script( $handle, 'astraElementorEditor', $localize_data );
}
/**
* Get formatted container layout options with 'title' and 'icon'.
*
* @return array Formatted content layout options.
*/
public static function get_formatted_container_layout_options() {
$options = Astra_Meta_Boxes::get_instance()->get_content_layout_options();
foreach ( $options as $key => $label ) {
$options[ $key ] = array(
'title' => $label,
'icon' => 'default' === $key ? 'layout-default' : $key, // alternatively we can use 'image' key to provide custom image URLs.
);
}
return $options;
}
/**
* Get formatted container style options with only 'title'.
*
* @return array Formatted content style options.
*/
public static function get_formatted_container_style_options() {
$options = Astra_Meta_Boxes::get_instance()->get_content_style_options();
return array_map(
static function( $title ) {
return array( 'title' => $title );
},
$options
);
}
/**
* Get formatted sidebar layout options with 'title' and 'icon'.
*
* @return array Formatted sidebar layout options.
*/
public static function get_formatted_sidebar_layout_options() {
$options = Astra_Meta_Boxes::get_instance()->get_sidebar_options();
foreach ( $options as $key => $label ) {
$options[ $key ] = array(
'title' => $label,
'icon' => 'default' === $key ? 'layout-default' : $key,
);
}
return $options;
}
/**
* Get formatted sidebar style options with only 'title'.
*
* @return array Formatted sidebar style options.
*/
public static function get_formatted_sidebar_style_options() {
$options = Astra_Meta_Boxes::get_instance()->get_sidebar_style_options();
return array_map(
static function( $title ) {
return array( 'title' => $title );
},
$options
);
}
/**
* Get formatted header enabled options with only 'title'.
* Usage: For Transparent and Sticky Header options.
*
* @return array Formatted header enabled options.
*/
public static function get_formatted_header_enabled_options() {
$options = Astra_Meta_Boxes::get_instance()->get_header_enabled_options();
return array_map(
static function( $title ) {
return array( 'title' => $title );
},
$options
);
}
/**
* Register additional document controls.
*
* Adds a new section and control to the Elementor Page Settings panel,
* providing a placeholder div for the React-powered Astra Settings UI.
*
* @param \Elementor\Core\DocumentTypes\PageBase $document The PageBase document instance.
*
* @since 4.11.3
*
* @psalm-suppress DocblockTypeContradiction
* @psalm-suppress UndefinedDocblockClass
* @psalm-suppress UndefinedClass
*/
public function register_document_controls( $document ) {
if ( ! class_exists( '\Elementor\Controls_Manager' ) || ! class_exists( '\Elementor\Core\DocumentTypes\PageBase' ) ) {
return;
}
// Only proceed if the document is a valid Elementor PageBase type and has elements.
if ( ! $document instanceof \Elementor\Core\DocumentTypes\PageBase || ! $document::get_property( 'has_elements' ) ) {
return;
}
$id = intval( get_the_ID() );
// Start a new section in the Elementor Page Settings -> Setting tab.
$document->start_controls_section(
'astra_section',
array(
'label' => esc_html__( 'Astra Settings', 'astra' ),
'tab' => \Elementor\Controls_Manager::TAB_SETTINGS,
)
);
// Container Section Title.
$document->add_control(
'ast-container-heading',
array(
'label' => __( 'Container', 'astra' ),
'type' => \Elementor\Controls_Manager::HEADING,
)
);
// Container Layout using Choose control with images.
$document->add_control(
'ast-site-content-layout',
array(
'classes' => 'ast-layout-control',
'label' => __( 'Container Layout', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_container_layout_options(),
'default' => get_post_meta( $id, 'ast-site-content-layout', true ),
'toggle' => false,
)
);
// Container Style using Choose control (button group style).
$document->add_control(
'site-content-style',
array(
'classes' => 'ast-selector-control',
'label' => __( 'Container Style', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_container_style_options(),
'default' => get_post_meta( $id, 'site-content-style', true ),
'description' => __( 'Container style will apply only when layout is set to either Normal or Narrow.', 'astra' ),
'toggle' => false,
)
);
// Sidebar Section Title.
$document->add_control(
'ast-sidebar-heading',
array(
'label' => __( 'Sidebar', 'astra' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
)
);
$document->add_control(
'site-sidebar-layout',
array(
'classes' => 'ast-layout-control',
'label' => __( 'Sidebar Layout', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_sidebar_layout_options(),
'default' => get_post_meta( $id, 'site-sidebar-layout', true ),
'description' => __( 'Sidebar will only apply when container layout is set to normal.', 'astra' ),
'toggle' => false,
)
);
$document->add_control(
'site-sidebar-style',
array(
'classes' => 'ast-selector-control',
'label' => __( 'Sidebar Style', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_sidebar_style_options(),
'default' => get_post_meta( $id, 'site-sidebar-style', true ),
'toggle' => false,
)
);
// Disable Elements Section Title.
$document->add_control(
'ast-disable-elements-heading',
array(
'label' => __( 'Disable Elements', 'astra' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
)
);
$controls = Astra_Meta_Boxes::get_instance()->get_disable_section_fields();
foreach ( $controls as $details ) {
$meta_key = $details['key'];
$document->add_control(
$meta_key,
array(
'label' => $details['label'],
'type' => \Elementor\Controls_Manager::SWITCHER,
'default' => get_post_meta( $id, $meta_key, true ) === 'disabled' ? 'yes' : '',
)
);
}
$document->add_control(
'ast-advanced-settings-heading',
array(
'label' => __( 'Advanced Settings', 'astra' ),
'type' => \Elementor\Controls_Manager::HEADING,
'separator' => 'before',
)
);
$document->add_control(
'ast-header-rows-popover',
array(
'classes' => 'ast-popover-control',
'type' => \Elementor\Controls_Manager::POPOVER_TOGGLE,
'label' => __( 'Header Rows', 'astra' ),
)
);
$document->start_popover();
$controls = Astra_Meta_Boxes::get_instance()->get_header_disable_meta_fields();
foreach ( $controls as $details ) {
$meta_key = $details['key'];
$document->add_control(
$meta_key,
array(
'label' => $details['label'],
'type' => \Elementor\Controls_Manager::SWITCHER,
'default' => get_post_meta( $id, $meta_key, true ) === 'disabled' ? 'yes' : '',
)
);
}
$document->end_popover();
$document->add_control(
'theme-transparent-header-meta',
array(
'classes' => 'ast-selector-control',
'label' => __( 'Transparent Header', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_header_enabled_options(),
'default' => get_post_meta( $id, 'theme-transparent-header-meta', true ),
'toggle' => false,
)
);
if ( defined( 'ASTRA_EXT_VER' ) && class_exists( 'Astra_Ext_Extension' ) && Astra_Ext_Extension::is_active( 'sticky-header' ) ) {
$document->add_control(
'stick-header-meta',
array(
'classes' => 'ast-selector-control',
'label' => __( 'Sticky Header', 'astra' ),
'type' => \Elementor\Controls_Manager::CHOOSE,
'options' => self::get_formatted_header_enabled_options(),
'default' => get_post_meta( $id, 'stick-header-meta', true ),
'toggle' => false,
)
);
$document->add_control(
'ast-sticky-header-rows-popover',
array(
'classes' => 'ast-popover-control',
'type' => \Elementor\Controls_Manager::POPOVER_TOGGLE,
'label' => __( 'Sticky Header Rows', 'astra' ),
'condition' => array(
'stick-header-meta' => 'enabled', // show only when Sticky Header is enabled.
),
)
);
$document->start_popover();
$controls = Astra_Meta_Boxes::get_instance()->get_sticky_header_options();
foreach ( $controls as $details ) {
$meta_key = $details['key'];
$document->add_control(
$meta_key,
array(
'label' => $details['label'],
'type' => \Elementor\Controls_Manager::SWITCHER,
'default' => get_post_meta( $id, $meta_key, true ) === 'disabled' ? 'yes' : '',
)
);
}
$document->end_popover();
}
$document->add_control(
'ast-save-changes-notice',
array(
'type' => \Elementor\Controls_Manager::NOTICE,
'notice_type' => 'warning',
'content' => __( 'Make sure to update your post for changes to take effect.', 'astra' ),
)
);
// Preview changes button.
$document->add_control(
'ast-preview-changes-button',
array(
'type' => \Elementor\Controls_Manager::BUTTON,
'button_type' => 'success',
'text' => esc_html__( 'Preview Changes', 'astra' ),
'event' => 'namespace:editor:astraRefresh',
'disabled' => true,
)
);
if ( ! defined( 'ASTRA_EXT_VER' ) ) {
$document->add_control(
'ast-pro-notice',
array(
'type' => \Elementor\Controls_Manager::RAW_HTML,
'raw' => sprintf(
'<div class="ast-pro-upgrade-cta-wrapper">
<img src="%1$s" alt="Astra Logo">
<p class="elementor-control-field-description">%2$s</p>
<a href="%3$s" class="ast-pro-upgrade-link" target="_blank">%4$s</a>
</div>',
esc_url( ASTRA_THEME_URI . 'inc/assets/images/astra-logo.svg' ),
__( 'Unlock your full design potential and build a website to be proud of with Astra Pro.', 'astra' ),
astra_get_pro_url( '/pricing/', 'free-theme', 'elementor-editor', 'upgrade' ),
__( 'Upgrade Now', 'astra' )
),
)
);
}
$document->end_controls_section();
// Add a info notice below the Hide Title control.
$document->start_injection(
array(
'of' => 'post_status',
'fallback' => array(
'of' => 'post_title',
),
)
);
$document->add_control(
'ast-hide-title-notice',
array(
'type' => \Elementor\Controls_Manager::NOTICE,
'notice_type' => 'info',
'content' => __( "Changes to 'Hide Title' will automatically sync with Astra’s 'Disable Title' option.", 'astra' ),
)
);
$document->end_injection();
}
/**
* Adds inline styles to enhance Astra controls in Elementor Page Settings.
*
* Optimizes layout and display of CHOOSE controls (like container and sidebar settings).
* by using grid layouts and ensuring button labels are visible.
*
* @since 4.11.3
*
* @return void
*/
public function add_custom_control_style() {
$css_rules = '
<style>
.ast-layout-control .elementor-control-field,
.ast-selector-control .elementor-control-field {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.ast-layout-control .elementor-control-input-wrapper,
.ast-selector-control .elementor-control-input-wrapper {
width: 100%;
}
.ast-layout-control .elementor-choices {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
height: auto;
}
.ast-layout-control .elementor-choices-label,
.ast-selector-control .elementor-choices-label {
position: relative;
width: 100%;
}
.ast-layout-control .elementor-choices-label {
min-height: 92.5px;
border-radius: 3px;
border: none !important;
}
.ast-selector-control .elementor-choices-label::before {
content: attr(data-tooltip);
}
.ast-popover-control .elementor-control-popover-toggle-reset-label {
display: none;
}
.elementor-control-ast-preview-changes-button.elementor-control {
position: sticky;
bottom: 0;
padding-top: 15px;
backdrop-filter: blur(2px);
}
.elementor-control-ast-preview-changes-button.elementor-control .elementor-control-input-wrapper,
.elementor-control-ast-preview-changes-button.elementor-control .elementor-button {
width: 100%;
}
.ast-pro-upgrade-cta-wrapper {
padding: 20px 0;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
}
.ast-pro-upgrade-cta-wrapper .elementor-control-field-description {
margin-top: 0;
}
.ast-pro-upgrade-cta-wrapper a.ast-pro-upgrade-link {
color: #0284C7;
width: 100%;
padding: 8px;
border: 1px solid #0284C7;
border-radius: 2px;
}
';
// Icons CSS.
$icon_svgs = array(
'.layout-default' => self::get_svg( 'layout-default' ),
'.normal-width-container' => self::get_svg( 'normal-width-container' ),
'.narrow-width-container' => self::get_svg( 'narrow-width-container' ),
'.full-width-container' => self::get_svg( 'full-width-container' ),
'.no-sidebar' => self::get_svg( 'no-sidebar' ),
'.left-sidebar' => self::get_svg( 'left-sidebar' ),
'.right-sidebar' => self::get_svg( 'right-sidebar' ),
);
foreach ( $icon_svgs as $selector => $svg ) {
$encoded_svg = self::transform_svg( $svg );
$css_rules .= "{$selector}::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: url(\"data:image/svg+xml;utf8,{$encoded_svg}\") no-repeat center / contain;
}";
}
$css_rules .= '</style>';
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- This is inline CSS and does not require escaping.
echo class_exists( 'Astra_Minify' ) ? Astra_Minify::trim_css( $css_rules ) : $css_rules;
}
/**
* Handle Elementor template redirect for previewing Astra settings changes.
*
* @since 4.11.3
*/
public function handle_preview() {
$post_id = intval( get_the_ID() );
$preview_id = intval( isset( $_GET['preview_id'] ) ? $_GET['preview_id'] : 0 );
$preview_nonce = isset( $_GET['preview_nonce'] ) && is_scalar( $_GET['preview_nonce'] ) ? sanitize_text_field( $_GET['preview_nonce'] ) : '';
/** @psalm-suppress UndefinedClass */
$is_elementor_editor_preview = class_exists( '\Elementor\Plugin' ) && \Elementor\Plugin::$instance->preview->is_preview_mode();
$is_elementor_frontend_preview = is_preview() && $post_id === $preview_id && wp_verify_nonce( $preview_nonce, 'post_preview_' . $preview_id );
// Bail early if not in Elementor preview.
if ( ! $is_elementor_editor_preview && ! $is_elementor_frontend_preview ) {
return;
}
$revision_id = $post_id;
$revisions = wp_get_post_revisions(
$post_id,
array(
'order' => 'DESC',
'orderby' => 'ID',
)
);
foreach ( $revisions as $revision ) {
// Elementor stores this meta in preview revisions.
if ( get_post_meta( $revision->ID, '_elementor_edit_mode', true ) ) {
$revision_id = $revision->ID;
break;
}
}
$settings = get_post_meta( $revision_id, '_elementor_page_settings', true );
$keys = self::get_astra_elementor_setting_keys();
foreach ( $keys as $meta_key ) {
$meta_val = isset( $settings[ $meta_key ] ) ? $settings[ $meta_key ] : get_post_meta( $post_id, $meta_key, true );
add_filter(
'get_post_metadata',
static function( $value, $object_id, $key ) use ( $post_id, $meta_key, $meta_val ) {
if ( $object_id === $post_id && $key === $meta_key ) {
return array( $meta_val === 'yes' ? 'disabled' : $meta_val );
}
return $value;
},
10,
3
);
}
// Ensure the title is enabled for Elementor preview so that Hide Title toggle works correctly.
add_action( 'astra_the_title_enabled', '__return_true', 999 );
}
/**
* Sync specific Astra settings from Elementor's Page Settings to post meta.
*
* This function checks if certain custom Elementor controls are enabled (like disabling the header, footer,
* or banner area) and updates the corresponding post meta values accordingly. If the setting is not enabled,
* the meta key is removed.
*
* @psalm-suppress UndefinedDocblockClass
* @param \Elementor\Core\Base\Document $document The Elementor document object being saved.
*
* @since 4.11.3
*
* @return void
*/
public function sync_save_settings( $document ) {
$post_id = $document->get_id();
if ( ! $post_id || wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return;
}
// Get fresh saved settings directly from the meta.
$page_settings = $document->get_meta( '_elementor_page_settings' );
// If the settings are not an array, initialize it as an empty array.
if ( ! is_array( $page_settings ) ) {
$page_settings = array();
}
// Sync astra site-post-title with elementor hide_title.
$page_settings['site-post-title'] = isset( $page_settings['hide_title'] ) ? $page_settings['hide_title'] : '';
$keys = array(
'ast-site-content-layout', // Container Layout.
'site-content-style', // Container Style.
'site-sidebar-layout', // Sidebar Layout.
'site-sidebar-style', // Sidebar Style.
'theme-transparent-header-meta', // Transparent Header.
'stick-header-meta', // Sticky Header (Pro Option).
);
foreach ( $keys as $meta_key ) {
if ( isset( $page_settings[ $meta_key ] ) ) {
$value = $page_settings[ $meta_key ];
if ( $value ) {
update_post_meta( $post_id, $meta_key, $value );
} else {
delete_post_meta( $post_id, $meta_key );
}
// Remove setting from Elementor's saved settings.
unset( $page_settings[ $meta_key ] );
}
}
$keys = array(
'site-post-title', // Astra Disable Title.
'ast-global-header-display', // Disable Header.
'footer-sml-layout', // Disable Footer.
'ast-banner-title-visibility', // Disable Banner Area.
'ast-breadcrumbs-content', // Disable breadcrumb.
'ast-hfb-above-header-display', // Disable Above Header.
'ast-main-header-display', // Disable Primary Header.
'ast-hfb-below-header-display', // Disable Below Header.
'ast-hfb-mobile-header-display', // Disable Mobile Header.
'header-above-stick-meta', // Stick Above Header (Pro Option).
'header-main-stick-meta', // Stick Primary Header (Pro Option).
'header-below-stick-meta', // Stick Below Header (Pro Option).
);
foreach ( $keys as $meta_key ) {
if ( isset( $page_settings[ $meta_key ] ) ) {
$value = $page_settings[ $meta_key ];
if ( $value === 'yes' ) {
update_post_meta( $post_id, $meta_key, 'disabled' );
} else {
delete_post_meta( $post_id, $meta_key );
}
// Remove setting from Elementor's saved settings.
unset( $page_settings[ $meta_key ] );
}
}
// $document->update_meta( '_elementor_page_settings', $page_settings );
update_post_meta( $post_id, '_elementor_page_settings', $page_settings );
}
/**
* Retrieves an SVG icon based on the given icon name.
*
* @param string $icon The name of the icon to retrieve.
*
* @since 4.11.3
*
* @return string The SVG code for the icon or an empty string if the icon does not exist.
*/
public static function get_svg( $icon = '' ) {
if ( ! class_exists( 'Astra_Builder_UI_Controller' ) ) {
return '';
}
// Ensure the SVG icons are loaded.
$svg_icons = Astra_Builder_UI_Controller::$ast_svgs;
if ( ! Astra_Builder_UI_Controller::$ast_svgs ) {
Astra_Builder_UI_Controller::fetch_svg_icon();
$svg_icons = Astra_Builder_UI_Controller::$ast_svgs;
}
return isset( $svg_icons[ $icon ] ) ? $svg_icons[ $icon ] : '';
}
/**
* Transforms SVG markup for use in inline CSS by modifying colors and encoding.
*
* @param string $svg The raw SVG markup.
*
* @since 4.11.3
*
* @return string The transformed and encoded SVG string.
*/
private static function transform_svg( $svg ) {
// Basic validation: check if input is a non-empty string.
if ( trim( $svg ) === '' ) {
return rawurlencode( "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'></svg>" );
}
// Replace only the first occurrence of stroke='#D1D5DB' with a semi-transparent color.
$svg = preg_replace( "/stroke='#D1D5DB'/", "stroke='#9DA5AE55'", $svg, 1 );
// Perform bulk replacements for remaining known values.
$svg = str_replace(
array( "fill='white'", "stroke='#D8DBDF'", "fill='#E5E7EB'", "fill='#D1D5DB'", "stroke='#D1D5DB'" ),
array( "fill='#9DA5AE55'", "stroke='#9DA5AE55'", "fill='currentColor'", "fill='currentColor'", "stroke='currentColor'" ),
$svg
);
// URL-encode the SVG for embedding as a background-image.
return rawurlencode( $svg );
}
/**
* Sync site-post-title meta to Elementor hide_title when post is saved via WP editor.
*
* @param int $post_id Post id.
*
* @since 4.11.9
*/
public function sync_site_post_title_to_elementor( $post_id ) {
// Skip if this is a revision or autosave.
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return;
}
// Bail early if this is an Elementor AJAX request.
if ( ( isset( $_REQUEST['action'] ) && 'elementor_ajax' === $_REQUEST['action'] ) ) {
return true;
}
// Skip if saving from Elementor to avoid conflicts.
if ( did_action( 'elementor/document/after_save' ) ) {
return;
}
// Skip if post builder is not Elementor.
if ( 'builder' !== get_post_meta( $post_id, '_elementor_edit_mode', true ) ) {
return;
}
// Get the site-post-title meta value.
$site_post_title = get_post_meta( $post_id, 'site-post-title', true );
// Get current Elementor page settings.
$elementor_settings = get_post_meta( $post_id, '_elementor_page_settings', true );
if ( ! is_array( $elementor_settings ) ) {
$elementor_settings = array();
}
// Check if we need to update the hide_title setting.
$current_hide_title = isset( $elementor_settings['hide_title'] ) ? $elementor_settings['hide_title'] : '';
$new_hide_title = 'disabled' === $site_post_title ? 'yes' : '';
// Only update if the value has changed.
if ( $current_hide_title !== $new_hide_title ) {
if ( 'yes' === $new_hide_title ) {
$elementor_settings['hide_title'] = 'yes';
} else {
unset( $elementor_settings['hide_title'] );
}
// Update the Elementor page settings meta.
empty( $elementor_settings )
? delete_post_meta( $post_id, '_elementor_page_settings' )
: update_post_meta( $post_id, '_elementor_page_settings', $elementor_settings );
// Regenerate Elementor CSS cache to update --page-title-display variable.
if ( class_exists( '\Elementor\Plugin' ) ) {
/** @psalm-suppress UndefinedClass */
\Elementor\Plugin::$instance->files_manager->clear_cache();
}
}
}
/**
* Get excluded post types for Astra Meta setting in Elementor editor.
*
* @since 4.11.11
* @return array
*/
public static function get_excluded_post_types() {
/**
* Filter to exclude post types from rendering Astra Meta setting in Elementor editor.
*
* @param array $excluded_post_types Array of post types to exclude.
*/
return apply_filters(
'astra_elementor_editor_excluded_post_types',
array(
'astra-advanced-hook', // Astra Theme Builder Advanced Layout.
'elementskit_template', // ElementsKit Template.
)
);
}
}
}
/**
* Initialize the class singleton.
*/
Astra_Elementor_Editor_Settings::get_instance();