PluginProbe ʕ •ᴥ•ʔ
Code Manager / 1.0.33
Code Manager v1.0.33
1.0.47 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.3 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.4 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
code-manager / Code_Manager / Code_Manager.php
code-manager / Code_Manager Last commit date
Code_Manager.php 2 years ago Code_Manager_Dashboard.php 2 years ago Code_Manager_Export.php 2 years ago Code_Manager_Form.php 2 years ago Code_Manager_Import.php 2 years ago Code_Manager_Import_File.php 2 years ago Code_Manager_List.php 2 years ago Code_Manager_List_View.php 2 years ago Code_Manager_Model.php 2 years ago Code_Manager_Preview.php 2 years ago Code_Manager_Settings.php 2 years ago Code_Manager_Tabs.php 2 years ago Message_Box.php 2 years ago WP_List_Table.php 2 years ago
Code_Manager.php
420 lines
1 <?php
2
3 /**
4 * Code Manager main class
5 *
6 * @package Code_Manager
7 */
8 namespace Code_Manager;
9
10 /**
11 * Class Code_Manager
12 *
13 * Add plugin actions and runs the code saved in the code manager table.
14 *
15 * @author Peter Schulz
16 * @since 1.0.0
17 */
18 class Code_Manager
19 {
20 const CM_MESSAGE = 'code_manager_alert_off' ;
21 const PHP_OPEN = '<?php' ;
22 const PHP_CLOSE = '?>' ;
23 const CSS_OPEN = '<style>' ;
24 const CSS_CLOSE = '</style>' ;
25 const JS_OPEN = '<script>' ;
26 const JS_CLOSE = '</script>' ;
27 /**
28 * Add Code Manager specific actions
29 *
30 * @param Object $loader Plugin loader.
31 * @since 1.0.0
32 */
33 public function add_actions( $loader )
34 {
35 $code_manager_model = null;
36 if ( null === $code_manager_model ) {
37 $code_manager_model = new Code_Manager_Model();
38 }
39
40 if ( is_admin() ) {
41 // Admin actions.
42 $loader->add_action( 'admin_action_code_manager_export', Code_Manager_Export::class, 'export' );
43 $loader->add_action( 'wp_ajax_code_manager_export', Code_Manager_Export::class, 'export_ajax' );
44 $loader->add_action( 'wp_ajax_nopriv_code_manager_export', Code_Manager_Export::class, 'export_ajax' );
45 $loader->add_action( 'wp_ajax_code_manager_update_code', $code_manager_model, 'update_code' );
46 $loader->add_action( 'wp_ajax_code_manager_activate_code', $code_manager_model, 'activate_code' );
47 $loader->add_action( 'wp_ajax_code_manager_activate_code_preview', $code_manager_model, 'activate_code_preview' );
48 $loader->add_action( 'wp_ajax_code_manager_deactivate_code_preview', $code_manager_model, 'deactivate_code_preview' );
49 $loader->add_action( 'wp_ajax_code_manager_reset_preview', $code_manager_model, 'reset_preview' );
50 $loader->add_action( 'wp_ajax_code_manager_get_code_list', $code_manager_model, 'get_code_list' );
51 $loader->add_action( 'wp_ajax_code_manager_code_name_exists', $code_manager_model, 'code_name_exists' );
52 $loader->add_action( 'wp_ajax_code_manager_is_code_preview_enabled', $code_manager_model, 'is_code_preview_enabled' );
53 $loader->add_action( 'wp_ajax_code_manager_get_code', $code_manager_model, 'get_code' );
54 $loader->add_action( 'wp_ajax_nopriv_code_manager_get_code', $code_manager_model, 'get_code' );
55 $loader->add_action( 'wp_ajax_code_manager_alert_off', Code_Manager::class, 'alert_off' );
56 }
57
58 }
59
60 /**
61 * Run shortcode
62 *
63 * @since 1.0.0
64 *
65 * @param array $atts Shortcode arguments.
66 * @var array
67 */
68 public function add_shortcode( $atts )
69 {
70 if ( self::code_manager_disabled() ) {
71 // Code manager disabled.
72 return '';
73 }
74 global $pagenow ;
75 if ( 'post.php' === $pagenow || 'edit.php' === $pagenow || 'post-new.php' === $pagenow ) {
76 // Prevent errors on execution if shortcode is shown in classic editor.
77 return '';
78 }
79 if ( isset( $_SERVER['CONTENT_TYPE'] ) && 'application/json' === $_SERVER['CONTENT_TYPE'] ) {
80 // Prevent errors on execution if shortcode is shown in Gutenberg editor.
81 return null;
82 }
83 global $wpda_shortcode_args ;
84 $wpda_shortcode_args = $atts;
85 // Allow user to define and use custom parameters.
86 $atts = array_change_key_case( (array) $atts, CASE_LOWER );
87 $wp_atts = shortcode_atts( array(
88 'id' => '',
89 'name' => '',
90 ), $atts );
91 if ( '' === $wp_atts['id'] && '' === $wp_atts['name'] ) {
92 return '';
93 }
94 ob_start();
95 $ids = explode( ',', $wp_atts['id'] );
96 foreach ( $ids as $id ) {
97 $this->run_shortcode_id( $id );
98 }
99 $names = explode( ',', $wp_atts['name'] );
100 foreach ( $names as $name ) {
101 $this->run_shortcode_name( $name );
102 }
103 $content = ob_get_contents();
104 ob_end_clean();
105 return $content;
106 }
107
108 /**
109 * Run shortcode from code id
110 *
111 * @param integer $id Code ID.
112 * @return void
113 */
114 protected function run_shortcode_id( $id )
115 {
116
117 if ( '' !== $id ) {
118 $code_manager_model = null;
119 if ( null === $code_manager_model ) {
120 $code_manager_model = new Code_Manager_Model();
121 }
122 $code_row = $code_manager_model::dml_query( $id );
123 if ( 1 === count( $code_row ) ) {
124 if ( '1' === $code_row[0]['code_enabled'] || Code_Manager_Preview::is_code_id_preview_enabled( $id ) ) {
125 $this->run_shortcode( $code_row[0]['code_type'], $code_row[0]['code'] );
126 }
127 }
128 }
129
130 }
131
132 /**
133 * Run shortcode from code name
134 *
135 * @param string $name Code name.
136 * @return void
137 */
138 protected function run_shortcode_name( $name )
139 {
140
141 if ( '' !== $name ) {
142 $code_manager_model = null;
143 if ( null === $code_manager_model ) {
144 $code_manager_model = new Code_Manager_Model();
145 }
146 $code_row = $code_manager_model::dml_query_by_name( $name );
147 if ( 1 === count( $code_row ) ) {
148 if ( '1' === $code_row[0]['code_enabled'] || Code_Manager_Preview::is_code_id_preview_enabled( $code_row[0]['code_id'] ) ) {
149 $this->run_shortcode( $code_row[0]['code_type'], $code_row[0]['code'] );
150 }
151 }
152 }
153
154 }
155
156 /**
157 * Adds code de pending on the code type
158 *
159 * @since 1.0.0
160 *
161 * @param string $code_type Code type (shortcodes only).
162 * @param string $code The code (PHP, JS, CSS or HTML).
163 */
164 protected function run_shortcode( $code_type, $code )
165 {
166
167 if ( strpos( $code_type, 'html' ) !== false ) {
168 echo wp_unslash( $code ) ;
169 // phpcs:ignore WordPress.Security.EscapeOutput
170 } elseif ( strpos( $code_type, 'css' ) !== false ) {
171 echo self::CSS_OPEN . wp_unslash( $code ) . self::CSS_CLOSE ;
172 // phpcs:ignore WordPress.Security.EscapeOutput
173 } elseif ( strpos( $code_type, 'javascript' ) !== false ) {
174 echo self::JS_OPEN . wp_unslash( $code ) . self::JS_CLOSE ;
175 // phpcs:ignore WordPress.Security.EscapeOutput
176 } elseif ( 'php shortcode' === $code_type ) {
177 $this->add_php_code( $code );
178 }
179
180 }
181
182 /**
183 * Run shortcode from back-end code block using code id
184 *
185 * @param integer $id Code ID.
186 * @return void
187 */
188 public function run_shortcode_id_from_anywhere( $id )
189 {
190 $this->run_shortcode_id( $id );
191 }
192
193 /**
194 * Run shortcode from back-end code block using code name
195 *
196 * @param string $name Code name.
197 * @return void
198 */
199 public function run_shortcode_name_from_anywhere( $name )
200 {
201 $this->run_shortcode_name( $name );
202 }
203
204 /**
205 * Adds PHP code
206 *
207 * @since 1.0.0
208 *
209 * @param string $php_code PHP code to be added.
210 */
211 protected function add_php_code( $php_code )
212 {
213
214 if ( Code_Manager::is_code_manager_page() ) {
215 // Do not execute any code on Code Manager pages!!!
216 // This is an admins rescue in case code fails and locks a server.
217 } else {
218 $php_code_valid = true;
219 $php_code_functions = $this->get_classes_and_functions( $php_code );
220 foreach ( $php_code_functions['functions'] as $php_code_function ) {
221
222 if ( function_exists( $php_code_function ) ) {
223 var_dump( "ERROR: Function {$php_code_function} is already declared" );
224 $php_code_valid = false;
225 }
226
227 }
228 foreach ( $php_code_functions['classes'] as $php_code_class ) {
229
230 if ( class_exists( $php_code_class ) ) {
231 var_dump( "ERROR: Class {$php_code_class} is already declared" );
232 $php_code_valid = false;
233 }
234
235 }
236 if ( $php_code_valid ) {
237 try {
238 eval($this->strip_code( $php_code ));
239 } catch ( \ParseError $e ) {
240 echo $e->getMessage() ;
241 } catch ( \Throwable $e ) {
242 echo $e->getMessage() ;
243 }
244 }
245 }
246
247 }
248
249 protected function get_classes_and_functions( $php_code )
250 {
251 $tokens = token_get_all( $php_code );
252 $class_names = array();
253 $has_class_name = false;
254 $parsing_class = false;
255 $function_names = array();
256 $parsing_function = false;
257 $open_braces = 0;
258 foreach ( $tokens as $token ) {
259 $token_start = $token[0];
260
261 if ( T_CLASS === $token_start ) {
262 $parsing_class = true;
263 } elseif ( T_FUNCTION === $token_start ) {
264 if ( !$parsing_class ) {
265 $parsing_function = true;
266 }
267 } elseif ( T_STRING === $token_start ) {
268
269 if ( $parsing_function ) {
270 $parsing_function = false;
271 $function_names[] = $token[1];
272 } elseif ( $parsing_class && !$has_class_name ) {
273 $class_names[] = $token[1];
274 $has_class_name = true;
275 }
276
277 } elseif ( '(' === $token_start || ';' === $token_start ) {
278 $parsing_function = false;
279 } elseif ( '{' === $token_start ) {
280 if ( $parsing_class ) {
281 $open_braces++;
282 }
283 } elseif ( '}' === $token_start ) {
284
285 if ( $parsing_class ) {
286 $open_braces--;
287 if ( 0 === $open_braces ) {
288 $parsing_class = false;
289 }
290 }
291
292 }
293
294 }
295 return array(
296 'classes' => $class_names,
297 'functions' => $function_names,
298 );
299 }
300
301 /**
302 * Remove PHP opening and closing tags (when found) from given code
303 *
304 * @since 1.0.0
305 *
306 * @param string $php_code PHP source code.
307 *
308 * @return string PHP code without PHP opening and closing tags
309 */
310 protected function strip_code( $php_code )
311 {
312 $php_code = rtrim( ltrim( $php_code ) );
313 if ( self::PHP_OPEN === strtolower( substr( $php_code, 0, 5 ) ) ) {
314 $php_code = substr( $php_code, 5 );
315 }
316 if ( self::PHP_CLOSE === substr( $php_code, strlen( $php_code ) - 2 ) ) {
317 $php_code = substr( $php_code, 0, strlen( $php_code ) - 2 );
318 }
319 return $php_code;
320 }
321
322 /**
323 * Checks if Code Manager is disabled
324 *
325 * (1) Disabled in settings page
326 * (2) Disabled in config file
327 *
328 * @since 1.0.0
329 *
330 * @return bool TRUE - Code Manager is disabled
331 */
332 public static function code_manager_disabled()
333 {
334 $plugin_code_execution = get_option( 'code_manager_plugin_code_execution' );
335 if ( false === $plugin_code_execution ) {
336 $plugin_code_execution = 'on';
337 }
338 return 'on' !== $plugin_code_execution || defined( 'CODE_MANAGER_DISABLED' ) && CODE_MANAGER_DISABLED;
339 }
340
341 /**
342 * Returns true if user is on a Code Manager back-end page
343 *
344 * @return bool
345 */
346 public static function is_code_manager_page()
347 {
348 return is_admin() && isset( $_REQUEST['page'] ) && (CODE_MANAGER_MENU_SLUG === $_REQUEST['page'] || CODE_MANAGER_SETTINGS_MENU_SLUG === $_REQUEST['page'] || 'code_manager_post' === $_REQUEST['page']);
349 }
350
351 /**
352 * Get current user login
353 *
354 * @return string
355 */
356 public static function get_current_user_login()
357 {
358 global $current_user ;
359
360 if ( isset( $current_user->user_login ) ) {
361 return $current_user->user_login;
362 } else {
363 $wp_user = wp_get_current_user();
364
365 if ( isset( $wp_user->data->user_login ) ) {
366 return $wp_user->data->user_login;
367 } else {
368 return 'anonymous';
369 }
370
371 }
372
373 }
374
375 /**
376 * Get current user id
377 *
378 * @return string
379 */
380 public static function get_current_user_id()
381 {
382 global $current_user ;
383
384 if ( isset( $current_user->ID ) ) {
385 return $current_user->ID;
386 } else {
387 $wp_user = wp_get_current_user();
388
389 if ( isset( $wp_user->data->ID ) ) {
390 return $wp_user->data->ID;
391 } else {
392 return -1;
393 }
394
395 }
396
397 }
398
399 public static function get_cm_message()
400 {
401 return get_user_meta( self::get_current_user_id(), self::CM_MESSAGE, true );
402 }
403
404 public static function alert_off()
405 {
406
407 if ( is_user_logged_in() && isset( $_REQUEST['wpnonce'] ) ) {
408 // Check if action is allowed.
409 $wpnonce = sanitize_text_field( wp_unslash( $_REQUEST['wpnonce'] ) );
410 // input var okay.
411 if ( wp_verify_nonce( $wpnonce, 'code-manager-' . Code_manager::get_current_user_login() ) ) {
412 // Turn off alarm.
413 update_user_meta( self::get_current_user_id(), self::CM_MESSAGE, 'hide' );
414 }
415 }
416
417 wp_die();
418 }
419
420 }