PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
← All changes | php/Integration/Evaluate_Functions.php +49 -30 3.10.1 → 4.0.0-beta.2 View file →
@@ -34,9 +34,15 @@
34 34 $this->db = $db;
35 35 add_action( 'plugins_loaded', [ $this, 'evaluate_early' ], 1 );
36 36 add_filter( 'code_snippets/execute_snippets', [ $this, 'disable_snippet_execution' ], 5 );
37 37
38 - if ( $this->is_safe_mode_requested() ) {
38 + // Only the query var is inspected here. This constructor runs while
39 + // plugins are still being included, which is before WordPress loads
40 + // pluggable.php, so a capability check at this point would call an
41 + // undefined wp_get_current_user() and take the whole request down.
42 + // The capability is checked in the callback instead, which never runs
43 + // before URLs are being generated.
44 + if ( $this->is_safe_mode_query_var_set() ) {
39 45 add_filter( 'home_url', [ $this, 'add_safe_mode_query_var' ] );
40 46 add_filter( 'admin_url', [ $this, 'add_safe_mode_query_var' ] );
41 47 }
42 48 }
@@ -41,25 +47,41 @@
41 47 }
42 48 }
43 49
44 50 /**
51 + * Check whether the safe mode query var is present on this request.
52 + *
53 + * Safe to call at any point, as it reads nothing but the request.
54 + *
55 + * @return bool
56 + */
57 + public function is_safe_mode_query_var_set(): bool {
58 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
59 + return ! empty( $_REQUEST['snippets-safe-mode'] );
60 + }
61 +
62 + /**
45 63 * Check if safe mode has been requested via query var.
46 64 *
65 + * Performs a capability check, so must not be called before pluggable
66 + * functions are available.
67 + *
47 68 * @return bool
48 69 */
49 70 public function is_safe_mode_requested(): bool {
50 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
51 - return ! empty( $_REQUEST['snippets-safe-mode'] ) && code_snippets()->current_user_can();
71 + return $this->is_safe_mode_query_var_set() && code_snippets()->current_user_can();
52 72 }
53 73
54 74 /**
55 75 * Inject the safe mode query var into URLs
56 76 *
57 - * @param string $url Original URL.
77 + * @param mixed $url Original URL, from an unknown earlier callback.
58 78 *
59 79 * @return string Modified URL.
60 80 */
61 - public function add_safe_mode_query_var( string $url ): string {
81 + public function add_safe_mode_query_var( $url ): string {
82 + $url = is_string( $url ) ? $url : '';
83 +
62 84 return $this->is_safe_mode_requested() ?
63 85 add_query_arg( 'snippets-safe-mode', true, $url ) :
64 86 $url;
65 87 }
@@ -108,14 +130,15 @@
108 130
109 131 /**
110 132 * Disable snippet execution if the necessary query var is set.
111 133 *
112 - * @param bool $execute_snippets Current filter value.
134 + * @param mixed $execute_snippets Current filter value, from an unknown
135 + * earlier callback.
113 136 *
114 137 * @return bool New filter value.
115 138 */
116 - public function disable_snippet_execution( bool $execute_snippets ): bool {
117 - return $execute_snippets && ! self::is_safe_mode_requested();
139 + public function disable_snippet_execution( $execute_snippets ): bool {
140 + return $execute_snippets && ! $this->is_safe_mode_requested();
118 141 }
119 142
120 143 /**
121 144 * Quickly deactivate a snippet with minimal overhead.
@@ -153,17 +176,17 @@
153 176 }
154 177 }
155 178
156 179 /**
157 - * Evaluate a snippet stored in a flat file.
180 + * Evaluate a snippet.
158 181 *
159 - * @param array $snippet Snippet data.
160 - * @param string $file_path Path to the snippet file.
161 - * @param array|null $edit_snippet Data of snippet currently being edited, if applicable.
182 + * @param array $snippet Snippet data.
183 + * @param string|null $file_path Path to the snippet file, or null if executing from the database.
184 + * @param array|null $edit_snippet Data of snippet currently being edited, if applicable.
162 185 *
163 186 * @return void
164 187 */
165 - private function evaluate_snippet_flat_file( array $snippet, string $file_path, ?array $edit_snippet = null ) {
188 + private function evaluate_snippet( array $snippet, ?string $file_path, ?array $edit_snippet ) {
166 189 $snippet_id = $snippet['id'];
167 190 $code = $snippet['code'];
168 191 $table_name = $snippet['table'];
169 192
@@ -176,9 +199,13 @@
176 199 return;
177 200 }
178 201
179 202 if ( apply_filters( 'code_snippets/allow_execute_snippet', true, $snippet_id, $table_name ) ) {
180 - execute_snippet_from_flat_file( $code, $file_path, $snippet_id );
203 + if ( is_null( $file_path ) ) {
204 + execute_snippet( $code, $snippet_id );
205 + } else {
206 + execute_snippet_from_flat_file( $code, $file_path, $snippet_id );
207 + }
181 208 }
182 209 }
183 210
184 211 /**
@@ -208,21 +235,11 @@
208 235 $active_snippets = $this->db->fetch_active_snippets( $scopes );
209 236 $edit_snippet = $this->get_currently_editing_snippet();
210 237
211 238 foreach ( $active_snippets as $snippet ) {
212 - $snippet_id = $snippet['id'];
213 - $code = $snippet['code'];
214 - $table_name = $snippet['table'];
215 -
216 - // If the snippet is a single-use snippet, deactivate it before execution to ensure that the process always happens.
217 - if ( 'single-use' === $snippet['scope'] ) {
218 - $this->quick_deactivate_snippet( $snippet_id, $table_name );
239 + if ( 'condition' !== $snippet['scope'] ) {
240 + $this->evaluate_snippet( $snippet, null, $edit_snippet );
219 241 }
220 -
221 - if ( apply_filters( 'code_snippets/allow_execute_snippet', true, $snippet_id, $table_name ) &&
222 - ( is_null( $edit_snippet ) || $edit_snippet['id'] !== $snippet_id || $edit_snippet['table'] !== $table_name ) ) {
223 - execute_snippet( $code, $snippet_id );
224 - }
225 242 }
226 243
227 244 return true;
228 245 }
@@ -238,13 +255,15 @@
238 255 $snippets = Snippet_Files::get_active_snippets_from_flat_files( $scopes, $type );
239 256 $edit_snippet = $this->get_currently_editing_snippet();
240 257
241 258 foreach ( $snippets as $snippet ) {
242 - $table_name = Snippet_Files::get_hashed_table_name( $snippet['table'] );
243 - $base_path = Snippet_Files::get_base_dir( $table_name, $type );
244 - $file = $base_path . '/' . $snippet['id'] . '.' . $type;
259 + if ( 'condition' !== $snippet['scope'] ) {
260 + $table_name = Snippet_Files::get_hashed_table_name( $snippet['table'] );
261 + $base_path = Snippet_Files::get_base_dir( $table_name, $type );
262 + $file = $base_path . '/' . $snippet['id'] . '.' . $type;
245 263
246 - $this->evaluate_snippet_flat_file( $snippet, $file, $edit_snippet );
264 + $this->evaluate_snippet( $snippet, $file, $edit_snippet );
265 + }
247 266 }
248 267
249 268 return true;
250 269 }