PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / trunk
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts vtrunk
2.7.7 2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 All 28 releases
← All changes | includes/class.plugin.php +427 -223 2.0.6trunk View file →
@@ -1,223 +1,427 @@
1 -<?php
2 - /**
3 - * PHP snippets plugin base
4 - * @author Webcraftic <wordpress.webraftic@gmail.com>
5 - * @copyright (c) 19.02.2018, Webcraftic
6 - * @version 1.0
7 - */
8 -
9 - // Exit if accessed directly
10 - if( !defined('ABSPATH') ) {
11 - exit;
12 - }
13 -
14 - if( !class_exists('WINP_Plugin') ) {
15 -
16 - class WINP_Plugin extends Wbcr_Factory404_Plugin {
17 -
18 - /**
19 - * @var Wbcr_Factory404_Plugin
20 - */
21 - private static $app;
22 -
23 - /**
24 - * @param string $plugin_path
25 - * @param array $data
26 - * @throws Exception
27 - */
28 - public function __construct($plugin_path, $data)
29 - {
30 - parent::__construct($plugin_path, $data);
31 -
32 - self::$app = $this;
33 -
34 - $this->setTextDomain();
35 - $this->setModules();
36 -
37 - $this->globalScripts();
38 -
39 - if( is_admin() ) {
40 - $this->adminScripts();
41 - }
42 - }
43 -
44 - /**
45 - * @return WINP_Plugin
46 - */
47 - public static function app()
48 - {
49 - return self::$app;
50 - }
51 -
52 - /**
53 - * @return bool
54 - */
55 - public function currentUserCan()
56 - {
57 - return current_user_can('manage_options');
58 - }
59 -
60 - protected function setTextDomain()
61 - {
62 -
63 - load_plugin_textdomain('insert-php', false, dirname(WINP_PLUGIN_BASE) . '/languages/');
64 - }
65 -
66 - protected function setModules()
67 - {
68 -
69 - $this->load(array(
70 - array('libs/factory/bootstrap', 'factory_bootstrap_404', 'admin'),
71 - array('libs/factory/forms', 'factory_forms_405', 'admin'),
72 - array('libs/factory/pages', 'factory_pages_405', 'admin'),
73 - array('libs/factory/types', 'factory_types_404'),
74 - array('libs/factory/taxonomies', 'factory_taxonomies_324'),
75 - array('libs/factory/metaboxes', 'factory_metaboxes_403', 'admin'),
76 - array('libs/factory/viewtables', 'factory_viewtables_403', 'admin'),
77 - array('libs/factory/shortcodes', 'factory_shortcodes_324', 'all'),
78 - array('libs/factory/notices', 'factory_notices_403', 'admin'),
79 -
80 - ));
81 - }
82 -
83 - private function registerPages()
84 - {
85 - $this->registerPage('WINP_ExportPage', WINP_PLUGIN_DIR . '/admin/pages/export.php');
86 - $this->registerPage('WINP_SettingsPage', WINP_PLUGIN_DIR . '/admin/pages/settings.php');
87 - }
88 -
89 - private function registerTypes()
90 - {
91 - $this->registerType('WSC_TasksItemType', WINP_PLUGIN_DIR . '/admin/types/snippets-post-types.php');
92 -
93 - require_once(WINP_PLUGIN_DIR . '/admin/types/snippets-taxonomy.php');
94 - Wbcr_FactoryTaxonomies324::register('WINP_SnippetsTaxonomy', $this);
95 - }
96 -
97 - private function registerShortcodes()
98 - {
99 - require_once(WINP_PLUGIN_DIR . '/includes/shortcodes.php');
100 - Wbcr_FactoryShortcodes324::register('WINP_SnippetShortcode', $this);
101 - }
102 -
103 - private function adminScripts()
104 - {
105 - require_once(WINP_PLUGIN_DIR . '/admin/includes/class.snippets.viewtable.php');
106 - require_once(WINP_PLUGIN_DIR . '/admin/boot.php');
107 -
108 - $this->registerTypes();
109 - $this->registerPages();
110 - }
111 -
112 - private function globalScripts()
113 - {
114 - $this->registerShortcodes();
115 -
116 - add_action('plugins_loaded', array($this, 'executeActiveSnippets'), 1);
117 - }
118 -
119 - /**
120 - * Execute the snippets once the plugins are loaded
121 - */
122 - public function executeActiveSnippets()
123 - {
124 - global $wpdb;
125 -
126 - $save_mode = false;
127 -
128 - if( isset($_REQUEST['wbcr-php-snippets-safe-mode']) && !isset($_COOKIE['wbcr-php-snippets-safe-mode']) && $this->currentUserCan() ) {
129 - $save_mode = true;
130 - setcookie("wbcr-php-snippets-safe-mode", 1, time() + 3600);
131 - }
132 -
133 - $snippets = $wpdb->get_results("SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} INNER JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id ) WHERE (
134 - ( {$wpdb->postmeta}.meta_key = '" . $this->getPrefix() . "snippet_scope' AND {$wpdb->postmeta}.meta_value = 'evrywhere' )
135 -) AND {$wpdb->posts}.post_type = '" . WINP_SNIPPETS_POST_TYPE . "' AND (({$wpdb->posts}.post_status = 'publish'))");
136 -
137 - if( empty($snippets) ) {
138 - return;
139 - }
140 -
141 - foreach((array)$snippets as $snippet) {
142 - $id = (int)$snippet->ID;
143 -
144 - $is_active = (int)WINP_Helper::getMetaOption($id, 'snippet_activate', 0);
145 - $code = WINP_Helper::getMetaOption($id, 'snippet_code');
146 -
147 - if( $is_active ) {
148 - if( isset($_POST['wbcr_inp_snippet_scope']) && isset($_POST['post_ID']) && (int)$_POST['post_ID'] === $id && $this->currentUserCan() ) {
149 - return;
150 - }
151 -
152 - if( ($save_mode || isset($_COOKIE['wbcr-php-snippets-safe-mode'])) && $this->currentUserCan() ) {
153 - return;
154 - }
155 -
156 - $this->executeSnippet($code, $id);
157 - }
158 - }
159 - }
160 -
161 - /**
162 - * Execute a snippet
163 - *
164 - * Code must NOT be escaped, as
165 - * it will be executed directly
166 - *
167 - * @param string $code The snippet code to execute
168 - * @param int $id The snippet ID
169 - * @param bool $catch_output Whether to attempt to suppress the output of execution using buffers
170 - *
171 - * @return mixed The result of the code execution
172 - */
173 - public function executeSnippet($code, $id = 0, $catch_output = true)
174 - {
175 -
176 - if( empty($code) ) {
177 - return false;
178 - }
179 -
180 - if( $catch_output ) {
181 - ob_start();
182 - }
183 -
184 - $result = eval($code);
185 -
186 - if( $catch_output ) {
187 - ob_end_clean();
188 - }
189 -
190 - return $result;
191 - }
192 -
193 - /**
194 - * Retrieve the first error in a snippet's code
195 - *
196 - * @param int $snippet_id
197 - *
198 - * @return array|bool
199 - */
200 - public function getSnippetError($snippet_id)
201 - {
202 - if( !intval($snippet_id) ) {
203 - return false;
204 - }
205 -
206 - $snippet_code = WINP_Helper::getMetaOption($snippet_id, 'snippet_code');
207 -
208 - $result = $this->executeSnippet($snippet_code, $snippet_id);
209 -
210 - if( false !== $result ) {
211 - return false;
212 - }
213 -
214 - $error = error_get_last();
215 -
216 - if( is_null($error) ) {
217 - return false;
218 - }
219 -
220 - return $error;
221 - }
222 - }
223 - }
1 +<?php
2 +/**
3 + * PHP snippets plugin base
4 + *
5 + * @package Woody_Code_Snippets
6 + */
7 +
8 +// Exit if accessed directly
9 +if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 +}
12 +
13 +if ( ! class_exists( 'WINP_Plugin' ) ) {
14 +
15 + class WINP_Plugin {
16 +
17 + /**
18 + * Custom license provider (overrides parent's premium property)
19 + *
20 + * @var WINP_License
21 + */
22 + public $premium;
23 +
24 + /**
25 + * @var WINP_Plugin
26 + */
27 + private static $app;
28 +
29 + /**
30 + * Snippets custom post type instance.
31 + *
32 + * @var WINP_SnippetsType|null
33 + */
34 + private $snippets_type;
35 +
36 + /**
37 + * @throws Exception
38 + */
39 + public function __construct() {
40 + self::$app = $this;
41 +
42 + // Initialize custom license provider.
43 + require_once WINP_PLUGIN_DIR . '/includes/class.license.php';
44 + $this->premium = new WINP_License();
45 +
46 + require_once WINP_PLUGIN_DIR . '/includes/class.rest.php';
47 + new WINP_Rest();
48 +
49 + require_once WINP_PLUGIN_DIR . '/admin/pages/class.settings.php';
50 + require_once WINP_PLUGIN_DIR . '/admin/pages/class.new-item.php';
51 + require_once WINP_PLUGIN_DIR . '/admin/pages/class.snippet-library.php';
52 +
53 + WINP_Settings::get_instance();
54 + WINP_NewItem::get_instance();
55 + WINP_SnippetLibrary::get_instance();
56 +
57 + $this->load_global();
58 +
59 + if ( is_admin() || WINP_Helper::doing_rest_api() ) {
60 +
61 + if ( WINP_Helper::doing_ajax() ) {
62 + require WINP_PLUGIN_DIR . '/admin/ajax/ajax.php';
63 + require WINP_PLUGIN_DIR . '/admin/ajax/snippet-library.php';
64 + }
65 +
66 + $this->load_backend();
67 + }
68 + add_action(
69 + 'init',
70 + function () {
71 + if ( WINP_Plugin::app()->premium->is_active() ) {
72 + update_option( WINP_PLUGIN_NAMESPACE . '_logger_flag', 'yes' );
73 + }
74 + }
75 + );
76 +
77 + add_filter( WINP_PLUGIN_NAMESPACE . '_logger_data', [ $this, 'get_logger_data' ] );
78 + add_filter( 'themeisle_sdk_blackfriday_data', [ $this, 'add_black_friday_data' ] );
79 + }
80 +
81 + /**
82 + * Get plugin instance
83 + *
84 + * @return WINP_Plugin
85 + */
86 + public static function app() {
87 + return self::$app;
88 + }
89 +
90 + /**
91 + * Survey data.
92 + *
93 + * @return array<string, mixed>
94 + */
95 + public function get_survey_data() {
96 + $install_time = get_option( WINP_PLUGIN_NAMESPACE . '_install', time() );
97 + $days_since_install = round( ( time() - $install_time ) / DAY_IN_SECONDS );
98 + $total_snippets = wp_count_posts( WINP_SNIPPETS_POST_TYPE );
99 + $total_snippets = isset( $total_snippets->publish ) ? $total_snippets->publish : 0;
100 +
101 + $data = [
102 + 'environmentId' => 'cmiooosih4vm0ad01eihjub64',
103 + 'attributes' => [
104 + 'free_version' => WINP_PLUGIN_VERSION,
105 + 'pro_version' => defined( 'WASP_PLUGIN_VERSION' ) ? WASP_PLUGIN_VERSION : '',
106 + 'install_days_number' => $days_since_install,
107 + 'license_status' => self::app()->premium->is_active(),
108 + 'total_snippets' => $total_snippets,
109 + ],
110 + ];
111 +
112 + if ( self::app()->premium->is_active() ) {
113 + $data['attributes']['license_key'] = apply_filters( 'themeisle_sdk_secret_masking', self::app()->premium->get_key() );
114 + }
115 +
116 + return $data;
117 + }
118 +
119 + /**
120 + * @return bool
121 + */
122 + public function current_user_car() {
123 + return current_user_can( 'manage_options' );
124 + }
125 +
126 + /**
127 + * Get Execute_Snippet object
128 + *
129 + * @return WINP_Execute_Snippet
130 + */
131 + public function get_execute_object() {
132 + require_once WINP_PLUGIN_DIR . '/includes/class.execute.snippet.php';
133 +
134 + return WINP_Execute_Snippet::app();
135 + }
136 +
137 + /**
138 + * Get WINP_Api object
139 + *
140 + * @return WINP_Api
141 + */
142 + public function get_api_object() {
143 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.request.php';
144 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.api.php';
145 +
146 + return new WINP_Api();
147 + }
148 +
149 + /**
150 + * Get WINP_Common_Snippet object
151 + *
152 + * @return WINP_Common_Snippet
153 + */
154 + public function get_common_object() {
155 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.common.snippet.php';
156 +
157 + return new WINP_Common_Snippet();
158 + }
159 +
160 + /**
161 + * Plugin activation hook.
162 + * Creates demo snippets on first activation and sets up capabilities.
163 + *
164 + * @return void
165 + */
166 + public function activation_hook() {
167 + // Add custom capabilities to administrator role.
168 + $this->get_snippets_type()->add_capabilities();
169 +
170 + // Create demo snippets with examples of use.
171 + if ( ! get_option( 'wbcr_inp_demo_snippets_created' ) ) {
172 + WINP_Helper::create_demo_snippets();
173 + }
174 +
175 + WINP_Helper::flush_page_cache();
176 + }
177 +
178 + /**
179 + * Plugin deactivation hook.
180 + * Removes custom capabilities.
181 + *
182 + * @return void
183 + */
184 + public function deactivation_hook() {
185 + // Remove custom capabilities from administrator role.
186 + $this->get_snippets_type()->remove_capabilities();
187 + }
188 +
189 + /**
190 + * Get the snippets post type handler, loading it on demand.
191 + *
192 + * The (de)activation hooks can run outside of admin/REST requests
193 + * (e.g. `wp plugin activate` via WP-CLI), where load_backend() and
194 + * therefore register_types() never ran.
195 + *
196 + * @return WINP_SnippetsType
197 + */
198 + private function get_snippets_type() {
199 + if ( is_null( $this->snippets_type ) ) {
200 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.snippets.viewtable.php';
201 + require_once WINP_PLUGIN_DIR . '/admin/types/snippets-post-types.php';
202 + $this->snippets_type = new WINP_SnippetsType();
203 + }
204 +
205 + return $this->snippets_type;
206 + }
207 +
208 + /**
209 + * Register custom post types and taxonomies.
210 + *
211 + * @throws \Exception Exception.
212 + * @since 2.2.0
213 + */
214 + private function register_types() {
215 + require_once WINP_PLUGIN_DIR . '/admin/types/snippets-post-types.php';
216 + $this->snippets_type = new WINP_SnippetsType();
217 +
218 + require_once WINP_PLUGIN_DIR . '/admin/types/snippets-taxonomy.php';
219 + new WINP_SnippetsTaxonomy();
220 + }
221 +
222 + /**
223 + * Register shortcodes.
224 + *
225 + * @since 2.2.0
226 + */
227 + private function register_shortcodes() {
228 + $action = WINP_HTTP::get( 'action', '' );
229 + if ( ! ( 'edit' == $action && is_admin() ) ) {
230 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcodes.php';
231 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-php.php';
232 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-text.php';
233 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-universal.php';
234 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-css.php';
235 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-js.php';
236 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-html.php';
237 + require_once WINP_PLUGIN_DIR . '/includes/shortcodes/shortcode-ad.php';
238 +
239 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodePhp', $this );
240 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeText', $this );
241 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeUniversal', $this );
242 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeCss', $this );
243 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeJs', $this );
244 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeHtml', $this );
245 + WINP_Helper::register_shortcode( 'WINP_SnippetShortcodeAdvert', $this );
246 + }
247 + }
248 +
249 + /**
250 + * Initialization and require files for backend and frontend.
251 + *
252 + * @since 2.2.0
253 + */
254 + private function load_global() {
255 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.gutenberg.snippet.php';
256 + require_once WINP_PLUGIN_DIR . '/includes/class.admin-bar.php';
257 +
258 + new WINP_Gutenberg_Snippet();
259 + WINP_Admin_Bar::instance();
260 +
261 + $this->get_execute_object()->register_hooks();
262 + $this->register_shortcodes();
263 + }
264 +
265 + /**
266 + * Initialization and require files for backend.
267 + *
268 + * @throws \Exception
269 + * @since 2.2.0
270 + */
271 + private function load_backend() {
272 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.snippets.viewtable.php';
273 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.filter.snippet.php';
274 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.actions.snippet.php';
275 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.notices.php';
276 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.admin.notices.php';
277 + require_once WINP_PLUGIN_DIR . '/admin/includes/class.request.php';
278 + require_once WINP_PLUGIN_DIR . '/admin/boot.php';
279 +
280 + $this->get_common_object()->register_hooks();
281 + $this->register_types();
282 +
283 + new WINP_Filter_List();
284 + new WINP_Actions_Snippet();
285 + WINP_Notices::instance();
286 + new WINP_Admin_Notices();
287 +
288 + if ( ! defined( 'E2E_TESTING' ) ) {
289 + add_filter(
290 + 'themeisle-sdk/survey/' . WINP_PLUGIN_SLUG,
291 + function ( $data, $page_slug ) {
292 + if ( empty( $page_slug ) ) {
293 + return $data;
294 + }
295 +
296 + return $this->get_survey_data();
297 + },
298 + 10,
299 + 2
300 + );
301 + }
302 + }
303 +
304 + /**
305 + * Метод проверяет активацию премиум плагина и наличие действующего лицензионного ключа
306 + *
307 + * @return bool
308 + */
309 + public function is_premium() {
310 + return $this->premium->is_active();
311 + }
312 +
313 + /**
314 + * Logger data.
315 + *
316 + * @return array<string, mixed>
317 + */
318 + public function get_logger_data() {
319 + $settings = WINP_Settings::get_instance()->get_settings();
320 +
321 + // Each settings has a lot of keys, we only want name and value items. So map them.
322 + $settings = array_map(
323 + function ( $setting ) {
324 + return [
325 + 'name' => isset( $setting['name'] ) ? $setting['name'] : '',
326 + 'value' => isset( $setting['value'] ) ? $setting['value'] : '',
327 + ];
328 + },
329 + $settings
330 + );
331 +
332 + $total_snippets = wp_count_posts( WINP_SNIPPETS_POST_TYPE );
333 + $total_snippets = isset( $total_snippets->publish ) ? $total_snippets->publish : 0;
334 +
335 + // Count snippets by type.
336 + $snippet_types = [ 'php', 'css', 'js', 'text', 'html', 'advert', 'universal' ];
337 + $types_count = [];
338 +
339 + foreach ( $snippet_types as $type ) {
340 + $count = get_posts(
341 + [
342 + 'post_type' => WINP_SNIPPETS_POST_TYPE,
343 + 'post_status' => 'publish',
344 + 'meta_key' => 'wbcr_inp_snippet_type',
345 + 'meta_value' => $type,
346 + 'posts_per_page' => -1,
347 + 'fields' => 'ids',
348 + ]
349 + );
350 +
351 + if ( ! empty( $count ) ) {
352 + $types_count[ $type ] = count( $count );
353 + }
354 + }
355 +
356 + return [
357 + 'settings' => $settings,
358 + 'stats' => [
359 + 'total_snippets' => $total_snippets,
360 + 'types' => $types_count,
361 + ],
362 + ];
363 + }
364 +
365 + /**
366 + * Set the black friday data.
367 + *
368 + * @param array<string, mixed> $configs The configuration array for the loaded products.
369 + *
370 + * @return array<string, mixed> The configurations.
371 + */
372 + public function add_black_friday_data( $configs ) {
373 + $config = $configs['default'];
374 +
375 + $message = __( 'Conditional logic, revision history, import/export. Manage your custom code properly. Exclusively for existing Woody users.', 'insert-php' );
376 + $cta_label = __( 'Get Woody Pro', 'insert-php' );
377 +
378 + $plan = apply_filters( 'product_woody_license_plan', 0 );
379 + $status = apply_filters( 'product_woody_license_status', 'invalid' );
380 + $license = apply_filters( 'product_woody_license_key', false );
381 + $pro_product_slug = defined( 'WASP_PLUGIN_FILE' ) ? basename( dirname( WASP_PLUGIN_FILE ) ) : '';
382 +
383 + $is_pro = 'valid' === $status;
384 + $is_expired = 'expired' === $status || 'active-expired' === $status;
385 +
386 + if ( $is_pro ) {
387 + // translators: %s is the discount percentage.
388 + $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - up to %s off', 'insert-php' ), '30%' );
389 + // translators: %1$s - discount, %2$s - discount.
390 + $message = sprintf( __( 'Upgrade your Woody Pro plan: %1$s off this week. Already on the plan you need? Renew early and save up to %2$s.', 'insert-php' ), '30%', '20%' );
391 + $cta_label = __( 'See your options', 'insert-php' );
392 + } elseif ( $is_expired ) {
393 + // translators: %s is the discount percentage.
394 + $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'insert-php' ), '50%' );
395 + $message = __( 'Your Woody Pro features are still here, just locked. Renew at a reduced rate this week.', 'insert-php' );
396 + $cta_label = __( 'Reactivate now', 'insert-php' );
397 + } else {
398 + // translators: %s - discount.
399 + $config['title'] = sprintf( __( 'Woody Pro: %s off this week', 'insert-php' ), '60%' );
400 + // translators: %s is the discount percentage.
401 + $config['plugin_meta_message'] = sprintf( __( 'Black Friday Sale - %s off', 'insert-php' ), '60%' );
402 + }
403 +
404 + $url_params = [
405 + 'utm_term' => $is_pro ? 'plan-' . $plan : 'free',
406 + 'lkey' => ! empty( $license ) ? $license : false,
407 + 'expired' => $is_expired ? '1' : false,
408 + ];
409 +
410 + if ( ( $is_pro || $is_expired ) && ! empty( $pro_product_slug ) ) {
411 + $config['plugin_meta_targets'] = [ $pro_product_slug ];
412 + }
413 +
414 + $config['cta_label'] = $cta_label;
415 + $config['message'] = $message;
416 +
417 + $config['sale_url'] = add_query_arg(
418 + $url_params,
419 + tsdk_translate_link( tsdk_utmify( 'https://themeisle.link/woody-bf', 'bfcm', 'woody' ) )
420 + );
421 +
422 + $configs[ WINP_PLUGIN_SLUG ] = $config;
423 +
424 + return $configs;
425 + }
426 + }
427 +}