diff --git a/includes/modules/shortcodes/types/elementor.php b/includes/modules/shortcodes/types/elementor.php new file mode 100644 index 0000000..0cf6b90 --- /dev/null +++ b/includes/modules/shortcodes/types/elementor.php @@ -0,0 +1,209 @@ + '', + 'id' => 0, + 'before' => '', + 'after' => '', + 'fallback' => '', + 'format' => '', + ]; + } + + /** + * Renders shortcode output. + * + * @since NEXT + * + * @param array $attributes Shortcode attributes. + * @param string $content Enclosed content (optional). + * + * @return string + */ + public function render( array $attributes, string $content = '' ) { + // Merges defaults. + $attributes = $this->get_attributes( $attributes ); + + // Parses dynamic attributes. + $attributes = anys_parse_dynamic_attributes( $attributes ); + + // Validates provider. + $provider_name = strtolower( (string) ( $attributes['name'] ?? '' ) ); + if ( $provider_name !== 'template' ) { + return ''; + } + + // Validates Elementor presence. + if ( ! did_action( 'elementor/loaded' ) || ! class_exists( '\Elementor\Plugin' ) ) { + $value = esc_html__( 'Elementor is not active.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Validates template ID. + $template_id = (int) ( $attributes['id'] ?? 0 ); + if ( $template_id <= 0 ) { + $value = esc_html__( 'Missing or invalid "id" attribute.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Fetches template post. + $template_post = get_post( $template_id ); + if ( ! $template_post ) { + $value = esc_html__( 'Template not found.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Validates post type. + if ( get_post_type( $template_post ) !== 'elementor_library' ) { + $value = esc_html__( 'The provided ID is not an Elementor template.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Enqueues assets when needed. + $this->anys_maybe_enqueue_elementor_assets( $attributes ); + + // Reads template type. + $template_type = get_post_meta( $template_id, '_elementor_template_type', true ); // 'section' | 'page' + if ( $template_type && ! in_array( $template_type, [ 'section', 'page' ], true ) ) { + $value = esc_html__( 'Unsupported Elementor template type.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Prevents recursion. + if ( is_singular( 'elementor_library' ) && get_the_ID() === $template_id ) { + $value = esc_html__( 'Recursive rendering detected.', 'anys' ); + $output = anys_wrap_output( $value, $attributes ); + return wp_kses_post( (string) $output ); + } + + // Builds cache key. + $cache_key = sprintf( + 'anys_elem_tpl_%d_%s_%s', + $template_id, + (string) strtotime( $template_post->post_modified_gmt ), + $template_type ? $template_type : 'na' + ); + + // Returns cached raw HTML when available. + $cached_html = get_transient( $cache_key ); + if ( $cached_html !== false ) { + // Raw HTML is intentionally not escaped to keep Elementor markup intact. + return anys_wrap_output( $cached_html, $attributes ); + } + + try { + // Renders template. + $html = \Elementor\Plugin::instance()->frontend->get_builder_content_for_display( $template_id, true ); + + // Wraps section when needed. + if ( $template_type === 'section' ) { + $html = '