PluginProbe
Post Snippets – Custom WordPress Code Snippets Customizer / 4.2.2
Post Snippets – Custom WordPress Code Snippets Customizer v4.2.2
4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.1 1.7.2 1.7.3 1.8 1.8.1 1.8.2 1.8.3 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.8.9.1 1.8.9.2 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 All 115 releases
post-snippets / src / PostSnippets / Edit.php

Edit.php in Post Snippets – Custom WordPress Code Snippets Customizer 4.2.2, at src/PostSnippets/Edit.php

1,772 lines 64.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace PostSnippets;
3
4 if ( ! defined( 'ABSPATH' ) ) exit;
5
6 /**
7 * Add or Edit Post Snippets.
8 *
9 * Class that renders out the HTML for Edit/Add snippet page.
10 *
11 */
12 class Edit {
13
14 private static $snippet_id = '';
15
16 public static $editSnippetPage = false;
17
18 protected $snippet_data;
19
20
21 function __construct() {
22
23 self::prepare();
24
25 $this->save_data();
26
27 $this->perform_actions_response();
28
29 $this->setup_code_editor();
30
31 $this->edit_snippets_meta_boxes();
32
33 $this->setup_sections();
34
35 $this->editPage();
36
37
38 }
39
40 public static function prepare(){
41
42 if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit' && isset($_REQUEST['snippet']) ){
43
44 self::$snippet_id = intval($_REQUEST['snippet']);
45
46 check_admin_referer( 'ps-snippets-hover-trigger_'.self::$snippet_id );
47
48 global $wpdb;
49
50 if( !$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM ".$wpdb->prefix.\PostSnippets::TABLE_NAME." WHERE ID = %d", self::$snippet_id) ) ){
51
52 self::$snippet_id = '';
53
54 wp_safe_redirect( admin_url('admin.php?page=post-snippets' ) );
55
56 }
57
58 if( !empty(self::$snippet_id) ){
59 self::$editSnippetPage = true;
60 }
61
62 }
63 }
64
65 public static function change_edit_snippet_page_title($admin_title, $title){
66
67
68 self::prepare();
69
70 if(self::$editSnippetPage){
71 $admin_title = str_replace( __("Add New", "post-snippets"), __("Edit Snippet", "post-snippets"), $admin_title);
72 return $admin_title;
73 }
74
75 return $admin_title;
76 }
77
78 function editPage(){
79
80
81 ?>
82 <div class="wrap">
83 <div id="icon-users" class="icon32"></div>
84
85 <?php
86
87 $edit_page = '';
88
89 if( self::$editSnippetPage ){
90 $page = self::get_snippet_page();
91 if( $page == 'post-snippets-edit-js' ){
92 $edit_page = "JS ";
93 }
94 elseif( $page == 'post-snippets-edit-css' ){
95 $edit_page = "CSS ";
96 }
97 ?>
98 <h1 class="wp-heading-inline"><?php echo $edit_page; esc_html_e( 'Edit', 'post-snippets' ); ?> Snippet</h1>
99 <a href="<?php echo esc_url("?page=$page") ?>" class="page-title-action"><?php esc_html_e( 'Add New', 'post-snippets' ); ?></a>
100 <?php
101 }
102 else{
103 ?>
104 <h1 class="wp-heading-inline"><?php echo $edit_page; esc_html_e( 'Add', 'post-snippets' ); ?> Snippet</h1>
105 <?php
106 }
107
108 ?>
109
110 <hr class="wp-header-end">
111 <form id="ps_edit_snippets" method="post">
112 <?php
113
114 wp_nonce_field( 'pspro_edit_snippet', 'pspro_edit_snippet_nonce', false );
115
116 // Pro
117
118 // wp_nonce_field('sync_up', 'sync_up');
119 // wp_nonce_field('sync_down', 'sync_down');
120
121 /* Used to save closed meta boxes and their order */
122 wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
123 wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
124
125 ?>
126
127 <div id="poststuff">
128 <!-- #post-body .metabox-holder goes here -->
129 <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
130 <!-- meta box containers here -->
131 <div id="post-body-content">
132 <!-- #post-body-content -->
133 <?php $this->body_content_cb(); ?>
134 </div>
135
136 <div id="postbox-container-1" class="postbox-container">
137 <?php
138 /**Add Meta Box to Side Bar */
139 do_meta_boxes('','side',null);
140
141 ?>
142
143 <div class ="save-button-area">
144
145 <?php
146
147 submit_button(__('Save','post-snippets'));
148
149 ?>
150
151 </div>
152
153 </div>
154
155 <div id="postbox-container-2" class="postbox-container">
156 <?php
157 /**Add Full witdh meta-boxes to bottom of Fixed content */
158 do_meta_boxes('','normal',null);
159 // do_meta_boxes('','advanced',null);
160
161 ?>
162 </div>
163
164
165 </div>
166 </div>
167
168
169
170 </form>
171
172 </div><!--/wrap -->
173
174 <?php
175
176 if( isset($_REQUEST['message']) && $_REQUEST['message'] == 1 ){
177
178 printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippet Added Successfully', 'post-snippets' ) );
179
180 }
181 }
182
183
184 /**
185 * Prints the jQuery script to initiliase the metaboxes
186 * Called on admin_footer-*
187 */
188 public static function footer_scripts(){
189 ?>
190 <script> postboxes.add_postbox_toggles(pagenow);</script>
191 <?php
192 }
193
194 /*
195 * Actions to be taken prior to page loading. This is after headers have been set.
196 * call on load-$hook
197 * This calls the add_meta_boxes hooks, adds screen options and enqueues the postbox.js script.
198 */
199 public static function page_actions(){
200
201 /* User can choose between 1 or 2 columns (default 2) */
202 add_screen_option('layout_columns', array('max' => 2, 'default' => 2) );
203
204 /* Enqueue WordPress' script for handling the metaboxes */
205 wp_enqueue_script('postbox');
206 }
207
208 public static function edit_snippets_meta_boxes(){
209
210 add_meta_box(
211 'ps_action_meta_box', //Meta box ID
212 __('Actions','post-snippets'), //Meta box Title
213 array(\PostSnippets::EDIT_CLASS, 'actions_metabox_content'), //Callback defining the metabox's innards
214 NULL, // Screen to which to add the meta box, blank means current screen
215 'side' // Context
216 );
217
218 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-js' || $_REQUEST['page'] === 'post-snippets-edit-css'){
219
220 add_meta_box(
221 'ps_option_meta_box', //Meta box ID
222 __('Options','post-snippets'), //Meta box Title
223 array(\PostSnippets::EDIT_CLASS, 'options_metabox_content'), //Callback defining the metabox's innards
224 NULL, // Screen to which to add the meta box, blank means current screen
225 'side' // Context
226 );
227
228 add_meta_box(
229 'ps_preview_meta_box', //Meta box ID
230 __('Preview','post-snippets'), //Meta box Title
231 array(\PostSnippets::EDIT_CLASS, 'preview_metabox_content'), //Callback defining the metabox's innards
232 NULL, // Screen to which to add the meta box, blank means current screen
233 'normal' // Context
234 );
235
236 add_meta_box(
237 'ps_pages_meta_box', //Meta box ID
238 __('Apply only on these URLs','post-snippets'), //Meta box Title
239 array(\PostSnippets::EDIT_CLASS, 'pages_metabox_content'), //Callback defining the metabox's innards
240 NULL, // Screen to which to add the meta box, blank means current screen
241 'normal' // Context
242 );
243
244 }
245
246
247 }
248
249 function body_content_cb(){
250 $this->snippetTitle();
251 $this->codeEditor();
252 // $this->setup_sections();
253 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit'){
254 do_settings_sections( 'post-snippets-edit' );
255 }
256 $this->description();
257 // submit_button(__('Save','post-snippets'));
258 }
259
260 static function actions_metabox_content(){
261
262 if( !self::$editSnippetPage ){
263 $disabled_action = "style = opacity:40%";
264 $disabled_action_cursor = "style = cursor:not-allowed";
265 }
266 else{
267 $disabled_action = '';
268 $disabled_action_cursor = '';
269 }
270
271 ?>
272
273 <div id="sync-up-confirm" title="<?php _e( 'Confirm', 'post-snippets' ) ?>" style="display:none;">
274 <p><span class="dashicons dashicons-warning" style="float:left; margin-right:12px;"></span>
275 <?php _e( 'Do you want to upload the current snippet to the cloud', 'post-snippets' ) ?>
276 </div>
277
278
279 <div id="sync-down-confirm" title="<?php _e( 'Confirm', 'post-snippets' ) ?>" style="display:none;">
280 <p><span class="dashicons dashicons-warning" style="float:left; margin-right:12px;"></span>
281 <?php _e( 'Replace Current Snippet From Cloud', 'post-snippets' ) ?>
282 </div>
283
284
285 <div id="sync-up-success" title="<?php _e( 'Success', 'post-snippets' ) ?>" style="display:none;">
286 <p><span class="dashicons dashicons-thumbs-up" style="float:left; margin-right:12px;"></span>
287 <p upload-success></p>
288 </div>
289
290 <div id="sync-up-error" title="<?php _e( 'Error', 'post-snippets' ) ?>" style="display:none;">
291 <p><span class="dashicons dashicons-warning" style="float:left; margin-right:12px;"></span>
292 <p data-error></p>
293 </div>
294
295 <div id="sp-loading" style="display:none;">
296 <span></span>
297 </div>
298
299
300
301 <div class="pspro_edit_duplicate_snippet" <?php echo esc_attr( $disabled_action ) ?>>
302
303 <span class="dashicons dashicons-admin-page" style="width:30px; height:30px; font-size:25px;"></span>
304 <button <?php echo esc_attr( $disabled_action_cursor ) ?> class="link_style_button" type="<?php echo (self::$editSnippetPage) ? esc_attr( "submit" ) : esc_attr( "button" ) ?>" name="duplicate" value><?php esc_html_e( "Duplicate Snippet", 'post-snippets' ) ?></button>
305
306 </div>
307
308 <?php /**Shortcode Option only on PHP code page */
309
310 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit'){
311 ?>
312 <div class="pspro_edit_copy_shortcode" style="margin-top:1rem; text-align:center;"><?php
313
314 if(self::$editSnippetPage){?>
315
316 <div id="pspro_edit_shortcode_copied">
317 <span id="pspro_edit_shortcode_copied_text"><?php esc_html_e( "Shortcode Copied", "post-snippets" ) ?></span>
318 </div>
319
320 <input type="text" name="" id="pspro_edit_shotcode_text" disabled value = "<?php echo (esc_attr( self::generate_shortcode_text() )) ?>" style="width:100%;<?php echo self::get_data('snippet_shortcode')?'':'display:none;'; ?>">
321
322 <?php
323 }
324 ?>
325
326 <button type = "button" class="button"
327 <?php echo self::$editSnippetPage ? ( ( self::get_data('snippet_shortcode') == 0 )?( esc_attr( 'disabled' ) ):'') : ( esc_attr( 'disabled' ) ) ?>>
328 <?php esc_html_e( "Copy Shortcode", 'post-snippets' ) ?>
329 </button>
330 </div>
331 <?php
332 }
333 ?>
334
335 <div class="pspro_edit_snippet_status" style="margin-top:1rem;">
336 <label for="pspro_edit_snippet_status" style="font-size:17px;"><?php esc_html_e( "Status", 'post-snippets' ) ?><br>
337 <select name="snippet_status" id="pspro_select_snippet_status" style="width:100%;">
338 <option value="1" <?php echo ( self::get_data('snippet_status') == 1 )?( esc_attr( 'selected' ) ):'' ?>><?php esc_html_e( "Active", 'post-snippets' ) ?></option>
339 <option value="0" <?php echo ( self::get_data('snippet_status') == 0 )?( esc_attr( 'selected' ) ):'' ?>><?php esc_html_e( "InActive", 'post-snippets' ) ?></option>
340 </select>
341 </label>
342 </div>
343 <?php
344 }
345
346
347 static function groups_meta_box_content(){
348
349 global $wpdb;
350 $table_name = $wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME;
351
352 $all_groups = $wpdb->get_results($wpdb->prepare("SELECT * FROM %1s", $table_name), ARRAY_A );
353 ?>
354
355 <div id="pspro_group_list" class="categorydiv">
356
357 <ul id="pspro_group-tabs" class="category-tabs">
358 <li class="tabs"> <?php esc_html_e( 'All Groups', 'post-snippets' ) ?></li>
359 </ul>
360
361 <div id="pspro-group-all" class="tabs-panel">
362
363 <ul id="pspro_group_checklist" data-wp-lists="list:pspro_group" class="categorychecklist form-no-clear">
364 <?php
365
366 $checked = ''; /** Preventing Further warning of undefind variable below */
367
368 foreach ($all_groups as $group_key => $group_value) {
369
370 if(self::$editSnippetPage){
371 $group_list = maybe_unserialize( self::get_data('snippet_group') );
372 $checked = in_array($group_value['ID'], $group_list)?"checked":"";
373 }
374
375 else{
376 $ungrouped_checked = (!strcmp($group_value['group_slug'], __('ungrouped','post-snippets') ))?"checked ":"";
377 }
378
379 ?>
380 <li id="pspro_group_<?php echo esc_attr( $group_value['ID'] )?>">
381 <label class="selectit">
382 <input value="<?php echo esc_attr( $group_value['ID'] )?>" type="checkbox" name="pspro_group_list[]" id="in_pspro_group_<?php echo esc_attr( $group_value['ID'] )?>"
383 <?php echo ( esc_attr( $ungrouped_checked?? '' ) );
384 echo ( esc_attr( $checked ) );
385 ?>/>
386 <?php
387 echo esc_html( $group_value['group_name'] );
388 ?>
389 </label>
390 </li>
391 <?php
392
393 }
394
395 ?>
396
397 </ul>
398 </div>
399 </div>
400 <?php
401 }
402
403 static function options_metabox_content(){
404
405 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-js'){
406
407
408 $jsLocation = self::getLocation('js');
409 if( empty($jsLocation) ){
410 $jsLocation = 'header';
411 }
412
413 ?>
414
415 <div id="pspro_edit_options_where">
416
417 <h3 id = "pspro_edit_js_where_on_page"><?php esc_html_e( "Where on page", "post-snippets" ) ?></h3>
418
419 <input type="radio" name="pspro_edit_js_where" id="pspro_edit_js_header" class="pspro_edit_js_radio" value="header" <?php echo ( $jsLocation == 'header' ) ? ( esc_attr( 'checked' ) ) : '' ?> >
420 <label for="pspro_edit_js_header" class="pspro_edit_js_label"><?php esc_html_e( "Header", "post-snippets" ) ?></label><br>
421
422 <input type="radio" name="pspro_edit_js_where" id="pspro_edit_js_footer" class="pspro_edit_js_radio" value="footer" <?php echo ( $jsLocation == 'footer' ) ? ( esc_attr( 'checked' ) ) : '' ?> >
423 <label for="pspro_edit_js_footer" class="pspro_edit_js_label"><?php esc_html_e( "Footer", "post-snippets" ) ?></label><br>
424
425 </div>
426
427
428 <?php
429 }
430
431 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-js' || $_REQUEST['page'] === 'post-snippets-edit-css'){
432
433 $location = self::getLocation('site');
434 if( empty($location) ){
435 $location = 'admin';
436 }
437 $available_site_locations = Edit::availableSiteLocations();
438
439 ?>
440
441 <div id="pspro_edit_options_where_in_site">
442
443 <h3 id = "pspro_edit_where_in_site"><?php esc_html_e( "Where in Site", "post-snippets" ) ?></h3>
444
445
446 <?php
447
448 foreach ($available_site_locations as $available_site_location_slug => $available_site_location) {
449 ?>
450 <input
451
452 type="radio" name="pspro_edit_where_site"
453 id="pspro_edit_<?php echo esc_attr( $available_site_location_slug ) ?>"
454 class="pspro_edit_js_radio"
455 value="<?php echo esc_attr( $available_site_location_slug ) ?>"
456 <?php echo ( $location == $available_site_location_slug ) ? ( esc_attr( 'checked' ) ) : '' ?>
457 >
458
459 <label
460
461 for="pspro_edit_<?php echo esc_attr( $available_site_location_slug ) ?>"
462 class="pspro_edit_js_label"><?php esc_html_e( $available_site_location, "post-snippets" )
463
464 ?></label><br>
465
466 <?php
467 }
468
469 ?>
470
471 </div>
472
473
474 <?php
475
476
477 }
478
479 }
480
481 static function preview_metabox_content(){
482
483 $pageLocation = self::getLocation('page');
484 $url = '';
485 if( is_array($pageLocation) && isset( $pageLocation['specific_page'] ) ){
486 $selected_page = $pageLocation['specific_page']; /**page_or_post_id */
487 $url = get_permalink( $selected_page );
488 }
489
490 ?>
491
492 <div id="pspro_edit_preview_page" class="pspro_edit_display_flex">
493
494 <input type="text" name="pspro_edit_preview_text" id="pspro_edit_preview_text" disabled
495 placeholder="<?php esc_attr_e( 'Full URL on which to preview the changes ...', 'post-snippets' )?>"
496 value = "<?php echo esc_url( $url )?>"
497 >
498
499 <button type="button" id="pspro_edit_preview_button" class="button button-primary" disabled><?php esc_html_e( 'Preview Changes', 'post-snippets' ) ?></button>
500
501 </div>
502
503 <?php
504
505
506 }
507
508 static function pages_metabox_content(){
509
510 $pages = self::getAllPagesAndPosts();
511 $pageLocation = self::getLocation('page');
512 $available_locations = Edit::availablePageLocations();
513 $disabled = 'disabled';
514 $selected_page = false;
515
516 if( empty($pageLocation) ){
517 $pageLocation = 'all_website';
518 }
519
520 if( is_array($pageLocation) && isset( $pageLocation['specific_page'] ) ){
521 $selected_page = $pageLocation['specific_page'];
522 $pageLocation = 'specific_page';
523 $disabled = '';
524 }
525
526 ?>
527 <div id="pspro_edit_select_location" class="pspro_edit_display_flex">
528
529 <select name="pspro_edit_location_select" id="pspro_edit_location_select">
530
531 <?php
532
533 foreach ($available_locations as $available_location_slug => $available_location) {
534 ?>
535 <option value="<?php echo esc_attr( $available_location_slug ) ?>" <?php echo ( $available_location_slug == $pageLocation ? 'selected' : '') ?>
536
537 ><?php esc_html_e( $available_location, 'post-snippets' ) ?></option>
538
539 <?php
540 }
541
542 ?>
543
544 </select>
545
546 <select name="pspro_edit_page_select" id="pspro_edit_page_select" <?php echo esc_attr( $disabled ) ?>>
547 <?php
548
549 foreach ($pages as $page) {
550 ?>
551 <option value="<?php echo esc_attr( $page->ID ) ?>" data-url = "<?php echo esc_attr( get_permalink($page->ID) ) ?>"
552 <?php echo ( $selected_page == $page->ID ? 'selected' : '' ) ?>
553
554 ><?php echo esc_attr( ( !empty($page->post_title) ) ? $page->post_title : $page->post_name ) ?></option>
555
556 <?php
557 }
558
559 ?>
560 </select>
561
562 <button type="button" id="pspro_edit_add_selection" class="button button-primary" disabled><?php esc_html_e( 'Add', 'post-snippets' ) ?></button>
563
564 </div>
565
566
567 <?php
568
569 }
570
571 static function getLocation($type = ''){
572
573 if( empty( $type ) ){
574 return '';
575 }
576
577 $location = Shortcode::filterVars( self::get_data('snippet_vars') );
578
579 if( $type === 'js' ){
580
581 if( !empty($location) ){
582
583 $location = array_keys($location);
584
585 if( !empty( $location[1] ) ){
586 $location = $location[1];
587 if($location !== 'header' && $location !== 'footer'){
588 $location = '';
589 }
590 }
591 else{
592 $location = '';
593 }
594 }
595 else{
596 $location = '';
597 }
598
599 return $location;
600 }
601 elseif( $type === 'site' ){
602
603 if( !empty($location) ){
604
605 $location = array_keys($location);
606
607 if( !empty( $location[2] ) ){
608 $location = $location[2];
609 $available_site_locations = array_keys( Edit::availableSiteLocations() );
610 if( !in_array($location, $available_site_locations) ){
611 $location = '';
612 }
613 }
614 else{
615 $location = '';
616 }
617 }
618 else{
619 $location = '';
620 }
621
622 return $location;
623 }
624 elseif( $type === 'page' ){
625
626 if( !empty($location) ){
627
628 $location_keys = array_keys($location);
629
630 if( !empty( $location_keys[0] ) ){
631
632 $location_type = $location_keys[0];
633 $available_locations = Edit::availablePageLocations();
634 $available_locations_slugs = array_keys($available_locations);
635
636 if($location_type === 'specific_page'){
637 $location_page = $location['specific_page'];
638
639 if( empty($location_page) || !Edit::isPageOrPost($location_page) ){
640 return '';
641 }
642
643 return array($location_type => $location_page);
644 }
645
646 if( !in_array( $location_type, $available_locations_slugs, true ) ){
647 return '';
648 }
649
650 return $location_type;
651 }
652 else{
653 $location = '';
654 }
655 }
656 else{
657 $location = '';
658 }
659
660 return $location;
661
662 }
663
664 return '';
665
666 }
667
668 static function getAllPagesAndPosts(){
669
670 $args = array(
671 'post_type' => array( 'page', 'post' ),
672 'numberposts' => -1
673 );
674
675 $pages = get_posts($args);
676
677 return $pages;
678
679 }
680
681 static function isPageOrPost( $id = '' ){
682
683 if( empty($id) ){
684 return false;
685 }
686
687 $pagesAndPosts = self::getAllPagesAndPosts();
688
689 if( !empty( $pagesAndPosts ) ){
690
691 foreach ($pagesAndPosts as $pageAndPost) {
692 if($id == $pageAndPost->ID){
693 return true;
694 }
695 continue;
696 }
697
698 return false;
699 }
700
701 return false;
702
703 }
704
705
706 function snippetTitle(){
707
708 ?>
709
710 <div id="titlediv">
711 <div id="titlewrap">
712 <?php
713 $title_placeholder = apply_filters( 'snippet_title_input', __( 'Enter Snippet Title' ) );
714 $snippet_title = self::get_data('snippet_title');
715 ?>
716 <label class="screen-reader-text" id="title-prompt-text" for="title"><?php echo esc_html($title_placeholder) ; ?></label>
717 <input type="text" name="snippet_title" size="30" value="<?php echo esc_attr( $snippet_title ); ?>" id="title" spellcheck="true" autocomplete="off" placeholder = "<?php echo esc_html($title_placeholder); ?>"/>
718
719 </div>
720
721 </div><!-- /titlediv -->
722
723 <?php
724
725 }
726
727 function setup_code_editor(){
728
729 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-js' || $_REQUEST['page'] === 'post-snippets-edit-css'){
730
731 if( $_REQUEST['page'] === 'post-snippets-edit-js' ){
732 $type = 'text/javascript';
733 }
734 elseif( $_REQUEST['page'] === 'post-snippets-edit-css' ){
735 $type = 'text/css';
736 }
737
738 $cm_settings['codeEditor'] = wp_enqueue_code_editor(array(
739 // 'type' => 'application/x-httpd-php',
740 // 'type' => 'text/javascript',
741 'type' => $type,
742 'codemirror' => array(
743 // 'value' => '<script>',
744 'gutters' => array("CodeMirror-lint-markers", "CodeMirror-foldgutter"/*, "CodeMirror-markergutter"*/),
745 // 'theme' => 'dracula.css'
746 // 'lineNumbers' => false
747 // 'mode' => array(
748 // 'name' => "php",
749 // 'startOpen' => true
750 // ),
751 // 'mode' => "text/x-php",
752 'foldGutter' => true,
753 // 'markerGutter' => true,
754 'lint' => true
755 // 'htmllint' => true
756
757 )
758 ));
759
760 wp_localize_script('post-snippets', 'cm_settings', $cm_settings);
761
762 wp_enqueue_script('wp-theme-plugin-editor');
763 wp_enqueue_style('wp-codemirror');
764 wp_enqueue_style( 'post-snippets-edit', plugin_dir_url( PS_MAIN_FILE_PATH ) . "assets/edit.css");
765 wp_enqueue_script( 'post-snippets-edit-menu', plugin_dir_url( PS_MAIN_FILE_PATH ) . 'assets/edit.js');
766
767 return;
768 }
769
770 wp_enqueue_style( 'post-snippets-editor', plugin_dir_url( PS_MAIN_FILE_PATH ) . 'assets/editor.css' );
771 wp_enqueue_script( 'post-snippets-editor', plugin_dir_url( PS_MAIN_FILE_PATH ) . 'assets/editor.js' );
772
773 wp_enqueue_style( 'post-snippets-edit', plugin_dir_url( PS_MAIN_FILE_PATH ) . "assets/edit.css");
774 wp_enqueue_script( 'post-snippets-edit-menu', plugin_dir_url( PS_MAIN_FILE_PATH ) . 'assets/edit.js');
775 }
776
777 function codeEditor(){
778
779 $snippet_content = self::get_data('snippet_content');
780
781 ?>
782 <style>
783 #ps_snippet_code_editor textarea{
784
785 width: 100%;
786 min-height: 60vh;
787 height: calc(100vh - 295px);
788 border: 1px solid #dcdcde;
789 box-sizing: border-box;
790
791 font-family: Consolas, Monaco, monospace;
792 font-size:13px;
793 background:#f6f7f7;
794 -moz-tab-size:4;
795 -o-tab-size:4;
796 tab-size:4;
797
798 }
799
800 .pspro_codeEditor_heading{
801
802 margin-top: 1.5rem !important;
803 margin-bottom: 1rem !important;
804
805 }
806 div#ps_snippet_code_editor{
807 margin-bottom: 1rem;
808 }
809 </style>
810 <input type="hidden" name="pspro-edit-code-editor-page" value="<?php echo esc_attr( self::get_snippet_page() ) ?>">
811 <div id="ps_snippet_code_editor">
812 <h1 class="pspro_codeEditor_heading wp-heading"> <?php esc_html_e( 'Code Editor:', 'post-snippets' ) ?> </h1>
813 <textarea name="snippet_content" id="ps_code_editor"><?php echo esc_html( stripslashes( $snippet_content ) ) ?></textarea>
814 </div>
815 <?php
816
817 }
818
819 public static function setup_sections(){
820
821
822 add_settings_section( 'pspro_edit_snippet',
823 '',
824 '',
825 'post-snippets-edit' );
826
827 add_settings_field( 'snippet_vars', //unique_name
828 __('Variables:','post-snippets'), //Label
829 array( \PostSnippets::EDIT_CLASS, 'add_section_fields' ), //Callback Func
830 'post-snippets-edit', //page slug
831 'pspro_edit_snippet', //section slug
832 // 'snippet_vars'
833 array(
834 'id' => 'snippet_vars',
835 'label_for' => 'pspro_snippet_vars',
836 'description' => __( 'Enter Variables For This Snippet', 'post-snippets' )
837 )
838 ); //value to pass to callback function
839
840 add_settings_field( 'snippet_shortcode',
841 __('Shortcode:','post-snippets'),
842 array( \PostSnippets::EDIT_CLASS, 'add_section_fields' ),
843 'post-snippets-edit',
844 'pspro_edit_snippet',
845 // 'snippet_shortcode'
846 array(
847 'id' => 'snippet_shortcode',
848 'label_for' => 'pspro_snippet_shortcode',
849 'description' => __( 'Enable Shortcode For This Snippet', 'post-snippets' )
850 )
851 );
852
853 add_settings_field( 'snippet_php',
854 __('PHP Code:','post-snippets'),
855 array( \PostSnippets::EDIT_CLASS, 'add_section_fields' ),
856 'post-snippets-edit',
857 'pspro_edit_snippet',
858 // 'snippet_php'
859 array(
860 'id' => 'snippet_php',
861 'label_for' => 'pspro_snippet_php',
862 'description' => __( 'Enable PHP Rendering For This Snippet', 'post-snippets' )
863 )
864 );
865
866
867 add_settings_field( 'snippet_wptexturize',
868 __('WPtexturize:','post-snippets'),
869 array( \PostSnippets::EDIT_CLASS, 'add_section_fields' ),
870 'post-snippets-edit',
871 'pspro_edit_snippet',
872 // 'snippet_wptexturize'
873 array(
874 'id' => 'snippet_wptexturize',
875 'label_for' => 'pspro_snippet_wptexturize',
876 'description' => __( 'Enable WP_Texturize For This Snippet', 'post-snippets' )
877 )
878 );
879 }
880
881 public static function add_section_fields( $arguments ) {
882
883 if($arguments['id'] == 'snippet_vars'){
884
885 $snippet_vars = self::get_data($arguments['id']);
886
887 ?>
888
889 <textarea
890 name="<?php echo esc_attr( $arguments['id'] ) ?>"
891 id="pspro_<?php echo esc_attr( $arguments['id'] ) ?>"
892 cols="55" rows="4"
893 ><?php echo esc_html( $snippet_vars ) ?></textarea>
894
895 <?php
896
897 return;
898 }
899 if($arguments['id'] == 'snippet_wptexturize'){
900 $is_checked = self::get_data($arguments['id']);
901
902 ?>
903
904 <input type="checkbox"
905 name="<?php echo esc_attr( $arguments['id'] ) ?>"
906 id="pspro_<?php echo esc_attr( $arguments['id'] ) ?>"
907 value = "1"
908 <?php echo ( ($is_checked)?esc_attr( 'checked' ):'' ) ?>
909
910 />
911
912 <?php
913 echo '<label>';
914 echo esc_html('Text enclosed in the tags <pre> <code>, <kbd>, <style>, <script>, and <tt> will be skipped.');
915 echo 'For more details please visit <a href="https://developer.wordpress.org/reference/functions/wptexturize/" target="_blank">WPtexturize</a>.';
916 echo '</label>';
917 }
918 else
919 {
920
921 $is_checked = self::get_data($arguments['id']);
922
923 ?>
924
925 <input type="checkbox"
926 name="<?php echo esc_attr( $arguments['id'] ) ?>"
927 id="pspro_<?php echo esc_attr( $arguments['id'] ) ?>"
928 value = "1"
929 <?php echo ( ($is_checked)?esc_attr( 'checked' ):'' ) ?>
930
931 />
932
933 <?php
934 }
935
936
937 }
938
939
940 function description(){
941
942 $snippet_desc = self::get_data('snippet_desc');
943 if ( isset( $snippet_desc ) && ! empty( $snippet_desc ) ) {
944 $snippet_desc = stripslashes( $snippet_desc );
945 }
946 else{
947 $snippet_desc ='';
948 }
949
950 ?>
951 <h1 class="ps_description_heading wp-heading" style="margin-top:1.5rem; margin-bottom:1.5rem"> <?php esc_html_e( 'Description:', 'post-snippets' ) ?> </h1>
952
953 <?php
954
955 wp_editor(stripslashes($snippet_desc), 'ps_snippet_description', array(
956
957 'textarea_name' => 'snippet_desc',
958
959 // 'wpautop' => true,
960 // 'media_buttons' => false,
961 // 'editor_class' => 'my_custom_class',
962 // 'textarea_rows' => 10
963
964 ) );
965
966
967 }
968
969 static function get_data($column){
970
971 $column = sanitize_key( $column );
972
973 if(self::$editSnippetPage){
974
975 global $wpdb;
976
977 $data = $wpdb->get_var($wpdb->prepare("SELECT $column FROM ".$wpdb->prefix.\PostSnippets::TABLE_NAME." WHERE ID = %d", self::$snippet_id));
978 }
979
980 else{
981
982 if($column == "snippet_title"){
983 $pattern = '/[\s]/i'; /**remove any WhiteSpaces */
984 $replacement = '';
985 $snippet_title = preg_replace($pattern, $replacement, $_REQUEST[$column]?? '');
986 return $snippet_title;
987 }
988
989 $data = $_REQUEST[$column]?? '';
990
991 }
992
993 return $data;
994 }
995
996
997 /**
998 * Change Group Count When any Snippet group changes
999 * or when a snippet is deleted or duplicated.
1000 *
1001 * @param Array $group_list - Group List
1002 * @param String $method - Whether to Increment or Decrement
1003 *
1004 * @return Void
1005 *
1006 */
1007 public static function change_group_count($group_list, $method){
1008
1009 global $wpdb;
1010
1011 if( !strcmp($method, 'increment') ){
1012
1013 foreach ($group_list as $key => $group_id) {
1014
1015 $group_count = $wpdb->get_var( $wpdb->prepare("SELECT group_count FROM ".$wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME." WHERE ID = %d", $group_id) );
1016 $group_count = $group_count + 1;
1017
1018 $group_count_updated = $wpdb->update(
1019
1020 $wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME,
1021 array( /**Data to update */
1022 'group_count' => $group_count
1023 ),
1024 array( /**Where Coulum = ? */
1025 'ID' => $group_id
1026 ),
1027 array( /**Data Format, %d or %s */
1028 '%d'
1029 ),
1030 array( /**Where Format, %d or %s */
1031 '%d'
1032 )
1033 );
1034 }
1035 }
1036
1037 elseif( !strcmp($method, 'decrement') ){
1038
1039 foreach ($group_list as $key => $group_id) {
1040
1041 $group_count = $wpdb->get_var( $wpdb->prepare("SELECT group_count FROM ".$wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME." WHERE ID = %d", $group_id) );
1042
1043 if($group_count == 0){ /**if there is no snippet in a group but a snippet is deleted, this condition would never met but just in case*/
1044
1045 continue;
1046 }
1047
1048 $group_count = $group_count - 1; /**Decrement Group Count */
1049
1050 $wpdb->update(
1051 $wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME,
1052 array( /**Data to update */
1053 'group_count' => $group_count
1054 ),
1055 array( /**Where Coulum = ? */
1056 'ID' => $group_id
1057 ),
1058 array( /**Data Format, %d or %s */
1059 '%d'
1060 ),
1061 array( /**Where Format, %d or %s */
1062 '%d'
1063 )
1064 );
1065 }
1066 }
1067 }
1068
1069 function is_JS(){
1070
1071 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-js' /*&& isset($_REQUEST['pspro_edit_location_select'])*/ ){
1072
1073 return true;
1074 }
1075 else{
1076 return false;
1077 }
1078 }
1079
1080 function JS_location(){
1081
1082 if( $this->is_JS() && isset( $_REQUEST['pspro_edit_js_where'] ) && ( $_REQUEST['pspro_edit_js_where'] === 'header' || $_REQUEST['pspro_edit_js_where'] === 'footer' ) ){
1083
1084 return $_REQUEST['pspro_edit_js_where'];
1085 }
1086 elseif( $this->is_JS() ){
1087 return 'header';
1088 }
1089 elseif( $this->is_CSS() ){
1090 return 'css';
1091 }
1092 else{
1093 return '';
1094 }
1095
1096 }
1097
1098 function is_CSS(){
1099
1100 if( isset($_REQUEST['page']) && $_REQUEST['page'] === 'post-snippets-edit-css' /*&& isset($_REQUEST['pspro_edit_location_select'])*/ ){
1101
1102 return true;
1103 }
1104 else{
1105 return false;
1106 }
1107 }
1108
1109 function codeLocation(){
1110
1111 if( ( $this->is_JS() || $this->is_CSS() ) && isset( $_REQUEST['pspro_edit_location_select'] ) && $this->siteLocation() != 'admin'){
1112
1113 $selected_location = $_REQUEST['pspro_edit_location_select'];
1114 $available_locations = Edit::availablePageLocations();
1115 $available_locations_slugs = array_keys($available_locations);
1116
1117 if( $selected_location === 'specific_page'){
1118
1119 if( isset( $_REQUEST['pspro_edit_page_select'] ) && is_numeric( $_REQUEST['pspro_edit_page_select'] ) ){
1120
1121 $specific_page_exist = Edit::isPageOrPost( $_REQUEST['pspro_edit_page_select'] );
1122
1123 if( $specific_page_exist ){
1124 return 'specific_page='.$_REQUEST['pspro_edit_page_select'];
1125 }
1126 else{
1127 return '';
1128 }
1129 }
1130
1131 return '';
1132
1133 }
1134
1135 elseif( in_array($selected_location, $available_locations_slugs, true) ){
1136
1137 return $selected_location;
1138 }
1139
1140 return '';
1141 }
1142 elseif( $this->siteLocation() == 'admin' ){
1143 return 'all_website';
1144 }
1145 else{
1146 return '';
1147 }
1148 }
1149
1150 function siteLocation(){
1151
1152 if( ( $this->is_JS() || $this->is_CSS() ) && isset( $_REQUEST['pspro_edit_where_site'] ) ){
1153
1154 $selected_location = $_REQUEST['pspro_edit_where_site'];
1155 $available_site_locations = array_keys( Edit::availableSiteLocations() );
1156
1157 if( in_array($selected_location, $available_site_locations) ){
1158 return $selected_location;
1159 }
1160 return 'admin';
1161 }
1162 return '';
1163 }
1164
1165 static function availablePageLocations(){
1166
1167 return array(
1168 'all_website' => 'All Website',
1169 'homepage' => 'Homepage',
1170 'all_pages' => 'All Pages',
1171 'all_posts' => 'All Posts',
1172 'specific_page' => 'Specific page / post'
1173 );
1174 }
1175
1176 static function availableSiteLocations(){
1177
1178 return array(
1179 'frontend' => 'In Front-End',
1180 'admin' => 'In Admin',
1181 );
1182
1183 }
1184
1185 function save_data(){
1186
1187 if( isset($_REQUEST['submit']) ){
1188
1189 check_admin_referer( 'pspro_edit_snippet', 'pspro_edit_snippet_nonce' );
1190
1191 global $wpdb;
1192 $table_name = $wpdb->prefix.\PostSnippets::TABLE_NAME;
1193
1194
1195
1196 //******************** Preparing Group List ************************* */
1197
1198 $upgrouped_id = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM ".$wpdb->prefix.\PostSnippets::GROUP_TABLE_NAME." WHERE group_slug = %s", __('ungrouped','post-snippets') ) );
1199 $group_list = $_REQUEST['pspro_group_list'] ?? array($upgrouped_id); /**If no group is selected */
1200
1201 //*************************** END ****************************** */
1202
1203
1204
1205 //******************** Preparing Snippet Title ************************* */
1206
1207 $snippet_title = self::filter_snippet_title( $_REQUEST['snippet_title'] );
1208
1209
1210 //****************************** END *********************************** */
1211
1212
1213 //******************** Preparing Snippet vars ************************* */
1214
1215 if( isset($_REQUEST['snippet_vars']) && !empty( $_REQUEST['snippet_vars'] ) ){
1216
1217 $snippet_vars = self::filter_snippet_vars( $_REQUEST['snippet_vars'] );
1218
1219 }
1220 elseif( isset($_REQUEST['snippet_vars']) && empty( $_REQUEST['snippet_vars'] ) ){
1221
1222 $snippet_vars = '';
1223
1224 }
1225 elseif( !isset($_REQUEST['snippet_vars']) && ( $this->is_JS() || $this->is_CSS() ) ){
1226
1227 $codeLocation = $this->codeLocation();
1228 $jsLocation = $this->JS_location();
1229 $siteLocation = $this->siteLocation();
1230
1231 if( !empty($codeLocation) && !empty($jsLocation) && !empty($siteLocation) ){
1232 $snippet_vars = $codeLocation.','.$jsLocation.','.$siteLocation;
1233 }
1234 else{
1235 return false;
1236 }
1237 }
1238 else{
1239 return false;
1240 }
1241
1242 //****************************** END *********************************** */
1243
1244
1245
1246 //******************** Preparing Snippet Content ************************* */
1247
1248 $snippet_content = $_REQUEST['snippet_content'];
1249 if ($this->is_CSS()) {
1250 // validate that the css snippet contains only css code
1251 //$snippet_content = wp_strip_all_tags($snippet_content);
1252 $snippet_content = wp_kses($snippet_content, array( 'style' => array() ));
1253 }
1254 // if( !empty($snippet_content) && $this->is_JS() ){
1255
1256 // $start = '<script type=\"text/javascript\">';
1257 // $end = '</script>';
1258
1259 // $snippet_content = $start.'\n'.$snippet_content.'\n'.$end;
1260
1261 // }
1262
1263 //****************************** END *********************************** */
1264
1265
1266
1267 //******************** Preparing Snippet Description ************************* */
1268
1269 $allowed_html = apply_filters( 'ps_snippet_desc_allowed_html', array(
1270 'h1' => array(),
1271 'h2' => array(),
1272 'h3' => array(),
1273 'h4' => array(),
1274 'h5' => array(),
1275 'h6' => array(),
1276 'b' => array(),
1277 'strong' => array(),
1278 'pre' => array(),
1279 'p' => array(),
1280 'ul' => array(),
1281 'ol' => array(),
1282 'li' => array(),
1283 ));
1284 $snippet_desc = wp_kses( $_REQUEST['snippet_desc'] ?? '', $allowed_html);
1285
1286 //****************************** END *********************************** */
1287
1288
1289
1290 //******************** Preparing Snippet PHP ************************* */
1291
1292 if( isset($_REQUEST['snippet_php']) ){
1293 $snippet_php = ( ($_REQUEST['snippet_php']?? 0 ) == 1) ? 1 : 0;
1294 }
1295 else{
1296 /**As this variable is not used in JS and CSS pages, they
1297 * can be used to save those pages. so new DB entry
1298 * doesn't need to be created.
1299 * 2 for JS and 3 for CSS.
1300 */
1301 if( $this->is_JS() ){
1302 $snippet_php = 2;
1303 }
1304 elseif( $this->is_CSS() ){
1305 $snippet_php = 3;
1306 }
1307 else{
1308 // return false;
1309 $snippet_php = '0';
1310 }
1311
1312 }
1313
1314 //****************************** END *********************************** */
1315
1316
1317 if( !empty($snippet_title) ){
1318
1319 if(self::$editSnippetPage){ /**This is a edit page of Previous Snippet */
1320
1321 $current_snippet_title = $wpdb->get_var( $wpdb->prepare("SELECT snippet_title FROM $table_name WHERE ID = %d", self::$snippet_id) );
1322
1323 if( $snippet_title != $current_snippet_title && $this->duplicate_title_check($snippet_title) ){
1324
1325 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'Duplicate Titles are Not Allowed', 'post-snippets' ) );
1326 return;
1327
1328 }
1329
1330 else{
1331
1332 $current_group_list = $group_list;
1333 $previous_group_list = maybe_unserialize( $wpdb->get_var( $wpdb->prepare("SELECT snippet_group FROM $table_name WHERE ID = %d", self::$snippet_id) ) );
1334
1335 $increment_count = array_diff($current_group_list, $previous_group_list);
1336
1337 $decrement_count = array_diff($previous_group_list, $current_group_list);
1338
1339 $snippet_updated = $wpdb->update(
1340 $table_name,
1341 array(
1342 'snippet_group' => maybe_serialize( $group_list ),
1343 'snippet_title' => $snippet_title,
1344 'snippet_content' => $snippet_content,
1345 'snippet_date' => current_time( 'mysql' ),
1346 'snippet_vars' => $snippet_vars,
1347 'snippet_desc' => $snippet_desc,
1348 'snippet_status' => ( ($_REQUEST['snippet_status']?? 0 ) == 1) ? 1 : 0, //Disable by default
1349 'snippet_shortcode' => ( ($_REQUEST['snippet_shortcode']?? 0 ) == 1) ? 1 : 0,
1350 'snippet_php' => $snippet_php,
1351 'snippet_wptexturize' => ( ($_REQUEST['snippet_wptexturize']?? 0 ) == 1) ? 1 : 0,
1352 ),
1353 array( /**Where Coulum = ? */
1354 'ID' => self::$snippet_id,
1355 ),
1356 array( /**Data Format, %d or %s */
1357 '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d'
1358 ),
1359 array( /**Where Format, %d or %s */
1360 '%d'
1361 )
1362 );
1363
1364
1365 if($snippet_updated){
1366
1367 printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippet Updated', 'post-snippets' ) );
1368 // return;
1369 }
1370
1371 elseif(!$snippet_updated){
1372
1373 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippet Update Failed', 'post-snippets' ) );
1374 // return;
1375 }
1376
1377 if( !empty($increment_count) || !empty($decrement_count) ){
1378
1379 //change group count here
1380 if( !empty($increment_count) ){ /**Increment Count of these groups */
1381
1382 self::change_group_count($increment_count, 'increment');
1383
1384 }
1385
1386 if( !empty($decrement_count) ){ /**Decrement Count of these groups */
1387
1388 self::change_group_count($decrement_count, 'decrement');
1389
1390 }
1391
1392 }
1393 }
1394 }
1395
1396 elseif( !self::$editSnippetPage && !$this->duplicate_title_check($snippet_title) ){ /**Adding New Snippet here */
1397
1398 $snippet_added = $wpdb->insert(
1399 $table_name,
1400 array(
1401 'snippet_group' => maybe_serialize( $group_list ),
1402 'snippet_title' => $snippet_title,
1403 'snippet_content' => $snippet_content,
1404 'snippet_date' => current_time( 'mysql' ),
1405 'snippet_vars' => $snippet_vars,
1406 'snippet_desc' => $snippet_desc,
1407 'snippet_status' => ( ($_REQUEST['snippet_status']?? 0 ) == 1) ? 1 : 0, //Disable by default
1408 'snippet_shortcode' => ( ($_REQUEST['snippet_shortcode']?? 0 ) == 1) ? 1 : 0,
1409 'snippet_php' => $snippet_php,
1410 'snippet_wptexturize' => ( ($_REQUEST['snippet_wptexturize']?? 0 ) == 1) ? 1 : 0,
1411 )
1412 );
1413
1414 if( $snippet_added ){
1415
1416 self::change_group_count($group_list, 'increment');
1417
1418 $page = self::get_snippet_page();
1419 $url = admin_url( sprintf('admin.php?page=%s&action=edit&snippet=%s&message=%s&_wpnonce=%s', $page, $wpdb->insert_id, 1, wp_create_nonce('ps-snippets-hover-trigger_'.$wpdb->insert_id) ) );
1420
1421 ?> <script> <?php echo("location.href = '".$url."';"); ?> </script> <?php
1422
1423 }
1424
1425 elseif(!$snippet_added){
1426
1427 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippet Not Added', 'post-snippets' ) );
1428
1429 }
1430 }
1431
1432 else{
1433
1434 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'Duplicate Titles are Not Allowed', 'post-snippets' ) );
1435
1436 }
1437 }
1438
1439 else{
1440
1441 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'Empty Title is Not Allowed', 'post-snippets' ) );
1442
1443 }
1444 }
1445 }
1446
1447 public static function get_snippet_page($id=''){
1448
1449 if(empty($id)){
1450
1451 if( isset($_REQUEST['page']) && ( $_REQUEST['page'] === 'post-snippets-edit' || $_REQUEST['page'] === 'post-snippets-edit-js' || $_REQUEST['page'] === 'post-snippets-edit-css' ) ){
1452 return $_REQUEST['page'];
1453 }
1454
1455 return 'post-snippets-edit';
1456 }else{
1457
1458 if($id == 2){
1459 return 'post-snippets-edit-js';
1460 }
1461 elseif($id == 3){
1462 return 'post-snippets-edit-css';
1463 }
1464 elseif($id == 0 || $id == 1){
1465 return 'post-snippets-edit';
1466 }
1467
1468 return 'post-snippets-edit';
1469
1470 }
1471
1472 }
1473
1474 public static function duplicate_title_check($snippet_title){
1475
1476 global $wpdb;
1477
1478 $table_name = $wpdb->prefix.\PostSnippets::TABLE_NAME;
1479
1480 $all_snippets_titles = $wpdb->get_results( $wpdb->prepare("SELECT snippet_title FROM %1s", $table_name), ARRAY_A );
1481
1482 $all_snippets_titles = array_column($all_snippets_titles, 'snippet_title');
1483
1484 $duplicate_title_exist = in_array($snippet_title, $all_snippets_titles);
1485
1486 if( $duplicate_title_exist ){
1487 /**Cause This function is also used to Increment
1488 * Title Count by number_duplicate_snippet_title,
1489 * otherwise, above written code would have to be
1490 * repeated.
1491 **/
1492
1493 return $all_snippets_titles;
1494
1495 }
1496 else{
1497
1498 return false;
1499
1500 }
1501
1502 }
1503
1504
1505 public static function number_duplicate_snippet_title($snippet_title){
1506
1507 if( empty($snippet_title) || !is_string($snippet_title) ){
1508 //redundancy
1509 $snippet_title = __('Untitled', 'post-snippets');
1510
1511 }
1512
1513 $all_snippets_titles = self::duplicate_title_check($snippet_title);
1514
1515 if(!$all_snippets_titles){
1516 return $snippet_title;
1517 }
1518
1519
1520 return self::increment_snippet_title( $all_snippets_titles, $snippet_title );
1521
1522
1523 }
1524
1525
1526 public static function increment_snippet_title( $all_snippets_titles, $snippet_title ){
1527
1528 /**Searching For Similar Titles */
1529 $same_titles = array();
1530 foreach ($all_snippets_titles as $title) {
1531 if( strpos( $title, $snippet_title ) === 0 ){
1532 $same_titles[] = $title;
1533 }
1534 }
1535
1536
1537 /**Incrementing Said Title */
1538 $counter = 1;
1539 while($counter){
1540
1541 if( in_array($snippet_title.'_'.$counter, $same_titles) ){
1542 $counter++;
1543 }
1544 else{
1545 break;
1546 }
1547 }
1548
1549 $new_snippet_title = $snippet_title.'_'.$counter;
1550
1551 return $new_snippet_title;
1552
1553 }
1554
1555
1556 static function generate_shortcode_text(){
1557
1558 if(self::$editSnippetPage){
1559
1560 $snippet_vars = Shortcode::filterVars( self::get_data('snippet_vars') );
1561
1562 $snippet_vars_text = '';
1563 foreach ($snippet_vars as $var => $value) {
1564 $snippet_vars_text .= ' '. $var . (!empty($value)?'=':'=""') . $value;
1565 }
1566
1567 $shortcode = '['.self::get_data('snippet_title') . $snippet_vars_text . ']';
1568
1569 return $shortcode;
1570 }
1571
1572
1573 }
1574
1575
1576 function perform_actions_response(){
1577
1578 if(self::$editSnippetPage){
1579
1580 if( isset($_REQUEST['download']) ){
1581
1582 check_admin_referer( 'pspro_edit_snippet', 'pspro_edit_snippet_nonce' );
1583
1584 $ie = new ImportExport();
1585
1586 $download_succeed = $ie->exportSnippets("(".self::$snippet_id.")");
1587
1588 if($download_succeed){
1589 printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippets Downloaded', 'post-snippets' ) );
1590
1591 }
1592 else{
1593 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'There has been an Error', 'post-snippets' ) );
1594 }
1595
1596 }
1597
1598
1599 if( isset($_REQUEST['upload']) ){
1600
1601 check_admin_referer( 'pspro_edit_snippet', 'pspro_edit_snippet_nonce' );
1602
1603
1604 }
1605
1606
1607 if( isset($_REQUEST['duplicate']) ){
1608
1609 check_admin_referer( 'pspro_edit_snippet', 'pspro_edit_snippet_nonce' );
1610
1611 if( PSallSnippets::duplicate_snippet(self::$snippet_id) ){
1612 printf('<div class="notice notice-success is-dismissible"><p>%s..</p></div>', esc_html__( 'Snippet Duplicated', 'post-snippets' ) );
1613 return;
1614 }
1615 else{
1616 printf('<div class="notice notice-error is-dismissible"><p>%s..</p></div>', esc_html__( 'There has been an Error', 'post-snippets' ) );
1617 }
1618
1619 }
1620
1621
1622 }
1623
1624
1625 }
1626
1627
1628 public static function addImportedSnippet( $imported_snippet = array() ){
1629
1630 if( !empty($imported_snippet) ){
1631
1632 global $wpdb;
1633 $table_name = $wpdb->prefix.\PostSnippets::TABLE_NAME;
1634
1635 $snippet_php = PSallSnippets::get_snippet_php($imported_snippet['snippet_php']);
1636
1637 // Sanitize imported snippet content to prevent XSS
1638 $sanitized_content = self::sanitize_snippet_content(
1639 $imported_snippet['snippet_content'] ?? '',
1640 $snippet_php
1641 );
1642
1643 $snippet_added = $wpdb->insert(
1644 $table_name,
1645 array(
1646 'snippet_group' => $imported_snippet['snippet_group'],
1647 'snippet_title' => self::filter_snippet_title( $imported_snippet['snippet_title'] ),
1648 'snippet_content' => $sanitized_content,
1649 'snippet_date' => current_time( 'mysql' ),
1650 'snippet_vars' => self::filter_snippet_vars( $imported_snippet['snippet_vars'] ),
1651 'snippet_desc' => sanitize_textarea_field($imported_snippet['snippet_desc'] ?? ''),
1652 'snippet_status' => (($imported_snippet['snippet_status']?? 0) == 1) ? 1 : 0, //Disable by default
1653 'snippet_shortcode' => (($imported_snippet['snippet_shortcode']?? 0) == 1) ? 1 : 0,
1654 'snippet_php' => $snippet_php,
1655 'snippet_wptexturize' => (($imported_snippet['snippet_wptexturize']?? 0) == 1) ? 1 : 0,
1656 )
1657 );
1658
1659 if($snippet_added){
1660 self::change_group_count( maybe_unserialize( $imported_snippet['snippet_group'] ), 'increment');
1661 return true;
1662 }
1663 else{
1664 return false;
1665 }
1666
1667 }
1668 else{
1669 return false;
1670 }
1671
1672
1673 }
1674
1675
1676 public static function filter_snippet_vars($vars = ''){
1677
1678 if( !empty($vars) ){
1679
1680 $string = $vars;
1681 $pattern = '/([^A-Za-z,=:_\d])/i'; /**remove any character from vars that are not Letters, Numbers or digits or Illegal php variable name */
1682 $replacement = '';
1683 $snippet_vars = preg_replace($pattern, $replacement, $string);
1684
1685 return $snippet_vars;
1686 }
1687 else{
1688 return $vars;
1689 }
1690 }
1691
1692 public static function filter_snippet_title($title = ''){
1693
1694 $title = sanitize_text_field( $title );
1695
1696 if( !isset($title) || empty($title) ){
1697 // $snippet_title = __( 'Untitled', 'post-snippets' );
1698 $snippet_title = self::number_duplicate_snippet_title(__('Untitled', 'post-snippets'));
1699 }
1700 else{
1701 $snippet_title = sanitize_text_field( $title );
1702 }
1703
1704 $pattern = '/[\s]/i'; /**remove any WhiteSpaces */
1705 $replacement = '';
1706 $snippet_title = preg_replace($pattern, $replacement, $snippet_title);
1707
1708 return $snippet_title;
1709 }
1710
1711 /**
1712 * Sanitize snippet content based on snippet type
1713 *
1714 * @param string $content The snippet content to sanitize
1715 * @param int $snippet_php The snippet type (0=regular, 1=PHP, 2=JS, 3=CSS)
1716 * @return string Sanitized content
1717 */
1718 public static function sanitize_snippet_content($content, $snippet_php = 0) {
1719 if (empty($content)) {
1720 return $content;
1721 }
1722
1723 // For JavaScript snippets, validate and sanitize dangerous patterns
1724 if ($snippet_php == 2) {
1725 // Remove potential XSS vectors while preserving legitimate JavaScript code
1726 $dangerous_patterns = array(
1727 '/<script[^>]*>/i', // Remove script tags (they shouldn't be in content)
1728 '/<\/script>/i', // Remove closing script tags
1729 '/javascript\s*:/i', // Remove javascript: protocol
1730 '/on\w+\s*=/i', // Remove event handlers (onclick, onerror, etc.)
1731 '/<iframe/i', // Remove iframe tags
1732 '/<object/i', // Remove object tags
1733 '/<embed/i', // Remove embed tags
1734 );
1735
1736 // Remove dangerous patterns
1737 foreach ($dangerous_patterns as $pattern) {
1738 $content = preg_replace($pattern, '', $content);
1739 }
1740
1741 // Additional validation: check for common XSS patterns
1742 $xss_patterns = array(
1743 '/document\.cookie/i',
1744 '/document\.write\s*\(/i',
1745 '/eval\s*\(/i',
1746 '/Function\s*\(/i',
1747 );
1748
1749 // Log or remove XSS patterns (for now, we'll allow but could be more strict)
1750 // In production, you might want to reject snippets with these patterns
1751
1752 return $content;
1753 }
1754
1755 // For CSS snippets, sanitize CSS-specific XSS vectors
1756 if ($snippet_php == 3) {
1757 // Remove potential XSS in CSS
1758 $content = preg_replace('/expression\s*\(/i', '', $content); // Remove CSS expressions
1759 $content = preg_replace('/javascript\s*:/i', '', $content); // Remove javascript: protocol
1760 $content = preg_replace('/@import/i', '', $content); // Remove @import (could be used for XSS)
1761 // Remove HTML tags from CSS
1762 $content = wp_strip_all_tags($content);
1763 return $content;
1764 }
1765
1766 // For regular snippets, use standard WordPress sanitization
1767 return wp_kses_post($content);
1768 }
1769
1770
1771 }
1772