PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.3.1
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.3.1
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
insert-php / admin / includes / class.common.snippet.php

class.common.snippet.php in Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts 2.3.1, at admin/includes/class.common.snippet.php

519 lines 17.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Common functions for snippets
4 *
5 * @author Webcraftic <wordpress.webraftic@gmail.com>
6 * @copyright (c) 16.11.2018, Webcraftic
7 * @version 1.0
8 */
9
10 // Exit if accessed directly
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 class WINP_Common_Snippet {
16
17 /**
18 * WINP_Common_Snippet constructor.
19 */
20 public function __construct() {
21 }
22
23 /**
24 * Register hooks
25 */
26 public function registerHooks() {
27 add_action( 'current_screen', [ $this, 'currentScreen' ] );
28 add_action( 'edit_form_before_permalink', [ $this, 'editFormBeforePermalink' ] );
29 add_action( 'admin_notices', [ $this, 'createUploadsDirectory' ] );
30 add_action( 'before_delete_post', [ $this, 'beforeDeletePost' ] );
31 add_action( 'save_post', [ $this, 'savePost' ] );
32 add_action( 'save_post_' . WINP_SNIPPETS_POST_TYPE, [ $this, 'save_snippet' ], 10, 3 );
33 add_action( 'auto-draft_to_publish', [ $this, 'publish_snippet' ] );
34
35 add_filter( 'script_loader_src', [ $this, 'unload_scripts' ], 10, 2 );
36 }
37
38 /**
39 * Create the custom-css-js dir in uploads directory
40 *
41 * Show a message if the directory is not writable
42 *
43 * Create an empty index.php file inside
44 */
45 public function createUploadsDirectory() {
46 $current_screen = get_current_screen();
47
48 // Check if we are editing a custom-css-js post
49 if ( $current_screen->base != 'post' || $current_screen->post_type != WINP_SNIPPETS_POST_TYPE ) {
50 return false;
51 }
52
53 $dir = WINP_UPLOAD_DIR;
54
55 // Create the dir if it doesn't exist
56 if ( ! file_exists( $dir ) ) {
57 wp_mkdir_p( $dir );
58 }
59
60 // Show a message if it couldn't create the dir
61 if ( ! file_exists( $dir ) ) { ?>
62 <div class="notice notice-error is-dismissible">
63 <p><?php printf( __( 'The %s directory could not be created', 'insert-php' ), '<b>winp-css-js</b>' ); ?></p>
64 <p><?php _e( 'Please run the following commands in order to make the directory', 'insert-php' ); ?>:
65 <br/><strong>mkdir <?php echo $dir; ?>; </strong><br/><strong>chmod 777 <?php echo $dir; ?>
66 ;</strong></p>
67 </div>
68 <?php return;
69 }
70
71 // Show a message if the dir is not writable
72 if ( ! wp_is_writable( $dir ) ) { ?>
73 <div class="notice notice-error is-dismissible">
74 <p><?php printf( __( 'The %s directory is not writable, therefore the CSS and JS files cannot be saved.', 'insert-php' ), '<b>' . $dir . '</b>' ); ?></p>
75 <p><?php _e( 'Please run the following command to make the directory writable', 'insert-php' ); ?>:<br/><strong>chmod
76 777 <?php echo $dir; ?> </strong></p>
77 </div>
78 <?php return;
79 }
80
81 // Write a blank index.php
82 if ( ! file_exists( $dir . '/index.php' ) ) {
83 $content = '<?php' . PHP_EOL . '// Silence is golden.';
84 @file_put_contents( $dir . '/index.php', $content );
85 }
86 }
87
88 /**
89 * Add quick buttons
90 */
91 public function currentScreenEdit() {
92 $strings = [
93 'php' => __( 'Php snippet', 'insert-php' ),
94 'text' => __( 'Text snippet', 'insert-php' ),
95 'css' => __( 'Css snippet', 'insert-php' ),
96 'js' => __( 'Js snippet', 'insert-php' ),
97 'html' => __( 'Html snippet', 'insert-php' ),
98 'universal' => __( 'Universal snippet', 'insert-php' ),
99 ];
100 $url = 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=';
101 ?>
102 <style>
103 .wrap .winp-page-title-action {
104 margin-left: 4px;
105 padding: 4px 8px;
106 position: relative;
107 top: -3px;
108 text-decoration: none;
109 border: 1px solid #ccc;
110 border-radius: 2px;
111 background: #f7f7f7;
112 text-shadow: none;
113 font-weight: 600;
114 font-size: 13px;
115 line-height: normal;
116 color: #0073aa;
117 cursor: pointer;
118 }
119 </style>
120 <script type="text/javascript">
121 /* <![CDATA[ */
122 jQuery(window).ready(function($) {
123 $('#wpbody-content a.page-title-action').hide();
124 var h1 = '<?php _e( 'Woody snippets', 'insert-php' ); ?> ';
125 h1 += ' <select class="winp-page-title-action">';
126 h1 += '<option value="<?php echo $url; ?>php"><?php echo $strings['php']; ?></option>';
127 h1 += '<option value="<?php echo $url; ?>text"><?php echo $strings['text']; ?></option>';
128 h1 += '<option value="<?php echo $url; ?>css"><?php echo $strings['css']; ?></option>';
129 h1 += '<option value="<?php echo $url; ?>js"><?php echo $strings['js']; ?></option>';
130 h1 += '<option value="<?php echo $url; ?>html"><?php echo $strings['html']; ?></option>';
131 h1 += '<option value="<?php echo $url; ?>universal"><?php echo $strings['universal']; ?></option>';
132 h1 += '</select>';
133 h1 += '<a href="#" id="winp-add-snippet-action" class="page-title-action"><?php _e( 'Add', 'insert-php' ); ?></a>';
134 $('#wpbody-content h1').html(h1);
135 $('#winp-add-snippet-action').click(function() {
136 window.location.href = $('select.winp-page-title-action').val();
137 });
138 });
139 </script>
140 <?php
141 }
142
143 /**
144 * Add quick buttons
145 */
146 public function currentScreenPost() {
147 $strings = [
148 'add' => [
149 'php' => __( 'Php snippet', 'insert-php' ),
150 'text' => __( 'Text snippet', 'insert-php' ),
151 'css' => __( 'Css snippet', 'insert-php' ),
152 'js' => __( 'Js snippet', 'insert-php' ),
153 'html' => __( 'Html snippet', 'insert-php' ),
154 'universal' => __( 'Universal snippet', 'insert-php' ),
155 ],
156 'edit' => [
157 'php' => __( 'Edit php snippet', 'insert-php' ),
158 'text' => __( 'Edit text snippet', 'insert-php' ),
159 'css' => __( 'Edit css snippet', 'insert-php' ),
160 'js' => __( 'Edit js snippet', 'insert-php' ),
161 'html' => __( 'Edit html snippet', 'insert-php' ),
162 'universal' => __( 'Edit universal snippet', 'insert-php' ),
163 ]
164 ];
165
166 $post_id = WINP_Plugin::app()->request->get( 'post', null );
167 if ( ! empty( $post_id ) ) {
168 $action = 'edit';
169 } else {
170 $action = 'add';
171 }
172 $type = WINP_Helper::get_snippet_type( $post_id );
173 $html = $strings[ $action ][ $type ];
174
175 if ( 'edit' == $action ) {
176 $url = 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=';
177 $html .= ' <select class="winp-page-title-action">';
178 $html .= '<option value="' . $url . 'php">' . $strings['add']['php'] . '</option>';
179 $html .= '<option value="' . $url . 'text">' . $strings['add']['text'] . '</option>';
180 $html .= '<option value="' . $url . 'css">' . $strings['add']['css'] . '</option>';
181 $html .= '<option value="' . $url . 'js">' . $strings['add']['js'] . '</option>';
182 $html .= '<option value="' . $url . 'html">' . $strings['add']['html'] . '</option>';
183 $html .= '<option value="' . $url . 'universal">' . $strings['add']['universal'] . '</option>';
184 $html .= '</select>';
185 $html .= '<a href="#" id="winp-add-snippet-action" class="page-title-action">' . __( 'Add', 'insert-php' ) . '</a>';
186 } ?>
187 <script type="text/javascript">
188 /* <![CDATA[ */
189 jQuery(window).ready(function($) {
190 $('#wpbody-content a.page-title-action').hide();
191 $('#wpbody-content h1').html('<?php echo $html; ?>');
192 $('#winp-add-snippet-action').click(function() {
193 window.location.href = $('select.winp-page-title-action').val();
194 });
195 });
196 /* ]]> */
197 </script>
198 <?php
199 }
200
201 /**
202 * Add quick buttons
203 *
204 * @param $current_screen
205 */
206 public function currentScreen( $current_screen ) {
207 if ( WINP_SNIPPETS_POST_TYPE !== $current_screen->post_type ) {
208 return;
209 }
210
211 // Код виджета поддержки пока что нужно скрыть
212 // add_action( 'admin_footer', array( $this, 'admin_footer' ) );
213
214 if ( $current_screen->base == 'post' ) {
215 add_action( 'admin_head', [ $this, 'currentScreenPost' ] );
216 }
217
218 if ( $current_screen->base == 'edit' ) {
219 add_action( 'admin_head', [ $this, 'currentScreenEdit' ] );
220 }
221 }
222
223 /**
224 * Show the Permalink edit form
225 *
226 * @param string $filename
227 * @param string $permalink
228 * @param string $filetype
229 */
230 public function editFormBeforePermalink( $filename = '', $permalink = '', $filetype = 'css' ) {
231 $filetype = WINP_Plugin::app()->request->get( 'winp_item', $filetype, true );
232
233 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
234 return;
235 }
236
237 if ( ! is_string( $filename ) ) {
238 global $post;
239
240 if ( ! is_object( $post ) ) {
241 return;
242 }
243
244 if ( WINP_SNIPPETS_POST_TYPE !== $post->post_type ) {
245 return;
246 }
247
248 $post = $filename;
249 $slug = WINP_Helper::getMetaOption( $post->ID, 'css_js_slug', '' );
250 $default_filetype = WINP_Helper::getMetaOption( $post->ID, 'filetype', '' );
251 if ( $default_filetype ) {
252 $filetype = $default_filetype;
253 } else {
254 $filetype = WINP_Helper::get_snippet_type( $post->ID );
255 }
256
257 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
258 return;
259 }
260
261 if ( ! @file_exists( WINP_UPLOAD_DIR . '/' . $slug . '.' . $filetype ) ) {
262 $slug = false;
263 }
264 $filename = ( $slug ) ? $slug : $post->ID;
265 }
266
267 if ( empty( $permalink ) ) {
268 $permalink = WINP_UPLOAD_URL . '/' . $filename . '.' . $filetype;
269 } ?>
270 <div class="inside">
271 <div id="edit-slug-box" class="hide-if-no-js">
272 <strong><?php _e( 'Permalink', 'insert-php' ) ?>:</strong>
273 <span id="sample-permalink"><a href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( WINP_UPLOAD_URL ) . '/'; ?><span id="editable-post-name"><?php echo esc_html( $filename ); ?></span>.<?php echo esc_html( $filetype ); ?></a></span>
274 <span id="winp-edit-slug-buttons"><button type="button" class="winp-edit-slug button button-small hide-if-no-js" aria-label="<?php _e( 'Edit permalink', 'insert-php' ) ?>"><?php _e( 'Edit', 'insert-php' ) ?></button></span>
275 <span id="editable-post-name-full"><?php echo esc_html( $filename ); ?></span>
276 </div>
277 <?php wp_nonce_field( 'winp-permalink', 'winp-permalink-nonce' ); ?>
278 </div>
279 <?php
280 }
281
282 /**
283 * Remove the JS/CSS file from the disk when deleting the post
284 *
285 * @param $postid
286 */
287 public function beforeDeletePost( $postid ) {
288 global $post;
289
290 if ( ! is_object( $post ) ) {
291 return;
292 }
293 if ( WINP_SNIPPETS_POST_TYPE !== $post->post_type ) {
294 return;
295 }
296 if ( ! wp_is_writable( WINP_UPLOAD_DIR ) ) {
297 return;
298 }
299
300 $default_filetype = WINP_Helper::get_snippet_type( $post->ID );
301 $filetype = WINP_Helper::getMetaOption( $postid, 'filetype', $default_filetype );
302
303 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
304 return;
305 }
306
307 $slug = WINP_Helper::getMetaOption( $postid, 'css_js_slug' );
308 $file_name = $postid . '.' . $filetype;
309
310 @unlink( WINP_UPLOAD_DIR . '/' . $file_name );
311
312 if ( ! empty( $slug ) ) {
313 @unlink( WINP_UPLOAD_DIR . '/' . $slug . '.' . $filetype );
314 }
315 }
316
317 /**
318 * Save post
319 *
320 * @param $post_id
321 */
322 public function savePost( $post_id ) {
323 $nonce = WINP_Plugin::app()->request->post( 'winp-permalink-nonce' );
324
325 if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'winp-permalink' ) ) {
326 return;
327 }
328
329 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
330 return;
331 }
332
333 if ( WINP_SNIPPETS_POST_TYPE != WINP_Plugin::app()->request->post( 'post_type' ) ) {
334 return;
335 }
336
337 $default_filetype = WINP_Helper::get_snippet_type( $post_id );
338 $filetype = WINP_Helper::getMetaOption( $post_id, 'filetype', $default_filetype );
339
340 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
341 return;
342 }
343
344 $plugin_title = WINP_Plugin::app()->getPluginTitle();
345 $before = $after = '';
346
347 $snippet_linking = WINP_Plugin::app()->request->post( WINP_Plugin::app()->getPrefix() . 'snippet_linking' );
348 $linking = ! empty( $snippet_linking ) ? $snippet_linking : 'external';
349 $content = get_post( $post_id )->post_content;
350
351 // Save the Custom Code in a file in `wp-content/uploads/winp-css-js`
352 if ( 'inline' == $linking ) {
353 $before = '<!-- start ' . $plugin_title . ' CSS and JS -->' . PHP_EOL;
354 $after = '<!-- end ' . $plugin_title . ' CSS and JS -->' . PHP_EOL;
355
356 if ( 'css' == $filetype ) {
357 $before .= '<style type="text/css">' . PHP_EOL;
358 $after = '</style>' . PHP_EOL . $after;
359 }
360
361 if ( 'js' == $filetype ) {
362 if ( ! preg_match( '/<script\b[^>]*>([\s\S]*?)<\/script>/im', $content ) ) {
363 $before .= '<script type="text/javascript">' . PHP_EOL;
364 $after = PHP_EOL . '</script>' . PHP_EOL . $after;
365 } else {
366 // the content has a <script> tag, then remove the comments so they don't show up on the frontend
367 $content = preg_replace( '@/\*[\s\S]*?\*/@', '', $content );
368 }
369 }
370 }
371
372 if ( 'external' == $linking ) {
373 $before = '/******* Do not edit this file *******' . PHP_EOL . $plugin_title . ' CSS and JS' . PHP_EOL . 'Saved: ' . date( 'M d Y | H:i:s' ) . ' */' . PHP_EOL;
374
375 // Save version for js and css file
376 WINP_Helper::updateMetaOption( $post_id, 'css_js_version', time() );
377 }
378
379 if ( wp_is_writable( WINP_UPLOAD_DIR ) ) {
380 $file_content = $before . $content . $after;
381
382 // save the file as the Permalink slug
383 $slug = WINP_Helper::getMetaOption( $post_id, 'css_js_slug' );
384 if ( $slug ) {
385 $file_name = $slug . '.' . $filetype;
386 $file_slug = $slug;
387 } else {
388 $file_name = $post_id . '.' . $filetype;
389 $file_slug = $post_id;
390 }
391
392 // Delete old file
393 $old_slug = WINP_Helper::getMetaOption( $post_id, 'css_js_exist_slug' );
394 if ( $old_slug ) {
395 @unlink( WINP_UPLOAD_DIR . '/' . $old_slug . '.' . $filetype );
396 }
397
398 // Save exist file slug
399 WINP_Helper::updateMetaOption( $post_id, 'css_js_exist_slug', $file_slug );
400
401 @file_put_contents( WINP_UPLOAD_DIR . '/' . $file_name, $file_content );
402 }
403 }
404
405 /**
406 * Action for pre saved snippet.
407 * Если это не обновление поста, если это "черновик", и есть параметр с id сниппета, то заполняем данные сниппета для просмотра
408 *
409 * @param $post_ID
410 * @param $current_post
411 * @param $update
412 */
413 public function save_snippet( $post_ID, $current_post, $update ) {
414 $snippet_id = WINP_Plugin::app()->request->get( 'snippet_id' );
415 $common = WINP_Plugin::app()->request->get( 'common', false );
416
417 if ( ! $update && 'auto-draft' == $current_post->post_status && ! empty( $snippet_id ) && WINP_SNIPPETS_POST_TYPE == $current_post->post_type ) {
418 $snippet = [];
419 $saved_snippets = get_user_meta( get_current_user_id(), WINP_Plugin::app()->getPrefix() . 'current_snippets', true );
420
421 if ( ! empty( $saved_snippets ) && isset( $saved_snippets[ $snippet_id ] ) ) {
422 $snippet = $saved_snippets[ $snippet_id ];
423 }
424
425 if ( empty( $snippet ) ) {
426 $_snippet = WINP_Plugin::app()->get_api_object()->get_snippet( $snippet_id, $common );
427 if ( ! empty( $_snippet ) ) {
428 $snippet = [
429 'title' => $_snippet->title,
430 'desc' => $_snippet->description,
431 'type' => $_snippet->type->slug,
432 'content' => $_snippet->content,
433 'type_id' => $_snippet->type_id,
434 'scope' => $_snippet->execute_everywhere,
435 ];
436 }
437 }
438
439 if ( ! empty( $snippet ) ) {
440 $post_data = [
441 'ID' => $post_ID,
442 'post_title' => $snippet['title'],
443 'post_content' => $snippet['content'],
444 ];
445 wp_update_post( $post_data );
446
447 WINP_Helper::updateMetaOption( $post_ID, 'snippet_api_snippet', $snippet_id );
448 WINP_Helper::updateMetaOption( $post_ID, 'snippet_type', $snippet['type'] );
449 WINP_Helper::updateMetaOption( $post_ID, 'snippet_api_type', $snippet['type_id'] );
450 WINP_Helper::updateMetaOption( $post_ID, 'snippet_description', $snippet['desc'] );
451 WINP_Helper::updateMetaOption( $post_ID, 'snippet_draft', true );
452 WINP_Helper::updateMetaOption( $post_ID, 'snippet_scope', $snippet['scope'] );
453
454 wp_redirect( admin_url( 'post.php?post=' . $post_ID . '&action=edit' ) );
455 }
456 }
457 }
458
459 /**
460 * Delete auto-draft status after post snippet is publishing
461 *
462 * @param $post
463 */
464 public function publish_snippet( $post ) {
465 if ( WINP_SNIPPETS_POST_TYPE == $post->post_type ) {
466 delete_post_meta( $post->ID, WINP_Plugin::app()->getPrefix() . 'snippet_draft' );
467 }
468 }
469
470 /**
471 * Action admin_footer
472 */
473 public function admin_footer() {
474 ?>
475 <script type="text/javascript">!function(e, t, n) {
476 function a() {
477 var e = t.getElementsByTagName("script")[0], n = t.createElement("script");
478 n.type = "text/javascript", n.async = !0, n.src = "https://beacon-v2.helpscout.net", e.parentNode.insertBefore(n, e)
479 }
480
481 if( e.Beacon = n = function(t, n, a) {
482 e.Beacon.readyQueue.push({
483 method: t,
484 options: n,
485 data: a
486 })
487 }, n.readyQueue = [], "complete" === t.readyState ) {
488 return a();
489 }
490 e.attachEvent ? e.attachEvent("onload", a) : e.addEventListener("load", a, !1)
491 }(window, document, window.Beacon || function() {
492 });</script>
493 <script type="text/javascript">window.Beacon('init', '1a4078fd-3e77-4692-bcfa-47bb4da0cee5')</script>
494 <?php
495 }
496
497 /**
498 * Unload specific scrips
499 *
500 * @param string $src
501 * @param string $handle
502 *
503 * @return bool|string
504 */
505 public function unload_scripts( $src, $handle ) {
506 global $post;
507
508 // Check if we are editing a snippet post
509 if ( is_admin() && ! empty( $post ) && $post->post_type == WINP_SNIPPETS_POST_TYPE ) {
510 // Unload ckeditor.js from theme The Rex
511 if ( 'bk-ckeditor-js' == $handle ) {
512 return false;
513 }
514 }
515
516 return $src;
517 }
518
519 }