PluginProbe
Snippet Shortcodes / trunk
Snippet Shortcodes vtrunk
5.2.1 5.2 5.1.8 5.1.6 5.1.7 5.1.5 trunk 1.0 1.1 1.2 1.3 1.3.1 1.4 1.5 1.5.1 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.8 2.0 2.0.1 All 74 releases
shortcode-variables / includes / marketing.php

marketing.php in Snippet Shortcodes trunk, at includes/marketing.php

523 lines 29.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined('ABSPATH') or die('Jog on!');
4
5 /**
6 * If we think we have a valid license, but the Premium plugin hasn't been installed then prompt the user to.
7 */
8 function sh_cd_prompt_to_install_premium() {
9
10 if ( true === sh_cd_is_premium_plugin_activated() ) {
11 return;
12 }
13
14 if ( false === (bool) get_option( 'sh-cd-license-valid', false ) ) {
15 return;
16 }
17
18 if ( false === empty( $_GET['dismiss-premium'] ) ) {
19 sh_cd_marketing_prompt_been_dismissed( '_yeken_shortcode_variables_install_premium_has_been_dismissed', 1 );
20 return;
21 }
22
23 if ( false === empty( sh_cd_marketing_prompt_been_dismissed( '_yeken_shortcode_variables_install_premium_has_been_dismissed' ) ) ) {
24 return;
25 }
26
27 $dismiss_url = add_query_arg( [ 'dismiss-premium' => 1 ], sh_cd_get_current_url() );
28
29 printf('<div class="notice notice-warning">
30 <p><strong>%1$s</strong>: %2$s</p>
31 <p>
32 %3$s
33 <a href="%4$s" class="button">%5$s</a>
34 </p>
35 </div>',
36 esc_html( SH_CD_PLUGIN_NAME ),
37 __( 'Shortcode Snippets now consists of two plugins: the one you currently have installed, and an additional plugin called <strong>"Snippet Shortcodes – Premium."</strong> You\'re seeing this message because it appears you may already have a Premium license. If that\'s the case, be sure to download and install the Premium plugin to continue accessing all Premium features.', SH_CD_SLUG ),
38 sh_cd_premium_shortcode_download( true ),
39 $dismiss_url,
40 __( 'Dismiss', SH_CD_SLUG ),
41 );
42 }
43 add_action( 'admin_notices', 'sh_cd_prompt_to_install_premium' );
44
45 /**
46 * If we think the premium plugin is installed, but not the latest version then prompt
47 */
48 function sh_cd_prompt_to_upgrade_premium() {
49
50 if ( false === sh_cd_is_premium_plugin_activated() ) {
51 return;
52 }
53
54 $latest_version = sh_cd_get_latest_premium_version();
55
56 if ( true === empty( $latest_version ) ) {
57 return;
58 }
59
60 if ( false === version_compare( $latest_version, YK_SS_PLUGIN_VERSION, '>' ) ) {
61 return;
62 }
63
64 if ( false === empty( $_GET[ 'dismiss-premium-upgrade' ] ) ) {
65 sh_cd_marketing_prompt_been_dismissed( '_yeken_shortcode_variables_upgrade_premium_has_been_dismissed', $_GET[ 'dismiss-premium-upgrade' ] );
66 return;
67 }
68
69 $version_dismissed = sh_cd_marketing_prompt_been_dismissed( '_yeken_shortcode_variables_upgrade_premium_has_been_dismissed' );
70
71 if ( false === empty( $version_dismissed ) && $version_dismissed === $latest_version ) {
72 return;
73 }
74
75 $dismiss_url = add_query_arg( [ 'dismiss-premium-upgrade' => $latest_version ], sh_cd_get_current_url() );
76
77 printf('<div class="notice notice-warning">
78 <p><strong>%1$s</strong>: %2$s</p>
79 <p>
80 <a href="%3$s" class="button">%6$s</a>
81 %7$s
82 <a href="%4$s" class="button">%5$s</a>
83 </p>
84 </div>',
85 esc_html( SH_CD_PLUGIN_NAME ),
86 __( 'A newer version of <strong>"Snippet Shortcodes – Premium"</strong> is available. Please update it from the Plugins screen to access the latest features and bug fixes.', SH_CD_SLUG ),
87 esc_url( admin_url('plugins.php') ),
88 $dismiss_url,
89 __( 'Dismiss', SH_CD_SLUG ),
90 __( 'Update both plugins via plugin screen', SH_CD_SLUG ),
91 sh_cd_premium_shortcode_download( true ),
92 );
93 }
94 add_action( 'admin_notices', 'sh_cd_prompt_to_upgrade_premium' );
95
96 /**
97 * Save the fact the user has dismissed the prompt to install the premium plugin
98 */
99 function sh_cd_marketing_prompt_been_dismissed( $key, $value = NULL ) {
100
101 if ( NULL !== $value ) {
102 update_option( $key, $value );
103 }
104
105 return get_option( $key ) ;
106 }
107
108 /**
109 * Return a link to the upgrade page
110 *
111 * @return string
112 */
113 function sh_cd_license_upgrade_link() {
114
115 $link = admin_url('admin.php?page=sh-cd-shortcode-variables-upgrade');
116
117 return esc_url( $link );
118 }
119
120 /**
121 * Return a list of all premium features
122 * @return array
123 */
124 function sh_cd_premium_features_list() {
125
126 return [
127 [ 'title' => 'Insert into header or footer', 'description' => 'Automaically insert your custom shortcode’s content into either your site’s header and/or footer.', 'read-more-url' => '' ],
128 [ 'title' => 'Limit header/footer to specific pages', 'description' => 'Restrict an auto-inserted header/footer shortcode to a chosen list of page slugs, instead of it appearing on every page.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/interactive-blocks/auto-insert-into-header-footer' ],
129 [ 'title' => 'Limit to certain device types', 'description' => 'Specify whether your custom shortcode should only be visible on Mobile, Tablet, Desktop or all three.', 'read-more-url' => '' ],
130 [ 'title' => 'Limit to user roles', 'description' => 'Show a custom shortcode only to guests or to specific WordPress user roles.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/role-targeting' ],
131 [ 'title' => 'Schedule visibility', 'description' => 'Optionally limit a custom shortcode to a start/end date and time window.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/visibility-scheduling' ],
132 [ 'title' => 'Render-count analytics', 'description' => 'See how many times each custom shortcode has been rendered, right on the edit screen.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/render-analytics' ],
133 [ 'title' => 'Content revision history', 'description' => 'Every save is kept as a revision (last 20 per shortcode), with one-click restore.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/revision-history' ],
134 [ 'title' => 'No limits', 'description' => 'Create unlimited custom shortcodes.', 'read-more-url' => '' ],
135 [ 'title' => 'Inline editor', 'description' => 'Ability to edit custom shortcodes without having to use a full editor.', 'read-more-url' => '' ],
136 [ 'title' => 'Duplicator', 'description' => 'Ability to duplicate custom shortcodes.', 'read-more-url' => '' ],
137 [ 'title' => 'Enable/Disable', 'description' => 'Ability to enable or disable custom shortcodes.', 'read-more-url' => '' ],
138 [ 'title' => 'Multi-site', 'description' => 'Use custom shortcodes throughout your entire multi-site, not just limited to the one child site', 'read-more-url' => '' ],
139 [ 'title' => 'CSV import & export', 'description' => 'Bulk import your custom shortcodes, or export your entire collection to CSV.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/csv-import' ],
140 [ 'title' => 'WooCommerce fields', 'description' => 'A ready-made shortcode to display WooCommerce fields.', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium/woocommerce-meta-fields' ],
141 [ 'title' => 'Fetch values from database', 'description' => 'A ready-made shortcode to fetch a value from any database table', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium/database-values-by-id' ],
142 [ 'title' => 'More ready-made shortcodes', 'description' => 'Display additional WordPress fields, as well as wrapping around PHP functionality like GET/POST values, number of users, etc', 'read-more-url' => 'https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium' ]
143
144 // [ 'title' => '', 'description' => '', 'read-more-url' => '' ],
145 ];
146
147 }
148 /**
149 * Return a list of slugs / titles for free presets
150 * @return array
151 */
152 function sh_cd_shortcode_presets_premium_list() {
153
154 return [
155 'db-value-by-id' => [ 'class' => 'SC_DB_VALUE_BY_ID', 'description' => __( 'Return a column value from a MySQL database for the given ID of search criteria e.g. <a href="https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium/database-values-by-id" rel="noopener" target="_blank">[sv slug="db-value-by-id" table="users" column="user_login" column-to-search="id" key="3" key-format="%d"]</a>', SH_CD_SLUG ), 'premium' => true, 'args' => [ '_sh_cd_func' => 'by-id' ] ],
156 'date' => [ 'class' => 'SC_DATE', 'description' => __( 'A shortcode that displays today\'s date with the ability to add or subtract days, months and years. To specify an interval to add or subtract onto the date use the parameter "interval" e.g. [sv slug="date" interval="-1 year"], [sv slug="date" interval="+5 days"], [sv slug="date" interval="+3 months"]. Intervals are based upon PHP intervals and are outlined here <a href="https://www.php.net/manual/en/dateinterval.createfromdatestring.php" target="_blank">https://www.php.net/manual/en/dateinterval.createfromdatestring.php</a>. Default is UK format (DD/MM/YYYY). Format can be changed by adding the parameter format="m/d/Y" onto the shortcode. Format syntax is based upon PHP date: <a href="http://php.net/manual/en/function.date.php" target="_blank">http://php.net/manual/en/function.date.php</a>', SH_CD_SLUG ), 'premium' => true ],
157 'site-language' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'Language code for the current site', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'language' ], 'premium' => true ],
158 'site-description' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'Site tagline (set in Settings > General)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'description' ], 'premium' => true ],
159 'site-wp-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The WordPress address (URL) (set in Settings > General)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'wpurl' ], 'premium' => true ],
160 'site-charset' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The "Encoding for pages and feeds" (set in Settings > Reading)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'charset' ], 'premium' => true ],
161 'site-wp-version' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The current WordPress version', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'version' ], 'premium' => true ],
162 'site-html-type' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The content-type (default: "text/html"). Themes and plugins', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'html_type' ], 'premium' => true ],
163 'site-stylesheet-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'URL to the stylesheet for the active theme.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'stylesheet_url' ], 'premium' => true ],
164 'site-stylesheet_directory' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'Directory path for the active theme.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'stylesheet_directory' ], 'premium' => true ],
165 'site-current-url' => [ 'class' => 'SC_CURRENT_URL', 'description' => __( 'Get the current URL.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'current_url' ], 'premium' => true],
166 'site-register-url' => [ 'class' => 'SC_REGISTER_URL', 'description' => __( 'Get the URL to the WordPress registration page.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'registration_url' ], 'premium' => true],
167 'site-template-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The URL of the active theme\'s directory.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'template_url' ], 'premium' => true],
168 'site-pingback-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The pingback XML-RPC file URL (xmlrpc.php)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'pingback_url' ], 'premium' => true ],
169 'site-atom-feed' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The Atom feed URL (/feed/atom)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'atom_url' ], 'premium' => true ],
170 'site-rdf-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The RDF/RSS 1.0 feed URL (/feed/rfd)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'rdf_url' ], 'premium' => true ],
171 'site-rss-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The RSS 0.92 feed URL (/feed/rss)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'rss_url' ], 'premium' => true ],
172 'site-rss2-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The RSS 2.0 feed URL (/feed)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'rss2_url' ], 'premium' => true ],
173 'site-comments-atom-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The comments Atom feed URL (/comments/feed)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'comments_atom_url' ], 'premium' => true ],
174 'site-comments-rss2-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The comments RSS 2.0 feed URL (/comments/feed)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'comments_rss2_url' ], 'premium' => true ],
175 'php-server-info' => [ 'class' => 'SC_SERVER_INFO', 'description' => __( 'Display data from the PHP $_SERVER global e.g. [sv slug="server-info" field="SERVER_SOFTWARE"]. <a href="http://php.net/manual/en/reserved.variables.server.php" rel="noopener" target="_blank">Allowed values for field attribute</a>.', SH_CD_SLUG ), 'premium' => true ],
176 'php-unique-id' => [ 'class' => 'SC_UNIQUE_ID', 'description' => __( 'Generate a unique ID. Based upon <a href="http://php.net/manual/en/function.uniqid.php" rel="noopener" target="_blank">uniqid()</a>. If you wish the unique ID to be prefixed, add a the prefix attribute e.g. [sv slug="php-unique-id" prefix="yeken"]', SH_CD_SLUG ), 'premium' => true ],
177 'php-timestamp' => [ 'class' => 'SC_TIMESTAMP', 'description' => __( 'Display the current unix timestamp. Based upon <a href="http://php.net/manual/en/function.time.php" rel="noopener" target="_blank">time()</a>.', SH_CD_SLUG ), 'premium' => true ],
178 'php-random-number' => [ 'class' => 'SC_RAND_NUMBER', 'description' => __( 'Display a random number. Based upon <a href="http://php.net/manual/en/function.rand.php" rel="noopener" target="_blank">rand()</a>. It also supports the optional arguments of min and max e.g. [sv slug="php-random-number" min="5" max="20" ]', SH_CD_SLUG ), 'premium' => true ],
179 'php-random-string' => [ 'class' => 'SC_RAND_STRING', 'description' => __( 'Display a random string of characters. It also supports the optional argument of "length". This specifies the number of characters you wish to display (default is 10) [sv slug="php-random-string" length="15"]', SH_CD_SLUG ), 'premium' => true ],
180 'php-post-value' => [ 'class' => 'SC_POST_VALUE', 'description' => __( 'Display a value from the $_POST array. The "key" arguments specifies which array value to render. It also supports the optional arguments of "default". If there is no value in the array for the given "key" then the "default" will be displayed. [sv slug="php-post-value" key="username" default="Not Found"]', SH_CD_SLUG ), 'premium' => true ],
181 'php-get-value' => [ 'class' => 'SC_GET_VALUE', 'description' => __( 'Display a value from the $_GET array. The "key" arguments specifies which array value to render. It also supports the optional arguments of "default". If there is no value in the array for the given "key" then the "default" will be displayed. [sv slug="php-get-value" key="username" default="Not Found"]', SH_CD_SLUG ), 'premium' => true ],
182 'php-info' => [ 'class' => 'SC_PHP_INFO', 'description' => __( 'Display PHP Info', SH_CD_SLUG ), 'premium' => true ],
183 'post-id' => [ 'class' => 'SC_POST_ID', 'description' => __( 'Display ID for the current post.', SH_CD_SLUG ), 'premium' => true ],
184 'post-author' => [ 'class' => 'SC_POST_AUTHOR', 'description' => __( 'Display the author\'s display name or ID. The optional argument "field" allows you to specify whether you wish to display the author\'s "display-name" or "id". [sv slug="post-author" field="id" ]', SH_CD_SLUG ), 'premium' => true ],
185 'post-counts' => [ 'class' => 'SC_POST_COUNTS', 'description' => __( 'Display a count of posts for certain statuses. Using the argument status, specify whether to return a count for all posts that have a status of "publish" (default), "future", "draft", "pending" or "private". [sv slug="post-counts" status="draft"]', SH_CD_SLUG ), 'premium' => true ],
186 'user-counts' => [ 'class' => 'SC_USER_COUNTS', 'description' => __( 'Display a count of all WordPress users or the number of WordPress users for a given role e.g. [sv slug="user-counts" role="subscriber"] or [sv slug="user-counts"]', SH_CD_SLUG ), 'premium' => true ],
187 'user-profile-photo' => [ 'class' => 'SC_AVATAR', 'description' => __( 'Display the WordPress profile photo for the logged in user e.g. [sv slug="user-profile-photo" width="150"] or [sv slug="user-profile-photo"]. Please note, width defaults to 96px.', SH_CD_SLUG ), 'premium' => true ],
188 'user-meta' => [ 'class' => 'SC_USER_META', 'description' => __( 'Display a WordPress user meta field (wraps get_user_meta) field e.g. last_name. Read more: <a href="https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium/wordpress-user-fields" rel="noopener" target="_blank">[sv slug="user-meta" field="last_name"]</a>', SH_CD_SLUG ), 'premium' => true ],
189 'woocommerce' => [ 'class' => 'SC_USER_META', 'description' => __( 'Display a Woocommerce user profile field e.g. billing_phone. Read more: <a href="https://yeken.gitbook.io/snippet-shortcodes/features/ready-made/premium/woocommerce-meta-fields" rel="noopener" target="_blank">[sv slug="woocommerce" field="billing_phone"]</a>', SH_CD_SLUG ), 'premium' => true ],
190 'copy-code' => [ 'class' => 'SC_COPY_CODE', 'description' => __( 'A ready-made, styled code snippet with a "Copy" button. Add the text to display via the "code" attribute e.g. [sv slug="copy-code" code="npm install my-package"]', SH_CD_SLUG ), 'premium' => true ],
191 'countdown' => [ 'class' => 'SC_COUNTDOWN', 'description' => __( 'A countdown timer counting down to a given date/time. Specify the target via the "date" attribute (e.g. date="2026-12-31T23:59:59") and an optional "label" attribute for the heading text e.g. [sv slug="countdown" date="2026-12-31T23:59:59" label="Sale ends in"]', SH_CD_SLUG ), 'premium' => true ]
192
193 // '' => [ 'class' => '', 'description' => '', 'premium' => true ]
194 ];
195 }
196
197 /**
198 * Return a list of slugs / titles for free presets
199 * @return array
200 */
201 function sh_cd_shortcode_presets_free_list() {
202
203 return [
204 'todays-date' => [ 'class' => 'SC_TODAYS_DATE', 'description' => __( 'Displays today\'s date. Default is UK format (DD/MM/YYYY). Format can be changed by adding the parameter format="m/d/Y" onto the shortcode. Format syntax is based upon PHP date: <a href="http://php.net/manual/en/function.date.php" target="_blank">http://php.net/manual/en/function.date.php</a>', SH_CD_SLUG ) ],
205 'user-ip' => [ 'class' => 'SC_USER_IP', 'description' => __( 'Display the current user\'s IP address.', SH_CD_SLUG )],
206 'user-agent' => [ 'class' => 'SC_USER_AGENT', 'description' => __( 'Display the current user\'s User Agent', SH_CD_SLUG ) ],
207 'site-url' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'The Site address (URL) (set in Settings > General)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'url' ] ],
208 'site-title' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'Displays the site title.', SH_CD_SLUG ) ],
209 'admin-email' => [ 'class' => 'SC_BLOG_INFO', 'description' => __( 'Admin email (set in Settings > General)', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'admin_email' ] ],
210 'page-title' => [ 'class' => 'SC_PAGE_TITLE', 'description' => __( 'Displays the page title.', SH_CD_SLUG ) ],
211 'login-page' => [ 'class' => 'SC_LOGIN_PAGE', 'description' => __( 'Wordpress login page. Add the parameter "redirect" to specify where the user is taken after a successful login e.g. redirect="http://www.google.co.uk".', SH_CD_SLUG ) ],
212 'privacy-url' => [ 'class' => 'SC_POLICY_URL', 'description' => __( 'Displays the privacy page URL.', SH_CD_SLUG ) ],
213 'username' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the logged in username.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'user_login' ] ],
214 'user-id' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the current user\'s ID.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'ID' ] ],
215 'user-email' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the current user\'s email address.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'user_email' ] ],
216 'first-name' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the current user\'s username.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'user_firstname' ] ],
217 'last-name' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the current user\'s last name.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'user_lastname' ] ],
218 'display-name' => [ 'class' => 'SC_USER_INFO', 'description' => __( 'Display the current user\'s display name.', SH_CD_SLUG ), 'args' => [ '_sh_cd_func' => 'display_name' ] ]
219 ];
220
221 // '' => [ 'class' => '', 'description' => '', 'args' => [ '_sh_cd_func' => 'admin_email' ] ]
222 }
223
224 /**
225 * Display a table of premium features
226 *
227 * @return string
228 */
229 function sh_cd_display_premium( $list = false ) {
230
231 $premium_user = sh_cd_is_premium();
232 $upgrade_link = sprintf( '<a class="button sh-cd-upgrade-button" href="%1$s"><i class="fas fa-check"></i> %2$s</a>', sh_cd_license_upgrade_link(), __('Upgrade now', SH_CD_SLUG ) );
233
234 $html = ( $list ) ? '<ul class="sh-cd-promo-list">' :
235 sprintf('<table class="widefat sh-cd-table" width="100%%">
236 <tr class="row-title">
237 <th class="row-title" width="30%%">%s</th>
238 <th width="*">%s</th>
239 </tr>
240 ', __('Premium Feature', SH_CD_SLUG ),
241 __('Description', SH_CD_SLUG )
242 );
243
244 $class = '';
245
246 foreach ( sh_cd_premium_features_list() as $feature ) {
247
248 $class = ($class == 'alternate') ? '' : 'alternate';
249
250 $title = ( empty( $feature[ 'read-more-url' ] ) ) ? esc_html( $feature[ 'title' ] ) : sprintf( '<a href="%s" target="_blank" rel="noopener">%s</a>', esc_url( $feature[ 'read-more-url' ] ), esc_html( $feature[ 'title' ] ) );
251
252 $template = ( $list ) ? '<li class="%s"><span>%s</span> - %s</li>' :
253 '<tr class="%s">
254 <td class="sh-cd-bold">%s</td>
255 <td>%s</td>
256 </tr>';
257
258 $html .= sprintf( $template,
259 $class,
260 $title,
261 esc_html( $feature[ 'description' ] )
262 );
263 }
264
265 $html .= ( $list ) ? '</ul>' : '</table>';
266
267 return $html;
268 }
269
270 /**
271 * Display a table of premade shortcodes
272 *
273 * @param string $display
274 * @return string
275 */
276 function sh_cd_display_premade_shortcodes( $display = 'all' ) {
277
278 $premium_user = sh_cd_is_premium();
279 $upgrade_link = sprintf( '<a class="button sh-cd-upgrade-button" href="%1$s"><i class="fa-regular fa-star"></i> %2$s</a>', sh_cd_license_upgrade_link(), __('Upgrade now', SH_CD_SLUG ) );
280
281 switch ( $display ) {
282 case 'free':
283 $shortcodes = sh_cd_shortcode_presets_free_list();
284 $show_premium_col = false;
285 break;
286 case 'premium':
287 $shortcodes = sh_cd_shortcode_presets_premium_list();
288 $show_premium_col = false;
289 break;
290 default:
291 $shortcodes = sh_cd_presets_both_lists();
292 $show_premium_col = true;
293 }
294
295 $html = sprintf('<table class="widefat sh-cd-table" width="100%%">
296 <tr class="row-title">
297 <th class="row-title" width="30%%">%s</th>', __('Shortcode', SH_CD_SLUG ) );
298
299 if ( true === $show_premium_col) {
300 $html .= sprintf( '<th class="row-title">%s</th>', __('Premium', SH_CD_SLUG ) );
301 }
302
303 $html .= sprintf( '<th width="*">%s</th>
304 </tr>', __('Description', SH_CD_SLUG ) );
305
306 $class = '';
307
308 foreach ( $shortcodes as $key => $data ) {
309
310 $class = ($class == 'alternate') ? '' : 'alternate';
311
312 $shortcode = '[' . SH_CD_SHORTCODE. ' slug=&quot;' . $key . '&quot;]';
313
314 $premium_shortcode = ( true === isset( $data['premium'] ) && true === $data['premium'] );
315
316 $html .= sprintf( '<tr class="%s"><td>%s <i class="far fa-copy sh-cd-copy-trigger sh-cd-tooltip" data-clipboard-text="%2$s" title="%3$s"></i></td>',
317 $class,
318 esc_html( $shortcode ),
319 __( 'Copy to clipboard', SH_CD_SLUG )
320 );
321
322
323 if ( true === $show_premium_col) {
324
325 $html .= sprintf( '<td align="middle">%s%s</td>',
326 ( true === $premium_shortcode && true === $premium_user ) ? '<i class="fas fa-star"></i>' : '',
327 ( true == $premium_shortcode && false === $premium_user ) ? $upgrade_link : ''
328 );
329 }
330
331 $html .= sprintf( '<td>%s</td></tr>', wp_kses_post( $data['description'] ) );
332
333 }
334
335 $html .= '</table>';
336
337 return $html;
338 }
339
340 /**
341 * Fetch the latest version of the premium plugin
342 */
343 function sh_cd_get_latest_premium_version() {
344
345 if ( $cache = get_transient( '_yeken_shortcode_variables_latest_premium_version' ) ) {
346 return $cache;
347 }
348
349 $response = wp_remote_get( SH_CD_YEKEN_PREMIUM_RELEASE_MANIFEST );
350 $version = NULL;
351
352 // All ok?
353 if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
354
355 $body = wp_remote_retrieve_body( $response );
356
357 if ( false === empty( $body ) ) {
358
359 $body = json_decode( $body, true );
360
361 $version = ( false === empty( $body[ 'version' ] ) ) ? $body[ 'version' ] : NULL;
362
363 set_transient( '_yeken_shortcode_variables_latest_premium_version', $version, DAY_IN_SECONDS );
364 }
365 }
366
367 return $version;
368 }
369
370 /**
371 * Display admin notice for notification from yeken.uk
372 */
373 function sh_cd_get_marketing_message() {
374
375 if ( $cache = get_transient( '_yeken_shortcode_variables_update' ) ) {
376 return $cache;
377 }
378
379 $response = wp_remote_get( SH_CD_YEKEN_UPDATES_URL );
380
381 // All ok?
382 if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
383
384 $body = wp_remote_retrieve_body( $response );
385
386 if ( false === empty( $body ) ) {
387 $body = json_decode( $body, true );
388
389 set_transient( '_yeken_shortcode_variables_update', $body, DAY_IN_SECONDS );
390
391 return $body;
392 }
393 }
394
395 return NULL;
396 }
397
398 /**
399 * Get/Set key of notice last dismissed.
400 */
401 function sh_cd_marketing_update_key_last_dismissed( $key = NULL ) {
402
403 if ( NULL !== $key ) {
404 update_option( '_yeken_shortcode_variables_update_key_last_dismissed', $key );
405 }
406
407 return (int) get_option( '_yeken_shortcode_variables_update_key_last_dismissed' ) ;
408
409 }
410
411 /**
412 * Display HTML for admin notice
413 */
414 function sh_cd_updates_display_notice( $json ) {
415
416 if ( false === is_array( $json ) ) {
417 return;
418 }
419
420 $button = '';
421
422 if ( !empty( $json[ 'url'] ) && !empty( $json[ 'url-title' ] ) ) {
423 $button = sprintf( '<p>
424 <a href="%1$s" class="button button-primary" target="_blank" rel="noopener">%2$s</a>
425 </p>',
426 esc_url( $json[ 'url' ] ),
427 sh_cd_wp_kses( $json[ 'url-title' ] )
428 );
429 }
430
431
432 printf('<div class="updated notice is-dismissible sh-cd-update-notice" data-update-key="%4$s" data-nonce="%5$s">
433 <p><strong>%1$s</strong>: %2$s</p>
434 %3$s
435 </div>',
436 esc_html( SH_CD_PLUGIN_NAME ),
437 !empty( $json[ 'message' ] ) ? esc_html( $json[ 'message' ] ) : '',
438 $button,
439 esc_html( $json[ '_update_key' ] ),
440 esc_attr( wp_create_nonce( 'sh-cd-nonce' ) )
441 );
442 }
443
444 /**
445 * display and admin notice if one exists and hasn't been dismissed already.
446 */
447 function sh_cd_updates_admin_notice() {
448
449 $json = sh_cd_get_marketing_message();
450
451 if ( true === empty( $json ) ) {
452 return false;
453 }
454
455 if ( $json[ '_update_key' ] <> sh_cd_marketing_update_key_last_dismissed() ) {
456 sh_cd_updates_display_notice( $json );
457 }
458 }
459 add_action( 'admin_notices', 'sh_cd_updates_admin_notice' );
460
461 /**
462 * Ajax handler to dismiss setup wizard
463 */
464 function sh_cd_updates_ajax_dismiss() {
465
466 check_ajax_referer( 'sh-cd-nonce', 'security' );
467
468 if ( true === empty( $_POST[ 'update_key' ] ) ) {
469 return;
470 }
471
472 $update_key = (int) $_POST[ 'update_key' ];
473
474 if ( false === empty( $update_key ) ) {
475 sh_cd_marketing_update_key_last_dismissed( $update_key );
476 }
477 }
478 add_action( 'wp_ajax_sh_cd_dismiss_notice', 'sh_cd_updates_ajax_dismiss' );
479
480 /**
481 * Text to display on upgrade and license page
482 */
483 function sh_cd_marketing_upgrade_page_text() {
484 ?>
485 <h4 class="sh-cd-promo"><i class="fa-regular fa-star"></i> <?php echo __( 'Unlock these extra features when you upgrade:', SH_CD_SLUG ); ?></h4>
486 <?php echo sh_cd_display_premium(); ?>
487 <h4 class="sh-cd-promo"><i class="fa-regular fa-star"></i> <?php echo __( 'Extra Premium shortcodes', SH_CD_SLUG ); ?>:</h4>
488 <p><?php echo __( 'Upgrade to the Premium version of Snippet Shortcodes to unlock these additional shortcodes.', SH_CD_SLUG ); ?>:</p>
489 <?php echo sh_cd_display_premade_shortcodes( 'premium' ); ?>
490 <?php
491 }
492
493 /**
494 * Marketing prompt to upgrade on Edit page to get additional shortcode options
495 *
496 * @return void
497 */
498 function sh_cd_marketing_page_edit_additional_options() {
499
500 $title = __( 'Unlock these additional settings by upgrading to Premium', SH_CD_SLUG ) ;
501
502 // A plain list rather than a fixed sprintf() placeholder count, so adding/removing an
503 // item later doesn't also require recounting %s tokens - see CLAUDE.md's note on keeping
504 // this in sync with new features.
505 $items = [
506 __( '<span>Insert into Header / Footer</span> - specify whether to automatically insert the shortcode content into the WP Header or Footer.', SH_CD_SLUG ),
507 __( '<span>Limit header/footer to specific pages</span> - restrict automatic header/footer insertion to a chosen list of page slugs, instead of it appearing on every page.', SH_CD_SLUG ),
508 __( '<span>Limit to mobile or desktop</span> - specify whether a shortcode should only appear on mobile or desktop devices.', SH_CD_SLUG ),
509 __( '<span>Limit to user roles</span> - show a shortcode only to guests or to specific WordPress user roles.', SH_CD_SLUG ),
510 __( '<span>Schedule visibility</span> - limit a shortcode to a start and/or end date and time window.', SH_CD_SLUG ),
511 __( '<span>Global shortcodes</span> - specify whether a shortcode should be available across all sites in your multisite network.', SH_CD_SLUG ),
512 __( '<span>Disable shortcodes</span> - have the ability to disable shortcodes so content will not appear at the location of the shortcode in the public facing site.', SH_CD_SLUG ),
513 __( '<span>Edit Slug</span> - have the ability to change the slug of an existing shortcode.', SH_CD_SLUG ),
514 __( '<span>Render-count analytics</span> - see how many times each shortcode has been rendered, right on this screen.', SH_CD_SLUG ),
515 __( '<span>Revision history</span> - restore a previous version of a shortcode\'s content, with the last 20 revisions kept automatically.', SH_CD_SLUG ),
516 ];
517
518 $content = '<ul><li>' . implode( '</li><li>', $items ) . '</li></ul>';
519
520 sh_cd_display_pro_upgrade_notice( $title, $content, 'sh-cd-page-edit-marketing-prompt' );
521 }
522
523