PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / 2.7.9
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts v2.7.9
2.7.9 2.7.8 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 All 30 releases
← All changes | admin/includes/class.actions.snippet.php +621 -394 2.2.4 → 2.7.9 View file →
@@ -1,394 +1,621 @@
1 -<?php
2 -/**
3 - * Export snippet
4 - * @author Webcraftic <[email protected]>
5 - * @copyright (c) 16.11.2018, Webcraftic
6 - * @version 1.0
7 - */
8 -
9 -// Exit if accessed directly
10 -if ( ! defined( 'ABSPATH' ) ) {
11 - exit;
12 -}
13 -
14 -class WINP_Export_Snippet {
15 -
16 - /**
17 - * WINP_Export_Snippet constructor.
18 - */
19 - public function __construct() {
20 - $this->registerHooks();
21 - }
22 -
23 - /**
24 - * Register hooks
25 - */
26 - public function registerHooks() {
27 - add_filter( 'post_row_actions', array( $this, 'postRowActions' ), 10, 2 );
28 - add_filter( 'bulk_actions-edit-' . WINP_SNIPPETS_POST_TYPE, array( $this, 'actionBulkEditPost' ) );
29 - add_filter( 'handle_bulk_actions-edit-' . WINP_SNIPPETS_POST_TYPE, array(
30 - $this,
31 - 'handleActionBulkEditPost',
32 - ), 10, 3 );
33 -
34 - add_action( 'post_submitbox_start', array( $this, 'postSubmitboxStart' ) );
35 - add_action( 'admin_init', array( $this, 'adminInit' ) );
36 - add_action( 'current_screen', array( $this, 'current_screen' ) );
37 - add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
38 - }
39 -
40 - /**
41 - * Get export url
42 - *
43 - * @param $post_id
44 - *
45 - * @return string
46 - */
47 - private function getExportUrl( $post_id ) {
48 - $url = admin_url( 'post.php?post=' . $post_id );
49 -
50 - return add_query_arg(
51 - array(
52 - 'action' => 'export',
53 - 'nonce' => wp_create_nonce( 'winp_export_snippet' ),
54 - ),
55 - $url
56 - );
57 - }
58 -
59 - /**
60 - * Get close url
61 - *
62 - * @param $post_id
63 - *
64 - * @return string
65 - */
66 - private function get_close_url( $post_id ) {
67 - $url = admin_url( 'post.php?post=' . $post_id );
68 -
69 - return add_query_arg( array( 'action' => 'close' ), $url );
70 - }
71 -
72 - /**
73 - * postRowActions
74 - *
75 - * @param $actions
76 - * @param $post
77 - *
78 - * @return mixed
79 - */
80 - public function postRowActions( $actions, $post ) {
81 - if ( $post->post_type == WINP_SNIPPETS_POST_TYPE ) {
82 - $export_link = $this->getExportUrl( $post->ID );
83 -
84 - if ( isset( $actions['trash'] ) ) {
85 - $trash = $actions['trash'];
86 - unset( $actions['trash'] );
87 - }
88 -
89 - $actions['export'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $export_link ), esc_html( __( 'Export', 'insert-php' ) ) );
90 -
91 - if ( isset( $trash ) ) {
92 - $actions['trash'] = $trash;
93 - }
94 - }
95 -
96 - return $actions;
97 - }
98 -
99 - /**
100 - * actionBulkEditPost
101 - *
102 - * @param $bulk_actions
103 - *
104 - * @return mixed
105 - */
106 - public function actionBulkEditPost( $bulk_actions ) {
107 - $pro = WINP_Plugin::app()->get_api_object()->is_key() ? '' : ' (PRO)';
108 -
109 - $bulk_actions['exportsnp'] = __( 'Export' . $pro, 'insert-php' );
110 - $bulk_actions['deletesnp'] = __( 'Delete', 'insert-php' );
111 - $bulk_actions['deactivate'] = __( 'Deactivate', 'insert-php' );
112 - $bulk_actions['activate'] = __( 'Activate', 'insert-php' );
113 -
114 - return $bulk_actions;
115 - }
116 -
117 - /**
118 - * handleActionBulkEditPost
119 - *
120 - * @param $redirect_to
121 - * @param $doaction
122 - * @param $post_ids
123 - *
124 - * @return mixed
125 - */
126 - public function handleActionBulkEditPost( $redirect_to, $doaction, $post_ids ) {
127 - $actions = array(
128 - 'exportsnp' => 1,
129 - 'deletesnp' => 1,
130 - 'deactivate' => 1,
131 - 'activate' => 1
132 - );
133 -
134 - if ( ! isset( $actions[ $doaction ] ) ) {
135 - return $redirect_to;
136 - }
137 -
138 - if ( count( $post_ids ) ) {
139 - switch ( $doaction ) {
140 - case 'exportsnp':
141 - if ( WINP_Plugin::app()->get_api_object()->is_key() ) {
142 - $nonce = WINP_Plugin::app()->request->get( '_wpnonce', '' );
143 - if ( wp_verify_nonce( $nonce, 'bulk-posts' ) ) {
144 - $this->exportSnippets( $post_ids );
145 - }
146 - }
147 - break;
148 - case 'deletesnp':
149 - $this->deleteSnippets( $post_ids );
150 - break;
151 - case 'deactivate':
152 - $this->deactivateSnippets( $post_ids );
153 - break;
154 - case 'activate':
155 - $this->activateSnippets( $post_ids );
156 - break;
157 - }
158 - }
159 -
160 - return $redirect_to;
161 - }
162 -
163 - /**
164 - * Выводим кнопки в форме редактирования сниппета, возле кнопки публикации / обновления
165 - */
166 - public function postSubmitboxStart() {
167 - global $post;
168 -
169 - if (
170 - $post
171 - && WINP_SNIPPETS_POST_TYPE == $post->post_type
172 - ) {
173 - if ( WINP_Helper::getMetaOption( $post->ID, 'snippet_draft', false ) ) {
174 - $close_link = $this->get_close_url( $post->ID );
175 - 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>";
176 - } else {
177 - $export_link = $this->getExportUrl( $post->ID );
178 - echo "<div id='winp-export-action'>" . sprintf( '<a href="%1$s">%2$s</a>', esc_url( $export_link ), esc_html( __( 'Export', 'insert-php' ) ) ) . "</div>";
179 - }
180 - }
181 - }
182 -
183 - /**
184 - * Get taxonomy tags
185 - *
186 - * @param $snippet_id
187 - *
188 - * @return array
189 - */
190 - private function getTaxonomyTags( $snippet_id )
191 - {
192 - $tags = array();
193 -
194 - if ( $snippet_id ) {
195 - return wp_get_post_terms( $snippet_id, WINP_SNIPPETS_TAXONOMY, array( "fields" => "slugs" ) );
196 - }
197 -
198 - return $tags;
199 - }
200 -
201 - /**
202 - * Get post meta
203 - *
204 - * @param $post_id
205 - * @param $meta_name
206 - *
207 - * @return mixed
208 - */
209 - private function getMeta( $post_id, $meta_name ) {
210 - return get_post_meta( $post_id, WINP_Plugin::app()->getPrefix() . $meta_name, true );
211 - }
212 -
213 - /**
214 - * Set up the current page to act like a downloadable file instead of being shown in the browser
215 - *
216 - * @param string $format
217 - * @param array $ids
218 - * @param string $mime_type
219 - *
220 - * @return array
221 - */
222 - public function prepareExport( $format, $ids, $mime_type = '' ) {
223 - $snippets = array();
224 -
225 - if ( count( $ids ) ) {
226 - foreach ( $ids as $id ) {
227 - $post = get_post( $id );
228 - $snippets[] = array(
229 - 'name' => $post->post_name,
230 - 'title' => $post->post_title,
231 - 'content' => $post->post_content,
232 - 'location' => $this->getMeta( $id, 'snippet_location' ),
233 - 'type' => $this->getMeta( $id, 'snippet_type' ),
234 - 'filters' => $this->getMeta( $id, 'snippet_filters' ),
235 - 'changed_filters' => $this->getMeta( $id, 'changed_filters' ),
236 - 'scope' => $this->getMeta( $id, 'snippet_scope' ),
237 - 'description' => $this->getMeta( $id, 'snippet_description' ),
238 - 'attributes' => $this->getMeta( $id, 'snippet_tags' ),
239 - 'tags' => $this->getTaxonomyTags( $id )
240 - );
241 - }
242 - }
243 -
244 - /* Build the export filename */
245 - if ( 1 == count( $ids ) ) {
246 - $name = $snippets[0]['title'];
247 - $title = strtolower( $name );
248 - } else {
249 - /* Otherwise, use the site name as set in Settings > General */
250 - $title = strtolower( get_bloginfo( 'name' ) );
251 - }
252 -
253 - $filename = "{$title}.php-code-snippets.{$format}";
254 -
255 - /* Set HTTP headers */
256 - header( 'Content-Disposition: attachment; filename=' . sanitize_file_name( $filename ) );
257 -
258 - if ( '' !== $mime_type ) {
259 - header( "Content-Type: $mime_type; charset=" . get_bloginfo( 'charset' ) );
260 - }
261 -
262 - return $snippets;
263 - }
264 -
265 - /**
266 - * Export snippets in JSON format
267 - *
268 - * @param array $ids
269 - */
270 - public function exportSnippets( $ids ) {
271 - $snippets = $this->prepareExport( 'json', $ids, 'application/json' );
272 -
273 - $data = array(
274 - 'generator' => 'PHP Code Snippets v' . WINP_PLUGIN_VERSION,
275 - 'date_created' => date( 'Y-m-d H:i' ),
276 - 'snippets' => $snippets,
277 - );
278 -
279 - echo wp_json_encode( $data, 0 );
280 - exit;
281 - }
282 -
283 - /**
284 - * Delete snippets
285 - *
286 - * @param $ids
287 - */
288 - private function deleteSnippets( $ids ) {
289 - if ( count( $ids ) ) {
290 - foreach ( $ids as $id ) {
291 - wp_trash_post( $id );
292 - }
293 - }
294 - }
295 -
296 - /**
297 - * Deactivate snippets
298 - *
299 - * @param $ids
300 - */
301 - private function deactivateSnippets( $ids ) {
302 - if ( count( $ids ) ) {
303 - foreach ( $ids as $id ) {
304 - update_post_meta( $id, WINP_Plugin::app()->getPrefix() . 'snippet_activate', 0 );
305 - }
306 - }
307 - }
308 -
309 - /**
310 - * Activate snippets
311 - *
312 - * @param $ids
313 - */
314 - private function activateSnippets( $ids ) {
315 - if ( count( $ids ) ) {
316 - foreach ( $ids as $id ) {
317 - $is_activate = (int) WINP_Helper::getMetaOption( $id, 'snippet_activate', 0 );
318 - $snippet_scope = WINP_Helper::getMetaOption( $id, 'snippet_scope' );
319 - $snippet_type = WINP_Helper::get_snippet_type( $id );
320 -
321 - if ( ( $snippet_scope == 'evrywhere' || $snippet_scope == 'auto' ) && ! $is_activate && $snippet_type != WINP_SNIPPET_TYPE_TEXT && WINP_Plugin::app()->getExecuteObject()->getSnippetError( $id ) ) {
322 - continue;
323 - }
324 -
325 - update_post_meta( $id, WINP_Plugin::app()->getPrefix() . 'snippet_activate', 1 );
326 - }
327 - }
328 - }
329 -
330 - /**
331 - * Action admin_init
332 - */
333 - public function adminInit() {
334 - $post = WINP_Plugin::app()->request->get( 'post', 0 );
335 - $action = WINP_Plugin::app()->request->get( 'action', '', 'sanitize_key' );
336 -
337 - if ( ! empty( $action ) && ! empty( $post ) ) {
338 - $ids = is_array( $post ) ? $post : array( absint( $post ) );
339 - switch ( $action ) {
340 - case 'export':
341 - $nonce = WINP_Plugin::app()->request->get( 'nonce', '' );
342 - if ( wp_verify_nonce( $nonce, 'winp_export_snippet' ) ) {
343 - $this->exportSnippets( $ids );
344 - }
345 - break;
346 - case 'close':
347 - wp_delete_post( $ids[0] );
348 -
349 - wp_redirect( admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&page=snippet-library-wbcr_insert_php' ) );
350 - exit();
351 - break;
352 - default:
353 - return;
354 - }
355 - }
356 - }
357 -
358 - /**
359 - * Action current_screen
360 - * Add script for disabled export button
361 - */
362 - public function current_screen() {
363 - $current_screen = get_current_screen();
364 -
365 - if (
366 - 'edit-wbcr-snippets' === $current_screen->id
367 - && WINP_SNIPPETS_POST_TYPE === $current_screen->post_type
368 - && ! WINP_Plugin::app()->get_api_object()->is_key()
369 - ) {
370 - wp_enqueue_script( 'winp-snippet-list', WINP_PLUGIN_URL . '/admin/assets/js/snippet-list.js' );
371 - }
372 - }
373 -
374 - /**
375 - * Add style for close button for auto-draft snippet (preview)
376 - */
377 - public function admin_enqueue_scripts() {
378 - global $post;
379 -
380 - $current_screen = get_current_screen();
381 -
382 - if (
383 - 'wbcr-snippets' === $current_screen->id
384 - && WINP_SNIPPETS_POST_TYPE === $post->post_type
385 - && WINP_Helper::getMetaOption( get_the_ID(), 'snippet_draft', false )
386 - ) {
387 - wp_enqueue_style( 'winp-snippet-preview', WINP_PLUGIN_URL . '/admin/assets/css/snippet-preview.css' );
388 -
389 - // Remove Clear cache button for WP-Rocket plugin in preview snippet page
390 - remove_action( 'post_submitbox_start', 'rocket_post_submitbox_start' );
391 - }
392 - }
393 -
394 -}
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 +}