Post Snippets - Version 3.0.3

Version Description

Download this release

Release Info

Developer davdebcom
Plugin Icon 128x128 Post Snippets
Version 3.0.3
Comparing to
See all releases

Code changes from version 3.0.2 to 3.0.3

assets/post-snippets.css CHANGED
@@ -68,6 +68,8 @@
68
  display: none !important;
69
  }
70
 
 
 
71
 
72
  #post-snippets-dialog label {
73
  width: 60px;
68
  display: none !important;
69
  }
70
 
71
+ /** Fix for when editors (TinyMCE Advanced) stack above the PS dialog **/
72
+ .ui-dialog { z-index: 1000 !important ;}
73
 
74
  #post-snippets-dialog label {
75
  width: 60px;
assets/post-snippets.js CHANGED
@@ -57,15 +57,15 @@ jQuery(document).ready(function ($) {
57
  * Bulk check/uncheck
58
  */
59
  $('.check-column input').on('change', function () {
60
- if( $(this).is(":checked") ){
61
- $('.post-snippets-item input[name^="checked"]').each(function(){
62
  $(this).attr('checked', true);
63
  });
64
- }else{
65
- $('.post-snippets-item input[name^="checked"]').each(function(){
66
- $(this).attr('checked', false);
67
- });
68
- }
69
  });
70
  /**
71
  * Update title real time
@@ -82,9 +82,9 @@ jQuery(document).ready(function ($) {
82
  var item = $(this).closest('.post-snippets-item');
83
  var openItems = getFromLocalStorage();
84
  var key = parseInt(item.data('order'));
85
- if( _.contains(openItems, key) ){
86
  setInLocalStorage(_.without(openItems, key));
87
- }else{
88
  setInLocalStorage(_.union(openItems, [key]));
89
  }
90
  $(this).closest('.post-snippets-item').toggleClass('open');
@@ -114,7 +114,13 @@ jQuery(document).ready(function ($) {
114
  'title': title
115
  };
116
  $.post(ajaxurl, data, function (res) {
117
- wrap.toggleClass('edit');
 
 
 
 
 
 
118
  });
119
  return false;
120
  });
@@ -144,8 +150,8 @@ jQuery(document).ready(function ($) {
144
  */
145
  function getFromLocalStorage(name) {
146
  var optionName = name || 'openSnippets';
147
- var savedValue = localStorage.getItem(optionName);
148
- if(savedValue !== null){
149
  return JSON.parse(savedValue);
150
  }
151
  return [];
@@ -157,7 +163,7 @@ jQuery(document).ready(function ($) {
157
  $('.post-snippets .post-snippets-item').each(function () {
158
  var key = $(this).data('order');
159
  var openSnippets = getFromLocalStorage();
160
- if( _.contains(openSnippets, key) ){
161
  $(this).addClass('open');
162
  }
163
  });
@@ -166,14 +172,33 @@ jQuery(document).ready(function ($) {
166
  * Handle Expand Collapse
167
  */
168
  $('.expand-collapse a').on('click', function () {
169
- var isExpand = ! $('.expand-collapse').hasClass('expanded');
170
- if( isExpand ){
171
  $('.post-snippets-item').not('.open').find('.toggle-post-snippets-data').trigger('click');
172
- }else{
173
  $('.post-snippets-item.open').find('.toggle-post-snippets-data').trigger('click');
174
  }
175
  $('.expand-collapse').toggleClass('expanded');
176
  return false;
177
  });
178
 
179
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  * Bulk check/uncheck
58
  */
59
  $('.check-column input').on('change', function () {
60
+ if ($(this).is(":checked")) {
61
+ $('.post-snippets-item input[name^="checked"]').each(function () {
62
  $(this).attr('checked', true);
63
  });
64
+ } else {
65
+ $('.post-snippets-item input[name^="checked"]').each(function () {
66
+ $(this).attr('checked', false);
67
+ });
68
+ }
69
  });
70
  /**
71
  * Update title real time
82
  var item = $(this).closest('.post-snippets-item');
83
  var openItems = getFromLocalStorage();
84
  var key = parseInt(item.data('order'));
85
+ if (_.contains(openItems, key)) {
86
  setInLocalStorage(_.without(openItems, key));
87
+ } else {
88
  setInLocalStorage(_.union(openItems, [key]));
89
  }
90
  $(this).closest('.post-snippets-item').toggleClass('open');
114
  'title': title
115
  };
116
  $.post(ajaxurl, data, function (res) {
117
+ if(res.success){
118
+ wrap.find('input.post-snippet-title').val(res.data);
119
+ wrap.find('span.post-snippet-title').text(res.data);
120
+ wrap.toggleClass('edit');
121
+ }else{
122
+ alert(res.data);
123
+ }
124
  });
125
  return false;
126
  });
150
  */
151
  function getFromLocalStorage(name) {
152
  var optionName = name || 'openSnippets';
153
+ var savedValue = localStorage.getItem(optionName);
154
+ if (savedValue !== null) {
155
  return JSON.parse(savedValue);
156
  }
157
  return [];
163
  $('.post-snippets .post-snippets-item').each(function () {
164
  var key = $(this).data('order');
165
  var openSnippets = getFromLocalStorage();
166
+ if (_.contains(openSnippets, key)) {
167
  $(this).addClass('open');
168
  }
169
  });
172
  * Handle Expand Collapse
173
  */
174
  $('.expand-collapse a').on('click', function () {
175
+ var isExpand = !$('.expand-collapse').hasClass('expanded');
176
+ if (isExpand) {
177
  $('.post-snippets-item').not('.open').find('.toggle-post-snippets-data').trigger('click');
178
+ } else {
179
  $('.post-snippets-item.open').find('.toggle-post-snippets-data').trigger('click');
180
  }
181
  $('.expand-collapse').toggleClass('expanded');
182
  return false;
183
  });
184
 
185
+
186
+ $('form.post-snippets-wrap').on('submit', function (e) {
187
+ var list_of_values = [];
188
+
189
+ $('input.post-snippet-title').each(function (key, element) {
190
+ var val = $(element).val().trim();
191
+ if( $.inArray(val, list_of_values)){
192
+ list_of_values.push(val);
193
+ }else{
194
+ alert('Duplicate title is not allowed. Please use different title for each snippets.');
195
+ $(element).closest('.post-snippets-item').css('border', '1px solid red');
196
+ e.preventDefault();
197
+ return false;
198
+ }
199
+ });
200
+
201
+ return true ;
202
+ });
203
+
204
+ });
post-snippets.php CHANGED
@@ -14,7 +14,7 @@
14
  * Plugin Name: Post Snippets
15
  * Plugin URI: https://www.postsnippets.com
16
  * Description: Create a library of reusable content and insert it into your posts and pages. Navigate to "Settings > Post Snippets" to get started.
17
- * Version: 3.0.2
18
  * Author: David de Boer
19
  * Author URI: https://www.postsnippets.com
20
  * License: GPL-2.0+
14
  * Plugin Name: Post Snippets
15
  * Plugin URI: https://www.postsnippets.com
16
  * Description: Create a library of reusable content and insert it into your posts and pages. Navigate to "Settings > Post Snippets" to get started.
17
+ * Version: 3.0.3
18
  * Author: David de Boer
19
  * Author URI: https://www.postsnippets.com
20
  * License: GPL-2.0+
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Post Snippets ===
2
- Contributors: davdebcom, freemius
3
  Tags: custom snippet, custom shortcode, snippet, snippets, shortcode, shortcodes, block, blocks, html
4
  Requires at least: 3.3
5
  Tested up to: 4.9
6
  Requires PHP: 5.3
7
- Stable tag: 3.0.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -97,6 +97,13 @@ your clients to be able to use PHP code in a post snippet.
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
100
  = Version 3.0.2 - 13 Jan 2018 =
101
 
102
  * Fixed a PHP error by changing a new style array syntax to the version that also works in PHP 5.3 (this: array())
1
  === Post Snippets ===
2
+ Contributors: davdebcom
3
  Tags: custom snippet, custom shortcode, snippet, snippets, shortcode, shortcodes, block, blocks, html
4
  Requires at least: 3.3
5
  Tested up to: 4.9
6
  Requires PHP: 5.3
7
+ Stable tag: 3.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
97
 
98
  == Changelog ==
99
 
100
+ = Version 3.0.3 - 15 Feb 2018 =
101
+
102
+ * FIX:
103
+ * Check for unique titles/shortcodes when creating new snippets, prevent duplicates
104
+ * Improper slashes parsing, some users woudl see multiple clashes in shortcodes/PHP code, causing snippets to not render correctly
105
+ * Prevent some editors (TinyMCE Advanced) from stacking above the Post Snippets dialog, add zindex to .ui-dialog
106
+
107
  = Version 3.0.2 - 13 Jan 2018 =
108
 
109
  * Fixed a PHP error by changing a new style array syntax to the version that also works in PHP 5.3 (this: array())
src/PostSnippets/Admin.php CHANGED
@@ -9,49 +9,55 @@ namespace PostSnippets;
9
  * methods to simply the maintainance of the admin screen.
10
  *
11
  */
12
- class Admin
13
- {
14
  /**
15
  * Plugin settings.
16
  *
17
  * @var array
18
  */
19
- protected $settings ;
 
20
  /**
21
  * Defines hooks and filters for admin page.
22
  */
23
- public function __construct()
24
- {
25
  add_action( 'admin_menu', array( &$this, 'menu' ) );
26
  add_action( 'admin_init', array( &$this, 'init' ) );
27
  add_action( 'current_screen', array( &$this, 'addHeaderXss' ) );
28
- add_filter( 'plugin_action_links_' . plugin_basename( PS_PATH . 'post-snippets.php' ), array( $this, 'actionLinks' ) );
 
 
 
 
29
  // Newsletter sign-up admin notice
30
  add_action( 'admin_notices', array( $this, 'admin_notice_newsletter' ) );
 
31
  // Get started admin notice
32
  add_action( 'admin_notices', array( $this, 'admin_notice_get_started' ) );
 
33
  add_action( 'wp_ajax_update_post_snippets_order', array( $this, 'update_snippets_order' ) );
34
  add_action( 'wp_ajax_update_post_snippet_title', array( $this, 'update_post_snippet_title' ) );
35
  }
36
-
 
37
  // -------------------------------------------------------------------------
38
  // Setup
39
  // -------------------------------------------------------------------------
 
40
  /**
41
  * Register the administration page.
42
  *
43
  * @return void
44
  */
45
- public function menu()
46
- {
47
  $capability = 'manage_options';
48
-
49
- if ( defined( 'POST_SNIPPETS_ALLOW_EDIT_POSTS' ) and current_user_can( 'edit_posts' ) ) {
50
- $allowed = true;
 
51
  $capability = 'edit_posts';
52
  }
53
-
54
-
55
  if ( current_user_can( 'manage_options' ) or isset( $allowed ) ) {
56
  $optionPage = add_options_page(
57
  'Post Snippets',
@@ -70,62 +76,62 @@ class Admin
70
  array( &$this, 'overviewPage' )
71
  );
72
  }
73
-
74
- add_action( 'admin_print_scripts-' . $optionPage, array( &$this, 'scripts' ) );
 
 
 
75
  }
76
-
77
  /**
78
  * Initialize assets for the administration page.
79
  *
80
  * @return void
81
  */
82
- public function init()
83
- {
84
- wp_register_script(
85
- 'post-snippets',
86
- plugins_url( '/assets/post-snippets.js', \PostSnippets::FILE ),
87
- array( 'jquery' ),
88
- PS_VERSION,
89
- true
90
- );
91
  $this->registerSettings();
92
  }
93
-
94
  /**
95
  * Enqueue scripts to be loaded.
96
  *
97
  * @return void
98
  */
99
- public function scripts()
100
- {
101
  // Localize the strings in the script
102
  $translation_array = array(
103
- 'invalid_shortcode' => __( 'Invalid shortcode name', 'post-snippets' ),
104
  );
105
  wp_localize_script( 'post-snippets', 'post_snippets', $translation_array );
 
106
  // Add CSS for Pro features page
107
  $features_style_url = plugins_url( '/assets/features.css', \PostSnippets::FILE );
108
- wp_register_style(
109
- 'post-snippets-features',
110
- $features_style_url,
111
- array(),
112
- PS_VERSION
113
- );
114
  wp_enqueue_style( 'post-snippets-features' );
 
115
  // Add CSS for newsletter opt-in
116
  $features_style_url = plugins_url( '/assets/newsletter.css', \PostSnippets::FILE );
117
- wp_register_style(
118
- 'post-snippets-newsletter',
119
- $features_style_url,
120
- array(),
121
- PS_VERSION
122
- );
123
  wp_enqueue_style( 'post-snippets-newsletter' );
 
124
  wp_enqueue_script( 'jquery-ui-sortable' );
125
  wp_enqueue_script( 'underscore' );
 
 
 
 
 
126
  wp_enqueue_script( 'post-snippets' );
127
  }
128
-
129
  /**
130
  * Add X-XSS-Protection header.
131
  *
@@ -133,13 +139,12 @@ class Admin
133
  * forms. This header disables that functionlity on the Post Snippets admin
134
  * screen only.
135
  */
136
- public function addHeaderXss( $current_screen )
137
- {
138
  if ( $current_screen->base == 'settings_page_post-snippets/post-snippets' ) {
139
  header( 'X-XSS-Protection: 0' );
140
  }
141
  }
142
-
143
  /**
144
  * Quick link to the Post Snippets Settings page from the Plugins page.
145
  *
@@ -147,76 +152,99 @@ class Admin
147
  *
148
  * @return array $links Array with all the plugin's action links
149
  */
150
- public function actionLinks( $links )
151
- {
152
  $links[] = '<a href="' . PS_MAIN_PAGE_URL . '">' . __( 'Settings', 'post-snippets' ) . '</a>';
 
153
  return $links;
154
  }
155
-
 
156
  // -------------------------------------------------------------------------
157
  // Handle form submissions
158
  // -------------------------------------------------------------------------
 
159
  /**
160
  * Add New Snippet.
161
  */
162
- private function add()
163
- {
164
-
165
- if ( isset( $_POST['add-snippet'] ) && isset( $_POST['update_snippets_nonce'] ) && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' ) ) {
 
166
  $snippets = get_option( \PostSnippets::OPTION_KEY );
167
- if ( empty($snippets) ) {
168
  $snippets = array();
169
  }
170
- array_push( $snippets, array(
171
- 'title' => 'Untitled',
172
- 'vars' => '',
173
- 'description' => '',
174
- 'shortcode' => false,
175
- 'php' => false,
176
- 'wptexturize' => false,
177
- 'snippet' => '',
178
- ) );
 
 
 
 
 
179
  update_option( \PostSnippets::OPTION_KEY, $snippets );
180
- $this->message( __( 'A snippet named Untitled has been added.', 'post-snippets' ) );
 
 
 
 
 
181
  }
182
-
183
  }
184
-
185
  /**
186
  * Delete Snippet/s.
187
  */
188
- private function delete()
189
- {
190
-
191
- if ( isset( $_POST['delete-snippets'] ) && isset( $_POST['update_snippets_nonce'] ) && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' ) ) {
 
192
  $snippets = get_option( \PostSnippets::OPTION_KEY );
193
-
194
- if ( empty($snippets) || !isset( $_POST['checked'] ) ) {
195
- $this->message( __( 'Nothing selected to delete.', 'post-snippets' ) );
 
 
 
196
  return;
197
  }
198
-
199
- $delete = $_POST['checked'];
200
  $newsnippets = array();
201
  foreach ( $snippets as $key => $snippet ) {
202
  if ( in_array( $key, $delete ) == false ) {
203
  array_push( $newsnippets, $snippet );
204
  }
205
  }
 
206
  update_option( \PostSnippets::OPTION_KEY, $newsnippets );
207
- $this->message( __( 'Selected snippets have been deleted.', 'post-snippets' ) );
 
 
 
 
 
208
  }
209
-
210
  }
211
-
212
  /**
213
  * Update Snippet/s.
214
  */
215
- private function update()
216
- {
217
-
218
- if ( isset( $_POST['update-snippets'] ) && isset( $_POST['update_snippets_nonce'] ) && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' ) ) {
219
- $default = array(
 
220
  'title' => '',
221
  'snippet' => '',
222
  'description' => '',
@@ -226,32 +254,37 @@ class Admin
226
  'wptexturize' => '0',
227
  );
228
  $formatted_snippets = array();
229
-
230
- if ( !empty($_POST['snippets']) ) {
231
  $snippets = map_deep( $_POST['snippets'], 'trim' );
232
  $i = 0;
233
- foreach ( $snippets as $snippet ) {
234
- if ( empty($snippets) ) {
 
235
  continue;
236
  }
 
237
  $snippet = wp_parse_args( $snippet, $default );
 
238
  $snippet['title'] = str_replace( ' ', '', $snippet['title'] );
 
239
  if ( defined( 'POST_SNIPPETS_DISABLE_PHP' ) ) {
240
  $snippet['php'] = '0';
241
  }
242
- $snippet['snippet'] = wp_specialchars_decode( trim( stripslashes( $snippet['snippet'] ) ), ENT_NOQUOTES );
243
  $snippet['description'] = wp_specialchars_decode( trim( stripslashes( $snippet['description'] ) ), ENT_NOQUOTES );
244
- $formatted_snippets[$i] = $snippet;
 
245
  $i++;
246
  }
 
247
  }
248
-
249
  update_option( \PostSnippets::OPTION_KEY, $formatted_snippets );
250
  $this->message( __( 'Snippets have been updated.', 'post-snippets' ) );
251
  }
252
-
253
  }
254
-
255
  /**
256
  * Update User Option.
257
  *
@@ -259,17 +292,16 @@ class Admin
259
  *
260
  * @since Post Snippets 1.9.7
261
  */
262
- private function setUserOptions()
263
- {
264
-
265
- if ( isset( $_POST['post_snippets_user_nonce'] ) && wp_verify_nonce( $_POST['post_snippets_user_nonce'], 'post_snippets_user_options' ) ) {
266
- $id = get_current_user_id();
267
- $render = ( isset( $_POST['render'] ) ? true : false );
268
  update_user_meta( $id, \PostSnippets::USER_META_KEY, $render );
269
  }
270
-
271
  }
272
-
273
  /**
274
  * Get User Option.
275
  *
@@ -278,28 +310,29 @@ class Admin
278
  * @since Post Snippets 1.9.7
279
  * @return boolean If overview should be rendered on output or not
280
  */
281
- private function getUserOptions()
282
- {
283
- $id = get_current_user_id();
284
  $options = get_user_meta( $id, \PostSnippets::USER_META_KEY, true );
 
285
  return $options;
286
  }
287
-
 
288
  // -------------------------------------------------------------------------
289
  // HTML generation for option pages
290
  // -------------------------------------------------------------------------
 
291
  /**
292
  * Display Flashing Message.
293
  *
294
  * @param string $message Message to display to the user.
295
  */
296
- private function message( $message )
297
- {
298
  if ( $message ) {
299
- echo "<div class='updated'><p><strong>{$message}</strong></p></div>" ;
300
  }
301
  }
302
-
303
  /**
304
  * Creates the snippets administration page.
305
  *
@@ -307,38 +340,41 @@ class Admin
307
  *
308
  * @since Post Snippets 1.8.8
309
  */
310
- public function optionsPage()
311
- {
312
  // Handle Form Submits
313
  $this->add();
314
  $this->delete();
315
  $this->update();
 
316
  // Header
317
- echo '
318
  <!-- Create a header in the default WordPress \'wrap\' container -->
319
  <div class="wrap">
320
  <div id="icon-plugins" class="icon32"></div>
321
  <h2>Post Snippets</h2>
322
- ' ;
 
323
  // Tabs
324
- $active_tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets' );
325
- $base_url = '?page=' . PS_DIRECTORY . '/post-snippets.php&amp;tab=';
326
- $tabs = array(
327
  'snippets' => __( 'Manage Snippets', 'post-snippets' ),
328
  'options' => __( 'Options', 'post-snippets' ),
329
  'tools' => __( 'Import/Export', 'post-snippets' ),
330
  );
 
331
  if ( postsnippets_fs()->is_not_paying() ) {
332
  $tabs['features'] = __( 'Pro features', 'post-snippets' );
333
  }
334
- echo '<h2 class="nav-tab-wrapper">' ;
 
335
  foreach ( $tabs as $tab => $title ) {
336
- $active = ( $active_tab == $tab ? ' nav-tab-active' : '' );
337
- echo "<a href='{$base_url}{$tab}' class='nav-tab {$active} tab-{$tab}'>{$title}</a>" ;
338
  }
339
- echo '</h2>' ;
 
340
  // Tab content
341
-
342
  if ( $active_tab == 'snippets' ) {
343
  $this->tabSnippets();
344
  } elseif ( $active_tab == 'options' ) {
@@ -348,75 +384,79 @@ class Admin
348
  } else {
349
  $this->tabFeatures();
350
  }
351
-
352
  // Close it
353
- echo '</div>' ;
354
  }
355
-
356
  /**
357
  * Tab to Manage Snippets.
358
  *
359
  * @since Post Snippets 2.0
360
  */
361
- private function tabSnippets()
362
- {
363
- echo '<p class="description post-snippets-documentation-note">' ;
364
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
365
- echo '</p>' ;
 
366
  $data = array();
367
- echo View::render( 'admin_snippets', $data ) ;
368
  }
369
-
370
  /**
371
  * Tab to set options for the plugin.
372
  *
373
  * @return void
374
  */
375
- private function tabOptions()
376
- {
377
- echo '<p class="description post-snippets-documentation-note">' ;
378
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
379
- echo '</p>' ;
 
380
  $data = array();
381
- echo View::render( 'admin_options', $data ) ;
382
  }
383
-
384
  /**
385
  * Tab for Import/Export
386
  *
387
  * @since Post Snippets 2.0
388
  */
389
- private function tabTools()
390
- {
391
- echo '<p class="description post-snippets-documentation-note">' ;
392
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
393
- echo '</p>' ;
 
394
  $ie = new ImportExport();
 
395
  // Create header and export html form
396
  printf( "<h3>%s</h3>", __( 'Import/Export', 'post-snippets' ) );
397
  printf( "<h4>%s</h4>", __( 'Export', 'post-snippets' ) );
398
- echo '<form method="post">' ;
399
- echo '<p>' ;
400
  _e( 'Export your snippets for backup or to import them on another site.', 'post-snippets' );
401
- echo '</p>' ;
402
  printf( "<input type='submit' class='button' name='postsnippets_export' value='%s' />", __( 'Export Snippets', 'post-snippets' ) );
403
- echo '</form>' ;
 
404
  // Export logic, and import html form and logic
405
  $ie->exportSnippets();
406
- echo $ie->importSnippets() ;
407
  }
408
-
409
  /**
410
  * Tab for Pro features
411
  *
412
  * @since Post Snippets 2.5.4
413
  */
414
- private function tabFeatures()
415
- {
416
  $features = new Features();
417
- echo $features->showFeatures() ;
 
 
418
  }
419
-
 
420
  /**
421
  * Creates a read-only overview page.
422
  *
@@ -425,36 +465,43 @@ class Admin
425
  *
426
  * @since Post Snippets 1.9.7
427
  */
428
- public function overviewPage()
429
- {
430
  // Header
431
- echo '<div class="wrap">' ;
432
- echo '<h2>Post Snippets</h2>' ;
433
- echo '<p>' ;
434
  _e( 'This is an overview of all snippets defined for this site. These snippets are inserted into posts from the post editor using the Post Snippets button. You can choose to see the snippets here as-is or as they are actually rendered on the website. Enabling rendered snippets for this overview might look strange if the snippet have dependencies on variables, CSS or other parameters only available on the frontend. If that is the case it is recommended to keep this option disabled.', 'post-snippets' );
435
- echo '</p>' ;
 
436
  // Form
437
  $this->setUserOptions();
438
  $render = $this->getUserOptions();
439
- echo '<form method="post" action="">' ;
 
440
  wp_nonce_field( 'post_snippets_user_options', 'post_snippets_user_nonce' );
 
441
  $this->checkbox( __( 'Display rendered snippets', 'post-snippets' ), 'render', $render );
442
  $this->submit( 'update-post-snippets-user', __( 'Update', 'post-snippets' ) );
443
- echo '</form>' ;
 
444
  // Snippet List
445
  $snippets = get_option( \PostSnippets::OPTION_KEY );
446
- if ( !empty($snippets) ) {
447
  foreach ( $snippets as $key => $snippet ) {
448
- echo "<hr style='border: none;border-top:1px dashed #aaa; margin:24px 0;' />" ;
449
- echo "<h3>{$snippet['title']}" ;
 
450
  if ( $snippet['description'] ) {
451
- echo "<span class='description'> {$snippet['description']}</span>" ;
452
  }
453
- echo "</h3>" ;
 
454
  if ( $snippet['vars'] ) {
455
  printf( "<strong>%s:</strong> {$snippet['vars']}<br/>", __( 'Variables', 'post-snippets' ) );
456
  }
 
457
  // echo "<strong>Variables:</strong> {$snippet['vars']}<br/>";
 
458
  $options = array();
459
  if ( $snippet['shortcode'] ) {
460
  array_push( $options, 'Shortcode' );
@@ -468,40 +515,46 @@ class Admin
468
  if ( $options ) {
469
  printf( "<strong>%s:</strong> %s<br/>", __( 'Options', 'post-snippets' ), implode( ', ', $options ) );
470
  }
 
471
  printf( "<br/><strong>%s:</strong><br/>", __( 'Snippet', 'post-snippets' ) );
472
-
473
  if ( $render ) {
474
- echo do_shortcode( $snippet['snippet'] ) ;
475
  } else {
476
- echo "<code>" ;
477
- echo nl2br( htmlspecialchars( $snippet['snippet'], ENT_NOQUOTES ) ) ;
478
- echo "</code>" ;
479
  }
480
-
481
  }
482
  }
483
  // Close
484
- echo '</div>' ;
485
  }
486
-
 
487
  // -------------------------------------------------------------------------
488
  // Register and callbacks for the options tab
489
  // -------------------------------------------------------------------------
 
490
  /**
491
  * Register settings for the options tab.
492
  *
493
  * @return void
494
  */
495
- protected function registerSettings()
496
- {
497
  $this->settings = get_option( \PostSnippets::SETTINGS );
498
- register_setting( \PostSnippets::SETTINGS, \PostSnippets::SETTINGS );
 
 
 
 
 
499
  add_settings_section(
500
  'general_section',
501
  __( 'General', 'post-snippets' ),
502
  null,
503
  'post-snippets'
504
  );
 
505
  add_settings_field(
506
  'exclude_from_custom_editors',
507
  __( 'Exclude from Custom Editors', 'post-snippets' ),
@@ -509,13 +562,13 @@ class Admin
509
  'post-snippets',
510
  'general_section',
511
  array(
512
- 'id' => 'exclude_from_custom_editors',
513
- 'label_for' => 'exclude_from_custom_editors',
514
- 'description' => __( 'Checking this only includes Post Snippets on standard WordPress post editing screens.', 'post-snippets' ),
515
- )
516
  );
517
  }
518
-
519
  /**
520
  * Callback for HTML generator for exlusion of custom editors.
521
  *
@@ -523,21 +576,26 @@ class Admin
523
  *
524
  * @return void
525
  */
526
- public function cbExcludeFromCustomEditors( $args )
527
- {
528
- $checked = ( isset( $this->settings[$args['id']] ) ? $this->settings[$args['id']] : false );
529
- echo "<input type='checkbox' id='{$args['id']}' " ;
530
- echo "name='" . \PostSnippets::SETTINGS . "[{$args['id']}]' value='1' " ;
 
 
531
  if ( $checked ) {
532
- echo 'checked ' ;
533
  }
534
- echo " />" ;
535
- echo "<span class='description'>{$args['description']}</span>" ;
 
536
  }
537
-
 
538
  // -------------------------------------------------------------------------
539
  // HTML and Form element methods for Snippets form
540
  // -------------------------------------------------------------------------
 
541
  /**
542
  * Checkbox.
543
  *
@@ -549,17 +607,16 @@ class Admin
549
  *
550
  * @return void
551
  */
552
- public static function checkbox( $label, $name, $checked )
553
- {
554
- echo "<label for=\"{$name}\">" ;
555
  printf( '<input type="checkbox" name="%1$s" id="%1$s" value="true"', $name );
556
  if ( $checked ) {
557
- echo ' checked' ;
558
  }
559
- echo ' />' ;
560
- echo " {$label}</label><br/>" ;
561
  }
562
-
563
  /**
564
  * Submit.
565
  *
@@ -574,25 +631,16 @@ class Admin
574
  *
575
  * @return void
576
  */
577
- public static function submit(
578
- $name,
579
- $label,
580
- $class = 'button-primary',
581
- $wrap = true
582
- )
583
- {
584
- $btn = sprintf(
585
- '<input type="submit" name="%s" value="%s" class="%s" />&nbsp;&nbsp;&nbsp;',
586
- $name,
587
- $label,
588
- $class
589
- );
590
  if ( $wrap ) {
591
  $btn = "<div class=\"submit\">{$btn}</div>";
592
  }
593
- echo $btn ;
 
594
  }
595
-
596
  /**
597
  *
598
  * Show newsletter opt-in, only in Post Snippets.
@@ -601,30 +649,31 @@ class Admin
601
  *
602
  * @since 2.5.4
603
  */
604
- public function admin_notice_newsletter()
605
- {
606
  // Hide newsletter opt-in if option is true
607
  if ( get_option( 'ps_hide_admin_notice_newsletter' ) == true ) {
608
  return;
609
  }
 
610
  // Set option if "hide" button click detected (custom querystring value set to 1).
611
-
612
- if ( !empty($_REQUEST['ps-dismiss-newsletter-nag']) ) {
613
  update_option( 'ps_hide_admin_notice_newsletter', true );
 
614
  return;
615
  }
616
-
617
  // Show newsletter notice.
618
-
619
  if ( strpos( get_current_screen()->id, '/post-snippets' ) !== false ) {
620
- $active_tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets' );
621
  if ( $active_tab != 'features' ) {
622
- include_once PS_PATH . '/views/admin_notice_newsletter.php';
623
  }
 
624
  }
625
-
626
  }
627
-
 
628
  /**
629
  *
630
  * Show 'Get started' admin notice', everywhere.
@@ -632,80 +681,85 @@ class Admin
632
  *
633
  * @since 2.5.4
634
  */
635
- public function admin_notice_get_started()
636
- {
637
  // Hide newsletter opt-in if option is true
638
  if ( get_option( 'ps_hide_admin_notice_get_started' ) == true ) {
639
  return;
640
  }
 
641
  // Set option if "hide" button click detected (custom query string value set to 1).
642
-
643
- if ( !empty($_REQUEST['ps-dismiss-get-started-nag']) ) {
644
  update_option( 'ps_hide_admin_notice_get_started', true );
 
645
  return;
646
  }
647
-
648
  // Show newsletter notice.
649
-
650
  if ( strpos( get_current_screen()->id, '/post-snippets' ) == false ) {
651
- $active_tab = ( isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets' );
652
  if ( $active_tab != 'features' ) {
653
- include_once PS_PATH . '/views/admin_notice_get_started.php';
654
  }
 
655
  }
656
-
657
  }
658
-
659
  /**
660
  * Save Updated sorting
661
  */
662
- public function update_snippets_order()
663
- {
664
- if ( empty($_POST['order']) || !is_array( $_POST['order'] ) ) {
665
- wp_send_json_error( 'order data not received' );
666
  }
667
- if ( !current_user_can( 'manage_options' ) ) {
668
- wp_send_json_error( 'permission denied' );
669
  }
670
- $orders = array_map( 'intval', $_POST['order'] );
671
  $snippets = get_option( 'post_snippets_options', array() );
672
- if ( empty($snippets) ) {
673
- wp_send_json_error( 'snippets empty' );
674
  }
675
  $updated_order = array();
676
  foreach ( $orders as $order ) {
677
- if ( isset( $snippets[$order] ) ) {
678
- $updated_order[] = $snippets[$order];
679
  }
680
  }
681
  update_option( 'post_snippets_options', $updated_order );
682
- wp_send_json_success( 'success' );
683
  }
684
-
685
  /**
686
  * Save Updated title
687
  */
688
- public function update_post_snippet_title()
689
- {
690
- if ( !isset( $_POST['key'] ) || empty($_POST['title']) ) {
691
  wp_send_json_error();
692
  }
693
- if ( !current_user_can( 'manage_options' ) ) {
694
  wp_send_json_error();
695
  }
696
- $key = intval( $_POST['key'] );
697
- $title = sanitize_title( $_POST['title'] );
698
  $snippets = get_option( 'post_snippets_options', array() );
699
- if ( empty($snippets) ) {
700
  wp_send_json_error();
701
  }
702
-
703
- if ( isset( $snippets[$key] ) ) {
704
- $snippets[$key]['title'] = $title;
 
 
 
 
 
 
 
705
  update_option( 'post_snippets_options', $snippets );
706
  }
707
-
708
- wp_send_json_success();
709
  }
710
 
711
  }
9
  * methods to simply the maintainance of the admin screen.
10
  *
11
  */
12
+ class Admin {
 
13
  /**
14
  * Plugin settings.
15
  *
16
  * @var array
17
  */
18
+ protected $settings;
19
+
20
  /**
21
  * Defines hooks and filters for admin page.
22
  */
23
+ public function __construct() {
 
24
  add_action( 'admin_menu', array( &$this, 'menu' ) );
25
  add_action( 'admin_init', array( &$this, 'init' ) );
26
  add_action( 'current_screen', array( &$this, 'addHeaderXss' ) );
27
+ add_filter( 'plugin_action_links_' . plugin_basename( PS_PATH . 'post-snippets.php' ), array(
28
+ $this,
29
+ 'actionLinks'
30
+ ) );
31
+
32
  // Newsletter sign-up admin notice
33
  add_action( 'admin_notices', array( $this, 'admin_notice_newsletter' ) );
34
+
35
  // Get started admin notice
36
  add_action( 'admin_notices', array( $this, 'admin_notice_get_started' ) );
37
+
38
  add_action( 'wp_ajax_update_post_snippets_order', array( $this, 'update_snippets_order' ) );
39
  add_action( 'wp_ajax_update_post_snippet_title', array( $this, 'update_post_snippet_title' ) );
40
  }
41
+
42
+
43
  // -------------------------------------------------------------------------
44
  // Setup
45
  // -------------------------------------------------------------------------
46
+
47
  /**
48
  * Register the administration page.
49
  *
50
  * @return void
51
  */
52
+ public function menu() {
 
53
  $capability = 'manage_options';
54
+ if ( defined( 'POST_SNIPPETS_ALLOW_EDIT_POSTS' )
55
+ and current_user_can( 'edit_posts' )
56
+ ) {
57
+ $allowed = true;
58
  $capability = 'edit_posts';
59
  }
60
+
 
61
  if ( current_user_can( 'manage_options' ) or isset( $allowed ) ) {
62
  $optionPage = add_options_page(
63
  'Post Snippets',
76
  array( &$this, 'overviewPage' )
77
  );
78
  }
79
+
80
+ add_action(
81
+ 'admin_print_scripts-' . $optionPage,
82
+ array( &$this, 'scripts' )
83
+ );
84
  }
85
+
86
  /**
87
  * Initialize assets for the administration page.
88
  *
89
  * @return void
90
  */
91
+ public function init() {
92
+ wp_register_script( 'post-snippets', plugins_url( '/assets/post-snippets.js', \PostSnippets::FILE ), array( 'jquery' ), PS_VERSION, true );
93
+ if ( postsnippets_fs()->is__premium_only() ) {
94
+ wp_register_script( 'post-snippets-pro', plugins_url( '/assets/post-snippets-pro.js', \PostSnippets::FILE ), array(
95
+ 'jquery',
96
+ 'post-snippets'
97
+ ), PS_VERSION, true );
98
+ }
99
+
100
  $this->registerSettings();
101
  }
102
+
103
  /**
104
  * Enqueue scripts to be loaded.
105
  *
106
  * @return void
107
  */
108
+ public function scripts() {
 
109
  // Localize the strings in the script
110
  $translation_array = array(
111
+ 'invalid_shortcode' => __( 'Invalid shortcode name', 'post-snippets' )
112
  );
113
  wp_localize_script( 'post-snippets', 'post_snippets', $translation_array );
114
+
115
  // Add CSS for Pro features page
116
  $features_style_url = plugins_url( '/assets/features.css', \PostSnippets::FILE );
117
+ wp_register_style( 'post-snippets-features', $features_style_url, array(), PS_VERSION );
 
 
 
 
 
118
  wp_enqueue_style( 'post-snippets-features' );
119
+
120
  // Add CSS for newsletter opt-in
121
  $features_style_url = plugins_url( '/assets/newsletter.css', \PostSnippets::FILE );
122
+ wp_register_style( 'post-snippets-newsletter', $features_style_url, array(), PS_VERSION );
 
 
 
 
 
123
  wp_enqueue_style( 'post-snippets-newsletter' );
124
+
125
  wp_enqueue_script( 'jquery-ui-sortable' );
126
  wp_enqueue_script( 'underscore' );
127
+
128
+ if ( postsnippets_fs()->is__premium_only() ) {
129
+ wp_enqueue_script( 'post-snippets-pro' );
130
+ }
131
+
132
  wp_enqueue_script( 'post-snippets' );
133
  }
134
+
135
  /**
136
  * Add X-XSS-Protection header.
137
  *
139
  * forms. This header disables that functionlity on the Post Snippets admin
140
  * screen only.
141
  */
142
+ public function addHeaderXss( $current_screen ) {
 
143
  if ( $current_screen->base == 'settings_page_post-snippets/post-snippets' ) {
144
  header( 'X-XSS-Protection: 0' );
145
  }
146
  }
147
+
148
  /**
149
  * Quick link to the Post Snippets Settings page from the Plugins page.
150
  *
152
  *
153
  * @return array $links Array with all the plugin's action links
154
  */
155
+ public function actionLinks( $links ) {
156
+
157
  $links[] = '<a href="' . PS_MAIN_PAGE_URL . '">' . __( 'Settings', 'post-snippets' ) . '</a>';
158
+
159
  return $links;
160
  }
161
+
162
+
163
  // -------------------------------------------------------------------------
164
  // Handle form submissions
165
  // -------------------------------------------------------------------------
166
+
167
  /**
168
  * Add New Snippet.
169
  */
170
+ private function add() {
171
+ if ( isset( $_POST['add-snippet'] )
172
+ && isset( $_POST['update_snippets_nonce'] )
173
+ && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' )
174
+ ) {
175
  $snippets = get_option( \PostSnippets::OPTION_KEY );
176
+ if ( empty( $snippets ) ) {
177
  $snippets = array();
178
  }
179
+
180
+ array_push(
181
+ $snippets,
182
+ array(
183
+ 'title' => 'Untitled',
184
+ 'vars' => '',
185
+ 'description' => '',
186
+ 'shortcode' => false,
187
+ 'php' => false,
188
+ 'wptexturize' => false,
189
+ 'snippet' => ''
190
+ )
191
+ );
192
+
193
  update_option( \PostSnippets::OPTION_KEY, $snippets );
194
+ $this->message(
195
+ __(
196
+ 'A snippet named Untitled has been added.',
197
+ 'post-snippets'
198
+ )
199
+ );
200
  }
 
201
  }
202
+
203
  /**
204
  * Delete Snippet/s.
205
  */
206
+ private function delete() {
207
+ if ( isset( $_POST['delete-snippets'] )
208
+ && isset( $_POST['update_snippets_nonce'] )
209
+ && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' )
210
+ ) {
211
  $snippets = get_option( \PostSnippets::OPTION_KEY );
212
+
213
+ if ( empty( $snippets ) || ! isset( $_POST['checked'] ) ) {
214
+ $this->message(
215
+ __( 'Nothing selected to delete.', 'post-snippets' )
216
+ );
217
+
218
  return;
219
  }
220
+
221
+ $delete = $_POST['checked'];
222
  $newsnippets = array();
223
  foreach ( $snippets as $key => $snippet ) {
224
  if ( in_array( $key, $delete ) == false ) {
225
  array_push( $newsnippets, $snippet );
226
  }
227
  }
228
+
229
  update_option( \PostSnippets::OPTION_KEY, $newsnippets );
230
+ $this->message(
231
+ __(
232
+ 'Selected snippets have been deleted.',
233
+ 'post-snippets'
234
+ )
235
+ );
236
  }
 
237
  }
238
+
239
  /**
240
  * Update Snippet/s.
241
  */
242
+ private function update() {
243
+ if ( isset( $_POST['update-snippets'] )
244
+ && isset( $_POST['update_snippets_nonce'] )
245
+ && wp_verify_nonce( $_POST['update_snippets_nonce'], 'update_snippets' )
246
+ ) {
247
+ $default = array(
248
  'title' => '',
249
  'snippet' => '',
250
  'description' => '',
254
  'wptexturize' => '0',
255
  );
256
  $formatted_snippets = array();
257
+
258
+ if ( ! empty( $_POST['snippets'] ) ) {
259
  $snippets = map_deep( $_POST['snippets'], 'trim' );
260
  $i = 0;
261
+
262
+ foreach ( $snippets as $snippet ){
263
+ if ( empty( $snippets ) ) {
264
  continue;
265
  }
266
+
267
  $snippet = wp_parse_args( $snippet, $default );
268
+
269
  $snippet['title'] = str_replace( ' ', '', $snippet['title'] );
270
+
271
  if ( defined( 'POST_SNIPPETS_DISABLE_PHP' ) ) {
272
  $snippet['php'] = '0';
273
  }
274
+ $snippet['snippet'] = wp_specialchars_decode( trim( stripslashes( $snippet['snippet'] ) ), ENT_NOQUOTES );
275
  $snippet['description'] = wp_specialchars_decode( trim( stripslashes( $snippet['description'] ) ), ENT_NOQUOTES );
276
+
277
+ $formatted_snippets[ $i ] = $snippet;
278
  $i++;
279
  }
280
+
281
  }
282
+
283
  update_option( \PostSnippets::OPTION_KEY, $formatted_snippets );
284
  $this->message( __( 'Snippets have been updated.', 'post-snippets' ) );
285
  }
 
286
  }
287
+
288
  /**
289
  * Update User Option.
290
  *
292
  *
293
  * @since Post Snippets 1.9.7
294
  */
295
+ private function setUserOptions() {
296
+ if ( isset( $_POST['post_snippets_user_nonce'] )
297
+ && wp_verify_nonce( $_POST['post_snippets_user_nonce'], 'post_snippets_user_options' )
298
+ ) {
299
+ $id = get_current_user_id();
300
+ $render = isset( $_POST['render'] ) ? true : false;
301
  update_user_meta( $id, \PostSnippets::USER_META_KEY, $render );
302
  }
 
303
  }
304
+
305
  /**
306
  * Get User Option.
307
  *
310
  * @since Post Snippets 1.9.7
311
  * @return boolean If overview should be rendered on output or not
312
  */
313
+ private function getUserOptions() {
314
+ $id = get_current_user_id();
 
315
  $options = get_user_meta( $id, \PostSnippets::USER_META_KEY, true );
316
+
317
  return $options;
318
  }
319
+
320
+
321
  // -------------------------------------------------------------------------
322
  // HTML generation for option pages
323
  // -------------------------------------------------------------------------
324
+
325
  /**
326
  * Display Flashing Message.
327
  *
328
  * @param string $message Message to display to the user.
329
  */
330
+ private function message( $message ) {
 
331
  if ( $message ) {
332
+ echo "<div class='updated'><p><strong>{$message}</strong></p></div>";
333
  }
334
  }
335
+
336
  /**
337
  * Creates the snippets administration page.
338
  *
340
  *
341
  * @since Post Snippets 1.8.8
342
  */
343
+ public function optionsPage() {
 
344
  // Handle Form Submits
345
  $this->add();
346
  $this->delete();
347
  $this->update();
348
+
349
  // Header
350
+ echo '
351
  <!-- Create a header in the default WordPress \'wrap\' container -->
352
  <div class="wrap">
353
  <div id="icon-plugins" class="icon32"></div>
354
  <h2>Post Snippets</h2>
355
+ ';
356
+
357
  // Tabs
358
+ $active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets';
359
+ $base_url = '?page=' . PS_DIRECTORY . '/post-snippets.php&amp;tab=';
360
+ $tabs = array(
361
  'snippets' => __( 'Manage Snippets', 'post-snippets' ),
362
  'options' => __( 'Options', 'post-snippets' ),
363
  'tools' => __( 'Import/Export', 'post-snippets' ),
364
  );
365
+
366
  if ( postsnippets_fs()->is_not_paying() ) {
367
  $tabs['features'] = __( 'Pro features', 'post-snippets' );
368
  }
369
+
370
+ echo '<h2 class="nav-tab-wrapper">';
371
  foreach ( $tabs as $tab => $title ) {
372
+ $active = ( $active_tab == $tab ) ? ' nav-tab-active' : '';
373
+ echo "<a href='{$base_url}{$tab}' class='nav-tab {$active} tab-{$tab}'>{$title}</a>";
374
  }
375
+ echo '</h2>';
376
+
377
  // Tab content
 
378
  if ( $active_tab == 'snippets' ) {
379
  $this->tabSnippets();
380
  } elseif ( $active_tab == 'options' ) {
384
  } else {
385
  $this->tabFeatures();
386
  }
387
+
388
  // Close it
389
+ echo '</div>';
390
  }
391
+
392
  /**
393
  * Tab to Manage Snippets.
394
  *
395
  * @since Post Snippets 2.0
396
  */
397
+ private function tabSnippets() {
398
+ echo '<p class="description post-snippets-documentation-note">';
 
399
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
400
+ echo '</p>';
401
+
402
  $data = array();
403
+ echo View::render( 'admin_snippets', $data );
404
  }
405
+
406
  /**
407
  * Tab to set options for the plugin.
408
  *
409
  * @return void
410
  */
411
+ private function tabOptions() {
412
+ echo '<p class="description post-snippets-documentation-note">';
 
413
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
414
+ echo '</p>';
415
+
416
  $data = array();
417
+ echo View::render( 'admin_options', $data );
418
  }
419
+
420
  /**
421
  * Tab for Import/Export
422
  *
423
  * @since Post Snippets 2.0
424
  */
425
+ private function tabTools() {
426
+ echo '<p class="description post-snippets-documentation-note">';
 
427
  _e( 'Click \'Help\' in the top right for the documentation!', 'post-snippets' );
428
+ echo '</p>';
429
+
430
  $ie = new ImportExport();
431
+
432
  // Create header and export html form
433
  printf( "<h3>%s</h3>", __( 'Import/Export', 'post-snippets' ) );
434
  printf( "<h4>%s</h4>", __( 'Export', 'post-snippets' ) );
435
+ echo '<form method="post">';
436
+ echo '<p>';
437
  _e( 'Export your snippets for backup or to import them on another site.', 'post-snippets' );
438
+ echo '</p>';
439
  printf( "<input type='submit' class='button' name='postsnippets_export' value='%s' />", __( 'Export Snippets', 'post-snippets' ) );
440
+ echo '</form>';
441
+
442
  // Export logic, and import html form and logic
443
  $ie->exportSnippets();
444
+ echo $ie->importSnippets();
445
  }
446
+
447
  /**
448
  * Tab for Pro features
449
  *
450
  * @since Post Snippets 2.5.4
451
  */
452
+ private function tabFeatures() {
 
453
  $features = new Features();
454
+
455
+ echo $features->showFeatures();
456
+
457
  }
458
+
459
+
460
  /**
461
  * Creates a read-only overview page.
462
  *
465
  *
466
  * @since Post Snippets 1.9.7
467
  */
468
+ public function overviewPage() {
 
469
  // Header
470
+ echo '<div class="wrap">';
471
+ echo '<h2>Post Snippets</h2>';
472
+ echo '<p>';
473
  _e( 'This is an overview of all snippets defined for this site. These snippets are inserted into posts from the post editor using the Post Snippets button. You can choose to see the snippets here as-is or as they are actually rendered on the website. Enabling rendered snippets for this overview might look strange if the snippet have dependencies on variables, CSS or other parameters only available on the frontend. If that is the case it is recommended to keep this option disabled.', 'post-snippets' );
474
+ echo '</p>';
475
+
476
  // Form
477
  $this->setUserOptions();
478
  $render = $this->getUserOptions();
479
+
480
+ echo '<form method="post" action="">';
481
  wp_nonce_field( 'post_snippets_user_options', 'post_snippets_user_nonce' );
482
+
483
  $this->checkbox( __( 'Display rendered snippets', 'post-snippets' ), 'render', $render );
484
  $this->submit( 'update-post-snippets-user', __( 'Update', 'post-snippets' ) );
485
+ echo '</form>';
486
+
487
  // Snippet List
488
  $snippets = get_option( \PostSnippets::OPTION_KEY );
489
+ if ( ! empty( $snippets ) ) {
490
  foreach ( $snippets as $key => $snippet ) {
491
+ echo "<hr style='border: none;border-top:1px dashed #aaa; margin:24px 0;' />";
492
+
493
+ echo "<h3>{$snippet['title']}";
494
  if ( $snippet['description'] ) {
495
+ echo "<span class='description'> {$snippet['description']}</span>";
496
  }
497
+ echo "</h3>";
498
+
499
  if ( $snippet['vars'] ) {
500
  printf( "<strong>%s:</strong> {$snippet['vars']}<br/>", __( 'Variables', 'post-snippets' ) );
501
  }
502
+
503
  // echo "<strong>Variables:</strong> {$snippet['vars']}<br/>";
504
+
505
  $options = array();
506
  if ( $snippet['shortcode'] ) {
507
  array_push( $options, 'Shortcode' );
515
  if ( $options ) {
516
  printf( "<strong>%s:</strong> %s<br/>", __( 'Options', 'post-snippets' ), implode( ', ', $options ) );
517
  }
518
+
519
  printf( "<br/><strong>%s:</strong><br/>", __( 'Snippet', 'post-snippets' ) );
 
520
  if ( $render ) {
521
+ echo do_shortcode( $snippet['snippet'] );
522
  } else {
523
+ echo "<code>";
524
+ echo nl2br( htmlspecialchars( $snippet['snippet'], ENT_NOQUOTES ) );
525
+ echo "</code>";
526
  }
 
527
  }
528
  }
529
  // Close
530
+ echo '</div>';
531
  }
532
+
533
+
534
  // -------------------------------------------------------------------------
535
  // Register and callbacks for the options tab
536
  // -------------------------------------------------------------------------
537
+
538
  /**
539
  * Register settings for the options tab.
540
  *
541
  * @return void
542
  */
543
+ protected function registerSettings() {
 
544
  $this->settings = get_option( \PostSnippets::SETTINGS );
545
+
546
+ register_setting(
547
+ \PostSnippets::SETTINGS,
548
+ \PostSnippets::SETTINGS
549
+ );
550
+
551
  add_settings_section(
552
  'general_section',
553
  __( 'General', 'post-snippets' ),
554
  null,
555
  'post-snippets'
556
  );
557
+
558
  add_settings_field(
559
  'exclude_from_custom_editors',
560
  __( 'Exclude from Custom Editors', 'post-snippets' ),
562
  'post-snippets',
563
  'general_section',
564
  array(
565
+ 'id' => 'exclude_from_custom_editors',
566
+ 'label_for' => 'exclude_from_custom_editors',
567
+ 'description' => __( 'Checking this only includes Post Snippets on standard WordPress post editing screens.', 'post-snippets' )
568
+ )
569
  );
570
  }
571
+
572
  /**
573
  * Callback for HTML generator for exlusion of custom editors.
574
  *
576
  *
577
  * @return void
578
  */
579
+ public function cbExcludeFromCustomEditors( $args ) {
580
+ $checked = isset( $this->settings[ $args['id'] ] ) ?
581
+ $this->settings[ $args['id'] ] :
582
+ false;
583
+
584
+ echo "<input type='checkbox' id='{$args['id']}' ";
585
+ echo "name='" . \PostSnippets::SETTINGS . "[{$args['id']}]' value='1' ";
586
  if ( $checked ) {
587
+ echo 'checked ';
588
  }
589
+ echo " />";
590
+
591
+ echo "<span class='description'>{$args['description']}</span>";
592
  }
593
+
594
+
595
  // -------------------------------------------------------------------------
596
  // HTML and Form element methods for Snippets form
597
  // -------------------------------------------------------------------------
598
+
599
  /**
600
  * Checkbox.
601
  *
607
  *
608
  * @return void
609
  */
610
+ public static function checkbox( $label, $name, $checked ) {
611
+ echo "<label for=\"{$name}\">";
 
612
  printf( '<input type="checkbox" name="%1$s" id="%1$s" value="true"', $name );
613
  if ( $checked ) {
614
+ echo ' checked';
615
  }
616
+ echo ' />';
617
+ echo " {$label}</label><br/>";
618
  }
619
+
620
  /**
621
  * Submit.
622
  *
631
  *
632
  * @return void
633
  */
634
+ public static function submit( $name, $label, $class = 'button-primary', $wrap = true ) {
635
+ $btn = sprintf( '<input type="submit" name="%s" value="%s" class="%s" />&nbsp;&nbsp;&nbsp;', $name, $label, $class );
636
+
 
 
 
 
 
 
 
 
 
 
637
  if ( $wrap ) {
638
  $btn = "<div class=\"submit\">{$btn}</div>";
639
  }
640
+
641
+ echo $btn;
642
  }
643
+
644
  /**
645
  *
646
  * Show newsletter opt-in, only in Post Snippets.
649
  *
650
  * @since 2.5.4
651
  */
652
+ public function admin_notice_newsletter() {
653
+
654
  // Hide newsletter opt-in if option is true
655
  if ( get_option( 'ps_hide_admin_notice_newsletter' ) == true ) {
656
  return;
657
  }
658
+
659
  // Set option if "hide" button click detected (custom querystring value set to 1).
660
+ if ( ! empty( $_REQUEST['ps-dismiss-newsletter-nag'] ) ) {
 
661
  update_option( 'ps_hide_admin_notice_newsletter', true );
662
+
663
  return;
664
  }
665
+
666
  // Show newsletter notice.
 
667
  if ( strpos( get_current_screen()->id, '/post-snippets' ) !== false ) {
668
+ $active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets';
669
  if ( $active_tab != 'features' ) {
670
+ include_once( PS_PATH . '/views/admin_notice_newsletter.php' );
671
  }
672
+
673
  }
 
674
  }
675
+
676
+
677
  /**
678
  *
679
  * Show 'Get started' admin notice', everywhere.
681
  *
682
  * @since 2.5.4
683
  */
684
+ public function admin_notice_get_started() {
685
+
686
  // Hide newsletter opt-in if option is true
687
  if ( get_option( 'ps_hide_admin_notice_get_started' ) == true ) {
688
  return;
689
  }
690
+
691
  // Set option if "hide" button click detected (custom query string value set to 1).
692
+ if ( ! empty( $_REQUEST['ps-dismiss-get-started-nag'] ) ) {
 
693
  update_option( 'ps_hide_admin_notice_get_started', true );
694
+
695
  return;
696
  }
697
+
698
  // Show newsletter notice.
 
699
  if ( strpos( get_current_screen()->id, '/post-snippets' ) == false ) {
700
+ $active_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'snippets';
701
  if ( $active_tab != 'features' ) {
702
+ include_once( PS_PATH . '/views/admin_notice_get_started.php' );
703
  }
704
+
705
  }
 
706
  }
707
+
708
  /**
709
  * Save Updated sorting
710
  */
711
+ public function update_snippets_order() {
712
+ if ( empty( $_POST['order'] ) || ! is_array( $_POST['order'] ) ) {
713
+ wp_send_json_error('order data not received');
 
714
  }
715
+ if ( ! current_user_can( 'manage_options' ) ) {
716
+ wp_send_json_error('permission denied');
717
  }
718
+ $orders = array_map( 'intval', $_POST['order'] );
719
  $snippets = get_option( 'post_snippets_options', array() );
720
+ if ( empty( $snippets ) ) {
721
+ wp_send_json_error('snippets empty');
722
  }
723
  $updated_order = array();
724
  foreach ( $orders as $order ) {
725
+ if ( isset( $snippets[ $order ] ) ) {
726
+ $updated_order[] = $snippets[ $order ];
727
  }
728
  }
729
  update_option( 'post_snippets_options', $updated_order );
730
+ wp_send_json_success('success');
731
  }
732
+
733
  /**
734
  * Save Updated title
735
  */
736
+ public function update_post_snippet_title() {
737
+ if ( ! isset( $_POST['key'] ) || empty( $_POST['title'] ) ) {
 
738
  wp_send_json_error();
739
  }
740
+ if ( ! current_user_can( 'manage_options' ) ) {
741
  wp_send_json_error();
742
  }
743
+ $key = intval( $_POST['key'] );
744
+ $title = sanitize_title( $_POST['title'] );
745
  $snippets = get_option( 'post_snippets_options', array() );
746
+ if ( empty( $snippets ) ) {
747
  wp_send_json_error();
748
  }
749
+
750
+ foreach ( $snippets as $key =>$snippet){
751
+ if( $snippet['title'] == $title){
752
+ wp_send_json_error(__('Duplicate title is not allowed. Please use different title for each snippets.', 'post-snippets'));
753
+ }
754
+ }
755
+
756
+
757
+ if ( isset( $snippets[ $key ] ) ) {
758
+ $snippets[ $key ]['title'] = $title;
759
  update_option( 'post_snippets_options', $snippets );
760
  }
761
+
762
+ wp_send_json_success($title);
763
  }
764
 
765
  }
src/PostSnippets/Shortcode.php CHANGED
@@ -40,7 +40,7 @@ class Shortcode
40
  if ( $content != null ) {
41
  $attributes["content"] = $content;
42
  }
43
- $generated_content = addslashes( $snippet["snippet"] );
44
  // Disables auto conversion from & to &amp; as that should be done in snippet, not code (destroys php etc).
45
  // $snippet = str_replace("&", "&amp;", $snippet);
46
  foreach ( $attributes as $key => $val ) {
40
  if ( $content != null ) {
41
  $attributes["content"] = $content;
42
  }
43
+ $generated_content = $snippet["snippet"];
44
  // Disables auto conversion from & to &amp; as that should be done in snippet, not code (destroys php etc).
45
  // $snippet = str_replace("&", "&amp;", $snippet);
46
  foreach ( $attributes as $key => $val ) {