PluginProbe
Download Plugin / 2.4.6
Download Plugin v2.4.6
2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 2.0.0 2.0.1 2.0.2 All 47 releases
download-plugin / download-plugin.php

download-plugin.php in Download Plugin 2.4.6, at download-plugin.php

801 lines 26.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: Download Plugin
4 * Plugin URI: http://metagauss.com
5 * Description: Download any plugin from your WordPress admin panel's Plugins page by just one click! Now, download themes, users, blog posts, pages, custom posts, comments, attachments and much more.
6 * Version: 2.4.6
7 * Author: Download Plugin
8 * Author URI: https://profiles.wordpress.org/downloadplugin/
9 * Text Domain: download-plugin
10 * Requires at least: 4.8
11 * Tested up to: 7.0
12 * Requires PHP: 5.6
13 */
14
15 if ( !defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 if( !is_admin() ) return;
20
21 // plugin version
22 define('DPWAP_VERSION', '2.4.6');
23 // directory separator
24 if ( !defined( 'DS' ) ) define( 'DS', DIRECTORY_SEPARATOR );
25 // plugin file name
26 if ( !defined( 'DPWAP_PLUGIN_FILE' ) ) {
27 define( 'DPWAP_PLUGIN_FILE', __FILE__ );
28 }
29 if ( !defined( 'DPWAP_DIR' ) ) {
30 define( 'DPWAP_DIR', dirname( __FILE__ ) ); // Plugin dir
31 }
32 if ( !defined( 'DPWAP_URL' ) ) {
33 define( 'DPWAP_URL', plugin_dir_url( __FILE__ ) ); // Plugin url
34 }
35 if ( !defined( 'DPWAP_FREE_GUIDE_URL' ) ) {
36 define( 'DPWAP_FREE_GUIDE_URL', 'https://theeventprime.com/how-to-use-download-plugin-in-wordpress/' );
37 }
38 if ( !defined( 'DPWAP_PRO_GUIDE_URL' ) ) {
39 define( 'DPWAP_PRO_GUIDE_URL', 'https://theeventprime.com/how-to-use-download-plugin-in-wordpress/' );
40 }
41 if ( !defined( 'DPWAP_PREFIX' ) ) {
42 define( 'DPWAP_PREFIX', 'dpwap_' ); // Plugin Prefix
43 }
44
45 if ( ! function_exists( 'dpwap_add_utm_params' ) ) {
46 function dpwap_add_utm_params( $url, $medium, $campaign, $content = '' ) {
47 $args = array(
48 'utm_source' => 'download_plugin',
49 'utm_medium' => $medium,
50 'utm_campaign' => $campaign,
51 );
52
53 if ( '' !== $content ) {
54 $args['utm_content'] = $content;
55 }
56
57 return add_query_arg( $args, $url );
58 }
59 }
60
61 $dpwapUploadDir = wp_upload_dir();
62 if ( !defined( 'DPWAPUPLOADDIR_PATH' ) ) {
63 define( 'DPWAPUPLOADDIR_PATH', $dpwapUploadDir['basedir'] );
64 }
65 if ( !defined( 'DPWAP_PLUGINS_TEMP' ) ) {
66 define( 'DPWAP_PLUGINS_TEMP', $dpwapUploadDir['basedir'].'/dpwap_plugins' ); // Plugin Prefix
67 }
68
69 require_once dirname( DPWAP_PLUGIN_FILE ) . '/vendor/autoload.php';
70
71 register_activation_hook( DPWAP_PLUGIN_FILE, 'dpwap_on_plugin_activation' );
72 register_activation_hook( DPWAP_PLUGIN_FILE, 'dpwap_func_activate' );
73 register_deactivation_hook( DPWAP_PLUGIN_FILE, 'dpwap_on_plugin_deactivation' );
74
75 /**
76 * Handle Download Plugin activation.
77 */
78 function dpwap_on_plugin_activation() {
79 if ( defined( 'WP_INSTALLING' ) ) {
80 return;
81 }
82 $timestamp = time();
83 update_option( 'dpwap_pro_last_activation_time', $timestamp );
84 update_option( 'dpwap_pro_welcome_modal_pending', 1 );
85 update_option( 'dpwap_pro_welcome_modal_dismissed', 0 );
86 update_option( 'dpwap_pro_notice_dismissed_at', 0 );
87 update_option( 'dpwap_pro_notice_cooldown_until', $timestamp + DAY_IN_SECONDS );
88 update_option( 'dpwap_pro_notice_version', DPWAP_VERSION );
89 }
90
91 /**
92 * Handle Download Plugin deactivation.
93 */
94 function dpwap_on_plugin_deactivation() {
95 update_option( 'dpwap_pro_last_deactivation_time', time() );
96 }
97
98 /**
99 * Check if the paid Pro plugin is active.
100 *
101 * @return bool
102 */
103 function dpwap_is_pro_active() {
104 if ( defined( 'DPWAP_PRO_ACTIVE' ) && DPWAP_PRO_ACTIVE ) {
105 return true;
106 }
107
108 if ( ! function_exists( 'is_plugin_active' ) ) {
109 require_once ABSPATH . 'wp-admin/includes/plugin.php';
110 }
111
112 return is_plugin_active( 'download-plugin-pro/download-plugin-pro.php' );
113 }
114
115 add_action( 'plugins_loaded', 'dpwap_plugin_loaded' );
116
117 //register_activation_hook( __FILE__, 'dpwap_func_activate' );
118
119 register_uninstall_hook( __FILE__, 'dpwap_func_uninstall' );
120
121 function dpwap_plugin_loaded() {
122 static $instance;
123 if ( is_null( $instance ) ) {
124 $instance = new DPWAP\Main();
125 /**
126 * Download plugin loaded.
127 *
128 * Fires when Download plugin was fully loaded and instantiated.
129 *
130 */
131 do_action( 'dpwap_download_plugin_loaded' );
132 }
133 return $instance;
134 }
135
136 if( !function_exists( 'dpwap_func_activate' ) ) {
137 function dpwap_func_activate() {
138 update_option( 'download_plugin_do_activation_redirect', true );
139 }
140 }
141
142 if ( !function_exists( 'dpwap_func_uninstall' ) ){
143 function dpwap_func_uninstall() {
144 //delete_option( 'dpwap_popup_status' );
145 $folder = DPWAP_PLUGINS_TEMP;
146 $files = glob( "$folder/*" );
147 if ( !empty( $files) ) {
148 foreach( $files as $file ) {
149 if ( is_file( $file) ){
150 unlink( $file );
151 }
152 }
153 }
154 }
155 }
156
157 // enhancement start
158 // Add download link to post/page row actions
159 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'dpwap_plugin_action_links' );
160
161 function dpwap_plugin_action_links( $links ) {
162 $starter_url = dpwap_add_utm_params( DPWAP_FREE_GUIDE_URL, 'plugin_row_action', 'guide', 'learn_how_it_works' );
163 $pro_url = dpwap_add_utm_params( 'https://theeventprime.com/checkout/?download_id=43730&edd_action=add_to_cart&edd_options[price_id][]=1', 'plugin_row_action', 'pro_upgrade', 'upgrade_to_pro' );
164 $is_pro_active = function_exists( 'dpwap_is_pro_active' ) && dpwap_is_pro_active();
165
166 $starter_link = '<a href="' . esc_url( $starter_url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Learn how it works', 'download-plugin' ) . '</a>';
167 $pro_link = '<a href="' . esc_url( $pro_url ) . '" target="_blank" rel="noopener noreferrer" class="dpwap-pro-link" data-action="open-pro-modal" data-checkout-url="' . esc_url( $pro_url ) . '">' . esc_html__( 'Upgrade to Pro', 'download-plugin' ) . '</a>';
168
169 $result = array();
170 foreach ( $links as $key => $link ) {
171 $result[ $key ] = $link;
172 if ( 'deactivate' === $key ) {
173 if ( ! $is_pro_active ) {
174 $result['dpwap_free_pro_upgrade'] = $pro_link;
175 }
176 $result['dpwap_starter_guide'] = $starter_link;
177 }
178 }
179
180 if ( ! isset( $result['dpwap_starter_guide'] ) ) {
181 if ( ! $is_pro_active ) {
182 $result['dpwap_free_pro_upgrade'] = $pro_link;
183 }
184 $result['dpwap_starter_guide'] = $starter_link;
185 }
186
187 return $result;
188 }
189 function dpwap_add_download_link($actions, $post) {
190 if (current_user_can('manage_options')) {
191 $download_url = wp_nonce_url(
192 add_query_arg(
193 [
194 'dpwap_download' => 1,
195 'post_id' => $post->ID,
196 'type' => $post->post_type,
197 ],
198 admin_url('edit.php')
199 ),
200 'dpwap_download_post_' . $post->ID
201 );
202 $actions['dpwap_download'] = '<a href="' . esc_url($download_url) . '">Download</a>';
203 }
204 return $actions;
205 }
206 add_filter('post_row_actions', 'dpwap_add_download_link', 10, 2);
207 add_filter('page_row_actions', 'dpwap_add_download_link', 10, 2);
208 add_filter('tag_row_actions', 'dpwap_add_term_download_action', 10, 2);
209 add_action('admin_init', 'dpwap_register_taxonomy_download_hooks');
210 add_action('admin_init', 'dpwap_handle_download_term');
211
212 // Handle the download request
213 function dpwap_handle_download() {
214 if (isset($_GET['dpwap_download']) && current_user_can('manage_options')) {
215 $post_id = intval($_GET['post_id']);
216 // Verify the nonce
217 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'dpwap_download_post_' . $post_id)) {
218 wp_die(__('Invalid nonce specified', 'dpwap'), __('Error', 'dpwap'), ['response' => 403]);
219 }
220
221 $post_type = sanitize_text_field($_GET['type']);
222 $format = 'csv'; // Default to CSV
223
224 // Fetch the post and its metadata
225 $post = get_post($post_id);
226 $title = $post->post_title;
227 $post_type = $post->post_type;
228 $meta_data = get_post_meta($post_id);
229 $meta_data = array_combine(array_keys($meta_data), array_column($meta_data, '0'));
230
231 $data = array();
232 // Prepare the data
233 $data[] = [
234 'post' => $post,
235 'meta' => $meta_data,
236 ];
237
238 $type = !empty($title)?$title:$post_type;
239 $filename = sanitize_key($type).'.csv';
240
241 dpwap_export_bulk_csv($data,$filename);
242 exit;
243 }
244 }
245
246 add_action('admin_init', 'dpwap_handle_download');
247 add_action('admin_init', 'dpwap_add_bulk_filters');
248
249 function dpwap_add_bulk_filters()
250 {
251 $post_types = get_post_types();
252 if(!empty($post_types))
253 {
254 foreach ($post_types as $post_type) {
255 add_filter('bulk_actions-edit-'.$post_type, 'dpwap_register_bulk_download');
256 add_filter('bulk_actions-edit-'.$post_type, 'dpwap_register_bulk_download');
257 add_filter('handle_bulk_actions-edit-'.$post_type, 'dpwap_handle_bulk_download', 10, 3);
258 add_filter('handle_bulk_actions-edit-'.$post_type, 'dpwap_handle_bulk_download', 10, 3);
259 }
260 }
261 }
262
263 // Register bulk action for posts/pages
264 function dpwap_register_bulk_download($bulk_actions) {
265 if (current_user_can('manage_options')) {
266 $bulk_actions['dpwap_bulk_download'] = 'Download';
267 }
268 return $bulk_actions;
269 }
270
271 // Handle the bulk download
272 function dpwap_handle_bulk_download($redirect_to, $doaction, $post_ids) {
273 if ($doaction === 'dpwap_bulk_download' && current_user_can('manage_options')) {
274 check_admin_referer('bulk-posts');
275 $data = [];
276 foreach ($post_ids as $post_id) {
277 $post = get_post($post_id);
278 $post_type = $post->post_type;
279 $meta_data = get_post_meta($post_id);
280 $meta_data = array_combine(array_keys($meta_data), array_column($meta_data, '0'));
281 $data[] = ['post' => $post, 'meta' => $meta_data];
282 }
283 $type = !empty($post_type)?$post_type:'post';
284 $filename = sanitize_key($type).'.csv';
285 dpwap_export_bulk_csv($data,$filename);
286 exit;
287 }
288 return $redirect_to;
289 }
290
291 function dpwap_export_bulk_csv($data,$file_name) {
292 // Collect all unique post keys and meta keys from all posts.
293 // Meta keys will be prefixed with 'meta:' in the CSV headers to match the pro addon convention.
294 $all_post_keys = [];
295 $all_meta_keys = [];
296
297 foreach ($data as $item) {
298 $post = $item['post'];
299
300 // Collect post object properties.
301 foreach ($post as $key => $value) {
302 if (!in_array($key, $all_post_keys)) {
303 $all_post_keys[] = $key;
304 }
305 }
306
307 // Collect meta keys (will be prefixed with 'meta:' in headers).
308 $meta = $item['meta'];
309 foreach ($meta as $key => $value) {
310 if (!in_array($key, $all_meta_keys)) {
311 $all_meta_keys[] = $key;
312 }
313 }
314 }
315
316 $filename = !empty($file_name) ? $file_name : 'bulk_export.csv';
317 header('Content-Type: text/csv');
318 header('Content-Disposition: attachment;filename=' . $filename);
319 $output = fopen('php://output', 'w');
320
321 // CSV Headers: combine post fields and meta keys (with 'meta:' prefix).
322 $headers = $all_post_keys;
323 foreach ($all_meta_keys as $meta_key ) {
324 $headers[] = 'meta:' . $meta_key;
325 }
326 fputcsv($output, $headers);
327
328 // Export each post with its data.
329 foreach ($data as $item) {
330 $post = $item['post'];
331 $meta = $item['meta'];
332 $row = array();
333
334 // Add post data in the order of the post headers.
335 foreach ($all_post_keys as $key) {
336 $value = isset($post->$key) ? $post->$key : '';
337 if (is_array($value) || is_object($value)) {
338 $value = maybe_serialize($value);
339 }
340 $row[] = (string) $value;
341 }
342
343 // Add meta data in the order of the meta headers.
344 // For array/object meta (like Elementor, Divi data), use JSON encoding for better compatibility.
345 foreach ($all_meta_keys as $key) {
346 $value = isset($meta[$key]) ? $meta[$key] : '';
347 if (is_array($value) || is_object($value)) {
348 // Use JSON encoding for complex meta values (page builder data, etc).
349 $value = wp_json_encode($value);
350 }
351 $row[] = (string) $value;
352 }
353
354 fputcsv($output, $row);
355 }
356
357 fclose($output);
358 exit;
359 }
360
361 function dpwap_handle_download_comment() {
362 if (isset($_GET['dpwap_download_comment']) && current_user_can('manage_options')) {
363 $comment_id = intval($_GET['comment_id']);
364
365 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'dpwap_download_comment_' . $comment_id)) {
366 wp_die(__('Invalid nonce specified', 'dpwap'), __('Error', 'dpwap'), ['response' => 403]);
367 }
368
369 dpwap_export_comments([$comment_id]);
370 exit;
371 }
372
373 }
374
375 add_action('admin_init', 'dpwap_handle_download_comment');
376
377 function dpwap_handle_download_user() {
378 if (isset($_GET['dpwap_download_user']) && current_user_can('manage_options')) {
379 $user_id = intval($_GET['user_id']);
380
381 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'dpwap_download_user_' . $user_id)) {
382 wp_die(__('Invalid nonce specified', 'dpwap'), __('Error', 'dpwap'), ['response' => 403]);
383 }
384
385 dpwap_export_users([$user_id]);
386 exit;
387 }
388 }
389
390 add_action('admin_init', 'dpwap_handle_download_user');
391
392 function add_download_button_to_comment_row($actions, $comment) {
393 if (current_user_can('manage_options')) {
394 $download_link_csv = wp_nonce_url(
395 add_query_arg(
396 [
397 'dpwap_download_comment' => 1,
398 'comment_id' => $comment->comment_ID,
399 'format' => 'csv',
400 ],
401 admin_url('edit-comments.php')
402 ),
403 'dpwap_download_comment_' . $comment->comment_ID
404 );
405
406 $actions['download_comment'] = '<a href="' . esc_url($download_link_csv) . '">Download</a>';
407 }
408 return $actions;
409 }
410 add_filter('comment_row_actions', 'add_download_button_to_comment_row', 10, 2);
411
412 function add_download_button_to_user_row($actions, $user) {
413 if (current_user_can('manage_options')) {
414 $download_link_csv = wp_nonce_url(
415 add_query_arg([
416 'dpwap_download_user' => 1,
417 'user_id' => $user->ID,
418 'format' => 'csv',
419 ], admin_url('users.php')),
420 'dpwap_download_user_' . $user->ID
421 );
422
423 $actions['download_user'] = '<a href="' . esc_url($download_link_csv) . '">Download</a>';
424 }
425 return $actions;
426 }
427 add_filter('user_row_actions', 'add_download_button_to_user_row', 10, 2);
428
429 // Add bulk action for exporting comments
430 function dpwap_register_comment_bulk_action($bulk_actions) {
431 $bulk_actions['export_comments_to_csv'] = __('Download', 'dpwap');
432 return $bulk_actions;
433 }
434 add_filter('bulk_actions-edit-comments', 'dpwap_register_comment_bulk_action');
435
436 // Handle the bulk action for comments
437 function dpwap_handle_comment_bulk_action($redirect_to, $doaction, $comment_ids) {
438 if ($doaction === 'export_comments_to_csv') {
439 dpwap_export_comments($comment_ids, ($doaction === 'export_comments_to_csv') ? 'csv' : 'json');
440 }
441 return $redirect_to;
442 }
443 add_filter('handle_bulk_actions-edit-comments', 'dpwap_handle_comment_bulk_action', 10, 3);
444
445 // Add bulk action for exporting users
446 function dpwap_register_user_bulk_action($bulk_actions) {
447 $bulk_actions['export_users_to_csv'] = __('Download', 'dpwap');
448 return $bulk_actions;
449 }
450 add_filter('bulk_actions-users', 'dpwap_register_user_bulk_action');
451
452 // Handle the bulk action for users
453 function dpwap_handle_user_bulk_action($redirect_to, $doaction, $user_ids) {
454 if ($doaction === 'export_users_to_csv') {
455 dpwap_export_users($user_ids);
456 }
457 return $redirect_to;
458 }
459 add_filter('handle_bulk_actions-users', 'dpwap_handle_user_bulk_action', 10, 3);
460
461 function dpwap_export_users($user_ids) {
462 $data = [];
463
464 foreach ($user_ids as $user_id) {
465 $user = get_userdata($user_id);
466 $meta = get_user_meta($user_id);
467
468 $data[] = [
469 'user' => $user,
470 'meta' => $meta,
471 ];
472 }
473 dpwap_export_users_csv($data);
474 }
475
476
477
478
479
480
481 function dpwap_export_comments($comment_ids) {
482 $data = [];
483
484 foreach ($comment_ids as $comment_id) {
485 $comment = get_comment($comment_id);
486 $meta = get_comment_meta($comment_id);
487
488 $data[] = [
489 'comment' => $comment,
490 'meta' => $meta,
491 ];
492 }
493
494 dpwap_export_comments_csv($data);
495 }
496
497 function dpwap_export_users_csv($data)
498 {
499 // Collect all unique user keys and meta keys.
500 // Meta keys will be prefixed with 'meta:' in the CSV headers to maintain consistency.
501 $all_user_keys = [];
502 $all_meta_keys = [];
503
504 foreach ($data as $item) {
505 $user_data = $item['user']->data;
506 foreach ($user_data as $key => $value) {
507 if (!in_array($key, $all_user_keys)) {
508 $all_user_keys[] = $key;
509 }
510 }
511
512 $meta = $item['meta'];
513 foreach ($meta as $key => $value) {
514 if (!in_array($key, $all_meta_keys)) {
515 $all_meta_keys[] = $key;
516 }
517 }
518 }
519
520 $filename = 'users_export.csv';
521 header('Content-Type: text/csv');
522 header('Content-Disposition: attachment;filename=' . $filename);
523 $output = fopen('php://output', 'w');
524
525 // CSV Headers: combine user fields and meta keys (with 'meta:' prefix).
526 $headers = $all_user_keys;
527 foreach ($all_meta_keys as $meta_key) {
528 $headers[] = 'meta:' . $meta_key;
529 }
530 fputcsv($output, $headers);
531
532 foreach ($data as $item) {
533 $user_data = $item['user']->data;
534 $meta = $item['meta'];
535 $row = array();
536
537 // Add user data in the order of the user headers.
538 foreach ($all_user_keys as $key) {
539 $value = isset($user_data->$key) ? $user_data->$key : '';
540 $row[] = (string) $value;
541 }
542
543 // Add meta data in the order of the meta headers.
544 // User meta is stored as single values in an array, so we take the first element.
545 foreach ($all_meta_keys as $key) {
546 $value = '';
547 if (isset($meta[$key]) && is_array($meta[$key])) {
548 $value = reset($meta[$key]); // Get first value.
549 if (is_array($value) || is_object($value)) {
550 $value = wp_json_encode($value);
551 }
552 }
553 $row[] = (string) $value;
554 }
555
556 fputcsv($output, $row);
557 }
558
559 fclose($output);
560 exit;
561 }
562
563 function dpwap_export_comments_csv($data) {
564
565 // Collect all unique comment keys and meta keys.
566 // Meta keys will be prefixed with 'meta:' in the CSV headers to maintain consistency.
567 $all_comment_keys = [];
568 $all_meta_keys = [];
569
570 foreach ($data as $item) {
571 $comment = $item['comment'];
572 foreach ($comment as $key => $value) {
573 if (!in_array($key, $all_comment_keys)) {
574 $all_comment_keys[] = $key;
575 }
576 }
577
578 $meta = $item['meta'];
579 foreach ($meta as $key => $value) {
580 if (!in_array($key, $all_meta_keys)) {
581 $all_meta_keys[] = $key;
582 }
583 }
584 }
585
586 $filename = 'comments_export.csv';
587 header('Content-Type: text/csv');
588 header('Content-Disposition: attachment;filename=' . $filename);
589 $output = fopen('php://output', 'w');
590
591 // CSV Headers: combine comment fields and meta keys (with 'meta:' prefix).
592 $headers = $all_comment_keys;
593 foreach ($all_meta_keys as $meta_key) {
594 $headers[] = 'meta:' . $meta_key;
595 }
596 fputcsv($output, $headers);
597
598 foreach ($data as $item) {
599 $comment = $item['comment'];
600 $meta = $item['meta'];
601 $row = array();
602
603 // Add comment data in the order of the comment headers.
604 foreach ($all_comment_keys as $key) {
605 $value = isset($comment->$key) ? $comment->$key : '';
606 if (is_array($value) || is_object($value)) {
607 $value = maybe_serialize($value);
608 }
609 $row[] = (string) $value;
610 }
611
612 // Add meta data in the order of the meta headers.
613 foreach ($all_meta_keys as $key) {
614 $value = isset($meta[$key]) ? $meta[$key] : '';
615 if (is_array($value) || is_object($value)) {
616 $value = wp_json_encode($value);
617 }
618 $row[] = (string) $value;
619 }
620
621 fputcsv($output, $row);
622 }
623
624 fclose($output);
625 exit;
626 }
627
628 function dpwap_add_term_download_action( $actions, $term ) {
629 if ( ! current_user_can( 'manage_options' ) ) {
630 return $actions;
631 }
632
633 if ( empty( $term ) || ! isset( $term->term_id, $term->taxonomy ) ) {
634 return $actions;
635 }
636
637 $taxonomy = sanitize_key( $term->taxonomy );
638 $taxonomy_obj = get_taxonomy( $taxonomy );
639 if ( $taxonomy_obj && empty( $taxonomy_obj->show_ui ) ) {
640 return $actions;
641 }
642 $args = array(
643 'dpwap_download_term' => 1,
644 'term_id' => (int) $term->term_id,
645 'taxonomy' => $taxonomy,
646 );
647
648 if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
649 $args['post_type'] = sanitize_key( wp_unslash( $_REQUEST['post_type'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
650 }
651
652 $url = wp_nonce_url(
653 add_query_arg( $args, admin_url( 'edit-tags.php' ) ),
654 'dpwap_download_term_' . $term->term_id
655 );
656
657 $actions['dpwap_download'] = '<a href="' . esc_url( $url ) . '">' . esc_html__( 'Download', 'download-plugin' ) . '</a>';
658 return $actions;
659 }
660
661 function dpwap_register_taxonomy_download_hooks() {
662 if ( ! current_user_can( 'manage_options' ) ) {
663 return;
664 }
665 $taxonomies = get_taxonomies( array( 'show_ui' => true ), 'names' );
666 foreach ( $taxonomies as $taxonomy ) {
667 add_filter( 'bulk_actions-edit-' . $taxonomy, 'dpwap_register_term_bulk_download' );
668 add_filter( 'handle_bulk_actions-edit-' . $taxonomy, 'dpwap_handle_term_bulk_download', 10, 3 );
669 }
670 }
671
672 function dpwap_register_term_bulk_download( $bulk_actions ) {
673 if ( current_user_can( 'manage_options' ) ) {
674 $bulk_actions['dpwap_bulk_download_terms'] = __( 'Download', 'download-plugin' );
675 }
676 return $bulk_actions;
677 }
678
679 function dpwap_handle_term_bulk_download( $redirect_to, $doaction, $term_ids ) {
680 if ( 'dpwap_bulk_download_terms' !== $doaction || ! current_user_can( 'manage_options' ) ) {
681 return $redirect_to;
682 }
683
684 $taxonomy = isset( $_REQUEST['taxonomy'] ) ? sanitize_key( wp_unslash( $_REQUEST['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
685 if ( empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) {
686 return $redirect_to;
687 }
688
689 check_admin_referer( 'bulk-tags' );
690 dpwap_export_terms_csv( array_map( 'intval', (array) $term_ids ), $taxonomy );
691 exit;
692 }
693
694 function dpwap_handle_download_term() {
695 if ( ! isset( $_GET['dpwap_download_term'] ) || ! current_user_can( 'manage_options' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
696 return;
697 }
698
699 $term_id = isset( $_GET['term_id'] ) ? (int) $_GET['term_id'] : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
700 $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_key( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
701
702 if ( ! $term_id || empty( $taxonomy ) || ! taxonomy_exists( $taxonomy ) ) {
703 wp_die( esc_html__( 'Invalid term download request.', 'download-plugin' ) );
704 }
705
706 if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'dpwap_download_term_' . $term_id ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
707 wp_die( esc_html__( 'Invalid nonce specified.', 'download-plugin' ), esc_html__( 'Error', 'download-plugin' ), array( 'response' => 403 ) );
708 }
709
710 dpwap_export_terms_csv( array( $term_id ), $taxonomy );
711 exit;
712 }
713
714 function dpwap_export_terms_csv( $term_ids, $taxonomy ) {
715 if ( empty( $term_ids ) || ! taxonomy_exists( $taxonomy ) ) {
716 return;
717 }
718
719 $terms = array();
720 foreach ( $term_ids as $term_id ) {
721 $term = get_term( (int) $term_id, $taxonomy );
722 if ( $term && ! is_wp_error( $term ) ) {
723 $terms[] = $term;
724 }
725 }
726
727 if ( empty( $terms ) ) {
728 return;
729 }
730
731 // Collect all unique term keys and meta keys.
732 // Meta keys will be prefixed with 'meta:' in the CSV headers to maintain consistency.
733 $all_term_keys = array();
734 $all_meta_keys = array();
735
736 foreach ( $terms as $term ) {
737 $term_data = get_object_vars( $term );
738 foreach ( $term_data as $key => $value ) {
739 if ( ! in_array( $key, $all_term_keys, true ) ) {
740 $all_term_keys[] = $key;
741 }
742 }
743 $meta = get_term_meta( $term->term_id );
744 foreach ( $meta as $key => $values ) {
745 if ( ! in_array( $key, $all_meta_keys, true ) ) {
746 $all_meta_keys[] = $key;
747 }
748 }
749 }
750
751 $filename = sanitize_key( $taxonomy ) . '-terms.csv';
752 header( 'Content-Type: text/csv' );
753 header( 'Content-Disposition: attachment;filename=' . $filename );
754 $output = fopen( 'php://output', 'w' );
755
756 // CSV Headers: combine term fields and meta keys (with 'meta:' prefix).
757 $headers = $all_term_keys;
758 foreach ( $all_meta_keys as $meta_key ) {
759 $headers[] = 'meta:' . $meta_key;
760 }
761 fputcsv( $output, $headers );
762
763 foreach ( $terms as $term ) {
764 $term_data = get_object_vars( $term );
765 $meta = get_term_meta( $term->term_id );
766
767 $row = array();
768
769 // Add term data in the order of the term headers.
770 foreach ( $all_term_keys as $key ) {
771 $value = isset( $term_data[ $key ] ) ? $term_data[ $key ] : '';
772 if ( is_array( $value ) || is_object( $value ) ) {
773 $value = maybe_serialize( $value );
774 }
775 $row[] = (string) $value;
776 }
777
778 // Add meta data in the order of the meta headers.
779 foreach ( $all_meta_keys as $key ) {
780 $value = '';
781 if ( isset( $meta[ $key ] ) ) {
782 $meta_values = $meta[ $key ];
783 if ( is_array( $meta_values ) ) {
784 $value = reset( $meta_values ); // Get first value.
785 } else {
786 $value = $meta_values;
787 }
788 if ( is_array( $value ) || is_object( $value ) ) {
789 $value = wp_json_encode( $value );
790 }
791 }
792 $row[] = (string) $value;
793 }
794
795 fputcsv( $output, $row );
796 }
797
798 fclose( $output );
799 exit;
800 }
801