Post Snippets - Version 3.0.4

Version Description

Download this release

Release Info

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

Code changes from version 3.0.3 to 3.0.4

assets/post-snippets.css CHANGED
@@ -68,6 +68,7 @@
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
 
68
  display: none !important;
69
  }
70
 
71
+
72
  /** Fix for when editors (TinyMCE Advanced) stack above the PS dialog **/
73
  .ui-dialog { z-index: 1000 !important ;}
74
 
assets/post-snippets.js CHANGED
@@ -201,4 +201,4 @@ jQuery(document).ready(function ($) {
201
  return true ;
202
  });
203
 
204
- });
201
  return true ;
202
  });
203
 
204
+ });
freemius/config.php CHANGED
@@ -285,6 +285,9 @@
285
  if ( ! defined( 'WP_FS__TIME_24_HOURS_IN_SEC' ) ) {
286
  define( 'WP_FS__TIME_24_HOURS_IN_SEC', 86400 );
287
  }
 
 
 
288
 
289
  #--------------------------------------------------------------------------------
290
  #region Debugging
285
  if ( ! defined( 'WP_FS__TIME_24_HOURS_IN_SEC' ) ) {
286
  define( 'WP_FS__TIME_24_HOURS_IN_SEC', 86400 );
287
  }
288
+ if ( ! defined( 'WP_FS__TIME_WEEK_IN_SEC' ) ) {
289
+ define( 'WP_FS__TIME_WEEK_IN_SEC', 7 * WP_FS__TIME_24_HOURS_IN_SEC );
290
+ }
291
 
292
  #--------------------------------------------------------------------------------
293
  #region Debugging
freemius/includes/class-freemius.php CHANGED
@@ -3009,10 +3009,6 @@
3009
 
3010
  $this->parse_settings( $plugin_info );
3011
 
3012
- if ( $this->has_affiliate_program() ) {
3013
- $this->fetch_affiliate_and_terms();
3014
- }
3015
-
3016
  if ( ! self::is_ajax() ) {
3017
  if ( ! $this->is_addon() || $this->is_only_premium() ) {
3018
  add_action( 'admin_menu', array( &$this, '_prepare_admin_menu' ), WP_FS__LOWEST_PRIORITY );
@@ -7357,14 +7353,12 @@
7357
 
7358
  /**
7359
  * @author Leo Fajardo (@leorw)
7360
- * @since 1.2.3
7361
  */
7362
- private function fetch_affiliate_and_terms() {
7363
- $this->_logger->entrance();
7364
-
7365
  if ( ! is_object( $this->plugin_affiliate_terms ) ) {
7366
  $plugins_api = $this->get_api_plugin_scope();
7367
- $affiliate_terms = $plugins_api->get( '/aff.json?type=affiliation', true );
7368
 
7369
  if ( ! $this->is_api_result_entity( $affiliate_terms ) ) {
7370
  return;
@@ -7372,20 +7366,30 @@
7372
 
7373
  $this->plugin_affiliate_terms = new FS_AffiliateTerms( $affiliate_terms );
7374
  }
 
 
 
 
 
 
 
 
 
 
7375
 
7376
- if ( $this->is_registered() ) {
7377
  $users_api = $this->get_api_user_scope();
7378
- $result = $users_api->get( "/plugins/{$this->_plugin->id}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json", true );
7379
  if ( $this->is_api_result_object( $result, 'affiliates' ) ) {
7380
  if ( ! empty( $result->affiliates ) ) {
7381
  $affiliate = new FS_Affiliate( $result->affiliates[0] );
7382
 
7383
- if ( ! $affiliate->is_pending() && ! empty( $this->_storage->affiliate_application_data ) ) {
7384
- unset( $this->_storage->affiliate_application_data );
 
7385
  }
7386
 
7387
  if ( $affiliate->is_using_custom_terms ) {
7388
- $affiliate_terms = $users_api->get( "/plugins/{$this->_plugin->id}/affiliates/{$affiliate->id}/aff/{$affiliate->custom_affiliate_terms_id}.json", true );
7389
  if ( $this->is_api_result_entity( $affiliate_terms ) ) {
7390
  $this->custom_affiliate_terms = new FS_AffiliateTerms( $affiliate_terms );
7391
  }
@@ -7397,6 +7401,17 @@
7397
  }
7398
  }
7399
 
 
 
 
 
 
 
 
 
 
 
 
7400
  /**
7401
  * @author Leo Fajardo
7402
  * @since 1.2.3
@@ -7469,6 +7484,8 @@
7469
  }
7470
  }
7471
 
 
 
7472
  $api = $this->get_api_user_scope();
7473
  $result = $api->call(
7474
  ( "/plugins/{$this->_plugin->id}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json" ),
@@ -7490,6 +7507,7 @@
7490
  }
7491
 
7492
  $affiliate_application_data = array(
 
7493
  'stats_description' => $affiliate['stats_description'],
7494
  'promotion_method_description' => $affiliate['promotion_method_description'],
7495
  );
@@ -12671,6 +12689,8 @@
12671
  function _affiliation_page_render() {
12672
  $this->_logger->entrance();
12673
 
 
 
12674
  fs_enqueue_local_style( 'fs_affiliation', '/admin/affiliation.css' );
12675
 
12676
  $vars = array( 'id' => $this->_module_id );
@@ -13160,8 +13180,6 @@
13160
  if (
13161
  // Product has no affiliate program.
13162
  ! $this->has_affiliate_program() ||
13163
- // User is already an affiliate.
13164
- is_object( $this->affiliate ) ||
13165
  // User has applied for an affiliate account.
13166
  ! empty( $this->_storage->affiliate_application_data ) ) {
13167
  return false;
3009
 
3010
  $this->parse_settings( $plugin_info );
3011
 
 
 
 
 
3012
  if ( ! self::is_ajax() ) {
3013
  if ( ! $this->is_addon() || $this->is_only_premium() ) {
3014
  add_action( 'admin_menu', array( &$this, '_prepare_admin_menu' ), WP_FS__LOWEST_PRIORITY );
7353
 
7354
  /**
7355
  * @author Leo Fajardo (@leorw)
7356
+ * @since 1.2.4
7357
  */
7358
+ private function fetch_affiliate_terms() {
 
 
7359
  if ( ! is_object( $this->plugin_affiliate_terms ) ) {
7360
  $plugins_api = $this->get_api_plugin_scope();
7361
+ $affiliate_terms = $plugins_api->get( '/aff.json?type=affiliation', false, WP_FS__TIME_WEEK_IN_SEC );
7362
 
7363
  if ( ! $this->is_api_result_entity( $affiliate_terms ) ) {
7364
  return;
7366
 
7367
  $this->plugin_affiliate_terms = new FS_AffiliateTerms( $affiliate_terms );
7368
  }
7369
+ }
7370
+
7371
+ /**
7372
+ * @author Leo Fajardo (@leorw)
7373
+ * @since 1.2.4
7374
+ */
7375
+ private function fetch_affiliate_and_custom_terms() {
7376
+ if ( ! empty( $this->_storage->affiliate_application_data ) ) {
7377
+ $application_data = $this->_storage->affiliate_application_data;
7378
+ $flush = ( ! isset( $application_data['status'] ) || 'pending' === $application_data['status'] );
7379
 
 
7380
  $users_api = $this->get_api_user_scope();
7381
+ $result = $users_api->get( "/plugins/{$this->_plugin->id}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json", $flush, WP_FS__TIME_WEEK_IN_SEC );
7382
  if ( $this->is_api_result_object( $result, 'affiliates' ) ) {
7383
  if ( ! empty( $result->affiliates ) ) {
7384
  $affiliate = new FS_Affiliate( $result->affiliates[0] );
7385
 
7386
+ if ( ! isset( $application_data['status'] ) || $application_data['status'] !== $affiliate->status ) {
7387
+ $application_data['status'] = $affiliate->status;
7388
+ $this->_storage->affiliate_application_data = $application_data;
7389
  }
7390
 
7391
  if ( $affiliate->is_using_custom_terms ) {
7392
+ $affiliate_terms = $users_api->get( "/plugins/{$this->_plugin->id}/affiliates/{$affiliate->id}/aff/{$affiliate->custom_affiliate_terms_id}.json", $flush, WP_FS__TIME_WEEK_IN_SEC );
7393
  if ( $this->is_api_result_entity( $affiliate_terms ) ) {
7394
  $this->custom_affiliate_terms = new FS_AffiliateTerms( $affiliate_terms );
7395
  }
7401
  }
7402
  }
7403
 
7404
+ /**
7405
+ * @author Leo Fajardo (@leorw)
7406
+ * @since 1.2.3
7407
+ */
7408
+ private function fetch_affiliate_and_terms() {
7409
+ $this->_logger->entrance();
7410
+
7411
+ $this->fetch_affiliate_terms();
7412
+ $this->fetch_affiliate_and_custom_terms();
7413
+ }
7414
+
7415
  /**
7416
  * @author Leo Fajardo
7417
  * @since 1.2.3
7484
  }
7485
  }
7486
 
7487
+ $this->fetch_affiliate_terms();
7488
+
7489
  $api = $this->get_api_user_scope();
7490
  $result = $api->call(
7491
  ( "/plugins/{$this->_plugin->id}/aff/{$this->plugin_affiliate_terms->id}/affiliates.json" ),
7507
  }
7508
 
7509
  $affiliate_application_data = array(
7510
+ 'status' => 'pending',
7511
  'stats_description' => $affiliate['stats_description'],
7512
  'promotion_method_description' => $affiliate['promotion_method_description'],
7513
  );
12689
  function _affiliation_page_render() {
12690
  $this->_logger->entrance();
12691
 
12692
+ $this->fetch_affiliate_and_terms();
12693
+
12694
  fs_enqueue_local_style( 'fs_affiliation', '/admin/affiliation.css' );
12695
 
12696
  $vars = array( 'id' => $this->_module_id );
13180
  if (
13181
  // Product has no affiliate program.
13182
  ! $this->has_affiliate_program() ||
 
 
13183
  // User has applied for an affiliate account.
13184
  ! empty( $this->_storage->affiliate_application_data ) ) {
13185
  return false;
freemius/start.php CHANGED
@@ -15,7 +15,7 @@
15
  *
16
  * @var string
17
  */
18
- $this_sdk_version = '1.2.3';
19
 
20
  #region SDK Selection Logic --------------------------------------------------------------------
21
 
@@ -498,4 +498,4 @@
498
  function fs_dump_log() {
499
  FS_Logger::dump();
500
  }
501
- }
15
  *
16
  * @var string
17
  */
18
+ $this_sdk_version = '1.2.4';
19
 
20
  #region SDK Selection Logic --------------------------------------------------------------------
21
 
498
  function fs_dump_log() {
499
  FS_Logger::dump();
500
  }
501
+ }
freemius/templates/forms/affiliation.php CHANGED
@@ -99,11 +99,15 @@
99
  <?php if ( $affiliate->is_active() ) : ?>
100
  <div class="updated">
101
  <p><strong><?php
102
- echo esc_html( sprintf(
103
- fs_text_inline( "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s.", 'affiliate-application-accepted', $slug ),
104
  $plugin_title,
105
- sprintf( '<a href="%s" target="_blank">%s</a>', $members_dashboard_login_url, $members_dashboard_login_url )
106
- ) );
 
 
 
 
107
  ?></strong></p>
108
  </div>
109
  <?php else : ?>
@@ -361,7 +365,7 @@
361
  beforeSend: function() {
362
  $cancelButton.addClass( 'disabled' );
363
  $submitButton.addClass( 'disabled' );
364
- $submitButton.text( '<?php fs_esc_js_inline( 'Processing', 'processing' ) ?>...' );
365
  },
366
  success : function( result ) {
367
  if ( result.success ) {
99
  <?php if ( $affiliate->is_active() ) : ?>
100
  <div class="updated">
101
  <p><strong><?php
102
+ echo sprintf(
103
+ fs_esc_html_inline( "Your affiliate application for %s has been accepted! Log in to your affiliate area at: %s.", 'affiliate-application-accepted', $slug ),
104
  $plugin_title,
105
+ sprintf(
106
+ '<a href="%s" target="_blank">%s</a>',
107
+ $members_dashboard_login_url,
108
+ $members_dashboard_login_url
109
+ )
110
+ );
111
  ?></strong></p>
112
  </div>
113
  <?php else : ?>
365
  beforeSend: function() {
366
  $cancelButton.addClass( 'disabled' );
367
  $submitButton.addClass( 'disabled' );
368
+ $submitButton.text( '<?php fs_esc_js_echo_inline( 'Processing', 'processing' ) ?>...' );
369
  },
370
  success : function( result ) {
371
  if ( result.success ) {
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.3
18
  * Author: David de Boer
19
  * Author URI: https://www.postsnippets.com
20
  * License: GPL-2.0+
@@ -39,13 +39,17 @@ function postsnippets_fs()
39
  'public_key' => 'pk_58a2ec84c44485a459aae07bfaf5f',
40
  'is_premium' => false,
41
  'has_addons' => false,
42
- 'has_paid_plans' => false,
 
 
 
 
43
  'menu' => array(
44
  'slug' => 'post-snippets/post-snippets.php',
45
  'override_exact' => true,
46
- 'contact' => false,
47
- 'account' => false,
48
- 'support' => false,
49
  'parent' => array(
50
  'slug' => 'options-general.php',
51
  ),
@@ -76,7 +80,7 @@ if ( !defined( 'PS_MAIN_FILE' ) ) {
76
  define( 'PS_MAIN_FILE', basename( __FILE__ ) );
77
  }
78
  if ( !defined( 'PS_VERSION' ) ) {
79
- define( 'PS_VERSION', '3.0.1' );
80
  }
81
  if ( !defined( 'PS_MAIN_FILE_PATH' ) ) {
82
  define( 'PS_MAIN_FILE_PATH', __FILE__ );
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.4
18
  * Author: David de Boer
19
  * Author URI: https://www.postsnippets.com
20
  * License: GPL-2.0+
39
  'public_key' => 'pk_58a2ec84c44485a459aae07bfaf5f',
40
  'is_premium' => false,
41
  'has_addons' => false,
42
+ 'has_paid_plans' => true,
43
+ 'trial' => array(
44
+ 'days' => 7,
45
+ 'is_require_payment' => false,
46
+ ),
47
  'menu' => array(
48
  'slug' => 'post-snippets/post-snippets.php',
49
  'override_exact' => true,
50
+ 'contact' => true,
51
+ 'account' => true,
52
+ 'support' => true,
53
  'parent' => array(
54
  'slug' => 'options-general.php',
55
  ),
80
  define( 'PS_MAIN_FILE', basename( __FILE__ ) );
81
  }
82
  if ( !defined( 'PS_VERSION' ) ) {
83
+ define( 'PS_VERSION', '3.0.2' );
84
  }
85
  if ( !defined( 'PS_MAIN_FILE_PATH' ) ) {
86
  define( 'PS_MAIN_FILE_PATH', __FILE__ );
readme.txt CHANGED
@@ -1,10 +1,10 @@
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,13 +97,20 @@ your clients to be able to use PHP code in a post snippet.
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())
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.4
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.4 - 20 Feb 2018 =
101
+
102
+ * Add "Support forum" link to support forum
103
+ * Add "Contact Us" link with contact form
104
+ * Add "Account" and "Upgrade" link for Pro version
105
+ * Updated Freemius SDK to 1.2.4
106
+
107
  = Version 3.0.3 - 15 Feb 2018 =
108
 
109
  * FIX:
110
  * Check for unique titles/shortcodes when creating new snippets, prevent duplicates
111
  * Improper slashes parsing, some users woudl see multiple clashes in shortcodes/PHP code, causing snippets to not render correctly
112
  * Prevent some editors (TinyMCE Advanced) from stacking above the Post Snippets dialog, add zindex to .ui-dialog
113
+
114
  = Version 3.0.2 - 13 Jan 2018 =
115
 
116
  * 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,55 +9,49 @@ namespace PostSnippets;
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,62 +70,62 @@ class Admin {
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,12 +133,13 @@ class Admin {
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,99 +147,76 @@ class Admin {
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,37 +226,32 @@ class Admin {
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,16 +259,17 @@ class Admin {
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,29 +278,28 @@ class Admin {
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,41 +307,38 @@ class Admin {
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,79 +348,75 @@ class Admin {
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,43 +425,36 @@ class Admin {
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,46 +468,40 @@ class Admin {
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,13 +509,13 @@ class Admin {
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,26 +523,21 @@ class Admin {
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,16 +549,17 @@ class Admin {
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,16 +574,25 @@ class Admin {
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,31 +601,30 @@ class Admin {
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,85 +632,85 @@ class Admin {
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
  }
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
  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
  * 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
  *
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
  '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
  *
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
  * @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
  *
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
  } 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
  *
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
  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
  '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
  *
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
  *
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
  *
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
  *
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 ( get_current_screen()->id == 'settings_page_post-snippets/post-snippets' ) {
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
  *
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
+ foreach ( $snippets as $key => $snippet ) {
703
+ if ( $snippet['title'] == $title ) {
704
+ wp_send_json_error( __( 'Duplicate title is not allowed. Please use different title for each snippets.', 'post-snippets' ) );
 
705
  }
706
  }
707
+
708
+ if ( isset( $snippets[$key] ) ) {
709
+ $snippets[$key]['title'] = $title;
 
710
  update_option( 'post_snippets_options', $snippets );
711
  }
712
+
713
+ wp_send_json_success( $title );
714
  }
715
 
716
  }
src/PostSnippets/Features.php CHANGED
@@ -17,20 +17,11 @@ class Features {
17
  // Get amount of snippets
18
  $snippet_count = count( get_option( 'post_snippets_options', array() ) );
19
 
20
- // Get price for this site
21
- $prices = array ( '39', '49', '59', '69' );
22
 
23
- $stored_price = get_option( 'ps_pro_features_price' );
24
-
25
- if ( ($stored_price == false) || ($stored_price == '9' || '19' || '29' || '79' ) ) {
26
-
27
- // The option already exists, so we just update it.
28
- update_option( 'ps_pro_features_price', $prices[ array_rand( $prices ) ] );
29
-
30
- }
31
-
32
- // Now get the final price
33
- $price = get_option( 'ps_pro_features_price' );
34
 
35
  // Setup features
36
  $features = array (
@@ -129,7 +120,7 @@ ob_start();
129
  </p>
130
 
131
  <p class="ps_features_wrap_intro">
132
- <?php echo sprintf( __( 'It\'s the professional version of Post Snippets, starting at $%s per year. You get three votes. The Pro version makes development and support for both versions sustainable, so you get a <strong>higher quality</strong> plugin.', 'post-snippets' ), $price ); ?>
133
  </p>
134
 
135
  <p class="ps_features_wrap_intro"><?php _e( 'Other suggestions? Send an email to <a href="mailto:david@postsnippets.com">david@postsnippets.com</a>.', 'post-snippets' ); ?>
17
  // Get amount of snippets
18
  $snippet_count = count( get_option( 'post_snippets_options', array() ) );
19
 
20
+ // Delete any existing prices
21
+ delete_option( 'ps_pro_features_price' );
22
 
23
+ // Now set the final price
24
+ $price = '39.99';
 
 
 
 
 
 
 
 
 
25
 
26
  // Setup features
27
  $features = array (
120
  </p>
121
 
122
  <p class="ps_features_wrap_intro">
123
+ <?php echo sprintf( __( 'It\'s the professional version of Post Snippets, starting at $%s per year (excl. taxes). You get three votes. The Pro version makes development and support for both versions sustainable, so you get a <strong>higher quality</strong> plugin.', 'post-snippets' ), $price ); ?>
124
  </p>
125
 
126
  <p class="ps_features_wrap_intro"><?php _e( 'Other suggestions? Send an email to <a href="mailto:david@postsnippets.com">david@postsnippets.com</a>.', 'post-snippets' ); ?>