PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.7.7
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.7.7
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
insert-php / admin / includes / class.actions.snippet.php

class.actions.snippet.php in Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts 2.7.7, at admin/includes/class.actions.snippet.php

622 lines 16.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Export/clone snippet
4
5 * @package Woody_Code_Snippets
6 */
7
8 // Exit if accessed directly.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class WINP_Actions_Snippet
15 */
16 class WINP_Actions_Snippet {
17
18 /**
19 * WINP_Actions_Snippet constructor.
20 */
21 public function __construct() {
22 $this->register_hooks();
23 }
24
25 /**
26 * Register hooks
27 *
28 * @return void
29 */
30 public function register_hooks() {
31 add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 );
32 add_filter( 'bulk_actions-edit-' . WINP_SNIPPETS_POST_TYPE, [ $this, 'action_bulk_edit_post' ] );
33 add_filter(
34 'handle_bulk_actions-edit-' . WINP_SNIPPETS_POST_TYPE,
35 [
36 $this,
37 'handle_action_bulk_edit_post',
38 ],
39 10,
40 3
41 );
42
43 add_action( 'post_submitbox_start', [ $this, 'post_submitbox_start' ] );
44 add_action( 'admin_init', [ $this, 'admin_init' ] );
45 add_action( 'current_screen', [ $this, 'current_screen' ] );
46 add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
47 }
48
49 /**
50 * Get export url
51 *
52 * @param int $post_id Post ID.
53 *
54 * @return string
55 */
56 private function get_export_url( $post_id ) {
57 $url = admin_url( 'post.php?post=' . $post_id );
58
59 return add_query_arg(
60 [
61 'action' => 'export',
62 '_wpnonce' => wp_create_nonce( 'WINP_Actions_Snippet_' . $post_id ),
63 ],
64 $url
65 );
66 }
67
68 /**
69 * Get close url
70 *
71 * @param int $post_id Post ID.
72 *
73 * @return string
74 */
75 private function get_close_url( $post_id ) {
76 $url = admin_url( 'post.php?post=' . $post_id );
77
78 return add_query_arg(
79 [
80 'action' => 'close',
81 '_wpnonce' => wp_create_nonce( 'winp_close_snippet_' . $post_id ),
82 ],
83 $url
84 );
85 }
86
87 /**
88 * Get clone url
89 *
90 * @param int $post_id Post ID.
91 *
92 * @return string
93 */
94 private function get_clone_url( $post_id ) {
95 $url = admin_url( 'post.php?post=' . $post_id );
96
97 return add_query_arg(
98 [
99 'action' => 'clone',
100 '_wpnonce' => wp_create_nonce( 'winp_clone_snippet_' . $post_id ),
101 ],
102 $url
103 );
104 }
105
106 /**
107 * Post row actions
108 *
109 * @param array<string, string> $actions Array of row actions.
110 * @param WP_Post $post WP_Post object.
111 *
112 * @return mixed
113 */
114 public function post_row_actions( $actions, $post ) {
115 if ( WINP_SNIPPETS_POST_TYPE === $post->post_type ) {
116 $export_link = $this->get_export_url( $post->ID );
117 $clone_link = $this->get_clone_url( $post->ID );
118
119 if ( isset( $actions['trash'] ) ) {
120 $trash = $actions['trash'];
121 unset( $actions['trash'] );
122 }
123
124 $actions['export'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $export_link ), esc_html( __( 'Export', 'insert-php' ) ) );
125 $actions['clone'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $clone_link ), esc_html( __( 'Clone', 'insert-php' ) ) );
126
127 if ( isset( $trash ) ) {
128 $actions['trash'] = $trash;
129 }
130 }
131
132 return $actions;
133 }
134
135 /**
136 * Action bulk_edit_post
137 *
138 * @param array<string, string> $bulk_actions Array of bulk actions.
139 *
140 * @return mixed
141 */
142 public function action_bulk_edit_post( $bulk_actions ) {
143 $bulk_actions['activate'] = __( 'Activate', 'insert-php' );
144 $bulk_actions['deactivate'] = __( 'Deactivate', 'insert-php' );
145 $bulk_actions['exportsnp'] = __( 'Export', 'insert-php' );
146
147 // Don't show delete action for posts already in trash.
148 $current_screen = get_current_screen();
149 if ( ! $current_screen || ( isset( $_GET['post_status'] ) && 'trash' !== $_GET['post_status'] ) || ( ! isset( $_GET['post_status'] ) ) ) {
150 $bulk_actions['deletesnp'] = __( 'Delete', 'insert-php' );
151 $bulk_actions['clonenp'] = __( 'Clone', 'insert-php' );
152 }
153
154 return $bulk_actions;
155 }
156
157 /**
158 * Handle action bulk edit post
159 *
160 * @param string $redirect_to URL to redirect to.
161 * @param string $doaction Do action.
162 * @param array<int> $post_ids Array of post IDs.
163 *
164 * @return mixed
165 */
166 public function handle_action_bulk_edit_post( $redirect_to, $doaction, $post_ids ) {
167 if ( ! WINP_Plugin::app()->current_user_car() ) {
168 return false;
169 }
170
171 check_admin_referer( 'bulk-posts' );
172
173 $actions = [
174 'exportsnp' => 1,
175 'deletesnp' => 1,
176 'deactivate' => 1,
177 'activate' => 1,
178 'clonenp' => 1,
179 ];
180
181 if ( ! isset( $actions[ $doaction ] ) ) {
182 return $redirect_to;
183 }
184
185 if ( count( $post_ids ) ) {
186 switch ( $doaction ) {
187 case 'exportsnp':
188 $this->quick_export_snippets( $post_ids );
189 break;
190
191 case 'clonenp':
192 $this->clone_snippets( $post_ids );
193 break;
194
195 case 'deletesnp':
196 $this->delete_snippets( $post_ids );
197 break;
198
199 case 'deactivate':
200 $this->deactivate_snippets( $post_ids );
201 break;
202
203 case 'activate':
204 $this->activate_snippets( $post_ids );
205 break;
206 }
207 }
208
209 return $redirect_to;
210 }
211
212 /**
213 * Post submitbox start
214 *
215 * @return void
216 */
217 public function post_submitbox_start() {
218 global $post;
219
220 if ( $post && WINP_SNIPPETS_POST_TYPE == $post->post_type ) {
221 if ( WINP_Helper::getMetaOption( $post->ID, 'snippet_draft', false ) ) {
222 $close_link = $this->get_close_url( $post->ID );
223 echo "<div id='winp-close-action'>" . sprintf( '<a href="%1$s" class="button button-large">%2$s</a>', esc_url( $close_link ), esc_html( __( 'Close', 'insert-php' ) ) ) . '</div>';
224 } else {
225 $export_link = $this->get_export_url( $post->ID );
226 echo "<div id='winp-export-action'>" . sprintf( '<a href="%1$s">%2$s</a>', esc_url( $export_link ), esc_html( __( 'Export', 'insert-php' ) ) ) . '</div>';
227 }
228 }
229 }
230
231 /**
232 * Prepare data
233 *
234 * @param array<int> $ids Snippet IDs.
235 *
236 * @return array<mixed>
237 */
238 private function prepare_data( $ids ) {
239 $snippets = [];
240
241 if ( count( $ids ) ) {
242 foreach ( $ids as $id ) {
243 $post = get_post( $id );
244
245 if ( ! $post ) {
246 continue;
247 }
248
249 $snippet = [
250 'name' => $post->post_name,
251 'title' => $post->post_title,
252 'content' => $post->post_content,
253 'location' => $this->get_meta( $id, 'snippet_location' ),
254 'type' => $this->get_meta( $id, 'snippet_type' ),
255 'filters' => $this->get_meta( $id, 'snippet_filters' ),
256 'changed_filters' => $this->get_meta( $id, 'changed_filters' ),
257 'scope' => $this->get_meta( $id, 'snippet_scope' ),
258 'priority' => $this->get_meta( $id, 'snippet_priority' ),
259 'description' => $this->get_meta( $id, 'snippet_description' ),
260 'attributes' => $this->get_meta( $id, 'snippet_tags' ),
261 'tags' => $this->get_taxonomy_tags( $id ),
262 ];
263
264 $snippets[] = apply_filters( 'wbcr/inp/snippet/prepare_data', $snippet, $id, $this );
265 }
266 }
267
268 return $snippets;
269 }
270
271 /**
272 * Get file name
273 *
274 * @param string $format File format.
275 * @param array<int> $ids Snippet IDs.
276 * @param array<mixed> $snippets Snippets data.
277 *
278 * @return string
279 */
280 public function get_filename( $format, $ids, $snippets ) {
281 $snippets = empty( $snippets ) ? $this->prepare_data( $ids ) : $snippets;
282
283 /* Build the export filename */
284 if ( 1 == count( $ids ) ) {
285 $name = $snippets[0]['title'];
286 $title = strtolower( $name );
287 } else {
288 /* Otherwise, use the site name as set in Settings > General */
289 $title = strtolower( get_bloginfo( 'name' ) );
290 }
291
292 $filename = "{$title}.php-code-snippets.{$format}";
293
294 return $filename;
295 }
296
297 /**
298 * Export snippets - prepare and return export data
299 *
300 * @param array<int> $ids Snippet IDs to export.
301 * @param bool $zip Whether to create a zip file.
302 * @return array<mixed> Export data with filename, data, and count.
303 */
304 public function export_snippets( $ids, $zip = false ) {
305 $snippets = $this->prepare_data( $ids );
306 $filename = $this->get_filename( 'json', $ids, $snippets );
307
308 $data = [
309 'generator' => 'PHP Code Snippets v' . WINP_PLUGIN_VERSION,
310 'date_created' => gmdate( 'Y-m-d H:i' ),
311 'snippets' => $snippets,
312 ];
313
314 if ( $zip ) {
315 $zipname = str_replace( '.json', '.zip', $filename );
316 $upload_dir = wp_upload_dir();
317 $zippath = $upload_dir['path'] . '/' . $zipname;
318
319 $zip_archive = new ZipArchive();
320 if ( true === $zip_archive->open( $zippath, ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) {
321 // Add individual JSON file for each snippet.
322 foreach ( $snippets as $snippet ) {
323 $snippet_data = [
324 'generator' => 'PHP Code Snippets v' . WINP_PLUGIN_VERSION,
325 'date_created' => gmdate( 'Y-m-d H:i' ),
326 'snippets' => [ $snippet ],
327 ];
328 $json_content = wp_json_encode( $snippet_data, JSON_PRETTY_PRINT );
329
330 if ( false === $json_content ) {
331 continue;
332 }
333
334 $snippet_filename = sanitize_file_name( strtolower( $snippet['title'] ) ) . '.php-code-snippets.json';
335 $zip_archive->addFromString( $snippet_filename, $json_content );
336 }
337
338 $zip_archive->close();
339
340 $wp_filesystem = WINP_Helper::get_wp_filesystem();
341
342 if ( false !== $wp_filesystem ) {
343 $zip_content = $wp_filesystem->get_contents( $zippath );
344 $wp_filesystem->delete( $zippath, false, 'f' );
345
346 if ( false !== $zip_content && '' !== $zip_content ) {
347 return [
348 'filename' => $zipname,
349 'data' => $zip_content,
350 'count' => count( $snippets ),
351 'is_zip' => true,
352 ];
353 }
354 }
355
356 wp_delete_file( $zippath );
357 }
358 }
359
360 return [
361 'filename' => $filename,
362 'data' => $data,
363 'count' => count( $snippets ),
364 'is_zip' => false,
365 ];
366 }
367
368 /**
369 * Export snippets in JSON format
370 *
371 * @param array<int> $ids Snippet IDs.
372 *
373 * @return void
374 */
375 public function quick_export_snippets( $ids ) {
376 $snippets = $this->export_snippets( $ids, count( $ids ) > 1 );
377
378 $filename = $snippets['filename'];
379 $data = $snippets['data'];
380 $is_zip = $snippets['is_zip'];
381 $mime_type = $is_zip ? 'application/zip' : 'application/json';
382
383 /* Set HTTP headers */
384 header( 'Content-Disposition: attachment; filename=' . sanitize_file_name( $filename ) );
385 header( "Content-Type: $mime_type; charset=" . get_bloginfo( 'charset' ) );
386
387 // For zip files, output raw binary data. For JSON, encode the data.
388 if ( $is_zip ) {
389 $output = is_string( $data ) ? $data : (string) $data;
390 $wp_filesystem = WINP_Helper::get_wp_filesystem();
391
392 if ( false !== $wp_filesystem ) {
393 $wp_filesystem->put_contents( 'php://output', $output, false );
394 }
395 exit;
396 } else {
397 echo wp_json_encode( $data, JSON_PRETTY_PRINT );
398 }
399 exit;
400 }
401
402 /**
403 * Clone snippets
404 *
405 * @param array<int> $ids Snippet IDs.
406 *
407 * @return void
408 */
409 public function clone_snippets( $ids ) {
410 $snippets = $this->prepare_data( $ids );
411
412 if ( $snippets ) {
413 foreach ( $snippets as $snippet ) {
414 $data = [
415 'post_title' => $snippet['title'] . ' copy',
416 'post_content' => $snippet['content'],
417 'post_status' => 'draft',
418 'post_type' => WINP_SNIPPETS_POST_TYPE,
419 ];
420
421 $snippet['id'] = wp_insert_post( $data );
422
423 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_location', $snippet['location'] );
424 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_type', $snippet['type'] );
425 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_filters', $snippet['filters'] );
426 update_post_meta( $snippet['id'], 'wbcr_inp_changed_filters', $snippet['changed_filters'] );
427 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_scope', $snippet['scope'] );
428 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_priority', $snippet['priority'] );
429 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_description', $snippet['description'] );
430 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_tags', $snippet['attributes'] );
431 update_post_meta( $snippet['id'], 'wbcr_inp_snippet_activate', 0 );
432 $this->update_taxonomy_tags( $snippet['id'], $snippet['tags'] );
433
434 do_action( 'wbcr/inp/snippet/clone_meta', $snippet['id'], $snippet, $this );
435 }
436 }
437 }
438
439 /**
440 * Action admin_init
441 *
442 * @return void
443 */
444 public function admin_init() {
445 if ( ! WINP_Plugin::app()->current_user_car() ) {
446 return;
447 }
448
449 $post_id = WINP_HTTP::get( 'post', 0, 'intval' );
450 $action = WINP_HTTP::get( 'action' );
451
452 if ( ! empty( $action ) && ! empty( $post_id ) ) {
453 switch ( $action ) {
454 case 'export':
455 check_admin_referer( 'WINP_Actions_Snippet_' . $post_id );
456 $this->quick_export_snippets( [ $post_id ] );
457 break;
458
459 case 'clone':
460 check_admin_referer( 'winp_clone_snippet_' . $post_id );
461 $this->clone_snippets( [ $post_id ] );
462 wp_safe_redirect( admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE ) );
463 exit();
464
465 case 'close':
466 check_admin_referer( 'winp_close_snippet_' . $post_id );
467 wp_delete_post( $post_id );
468 wp_safe_redirect( admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&page=snippet-library' ) );
469 exit();
470
471 default:
472 return;
473 }
474 }
475 }
476
477 /**
478 * Action current_screen
479 * Add script for disabled export button
480 *
481 * @return void
482 */
483 public function current_screen() {
484 $current_screen = get_current_screen();
485
486 if ( null === $current_screen ) {
487 return;
488 }
489
490 if ( 'edit-wbcr-snippets' === $current_screen->id && WINP_SNIPPETS_POST_TYPE === $current_screen->post_type && ! WINP_Plugin::app()->get_api_object()->is_key() ) {
491 do_action( 'themeisle_internal_page', WINP_PLUGIN_SLUG, 'wbcr-snippets' );
492 }
493 }
494
495 /**
496 * Add style for close button for auto-draft snippet (preview)
497 *
498 * @return void
499 */
500 public function admin_enqueue_scripts() {
501 global $post;
502
503 $current_screen = get_current_screen();
504
505 if ( null === $current_screen ) {
506 return;
507 }
508
509 if ( 'wbcr-snippets' === $current_screen->id && WINP_SNIPPETS_POST_TYPE === $post->post_type && WINP_Helper::getMetaOption( get_the_ID(), 'snippet_draft', false ) ) {
510 wp_enqueue_style( 'winp-snippet-preview', WINP_PLUGIN_URL . '/admin/assets/css/snippet-preview.css', [], WINP_PLUGIN_VERSION );
511
512 // Remove Clear cache button for WP-Rocket plugin in preview snippet page.
513 remove_action( 'post_submitbox_start', 'rocket_post_submitbox_start' );
514 }
515 }
516
517 /**
518 * Delete snippets
519 *
520 * @param array<int> $ids Snippet IDs.
521 *
522 * @return void
523 */
524 private function delete_snippets( $ids ) {
525 if ( count( $ids ) ) {
526 foreach ( $ids as $id ) {
527 wp_trash_post( $id );
528 }
529 }
530 }
531
532 /**
533 * Deactivate snippets
534 *
535 * @param array<int> $ids Snippet IDs.
536 *
537 * @return void
538 */
539 private function deactivate_snippets( $ids ) {
540 if ( count( $ids ) ) {
541 foreach ( $ids as $id ) {
542 update_post_meta( $id, 'wbcr_inp_snippet_activate', 0 );
543 }
544 }
545 }
546
547 /**
548 * Activate snippets
549 *
550 * @param array<int> $ids Snippet IDs.
551 *
552 * @return void
553 */
554 private function activate_snippets( $ids ) {
555 if ( count( $ids ) ) {
556 foreach ( $ids as $id ) {
557 $is_activate = (int) WINP_Helper::getMetaOption( $id, 'snippet_activate', 0 );
558 $snippet_scope = WINP_Helper::getMetaOption( $id, 'snippet_scope' );
559 $snippet_type = WINP_Helper::get_snippet_type( $id );
560
561 if ( ( 'evrywhere' === $snippet_scope || 'auto' === $snippet_scope ) && ! $is_activate && WINP_SNIPPET_TYPE_TEXT !== $snippet_type && WINP_SNIPPET_TYPE_AD !== $snippet_type && WINP_Plugin::app()->get_execute_object()->getSnippetError( $id ) ) {
562 continue;
563 }
564
565 update_post_meta( $id, 'wbcr_inp_snippet_activate', 1 );
566 }
567 }
568 }
569
570
571 /**
572 * Get taxonomy tags
573 *
574 * @param int $snippet_id Snippet ID.
575 *
576 * @return array<string>
577 */
578 private function get_taxonomy_tags( $snippet_id ) {
579 $tags = [];
580
581 if ( $snippet_id ) {
582 $terms = wp_get_post_terms( $snippet_id, WINP_SNIPPETS_TAXONOMY, [ 'fields' => 'slugs' ] );
583 if ( ! is_wp_error( $terms ) ) {
584 return $terms;
585 }
586 }
587
588 return $tags;
589 }
590
591 /**
592 * Update taxonomy tags
593 *
594 * @param int $snippet_id Snippet ID.
595 * @param array<string> $tags Tags array.
596 *
597 * @return void
598 */
599 private function update_taxonomy_tags( $snippet_id, $tags ) {
600 if ( ! empty( $tags ) ) {
601 foreach ( $tags as $tag_slug ) {
602 $term = get_term_by( 'slug', $tag_slug, WINP_SNIPPETS_TAXONOMY );
603 if ( $term ) {
604 wp_set_post_terms( $snippet_id, [ $term->term_id ], WINP_SNIPPETS_TAXONOMY, true );
605 }
606 }
607 }
608 }
609
610 /**
611 * Get post meta
612 *
613 * @param int $post_id Post ID.
614 * @param string $meta_name Meta name.
615 *
616 * @return mixed
617 */
618 private function get_meta( $post_id, $meta_name ) {
619 return get_post_meta( $post_id, 'wbcr_inp_' . $meta_name, true );
620 }
621 }
622