balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

module.php (11365B)


      1 <?php
      2 namespace Elementor\Modules\PageTemplates;
      3 
      4 use Elementor\Controls_Manager;
      5 use Elementor\Core\Base\Document;
      6 use Elementor\Core\Base\Module as BaseModule;
      7 use Elementor\Core\Kits\Documents\Kit;
      8 use Elementor\Plugin;
      9 use Elementor\Utils;
     10 use Elementor\Core\DocumentTypes\PageBase as PageBase;
     11 use Elementor\Modules\Library\Documents\Page as LibraryPageDocument;
     12 
     13 if ( ! defined( 'ABSPATH' ) ) {
     14 	exit; // Exit if accessed directly
     15 }
     16 
     17 /**
     18  * Elementor page templates module.
     19  *
     20  * Elementor page templates module handler class is responsible for registering
     21  * and managing Elementor page templates modules.
     22  *
     23  * @since 2.0.0
     24  */
     25 class Module extends BaseModule {
     26 
     27 	/**
     28 	 * The of the theme.
     29 	 */
     30 	const TEMPLATE_THEME = 'elementor_theme';
     31 
     32 	/**
     33 	 * Elementor Canvas template name.
     34 	 */
     35 	const TEMPLATE_CANVAS = 'elementor_canvas';
     36 
     37 	/**
     38 	 * Elementor Header & Footer template name.
     39 	 */
     40 	const TEMPLATE_HEADER_FOOTER = 'elementor_header_footer';
     41 
     42 	/**
     43 	 * Print callback.
     44 	 *
     45 	 * Holds the page template callback content.
     46 	 *
     47 	 * @since 2.0.0
     48 	 * @access protected
     49 	 *
     50 	 * @var callable
     51 	 */
     52 	protected $print_callback;
     53 
     54 	/**
     55 	 * Get module name.
     56 	 *
     57 	 * Retrieve the page templates module name.
     58 	 *
     59 	 * @since 2.0.0
     60 	 * @access public
     61 	 *
     62 	 * @return string Module name.
     63 	 */
     64 	public function get_name() {
     65 		return 'page-templates';
     66 	}
     67 
     68 	/**
     69 	 * Template include.
     70 	 *
     71 	 * Update the path for the Elementor Canvas template.
     72 	 *
     73 	 * Fired by `template_include` filter.
     74 	 *
     75 	 * @since 2.0.0
     76 	 * @access public
     77 	 *
     78 	 * @param string $template The path of the template to include.
     79 	 *
     80 	 * @return string The path of the template to include.
     81 	 */
     82 	public function template_include( $template ) {
     83 		if ( is_singular() ) {
     84 			$document = Plugin::$instance->documents->get_doc_for_frontend( get_the_ID() );
     85 
     86 			if ( $document && $document::get_property( 'support_wp_page_templates' ) ) {
     87 				$page_template = $document->get_meta( '_wp_page_template' );
     88 
     89 				$template_path = $this->get_template_path( $page_template );
     90 
     91 				if ( self::TEMPLATE_THEME !== $page_template && ! $template_path && $document->is_built_with_elementor() ) {
     92 					$kit_default_template = Plugin::$instance->kits_manager->get_current_settings( 'default_page_template' );
     93 					$template_path = $this->get_template_path( $kit_default_template );
     94 				}
     95 
     96 				if ( $template_path ) {
     97 					$template = $template_path;
     98 
     99 					Plugin::$instance->inspector->add_log( 'Page Template', Plugin::$instance->inspector->parse_template_path( $template ), $document->get_edit_url() );
    100 				}
    101 			}
    102 		}
    103 
    104 		return $template;
    105 	}
    106 
    107 	/**
    108 	 * Add WordPress templates.
    109 	 *
    110 	 * Adds Elementor templates to all the post types that support
    111 	 * Elementor.
    112 	 *
    113 	 * Fired by `init` action.
    114 	 *
    115 	 * @since 2.0.0
    116 	 * @access public
    117 	 */
    118 	public function add_wp_templates_support() {
    119 		$post_types = get_post_types_by_support( 'elementor' );
    120 
    121 		foreach ( $post_types as $post_type ) {
    122 			add_filter( "theme_{$post_type}_templates", [ $this, 'add_page_templates' ], 10, 4 );
    123 		}
    124 	}
    125 
    126 	/**
    127 	 * Add page templates.
    128 	 *
    129 	 * Add the Elementor page templates to the theme templates.
    130 	 *
    131 	 * Fired by `theme_{$post_type}_templates` filter.
    132 	 *
    133 	 * @since 2.0.0
    134 	 * @access public
    135 	 * @static
    136 	 *
    137 	 * @param array $page_templates Array of page templates. Keys are filenames,
    138 	 *                              checks are translated names.
    139 	 *
    140 	 * @param \WP_Theme $wp_theme
    141 	 * @param \WP_Post $post
    142 	 *
    143 	 * @return array Page templates.
    144 	 */
    145 	public function add_page_templates( $page_templates, $wp_theme, $post ) {
    146 		if ( $post ) {
    147 			// FIX ME: Gutenberg not send $post as WP_Post object, just the post ID.
    148 			$post_id = ! empty( $post->ID ) ? $post->ID : $post;
    149 
    150 			$document = Plugin::$instance->documents->get( $post_id );
    151 			if ( $document && ! $document::get_property( 'support_wp_page_templates' ) ) {
    152 				return $page_templates;
    153 			}
    154 		}
    155 
    156 		$page_templates = [
    157 			self::TEMPLATE_CANVAS => _x( 'Elementor Canvas', 'Page Template', 'elementor' ),
    158 			self::TEMPLATE_HEADER_FOOTER => _x( 'Elementor Full Width', 'Page Template', 'elementor' ),
    159 			self::TEMPLATE_THEME => _x( 'Theme', 'Page Template', 'elementor' ),
    160 		] + $page_templates;
    161 
    162 		return $page_templates;
    163 	}
    164 
    165 	/**
    166 	 * Set print callback.
    167 	 *
    168 	 * Set the page template callback.
    169 	 *
    170 	 * @since 2.0.0
    171 	 * @access public
    172 	 *
    173 	 * @param callable $callback
    174 	 */
    175 	public function set_print_callback( $callback ) {
    176 		$this->print_callback = $callback;
    177 	}
    178 
    179 	/**
    180 	 * Print callback.
    181 	 *
    182 	 * Prints the page template content using WordPress loop.
    183 	 *
    184 	 * @since 2.0.0
    185 	 * @access public
    186 	 */
    187 	public function print_callback() {
    188 		while ( have_posts() ) :
    189 			the_post();
    190 			the_content();
    191 		endwhile;
    192 	}
    193 
    194 	/**
    195 	 * Print content.
    196 	 *
    197 	 * Prints the page template content.
    198 	 *
    199 	 * @since 2.0.0
    200 	 * @access public
    201 	 */
    202 	public function print_content() {
    203 		if ( ! $this->print_callback ) {
    204 			$this->print_callback = [ $this, 'print_callback' ];
    205 		}
    206 
    207 		call_user_func( $this->print_callback );
    208 	}
    209 
    210 	/**
    211 	 * Get page template path.
    212 	 *
    213 	 * Retrieve the path for any given page template.
    214 	 *
    215 	 * @since 2.0.0
    216 	 * @access public
    217 	 *
    218 	 * @param string $page_template The page template name.
    219 	 *
    220 	 * @return string Page template path.
    221 	 */
    222 	public function get_template_path( $page_template ) {
    223 		$template_path = '';
    224 		switch ( $page_template ) {
    225 			case self::TEMPLATE_CANVAS:
    226 				$template_path = __DIR__ . '/templates/canvas.php';
    227 				break;
    228 			case self::TEMPLATE_HEADER_FOOTER:
    229 				$template_path = __DIR__ . '/templates/header-footer.php';
    230 				break;
    231 		}
    232 
    233 		return $template_path;
    234 	}
    235 
    236 	/**
    237 	 * Register template control.
    238 	 *
    239 	 * Adds custom controls to any given document.
    240 	 *
    241 	 * Fired by `update_post_metadata` action.
    242 	 *
    243 	 * @since 2.0.0
    244 	 * @access public
    245 	 *
    246 	 * @param Document $document The document instance.
    247 	 */
    248 	public function action_register_template_control( $document ) {
    249 		if ( $document instanceof PageBase || $document instanceof LibraryPageDocument ) {
    250 			$this->register_template_control( $document );
    251 		}
    252 	}
    253 
    254 	/**
    255 	 * Register template control.
    256 	 *
    257 	 * Adds custom controls to any given document.
    258 	 *
    259 	 * @since 2.0.0
    260 	 * @access public
    261 	 *
    262 	 * @param Document $document   The document instance.
    263 	 * @param string   $control_id Optional. The control ID. Default is `template`.
    264 	 */
    265 	public function register_template_control( $document, $control_id = 'template' ) {
    266 		if ( ! Utils::is_cpt_custom_templates_supported() ) {
    267 			return;
    268 		}
    269 
    270 		require_once ABSPATH . '/wp-admin/includes/template.php';
    271 
    272 		$document->start_injection( [
    273 			'of' => 'post_status',
    274 			'fallback' => [
    275 				'of' => 'post_title',
    276 			],
    277 		] );
    278 
    279 		$control_options = [
    280 			'options' => array_flip( get_page_templates( null, $document->get_main_post()->post_type ) ),
    281 		];
    282 
    283 		$this->add_template_controls( $document, $control_id, $control_options );
    284 
    285 		$document->end_injection();
    286 	}
    287 
    288 	// The $options variable is an array of $control_options to overwrite the default
    289 	public function add_template_controls( Document $document, $control_id, $control_options ) {
    290 		// Default Control Options
    291 		$default_control_options = [
    292 			'label' => esc_html__( 'Page Layout', 'elementor' ),
    293 			'type' => Controls_Manager::SELECT,
    294 			'default' => 'default',
    295 			'options' => [
    296 				'default' => esc_html__( 'Default', 'elementor' ),
    297 			],
    298 		];
    299 
    300 		$control_options = array_replace_recursive( $default_control_options, $control_options );
    301 
    302 		$document->add_control(
    303 			$control_id,
    304 			$control_options
    305 		);
    306 
    307 		$document->add_control(
    308 			$control_id . '_default_description',
    309 			[
    310 				'type' => Controls_Manager::RAW_HTML,
    311 				'raw' => '<b>' . esc_html__( 'The default page template as defined in Elementor Panel → Hamburger Menu → Site Settings.', 'elementor' ) . '</b>',
    312 				'content_classes' => 'elementor-descriptor',
    313 				'condition' => [
    314 					$control_id => 'default',
    315 				],
    316 			]
    317 		);
    318 
    319 		$document->add_control(
    320 			$control_id . '_theme_description',
    321 			[
    322 				'type' => Controls_Manager::RAW_HTML,
    323 				'raw' => '<b>' . esc_html__( 'Default Page Template from your theme.', 'elementor' ) . '</b>',
    324 				'content_classes' => 'elementor-descriptor',
    325 				'condition' => [
    326 					$control_id => self::TEMPLATE_THEME,
    327 				],
    328 			]
    329 		);
    330 
    331 		$document->add_control(
    332 			$control_id . '_canvas_description',
    333 			[
    334 				'type' => Controls_Manager::RAW_HTML,
    335 				'raw' => '<b>' . esc_html__( 'No header, no footer, just Elementor', 'elementor' ) . '</b>',
    336 				'content_classes' => 'elementor-descriptor',
    337 				'condition' => [
    338 					$control_id => self::TEMPLATE_CANVAS,
    339 				],
    340 			]
    341 		);
    342 
    343 		$document->add_control(
    344 			$control_id . '_header_footer_description',
    345 			[
    346 				'type' => Controls_Manager::RAW_HTML,
    347 				'raw' => '<b>' . esc_html__( 'This template includes the header, full-width content and footer', 'elementor' ) . '</b>',
    348 				'content_classes' => 'elementor-descriptor',
    349 				'condition' => [
    350 					$control_id => self::TEMPLATE_HEADER_FOOTER,
    351 				],
    352 			]
    353 		);
    354 
    355 		if ( $document instanceof Kit ) {
    356 			$document->add_control(
    357 				'reload_preview_description',
    358 				[
    359 					'type' => Controls_Manager::RAW_HTML,
    360 					'raw' => esc_html__( 'Changes will be reflected in the preview only after the page reloads.', 'elementor' ),
    361 					'content_classes' => 'elementor-descriptor',
    362 				]
    363 			);
    364 		}
    365 	}
    366 
    367 	/**
    368 	 * Filter metadata update.
    369 	 *
    370 	 * Filters whether to update metadata of a specific type.
    371 	 *
    372 	 * Elementor don't allow WordPress to update the parent page template
    373 	 * during `wp_update_post`.
    374 	 *
    375 	 * Fired by `update_{$meta_type}_metadata` filter.
    376 	 *
    377 	 * @since 2.0.0
    378 	 * @access public
    379 	 *
    380 	 * @param bool   $check     Whether to allow updating metadata for the given type.
    381 	 * @param int    $object_id Object ID.
    382 	 * @param string $meta_key  Meta key.
    383 	 *
    384 	 * @return bool Whether to allow updating metadata of a specific type.
    385 	 */
    386 	public function filter_update_meta( $check, $object_id, $meta_key ) {
    387 		if ( '_wp_page_template' === $meta_key && Plugin::$instance->common ) {
    388 			/** @var \Elementor\Core\Common\Modules\Ajax\Module $ajax */
    389 			$ajax = Plugin::$instance->common->get_component( 'ajax' );
    390 
    391 			$ajax_data = $ajax->get_current_action_data();
    392 
    393 			$is_autosave_action = $ajax_data && 'save_builder' === $ajax_data['action'] && Document::STATUS_AUTOSAVE === $ajax_data['data']['status'];
    394 
    395 			// Don't allow WP to update the parent page template.
    396 			// (during `wp_update_post` from page-settings or save_plain_text).
    397 			if ( $is_autosave_action && ! wp_is_post_autosave( $object_id ) && Document::STATUS_DRAFT !== get_post_status( $object_id ) ) {
    398 				$check = false;
    399 			}
    400 		}
    401 
    402 		return $check;
    403 	}
    404 
    405 	/**
    406 	 * Support `wp_body_open` action, available since WordPress 5.2.
    407 	 *
    408 	 * @since 2.7.0
    409 	 * @access public
    410 	 */
    411 	public static function body_open() {
    412 		if ( function_exists( 'wp_body_open' ) ) {
    413 			wp_body_open();
    414 		} else {
    415 			do_action( 'wp_body_open' );
    416 		}
    417 	}
    418 
    419 	/**
    420 	 * Page templates module constructor.
    421 	 *
    422 	 * Initializing Elementor page templates module.
    423 	 *
    424 	 * @since 2.0.0
    425 	 * @access public
    426 	 */
    427 	public function __construct() {
    428 		add_action( 'init', [ $this, 'add_wp_templates_support' ] );
    429 
    430 		add_filter( 'template_include', [ $this, 'template_include' ], 11 /* After Plugins/WooCommerce */ );
    431 
    432 		add_action( 'elementor/documents/register_controls', [ $this, 'action_register_template_control' ] );
    433 
    434 		add_filter( 'update_post_metadata', [ $this, 'filter_update_meta' ], 10, 3 );
    435 	}
    436 }