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 | admin/includes/class.common.snippet.php +573 -217 2.4.4trunk View file →
@@ -1,35 +1,32 @@
1 1 <?php
2 2 /**
3 3 * Common functions for snippets
4 4 *
5 - * @author Webcraftic <wordpress.webraftic@gmail.com>
6 - * @copyright (c) 16.11.2018, Webcraftic
7 - * @version 1.0
5 + * @package Woody_Code_Snippets
8 6 */
9 7
10 -// Exit if accessed directly
8 +// Exit if accessed directly.
11 9 if ( ! defined( 'ABSPATH' ) ) {
12 10 exit;
13 11 }
14 12
13 +/**
14 + * Class for common snippet functions
15 + */
15 16 class WINP_Common_Snippet {
16 17
17 18 /**
18 - * WINP_Common_Snippet constructor.
19 - */
20 - public function __construct() {
21 - }
22 -
23 - /**
24 19 * Register hooks
20 + *
21 + * @return void
25 22 */
26 - public function registerHooks() {
27 - add_action( 'current_screen', [ $this, 'currentScreen' ] );
28 - add_action( 'edit_form_before_permalink', [ $this, 'editFormBeforePermalink' ] );
29 - add_action( 'admin_notices', [ $this, 'createUploadsDirectory' ] );
30 - add_action( 'before_delete_post', [ $this, 'beforeDeletePost' ] );
31 - add_action( 'save_post', [ $this, 'savePost' ] );
23 + public function register_hooks() {
24 + add_action( 'current_screen', [ $this, 'current_screen' ] );
25 + add_action( 'edit_form_before_permalink', [ $this, 'edit_form_before_permalink' ] );
26 + add_action( 'admin_notices', [ $this, 'create_uploads_directory' ] );
27 + add_action( 'before_delete_post', [ $this, 'before_delete_post' ] );
28 + add_action( 'save_post', [ $this, 'save_post' ] );
32 29 add_action( 'save_post_' . WINP_SNIPPETS_POST_TYPE, [ $this, 'save_snippet' ], 10, 3 );
33 30 add_action( 'auto-draft_to_publish', [ $this, 'publish_snippet' ] );
34 31
35 32 add_filter( 'script_loader_src', [ $this, 'unload_scripts' ], 10, 2 );
@@ -40,46 +37,70 @@
40 37 *
41 38 * Show a message if the directory is not writable
42 39 *
43 40 * Create an empty index.php file inside
41 + *
42 + * @return void
44 43 */
45 - public function createUploadsDirectory() {
44 + public function create_uploads_directory() {
46 45 $current_screen = get_current_screen();
47 46
48 - // Check if we are editing a custom-css-js post
49 - if ( $current_screen->base != 'post' || $current_screen->post_type != WINP_SNIPPETS_POST_TYPE ) {
50 - return false;
47 + // Check if we are editing a custom-css-js post.
48 + if ( 'post' !== $current_screen->base || WINP_SNIPPETS_POST_TYPE !== $current_screen->post_type ) {
49 + return;
51 50 }
52 51
53 52 $dir = WINP_UPLOAD_DIR;
54 53
55 - // Create the dir if it doesn't exist
54 + // Create the dir if it doesn't exist.
56 55 if ( ! file_exists( $dir ) ) {
57 56 wp_mkdir_p( $dir );
58 57 }
59 58
60 - // Show a message if it couldn't create the dir
59 + // Show a message if it couldn't create the dir.
61 60 if ( ! file_exists( $dir ) ) { ?>
62 - <div class="notice notice-error is-dismissible">
63 - <p><?php printf( __( 'The %s directory could not be created', 'insert-php' ), '<b>winp-css-js</b>' ); ?></p>
64 - <p><?php _e( 'Please run the following commands in order to make the directory', 'insert-php' ); ?>:
65 - <br/><strong>mkdir <?php echo $dir; ?>; </strong><br/><strong>chmod 777 <?php echo $dir; ?>
66 - ;</strong></p>
67 - </div>
68 - <?php return;
61 + <div class="notice notice-error is-dismissible">
62 + <?php
63 + /* translators: %s: Directory name */
64 + ?>
65 + <p>
66 + <?php
67 + printf(
68 + /* translators: %s: Directory path */
69 + esc_html__( 'The %s directory could not be created', 'insert-php' ),
70 + '<b>winp-css-js</b>'
71 + );
72 + ?>
73 + </p>
74 + <p><?php _e( 'Please run the following commands in order to make the directory', 'insert-php' ); ?>:
75 + <br/><strong>mkdir <?php echo $dir; ?>; </strong><br/><strong>chmod 777 <?php echo $dir; ?>
76 + ;</strong></p>
77 + </div>
78 + <?php
79 + return;
69 80 }
70 81
71 - // Show a message if the dir is not writable
72 - if ( ! wp_is_writable( $dir ) ) { ?>
73 - <div class="notice notice-error is-dismissible">
74 - <p><?php printf( __( 'The %s directory is not writable, therefore the CSS and JS files cannot be saved.', 'insert-php' ), '<b>' . $dir . '</b>' ); ?></p>
75 - <p><?php _e( 'Please run the following command to make the directory writable', 'insert-php' ); ?>:<br/><strong>chmod
76 - 777 <?php echo $dir; ?> </strong></p>
77 - </div>
78 - <?php return;
82 + // Show a message if the dir is not writable.
83 + if ( ! wp_is_writable( $dir ) ) {
84 + ?>
85 + <div class="notice notice-error is-dismissible">
86 + <p>
87 + <?php
88 + printf(
89 + /* translators: %s: Directory path */
90 + esc_html__( 'The %s directory is not writable, therefore the CSS and JS files cannot be saved.', 'insert-php' ),
91 + '<b>' . esc_html( $dir ) . '</b>'
92 + );
93 + ?>
94 + </p>
95 + <p><?php _e( 'Please run the following command to make the directory writable', 'insert-php' ); ?>:<br/><strong>chmod
96 + 777 <?php echo $dir; ?> </strong></p>
97 + </div>
98 + <?php
99 + return;
79 100 }
80 101
81 - // Write a blank index.php
102 + // Write a blank index.php.
82 103 if ( ! file_exists( $dir . '/index.php' ) ) {
83 104 $content = '<?php' . PHP_EOL . '// Silence is golden.';
84 105 @file_put_contents( $dir . '/index.php', $content );
85 106 }
@@ -86,121 +107,442 @@
86 107 }
87 108
88 109 /**
89 110 * Add quick buttons
111 + *
112 + * @return void
90 113 */
91 - public function currentScreenEdit() {
114 + public function current_screen_edit() {
92 115 $strings = [
93 - 'php' => __( 'Php snippet', 'insert-php' ),
94 - 'text' => __( 'Text snippet', 'insert-php' ),
95 - 'css' => __( 'Css snippet', 'insert-php' ),
96 - 'js' => __( 'Js snippet', 'insert-php' ),
97 - 'html' => __( 'Html snippet', 'insert-php' ),
98 - 'universal' => __( 'Universal snippet', 'insert-php' ),
99 - 'advert' => __( 'Advertisement snippet', 'insert-php' ),
116 + 'php' => __( 'PHP Snippet', 'insert-php' ),
117 + 'css' => __( 'CSS Snippet', 'insert-php' ),
118 + 'js' => __( 'JS Snippet', 'insert-php' ),
119 + 'text' => __( 'Text Snippet', 'insert-php' ),
120 + 'html' => __( 'HTML Snippet', 'insert-php' ),
121 + 'advert' => __( 'Advertisement', 'insert-php' ),
122 + 'universal' => __( 'Universal', 'insert-php' ),
100 123 ];
101 - $url = 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=';
102 - ?>
103 - <style>
104 - .wrap .winp-page-title-action {
105 - margin-left: 4px;
106 - padding: 4px 8px;
107 - position: relative;
108 - top: -3px;
109 - text-decoration: none;
110 - border: 1px solid #ccc;
111 - border-radius: 2px;
112 - background: #f7f7f7;
113 - text-shadow: none;
114 - font-weight: 600;
115 - font-size: 13px;
116 - line-height: normal;
117 - color: #0073aa;
118 - cursor: pointer;
119 - }
120 - </style>
121 - <script type="text/javascript">
122 - /* <![CDATA[ */
123 - jQuery(window).ready(function ($) {
124 - $('#wpbody-content a.page-title-action').hide();
125 - var h1 = '<?php _e( 'Woody snippets', 'insert-php' ); ?> ';
126 - h1 += ' <select class="winp-page-title-action">';
127 - h1 += '<option value="<?php echo $url; ?>php"><?php echo $strings['php']; ?></option>';
128 - h1 += '<option value="<?php echo $url; ?>text"><?php echo $strings['text']; ?></option>';
129 - h1 += '<option value="<?php echo $url; ?>css"><?php echo $strings['css']; ?></option>';
130 - h1 += '<option value="<?php echo $url; ?>js"><?php echo $strings['js']; ?></option>';
131 - h1 += '<option value="<?php echo $url; ?>html"><?php echo $strings['html']; ?></option>';
132 - h1 += '<option value="<?php echo $url; ?>universal"><?php echo $strings['universal']; ?></option>';
133 - h1 += '<option value="<?php echo $url; ?>advert"><?php echo $strings['advert']; ?></option>';
134 - h1 += '</select>';
135 - h1 += '<a href="#" id="winp-add-snippet-action" class="page-title-action"><?php _e( 'Add', 'insert-php' ); ?></a>';
136 - $('#wpbody-content h1').html(h1);
137 - $('#winp-add-snippet-action').click(function () {
138 - window.location.href = $('select.winp-page-title-action').val();
139 - });
140 - });
141 - </script>
142 - <?php
124 +
125 + $this->render_snippet_dropdown( $strings, __( 'New Snippet: PHP', 'insert-php' ) );
143 126 }
144 127
145 128 /**
146 129 * Add quick buttons
130 + *
131 + * @return void
147 132 */
148 - public function currentScreenPost() {
133 + public function current_screen_post() {
134 + global $post;
135 + $post_id = null;
136 +
137 + if ( ! empty( $post ) && is_object( $post ) && isset( $post->ID ) ) {
138 + $post_id = $post->ID;
139 + } else {
140 + $post_id = WINP_HTTP::get( 'post', null, 'absint' );
141 + }
142 +
143 + $type = WINP_Helper::get_snippet_type( $post_id );
144 +
149 145 $strings = [
150 - 'add' => [
151 - 'php' => __( 'Php snippet', 'insert-php' ),
152 - 'text' => __( 'Text snippet', 'insert-php' ),
153 - 'css' => __( 'Css snippet', 'insert-php' ),
154 - 'js' => __( 'Js snippet', 'insert-php' ),
155 - 'html' => __( 'Html snippet', 'insert-php' ),
156 - 'universal' => __( 'Universal snippet', 'insert-php' ),
157 - 'advert' => __( 'Advertisement snippet', 'insert-php' ),
158 - ],
159 - 'edit' => [
160 - 'php' => __( 'Edit php snippet', 'insert-php' ),
161 - 'text' => __( 'Edit text snippet', 'insert-php' ),
162 - 'css' => __( 'Edit css snippet', 'insert-php' ),
163 - 'js' => __( 'Edit js snippet', 'insert-php' ),
164 - 'html' => __( 'Edit html snippet', 'insert-php' ),
165 - 'universal' => __( 'Edit universal snippet', 'insert-php' ),
166 - 'advert' => __( 'Edit advertisement snippet', 'insert-php' ),
167 - ]
146 + 'php' => __( 'PHP Snippet', 'insert-php' ),
147 + 'css' => __( 'CSS Snippet', 'insert-php' ),
148 + 'js' => __( 'JS Snippet', 'insert-php' ),
149 + 'text' => __( 'Text Snippet', 'insert-php' ),
150 + 'html' => __( 'HTML Snippet', 'insert-php' ),
151 + 'advert' => __( 'Advertisement', 'insert-php' ),
152 + 'universal' => __( 'Universal', 'insert-php' ),
168 153 ];
169 154
170 - $post_id = WINP_Plugin::app()->request->get( 'post', null );
171 - if ( ! empty( $post_id ) ) {
172 - $action = 'edit';
173 - } else {
174 - $action = 'add';
155 + $label_map = [
156 + 'php' => __( 'New Snippet: PHP', 'insert-php' ),
157 + 'css' => __( 'New Snippet: CSS', 'insert-php' ),
158 + 'js' => __( 'New Snippet: JS', 'insert-php' ),
159 + 'text' => __( 'New Snippet: Text', 'insert-php' ),
160 + 'html' => __( 'New Snippet: HTML', 'insert-php' ),
161 + 'advert' => __( 'New Snippet: Advertisement', 'insert-php' ),
162 + 'universal' => __( 'New Snippet: Universal', 'insert-php' ),
163 + ];
164 +
165 + $button_label = isset( $label_map[ $type ] ) ? $label_map[ $type ] : __( 'New Snippet: PHP', 'insert-php' );
166 +
167 + $this->render_snippet_dropdown( $strings, $button_label, ! empty( $post_id ) );
168 + }
169 +
170 + /**
171 + * Render snippet type dropdown
172 + *
173 + * @param array<string, string> $strings Snippet type labels (type => label).
174 + * @param string $button_label Button label text.
175 + * @param bool $show_title Whether to show the edit title.
176 + *
177 + * @return void
178 + */
179 + private function render_snippet_dropdown( $strings, $button_label, $show_title = false ) {
180 + $type_display_labels = [
181 + 'php' => __( 'PHP', 'insert-php' ),
182 + 'css' => __( 'CSS', 'insert-php' ),
183 + 'js' => __( 'JS', 'insert-php' ),
184 + 'text' => __( 'Text', 'insert-php' ),
185 + 'html' => __( 'HTML', 'insert-php' ),
186 + 'advert' => __( 'Advertisement', 'insert-php' ),
187 + 'universal' => __( 'Universal', 'insert-php' ),
188 + ];
189 +
190 + // Get edit title if needed.
191 + $edit_title = '';
192 + if ( $show_title ) {
193 + global $post;
194 + $post_id = null;
195 +
196 + if ( ! empty( $post ) && is_object( $post ) && isset( $post->ID ) ) {
197 + $post_id = $post->ID;
198 + } else {
199 + $post_id = WINP_HTTP::get( 'post', null, 'absint' );
200 + }
201 +
202 + if ( ! empty( $post_id ) ) {
203 + $type = WINP_Helper::get_snippet_type( $post_id );
204 + $edit_labels = [
205 + 'php' => __( 'Edit PHP Snippet', 'insert-php' ),
206 + 'css' => __( 'Edit CSS Snippet', 'insert-php' ),
207 + 'js' => __( 'Edit JS Snippet', 'insert-php' ),
208 + 'text' => __( 'Edit Text Snippet', 'insert-php' ),
209 + 'html' => __( 'Edit HTML Snippet', 'insert-php' ),
210 + 'advert' => __( 'Edit Advertisement Snippet', 'insert-php' ),
211 + 'universal' => __( 'Edit Universal Snippet', 'insert-php' ),
212 + ];
213 + $edit_title = isset( $edit_labels[ $type ] ) ? $edit_labels[ $type ] : '';
214 + }
175 215 }
176 - $type = WINP_Helper::get_snippet_type( $post_id );
177 - $html = $strings[ $action ][ $type ];
216 + ?>
217 + <style>
218 + .winp-dropdown-button {
219 + position: relative;
220 + display: inline-flex;
221 + margin-left: 10px;
222 + }
223 + .winp-main-button {
224 + background: #6366f1;
225 + color: #fff;
226 + border: none;
227 + border-radius: 3px 0 0 3px;
228 + padding: 6px 12px;
229 + font-size: 13px;
230 + font-weight: 500;
231 + cursor: pointer;
232 + display: inline-flex;
233 + align-items: center;
234 + gap: 6px;
235 + box-shadow: 0 1px 2px rgba(0,0,0,0.05);
236 + text-decoration: none;
237 + }
238 + .winp-main-button:hover {
239 + background: #4f46e5;
240 + box-shadow: 0 2px 4px rgba(0,0,0,0.1);
241 + color: #fff;
242 + }
243 + .winp-main-button .dashicons {
244 + font-size: 16px;
245 + width: 16px;
246 + height: 16px;
247 + }
248 + .winp-dropdown-toggle {
249 + background: #6366f1;
250 + color: #fff;
251 + border: none;
252 + border-left: 1px solid rgba(255,255,255,0.2);
253 + border-radius: 0 3px 3px 0;
254 + padding: 6px 8px;
255 + font-size: 13px;
256 + font-weight: 500;
257 + cursor: pointer;
258 + display: inline-flex;
259 + align-items: center;
260 + box-shadow: 0 1px 2px rgba(0,0,0,0.05);
261 + }
262 + .winp-dropdown-toggle:hover {
263 + background: #4f46e5;
264 + box-shadow: 0 2px 4px rgba(0,0,0,0.1);
265 + }
266 + .winp-dropdown-toggle.active {
267 + background: #4f46e5 !important;
268 + border-color: rgba(255,255,255,0.2) !important;
269 + color: #fff !important;
270 + box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
271 + }
272 + .winp-dropdown-toggle .dashicons {
273 + font-size: 16px;
274 + width: 16px;
275 + height: 16px;
276 + transition: transform 0.3s ease;
277 + }
278 + .winp-dropdown-toggle.active .dashicons-arrow-down-alt2 {
279 + transform: rotate(180deg);
280 + }
281 + .winp-dropdown-menu {
282 + display: block;
283 + position: absolute;
284 + top: 100%;
285 + right: 0;
286 + margin-top: 4px;
287 + background: #fff;
288 + border: 1px solid #ddd;
289 + border-radius: 4px;
290 + box-shadow: 0 4px 12px rgba(0,0,0,0.15);
291 + min-width: 180px;
292 + z-index: 99999;
293 + opacity: 0;
294 + visibility: hidden;
295 + transform: translateY(-8px);
296 + transition: all 0.2s ease;
297 + overflow: hidden;
298 + }
299 + .winp-dropdown-menu.show {
300 + opacity: 1;
301 + visibility: visible;
302 + transform: translateY(0);
303 + }
304 + .winp-dropdown-item {
305 + display: flex;
306 + align-items: center;
307 + gap: 8px;
308 + padding: 6px 12px;
309 + cursor: pointer;
310 + text-decoration: none;
311 + color: #2c3338;
312 + border-bottom: 1px solid #f0f0f1;
313 + font-size: 13px;
314 + position: relative;
315 + }
316 + .winp-dropdown-item:first-child {
317 + border-top-left-radius: 4px;
318 + border-top-right-radius: 4px;
319 + }
320 + .winp-dropdown-item:last-child {
321 + border-bottom: none;
322 + border-bottom-left-radius: 4px;
323 + border-bottom-right-radius: 4px;
324 + }
325 + .winp-dropdown-item:hover,
326 + .winp-dropdown-item:focus {
327 + background: #eef2ff;
328 + color: #6366f1;
329 + outline: none;
330 + }
331 + .winp-snippet-icon {
332 + width: 26px;
333 + height: 26px;
334 + border-radius: 3px;
335 + display: flex;
336 + align-items: center;
337 + justify-content: center;
338 + font-size: 10px;
339 + font-weight: 700;
340 + color: #fff;
341 + flex-shrink: 0;
342 + box-shadow: 0 1px 2px rgba(0,0,0,0.1);
343 + }
344 + .winp-snippet-icon.php { background: linear-gradient(135deg, #8892BF 0%, #7380b0 100%); }
345 + .winp-snippet-icon.css { background: linear-gradient(135deg, #4A90E2 0%, #357abd 100%); }
346 + .winp-snippet-icon.js { background: linear-gradient(135deg, #F7C948 0%, #e6b938 100%); color: #333; }
347 + .winp-snippet-icon.text { background: linear-gradient(135deg, #7E8C8D 0%, #6d7a7b 100%); }
348 + .winp-snippet-icon.html { background: linear-gradient(135deg, #E74C3C 0%, #d63c2d 100%); }
349 + .winp-snippet-icon.advert { background: linear-gradient(135deg, #27AE60 0%, #229d56 100%); }
350 + .winp-snippet-icon.universal { background: linear-gradient(135deg, #9B59B6 0%, #8a4aa5 100%); }
351 +
352 + /* Keyboard navigation highlight */
353 + .winp-dropdown-item.keyboard-focus {
354 + background: #eef2ff;
355 + color: #6366f1;
356 + }
357 + </style>
358 + <script type="text/javascript">
359 + /* <![CDATA[ */
360 + jQuery(window).ready(function ($) {
361 + $('#wpbody-content a.page-title-action').hide();
362 +
363 + <?php if ( $show_title && ! empty( $edit_title ) ) : ?>
364 + // Update the h1 with edit title
365 + var currentH1 = $('#wpbody-content h1').text();
366 + $('#wpbody-content h1').text('<?php echo esc_js( $edit_title ); ?>');
367 + <?php endif; ?>
368 +
369 + // Determine the initial selected type from the button label
370 + var snippetTypes = {
371 + <?php
372 + $first = true;
373 + foreach ( $strings as $type => $label ) :
374 + if ( ! $first ) {
375 + echo ',';
376 + }
377 + echo "'" . esc_js( $type ) . "': '" . esc_js( $label ) . "'";
378 + $first = false;
379 + endforeach;
380 + ?>
381 + };
382 +
383 + var buttonLabel = '<?php echo esc_js( $button_label ); ?>';
384 + var selectedType = 'php'; // default
385 +
386 + // Try to determine the selected type from the button label
387 + for (var type in snippetTypes) {
388 + if (buttonLabel.indexOf(snippetTypes[type]) !== -1) {
389 + selectedType = type;
390 + break;
391 + }
392 + }
393 +
394 + // Base URL for creating new snippets
395 + var baseUrl = <?php echo wp_json_encode( admin_url( 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=' ) ); ?>;
178 396
179 - if ( 'edit' == $action ) {
180 - $url = 'post-new.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&winp_item=';
181 - $html .= ' <select class="winp-page-title-action">';
182 - $html .= '<option value="' . $url . 'php">' . $strings['add']['php'] . '</option>';
183 - $html .= '<option value="' . $url . 'text">' . $strings['add']['text'] . '</option>';
184 - $html .= '<option value="' . $url . 'css">' . $strings['add']['css'] . '</option>';
185 - $html .= '<option value="' . $url . 'js">' . $strings['add']['js'] . '</option>';
186 - $html .= '<option value="' . $url . 'html">' . $strings['add']['html'] . '</option>';
187 - $html .= '<option value="' . $url . 'universal">' . $strings['add']['universal'] . '</option>';
188 - $html .= '<option value="' . $url . 'advert">' . $strings['add']['advert'] . '</option>';
189 - $html .= '</select>';
190 - $html .= '<a href="#" id="winp-add-snippet-action" class="page-title-action">' . __( 'Add', 'insert-php' ) . '</a>';
191 - } ?>
192 - <script type="text/javascript">
193 - /* <![CDATA[ */
194 - jQuery(window).ready(function ($) {
195 - $('#wpbody-content a.page-title-action').hide();
196 - $('#wpbody-content h1').html('<?php echo $html; ?>');
197 - $('#winp-add-snippet-action').click(function () {
198 - window.location.href = $('select.winp-page-title-action').val();
199 - });
200 - });
201 - /* ]]> */
202 - </script>
397 + var dropdownHtml = '<div class="winp-dropdown-button">';
398 + dropdownHtml += '<a href="' + baseUrl + selectedType + '" class="winp-main-button" id="winp-main-action">';
399 + dropdownHtml += '<span class="dashicons dashicons-plus-alt2"></span>';
400 + dropdownHtml += '<span class="winp-button-text"><?php echo esc_js( $button_label ); ?></span>';
401 + dropdownHtml += '</a>';
402 + dropdownHtml += '<button class="winp-dropdown-toggle" type="button" aria-haspopup="true" aria-expanded="false">';
403 + dropdownHtml += '<span class="dashicons dashicons-arrow-down-alt2"></span>';
404 + dropdownHtml += '</button>';
405 + dropdownHtml += '<div class="winp-dropdown-menu" role="menu">';
406 + <?php foreach ( $strings as $type => $label ) : ?>
407 + dropdownHtml += '<a href="#" class="winp-dropdown-item" data-type="<?php echo esc_js( $type ); ?>" role="menuitem" tabindex="-1">';
408 + dropdownHtml += '<span class="winp-snippet-icon <?php echo esc_js( $type ); ?>"><?php echo esc_js( strtoupper( 'advert' === $type ? 'AD' : ( 'universal' === $type ? 'UNI' : $type ) ) ); ?></span>';
409 + dropdownHtml += '<span><?php echo esc_js( $label ); ?></span>';
410 + dropdownHtml += '</a>';
411 + <?php endforeach; ?>
412 + dropdownHtml += '</div>';
413 + dropdownHtml += '</div>';
414 +
415 + $('#wpbody-content h1').append(dropdownHtml);
416 +
417 + var $toggle = $('.winp-dropdown-toggle');
418 + var $mainButton = $('.winp-main-button');
419 + var $buttonText = $('.winp-button-text');
420 + var $menu = $('.winp-dropdown-menu');
421 + var $items = $('.winp-dropdown-item');
422 + var currentFocus = -1;
423 + var currentSelectedType = selectedType;
424 +
425 + // Type display labels from PHP
426 + var typeLabels = {
427 + <?php
428 + $first = true;
429 + foreach ( $type_display_labels as $type => $display_label ) :
430 + if ( ! $first ) {
431 + echo ',';
432 + }
433 + echo "'" . esc_js( $type ) . "': '" . esc_js( $display_label ) . "'";
434 + $first = false;
435 + endforeach;
436 + ?>
437 + };
438 +
439 + // Handle dropdown item click
440 + $items.on('click', function(e) {
441 + e.preventDefault();
442 + e.stopPropagation();
443 +
444 + var type = $(this).data('type');
445 + currentSelectedType = type;
446 +
447 + // Update button text and href
448 + if (typeLabels[type]) {
449 + var newLabel = 'New Snippet: ' + typeLabels[type];
450 + $buttonText.text(newLabel);
451 + $mainButton.attr('href', baseUrl + type);
452 + }
453 +
454 + closeDropdown();
455 + });
456 +
457 + // Toggle dropdown
458 + $toggle.on('click', function(e) {
459 + e.stopPropagation();
460 + var isOpen = $menu.hasClass('show');
461 +
462 + if (isOpen) {
463 + closeDropdown();
464 + } else {
465 + openDropdown();
466 + }
467 + });
468 +
469 + function openDropdown() {
470 + $menu.addClass('show');
471 + $toggle.addClass('active').attr('aria-expanded', 'true');
472 + $items.first().focus();
473 + currentFocus = 0;
474 + }
475 +
476 + function closeDropdown() {
477 + $menu.removeClass('show');
478 + $toggle.removeClass('active').attr('aria-expanded', 'false');
479 + $items.removeClass('keyboard-focus');
480 + currentFocus = -1;
481 + }
482 +
483 + // Close on outside click
484 + $(document).on('click', function(e) {
485 + if (!$(e.target).closest('.winp-dropdown-button').length) {
486 + closeDropdown();
487 + }
488 + });
489 +
490 + // Keyboard navigation
491 + $(document).on('keydown', function(e) {
492 + if (!$menu.hasClass('show')) {
493 + return;
494 + }
495 +
496 + // ESC key
497 + if (e.keyCode === 27) {
498 + e.preventDefault();
499 + closeDropdown();
500 + $toggle.focus();
501 + }
502 +
503 + // Arrow Down
504 + if (e.keyCode === 40) {
505 + e.preventDefault();
506 + currentFocus++;
507 + if (currentFocus >= $items.length) {
508 + currentFocus = 0;
509 + }
510 + setFocus();
511 + }
512 +
513 + // Arrow Up
514 + if (e.keyCode === 38) {
515 + e.preventDefault();
516 + currentFocus--;
517 + if (currentFocus < 0) {
518 + currentFocus = $items.length - 1;
519 + }
520 + setFocus();
521 + }
522 +
523 + // Enter or Space
524 + if (e.keyCode === 13 || e.keyCode === 32) {
525 + if (currentFocus > -1) {
526 + e.preventDefault();
527 + $items.eq(currentFocus).trigger('click');
528 + }
529 + }
530 + });
531 +
532 + function setFocus() {
533 + $items.removeClass('keyboard-focus');
534 + $items.eq(currentFocus).addClass('keyboard-focus').focus();
535 + }
536 +
537 + // Hover updates focus
538 + $items.on('mouseenter', function() {
539 + currentFocus = $items.index(this);
540 + $items.removeClass('keyboard-focus');
541 + });
542 + });
543 + /* ]]> */
544 + </script>
203 545 <?php
204 546 }
205 547
206 548 /**
@@ -205,24 +547,23 @@
205 547
206 548 /**
207 549 * Add quick buttons
208 550 *
209 - * @param $current_screen
551 + * @param \WP_Screen $current_screen WordPress screen object.
552 + *
553 + * @return void
210 554 */
211 - public function currentScreen( $current_screen ) {
555 + public function current_screen( $current_screen ) {
212 556 if ( WINP_SNIPPETS_POST_TYPE !== $current_screen->post_type ) {
213 557 return;
214 558 }
215 559
216 - // Код виджета поддержки пока что нужно скрыть
217 - // add_action( 'admin_footer', array( $this, 'admin_footer' ) );
218 -
219 - if ( $current_screen->base == 'post' ) {
220 - add_action( 'admin_head', [ $this, 'currentScreenPost' ] );
560 + if ( 'post' === $current_screen->base ) {
561 + add_action( 'admin_head', [ $this, 'current_screen_post' ] );
221 562 }
222 563
223 - if ( $current_screen->base == 'edit' ) {
224 - add_action( 'admin_head', [ $this, 'currentScreenEdit' ] );
564 + if ( 'edit' === $current_screen->base ) {
565 + add_action( 'admin_head', [ $this, 'current_screen_edit' ] );
225 566 }
226 567 }
227 568
228 569 /**
@@ -227,14 +568,16 @@
227 568
228 569 /**
229 570 * Show the Permalink edit form
230 571 *
231 - * @param string $filename
232 - * @param string $permalink
233 - * @param string $filetype
572 + * @param string|\WP_Post $filename Filename or post object.
573 + * @param string $permalink Permalink URL.
574 + * @param string $filetype File type.
575 + *
576 + * @return void
234 577 */
235 - public function editFormBeforePermalink( $filename = '', $permalink = '', $filetype = 'css' ) {
236 - $filetype = WINP_Plugin::app()->request->get( 'winp_item', $filetype, true );
578 + public function edit_form_before_permalink( $filename = '', $permalink = '', $filetype = 'css' ) {
579 + $filetype = WINP_HTTP::get( 'winp_item', $filetype, true );
237 580
238 581 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
239 582 return;
240 583 }
@@ -270,22 +613,23 @@
270 613 }
271 614
272 615 if ( empty( $permalink ) ) {
273 616 $permalink = WINP_UPLOAD_URL . '/' . $filename . '.' . $filetype;
274 - } ?>
275 - <div class="inside">
276 - <div id="edit-slug-box" class="hide-if-no-js">
277 - <strong><?php _e( 'Permalink', 'insert-php' ) ?>:</strong>
278 - <span id="sample-permalink"><a
279 - href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( WINP_UPLOAD_URL ) . '/'; ?><span
280 - id="editable-post-name"><?php echo esc_html( $filename ); ?></span>.<?php echo esc_html( $filetype ); ?></a></span>
281 - <span id="winp-edit-slug-buttons"><button type="button"
282 - class="winp-edit-slug button button-small hide-if-no-js"
283 - aria-label="<?php _e( 'Edit permalink', 'insert-php' ) ?>"><?php _e( 'Edit', 'insert-php' ) ?></button></span>
284 - <span id="editable-post-name-full"><?php echo esc_html( $filename ); ?></span>
285 - </div>
617 + }
618 + ?>
619 + <div class="inside">
620 + <div id="edit-slug-box" class="hide-if-no-js">
621 + <strong><?php _e( 'Permalink', 'insert-php' ); ?>:</strong>
622 + <span id="sample-permalink"><a
623 + href="<?php echo esc_url( $permalink ); ?>"><?php echo esc_html( WINP_UPLOAD_URL ) . '/'; ?><span
624 + id="editable-post-name"><?php echo esc_html( $filename ); ?></span>.<?php echo esc_html( $filetype ); ?></a></span>
625 + <span id="winp-edit-slug-buttons"><button type="button"
626 + class="winp-edit-slug button button-small hide-if-no-js"
627 + aria-label="<?php _e( 'Edit URL Slug', 'insert-php' ); ?>"><?php _e( 'Edit', 'insert-php' ); ?></button></span>
628 + <span id="editable-post-name-full"><?php echo esc_html( $filename ); ?></span>
629 + </div>
286 630 <?php wp_nonce_field( 'winp-permalink', 'winp-permalink-nonce' ); ?>
287 - </div>
631 + </div>
288 632 <?php
289 633 }
290 634
291 635 /**
@@ -290,11 +634,13 @@
290 634
291 635 /**
292 636 * Remove the JS/CSS file from the disk when deleting the post
293 637 *
294 - * @param $postid
638 + * @param int $postid Post ID.
639 + *
640 + * @return void
295 641 */
296 - public function beforeDeletePost( $postid ) {
642 + public function before_delete_post( $postid ) {
297 643 global $post;
298 644
299 645 if ( ! is_object( $post ) ) {
300 646 return;
@@ -325,12 +671,14 @@
325 671
326 672 /**
327 673 * Save post
328 674 *
329 - * @param $post_id
675 + * @param int $post_id Post ID.
676 + *
677 + * @return void
330 678 */
331 - public function savePost( $post_id ) {
332 - $nonce = WINP_Plugin::app()->request->post( 'winp-permalink-nonce' );
679 + public function save_post( $post_id ) {
680 + $nonce = WINP_HTTP::post( 'winp-permalink-nonce' );
333 681
334 682 if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'winp-permalink' ) ) {
335 683 return;
336 684 }
@@ -338,9 +686,9 @@
338 686 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
339 687 return;
340 688 }
341 689
342 - if ( WINP_SNIPPETS_POST_TYPE != WINP_Plugin::app()->request->post( 'post_type' ) ) {
690 + if ( WINP_SNIPPETS_POST_TYPE != WINP_HTTP::post( 'post_type' ) ) {
343 691 return;
344 692 }
345 693
346 694 $default_filetype = WINP_Helper::get_snippet_type( $post_id );
@@ -349,16 +697,16 @@
349 697 if ( ! in_array( $filetype, [ 'css', 'js' ] ) ) {
350 698 return;
351 699 }
352 700
353 - $plugin_title = WINP_Plugin::app()->getPluginTitle();
701 + $plugin_title = __( 'Woody Code Snippets', 'insert-php' );
354 702 $before = $after = '';
355 703
356 - $snippet_linking = WINP_Plugin::app()->request->post( WINP_Plugin::app()->getPrefix() . 'snippet_linking' );
704 + $snippet_linking = WINP_HTTP::post( 'wbcr_inp_snippet_linking' );
357 705 $linking = ! empty( $snippet_linking ) ? $snippet_linking : 'external';
358 706 $content = get_post( $post_id )->post_content;
359 707
360 - // Save the Custom Code in a file in `wp-content/uploads/winp-css-js`
708 + // Save the Custom Code in a file in `wp-content/uploads/winp-css-js`.
361 709 if ( 'inline' == $linking ) {
362 710 $before = '<!-- start ' . $plugin_title . ' CSS and JS -->' . PHP_EOL;
363 711 $after = '<!-- end ' . $plugin_title . ' CSS and JS -->' . PHP_EOL;
364 712
@@ -363,17 +711,17 @@
363 711 $after = '<!-- end ' . $plugin_title . ' CSS and JS -->' . PHP_EOL;
364 712
365 713 if ( 'css' == $filetype ) {
366 714 $before .= '<style type="text/css">' . PHP_EOL;
367 - $after = '</style>' . PHP_EOL . $after;
715 + $after = '</style>' . PHP_EOL . $after;
368 716 }
369 717
370 718 if ( 'js' == $filetype ) {
371 719 if ( ! preg_match( '/<script\b[^>]*>([\s\S]*?)<\/script>/im', $content ) ) {
372 720 $before .= '<script type="text/javascript">' . PHP_EOL;
373 - $after = PHP_EOL . '</script>' . PHP_EOL . $after;
721 + $after = PHP_EOL . '</script>' . PHP_EOL . $after;
374 722 } else {
375 - // the content has a <script> tag, then remove the comments so they don't show up on the frontend
723 + // the content has a <script> tag, then remove the comments so they don't show up on the frontend.
376 724 $content = preg_replace( '@/\*[\s\S]*?\*/@', '', $content );
377 725 }
378 726 }
379 727 }
@@ -380,9 +728,9 @@
380 728
381 729 if ( 'external' == $linking ) {
382 730 $before = '/******* Do not edit this file *******' . PHP_EOL . $plugin_title . ' CSS and JS' . PHP_EOL . 'Saved: ' . date( 'M d Y | H:i:s' ) . ' */' . PHP_EOL;
383 731
384 - // Save version for js and css file
732 + // Save version for js and css file.
385 733 WINP_Helper::updateMetaOption( $post_id, 'css_js_version', time() );
386 734 }
387 735
388 736 if ( wp_is_writable( WINP_UPLOAD_DIR ) ) {
@@ -387,9 +735,9 @@
387 735
388 736 if ( wp_is_writable( WINP_UPLOAD_DIR ) ) {
389 737 $file_content = $before . $content . $after;
390 738
391 - // save the file as the Permalink slug
739 + // save the file as the Permalink slug.
392 740 $slug = WINP_Helper::getMetaOption( $post_id, 'css_js_slug' );
393 741 if ( $slug ) {
394 742 $file_name = $slug . '.' . $filetype;
395 743 $file_slug = $slug;
@@ -397,15 +745,15 @@
397 745 $file_name = $post_id . '.' . $filetype;
398 746 $file_slug = $post_id;
399 747 }
400 748
401 - // Delete old file
749 + // Delete old file.
402 750 $old_slug = WINP_Helper::getMetaOption( $post_id, 'css_js_exist_slug' );
403 751 if ( $old_slug ) {
404 752 @unlink( WINP_UPLOAD_DIR . '/' . $old_slug . '.' . $filetype );
405 753 }
406 754
407 - // Save exist file slug
755 + // Save exist file slug.
408 756 WINP_Helper::updateMetaOption( $post_id, 'css_js_exist_slug', $file_slug );
409 757
410 758 @file_put_contents( WINP_UPLOAD_DIR . '/' . $file_name, $file_content );
411 759 }
@@ -414,19 +762,21 @@
414 762 /**
415 763 * Action for pre saved snippet.
416 764 * Если это не обновление поста, если это "черновик", и есть параметр с id сниппета, то заполняем данные сниппета для просмотра
417 765 *
418 - * @param $post_ID
419 - * @param $current_post
420 - * @param $update
766 + * @param int $post_ID Post ID.
767 + * @param \WP_Post $current_post Current post object.
768 + * @param bool $update Whether this is an existing post being updated.
769 + *
770 + * @return void
421 771 */
422 772 public function save_snippet( $post_ID, $current_post, $update ) {
423 - $snippet_id = WINP_Plugin::app()->request->get( 'snippet_id' );
424 - $common = WINP_Plugin::app()->request->get( 'common', false );
773 + $snippet_id = WINP_HTTP::get( 'snippet_id' );
774 + $common = WINP_HTTP::get( 'common', false );
425 775
426 776 if ( ! $update && 'auto-draft' == $current_post->post_status && ! empty( $snippet_id ) && WINP_SNIPPETS_POST_TYPE == $current_post->post_type ) {
427 777 $snippet = [];
428 - $saved_snippets = get_user_meta( get_current_user_id(), WINP_Plugin::app()->getPrefix() . 'current_snippets', true );
778 + $saved_snippets = get_user_meta( get_current_user_id(), 'wbcr_inp_current_snippets', true );
429 779
430 780 if ( ! empty( $saved_snippets ) && isset( $saved_snippets[ $snippet_id ] ) ) {
431 781 $snippet = $saved_snippets[ $snippet_id ];
432 782 }
@@ -459,11 +809,14 @@
459 809 WINP_Helper::updateMetaOption( $post_ID, 'snippet_api_type', $snippet['type_id'] );
460 810 WINP_Helper::updateMetaOption( $post_ID, 'snippet_description', $snippet['desc'] );
461 811 WINP_Helper::updateMetaOption( $post_ID, 'snippet_draft', true );
462 812 WINP_Helper::updateMetaOption( $post_ID, 'snippet_scope', $snippet['scope'] );
463 - WINP_Helper::updateMetaOption( $post_ID, 'snippet_priority', $snippet['priority'] );
464 813
465 - wp_redirect( admin_url( 'post.php?post=' . $post_ID . '&action=edit' ) );
814 + if ( isset( $snippet['priority'] ) ) {
815 + WINP_Helper::updateMetaOption( $post_ID, 'snippet_priority', $snippet['priority'] );
816 + }
817 +
818 + wp_safe_redirect( admin_url( 'post.php?post=' . $post_ID . '&action=edit' ) );
466 819 }
467 820 }
468 821 }
469 822
@@ -469,57 +822,61 @@
469 822
470 823 /**
471 824 * Delete auto-draft status after post snippet is publishing
472 825 *
473 - * @param $post
826 + * @param \WP_Post $post Post object.
827 + *
828 + * @return void
474 829 */
475 830 public function publish_snippet( $post ) {
476 831 if ( WINP_SNIPPETS_POST_TYPE == $post->post_type ) {
477 - delete_post_meta( $post->ID, WINP_Plugin::app()->getPrefix() . 'snippet_draft' );
832 + delete_post_meta( $post->ID, 'wbcr_inp_snippet_draft' );
478 833 }
479 834 }
480 835
481 836 /**
482 837 * Action admin_footer
838 + *
839 + * @return void
483 840 */
484 841 public function admin_footer() {
485 842 ?>
486 - <script type="text/javascript">!function (e, t, n) {
487 - function a() {
488 - var e = t.getElementsByTagName("script")[0], n = t.createElement("script");
489 - n.type = "text/javascript", n.async = !0, n.src = "https://beacon-v2.helpscout.net", e.parentNode.insertBefore(n, e)
490 - }
843 + <script type="text/javascript">!function (e, t, n) {
844 + function a() {
845 + var e = t.getElementsByTagName("script")[0], n = t.createElement("script");
846 + n.type = "text/javascript", n.async = !0, n.src = "https://beacon-v2.helpscout.net", e.parentNode.insertBefore(n, e)
847 + }
491 848
492 - if (e.Beacon = n = function (t, n, a) {
493 - e.Beacon.readyQueue.push({
494 - method: t,
495 - options: n,
496 - data: a
497 - })
498 - }, n.readyQueue = [], "complete" === t.readyState) {
499 - return a();
500 - }
501 - e.attachEvent ? e.attachEvent("onload", a) : e.addEventListener("load", a, !1)
502 - }(window, document, window.Beacon || function () {
503 - });</script>
504 - <script type="text/javascript">window.Beacon('init', '1a4078fd-3e77-4692-bcfa-47bb4da0cee5')</script>
849 + if (e.Beacon = n = function (t, n, a) {
850 + e.Beacon.readyQueue.push({
851 + method: t,
852 + options: n,
853 + data: a
854 + })
855 + }, n.readyQueue = [], "complete" === t.readyState) {
856 + return a();
857 + }
858 + e.attachEvent ? e.attachEvent("onload", a) : e.addEventListener("load", a, !1)
859 + }(window, document, window.Beacon || function () {
860 + });</script>
861 + <script type="text/javascript">window.Beacon('init', '1a4078fd-3e77-4692-bcfa-47bb4da0cee5')</script>
505 862 <?php
506 863 }
507 864
508 865 /**
509 - * Unload specific scrips
866 + * Unload specific scripts
510 867 *
511 - * @param string $src
512 - * @param string $handle
868 + * @param string $src Script source URL.
869 + * @param string $handle Script handle.
513 870 *
514 - * @return bool|string
871 + * @return bool|string False to prevent loading, otherwise the script source URL.
515 872 */
516 873 public function unload_scripts( $src, $handle ) {
517 874 global $post;
518 875
519 - // Check if we are editing a snippet post
876 + // Check if we are editing a snippet post.
520 877 if ( is_admin() && ! empty( $post ) && $post->post_type == WINP_SNIPPETS_POST_TYPE ) {
521 - // Unload ckeditor.js from theme The Rex
878 + // Unload ckeditor.js from theme The Rex.
522 879 if ( 'bk-ckeditor-js' == $handle ) {
523 880 return false;
524 881 }
525 882 }
@@ -525,6 +882,5 @@
525 882 }
526 883
527 884 return $src;
528 885 }
529 -
530 -}
886 +}