PluginProbe
Elementor Website Builder – more than just a page builder / 4.1.5
Elementor Website Builder – more than just a page builder v4.1.5
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 4.1.5, at core/frontend/render-mode-manager.php

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