PluginProbe
Elementor Website Builder – more than just a page builder / 3.29.0-dev4
Elementor Website Builder – more than just a page builder v3.29.0-dev4
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / core / frontend / render-mode-manager.php

render-mode-manager.php in Elementor Website Builder – more than just a page builder 3.29.0-dev4, at core/frontend/render-mode-manager.php

190 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Frontend;
3
4 use Elementor\Core\Frontend\RenderModes\Render_Mode_Base;
5 use Elementor\Core\Frontend\RenderModes\Render_Mode_Normal;
6 use Elementor\Modules\CloudLibrary\Render_Mode_Preview;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 class Render_Mode_Manager {
13 const QUERY_STRING_PARAM_NAME = 'render_mode';
14 const QUERY_STRING_POST_ID = 'post_id';
15
16 const QUERY_STRING_TEMPLATE_ID = 'template_id';
17 const QUERY_STRING_NONCE_PARAM_NAME = 'render_mode_nonce';
18 const NONCE_ACTION_PATTERN = 'render_mode_{post_id}';
19
20 /**
21 * @var Render_Mode_Base
22 */
23 private $current;
24
25 /**
26 * @var Render_Mode_Base[]
27 */
28 private $render_modes = [];
29
30 /**
31 * @param $post_id
32 * @param $render_mode_name
33 *
34 * @return string
35 */
36 public static function get_base_url( $post_id, $render_mode_name ) {
37 return add_query_arg( [
38 self::QUERY_STRING_POST_ID => $post_id,
39 self::QUERY_STRING_PARAM_NAME => $render_mode_name,
40 self::QUERY_STRING_NONCE_PARAM_NAME => wp_create_nonce( self::get_nonce_action( $post_id ) ),
41 'ver' => time(),
42 ], get_permalink( $post_id ) );
43 }
44
45 /**
46 * @param $post_id
47 *
48 * @return string
49 */
50 public static function get_nonce_action( $post_id ) {
51 return str_replace( '{post_id}', $post_id, self::NONCE_ACTION_PATTERN );
52 }
53
54 /**
55 * Register a new render mode into the render mode manager.
56 *
57 * @param $class_name
58 *
59 * @return $this
60 * @throws \Exception If the class does not extend Render_Mode_Base.
61 */
62 public function register_render_mode( $class_name ) {
63 if ( ! is_subclass_of( $class_name, Render_Mode_Base::class ) ) {
64 throw new \Exception( sprintf( "'%s' must extend 'Render_Mode_Base'.", esc_html( $class_name ) ) );
65 }
66
67 $this->render_modes[ $class_name::get_name() ] = $class_name;
68
69 return $this;
70 }
71
72 /**
73 * Get the current render mode.
74 *
75 * @return Render_Mode_Base
76 */
77 public function get_current() {
78 return $this->current;
79 }
80
81 /**
82 * @param Render_Mode_Base $render_mode
83 *
84 * @return $this
85 */
86 private function set_current( Render_Mode_Base $render_mode ) {
87 $this->current = $render_mode;
88
89 return $this;
90 }
91
92 /**
93 * Set render mode.
94 *
95 * @return $this
96 */
97 private function choose_render_mode() {
98 $post_id = null;
99 $template_id = null;
100 $key = null;
101 $nonce = null;
102
103 if ( isset( $_GET[ self::QUERY_STRING_POST_ID ] ) ) {
104 $post_id = $_GET[ self::QUERY_STRING_POST_ID ]; // phpcs:ignore -- Nonce will be checked next line.
105 }
106
107 if ( isset( $_GET[ self::QUERY_STRING_NONCE_PARAM_NAME ] ) ) {
108 $nonce = $_GET[ self::QUERY_STRING_NONCE_PARAM_NAME ]; // phpcs:ignore -- Nonce will be checked next line.
109 }
110
111 if ( isset( $_GET[ self::QUERY_STRING_PARAM_NAME ] ) ) {
112 $key = $_GET[ self::QUERY_STRING_PARAM_NAME ]; // phpcs:ignore -- Nonce will be checked next line.
113 }
114
115 if ( isset( $_GET[ self::QUERY_STRING_TEMPLATE_ID ] ) ) {
116 $template_id = $_GET[ self::QUERY_STRING_TEMPLATE_ID ]; // phpcs:ignore -- Nonce will be checked next line.
117 }
118
119 if (
120 $post_id &&
121 $nonce &&
122 wp_verify_nonce( $nonce, self::get_nonce_action( $post_id ) ) &&
123 $key &&
124 array_key_exists( $key, $this->render_modes )
125 ) {
126 $this->set_current( new $this->render_modes[ $key ]( $post_id ) );
127 } else if ( $this->is_preview_mode( $template_id, $key, $nonce ) ) {
128 $this->set_current( new $this->render_modes[ $key ]( $template_id ) );
129 } else {
130 $this->set_current( new Render_Mode_Normal( $post_id ) );
131 }
132
133 return $this;
134 }
135
136 private function is_preview_mode( $template_id, $render_mode, $nonce ) {
137 if ( empty( $template_id ) ) {
138 return false;
139 }
140
141 if ( Render_Mode_Preview::MODE !== $render_mode ) {
142 return false;
143 }
144
145 if ( ! array_key_exists( $render_mode, $this->render_modes ) ) {
146 return false;
147 }
148
149 if ( ! wp_verify_nonce( $nonce, self::get_nonce_action( $template_id ) ) ) {
150 wp_die( esc_html__( 'Not Authorized', 'elementor' ), esc_html__( 'Error', 'elementor' ), 403 );
151 }
152
153 return true;
154 }
155
156 /**
157 * Add actions base on the current render.
158 *
159 * @throws \Requests_Exception_HTTP_403 If the current render mode does not have the required permissions.
160 * @throws Status403 If the current render mode does not have the required permissions.
161 */
162 private function add_current_actions() {
163 if ( ! $this->current->get_permissions_callback() ) {
164 // WP >= 6.2-alpha
165 if ( class_exists( '\WpOrg\Requests\Exception\Http\Status403' ) ) {
166 throw new \WpOrg\Requests\Exception\Http\Status403();
167 } else {
168 throw new \Requests_Exception_HTTP_403();
169 }
170 }
171
172 // Run when 'template-redirect' actually because the the class is instantiate when 'template-redirect' run.
173 $this->current->prepare_render();
174 }
175
176 /**
177 * Render_Mode_Manager constructor.
178 *
179 * @throws \Exception If the render mode registration fails.
180 */
181 public function __construct() {
182 $this->register_render_mode( Render_Mode_Normal::class );
183
184 do_action( 'elementor/frontend/render_mode/register', $this );
185
186 $this->choose_render_mode();
187 $this->add_current_actions();
188 }
189 }
190