Code Snippets - Version 2.10.1

Version Description

(10 Feb 2018) = * Fixed: Prevent errors when trying to export no snippets * Fixed: Use wp_json_encode() to encode export data * Fixed: Check both the file extension and MIME type of uploaded import files

Download this release

Release Info

Developer bungeshea
Plugin Icon Code Snippets
Version 2.10.1
Comparing to
See all releases

Code changes from version 2.10.0 to 2.10.1

code-snippets.php CHANGED
@@ -10,7 +10,7 @@
10
  * @author Shea Bunge <shea@bungeshea.com>
11
  * @copyright 2012-2018 Shea Bunge
12
  * @license MIT http://opensource.org/licenses/MIT
13
- * @version 2.10.0
14
  * @link https://github.com/sheabunge/code-snippets
15
  */
16
 
@@ -20,7 +20,7 @@ Plugin URI: https://github.com/sheabunge/code-snippets
20
  Description: An easy, clean and simple way to add code snippets to your site. No need to edit to your theme's functions.php file again!
21
  Author: Shea Bunge
22
  Author URI: https://bungeshea.com
23
- Version: 2.10.0
24
  License: MIT
25
  License URI: license.txt
26
  Text Domain: code-snippets
@@ -42,7 +42,7 @@ if ( ! defined( 'ABSPATH' ) ) {
42
  * @since 2.0
43
  * @var string A PHP-standardized version number string
44
  */
45
- define( 'CODE_SNIPPETS_VERSION', '2.10.0' );
46
 
47
  /**
48
  * The full path to the main file of this plugin
10
  * @author Shea Bunge <shea@bungeshea.com>
11
  * @copyright 2012-2018 Shea Bunge
12
  * @license MIT http://opensource.org/licenses/MIT
13
+ * @version 2.10.1
14
  * @link https://github.com/sheabunge/code-snippets
15
  */
16
 
20
  Description: An easy, clean and simple way to add code snippets to your site. No need to edit to your theme's functions.php file again!
21
  Author: Shea Bunge
22
  Author URI: https://bungeshea.com
23
+ Version: 2.10.1.1
24
  License: MIT
25
  License URI: license.txt
26
  Text Domain: code-snippets
42
  * @since 2.0
43
  * @var string A PHP-standardized version number string
44
  */
45
+ define( 'CODE_SNIPPETS_VERSION', '2.10.1.1' );
46
 
47
  /**
48
  * The full path to the main file of this plugin
languages/code-snippets.pot CHANGED
@@ -8,7 +8,7 @@ msgid ""
8
  msgstr ""
9
  "Project-Id-Version: code-snippets 2.10.0\n"
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2018-01-18 16:05+1100\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -150,15 +150,23 @@ msgstr ""
150
  msgid "Import Snippets"
151
  msgstr ""
152
 
153
- #: php/admin-menus/class-import-menu.php:94
154
  msgid "Code Snippets"
155
  msgstr ""
156
 
157
- #: php/admin-menus/class-import-menu.php:95
158
  msgid "Import snippets from a code snippets export file"
159
  msgstr ""
160
 
161
- #: php/admin-menus/class-import-menu.php:111
 
 
 
 
 
 
 
 
162
  #, php-format
163
  msgid ""
164
  "Successfully imported <strong>%d</strong> snippet. <a href=\"%s\">Have fun!</"
@@ -169,10 +177,6 @@ msgid_plural ""
169
  msgstr[0] ""
170
  msgstr[1] ""
171
 
172
- #: php/admin-menus/class-import-menu.php:123
173
- msgid "An error occurred when processing the import file."
174
- msgstr ""
175
-
176
  #: php/admin-menus/class-manage-menu.php:22
177
  msgctxt "menu label"
178
  msgid "All Snippets"
@@ -480,50 +484,6 @@ msgid ""
480
  "<a href=\"%s\">Manage Snippets</a> page."
481
  msgstr ""
482
 
483
- #: php/class-export.php:89
484
- msgid ""
485
- "This is a code snippets export file generated by the Code Snippets WordPress "
486
- "plugin."
487
- msgstr ""
488
-
489
- #: php/class-export.php:91
490
- msgid "To import these snippets a WordPress site follow these steps:"
491
- msgstr ""
492
-
493
- #: php/class-export.php:92
494
- msgid "1. Log in to that site as an administrator."
495
- msgstr ""
496
-
497
- #: php/class-export.php:93
498
- msgid ""
499
- "2. Install the Code Snippets plugin using the directions provided at the "
500
- "above link."
501
- msgstr ""
502
-
503
- #: php/class-export.php:94
504
- msgid "3. Go to 'Tools: Import' in the WordPress admin panel."
505
- msgstr ""
506
-
507
- #: php/class-export.php:95
508
- msgid "4. Click on the \"Code Snippets\" importer in the list"
509
- msgstr ""
510
-
511
- #: php/class-export.php:96
512
- msgid "5. Upload this file using the form provided on that page."
513
- msgstr ""
514
-
515
- #: php/class-export.php:97
516
- msgid ""
517
- "6. Code Snippets will then import all of the snippets and associated "
518
- "information contained in this file into your site."
519
- msgstr ""
520
-
521
- #: php/class-export.php:98
522
- msgid ""
523
- "7. You will then have to visit the 'Snippets: All Snippets' admin menu and "
524
- "activate desired snippets."
525
- msgstr ""
526
-
527
  #: php/class-list-table.php:58
528
  msgid "Snippets per page"
529
  msgstr ""
@@ -642,29 +602,29 @@ msgstr ""
642
  msgid "Clear List"
643
  msgstr ""
644
 
645
- #: php/class-list-table.php:729
646
  msgid "Whoops, it looks like no snippets could be found."
647
  msgstr ""
648
 
649
- #: php/class-list-table.php:733
650
  msgid "Perhaps you would like to add a new one?"
651
  msgstr ""
652
 
653
- #: php/class-list-table.php:1031
654
  msgid "Search results"
655
  msgstr ""
656
 
657
- #: php/class-list-table.php:1034
658
  #, php-format
659
  msgid " for &#8220;%s&#8221;"
660
  msgstr ""
661
 
662
- #: php/class-list-table.php:1038
663
  #, php-format
664
  msgid " in tag &#8220;%s&#8221;"
665
  msgstr ""
666
 
667
- #: php/class-list-table.php:1046
668
  msgid "Clear Filters"
669
  msgstr ""
670
 
8
  msgstr ""
9
  "Project-Id-Version: code-snippets 2.10.0\n"
10
  "Report-Msgid-Bugs-To: \n"
11
+ "POT-Creation-Date: 2018-02-11 00:17+1100\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
150
  msgid "Import Snippets"
151
  msgstr ""
152
 
153
+ #: php/admin-menus/class-import-menu.php:102
154
  msgid "Code Snippets"
155
  msgstr ""
156
 
157
+ #: php/admin-menus/class-import-menu.php:103
158
  msgid "Import snippets from a code snippets export file"
159
  msgstr ""
160
 
161
+ #: php/admin-menus/class-import-menu.php:115
162
+ msgid "An error occurred when processing the import files."
163
+ msgstr ""
164
+
165
+ #: php/admin-menus/class-import-menu.php:125
166
+ msgid "No snippets were imported."
167
+ msgstr ""
168
+
169
+ #: php/admin-menus/class-import-menu.php:131
170
  #, php-format
171
  msgid ""
172
  "Successfully imported <strong>%d</strong> snippet. <a href=\"%s\">Have fun!</"
177
  msgstr[0] ""
178
  msgstr[1] ""
179
 
 
 
 
 
180
  #: php/admin-menus/class-manage-menu.php:22
181
  msgctxt "menu label"
182
  msgid "All Snippets"
484
  "<a href=\"%s\">Manage Snippets</a> page."
485
  msgstr ""
486
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  #: php/class-list-table.php:58
488
  msgid "Snippets per page"
489
  msgstr ""
602
  msgid "Clear List"
603
  msgstr ""
604
 
605
+ #: php/class-list-table.php:728
606
  msgid "Whoops, it looks like no snippets could be found."
607
  msgstr ""
608
 
609
+ #: php/class-list-table.php:732
610
  msgid "Perhaps you would like to add a new one?"
611
  msgstr ""
612
 
613
+ #: php/class-list-table.php:1030
614
  msgid "Search results"
615
  msgstr ""
616
 
617
+ #: php/class-list-table.php:1033
618
  #, php-format
619
  msgid " for &#8220;%s&#8221;"
620
  msgstr ""
621
 
622
+ #: php/class-list-table.php:1037
623
  #, php-format
624
  msgid " in tag &#8220;%s&#8221;"
625
  msgstr ""
626
 
627
+ #: php/class-list-table.php:1045
628
  msgid "Clear Filters"
629
  msgstr ""
630
 
php/admin-menus/class-edit-menu.php CHANGED
@@ -109,12 +109,12 @@ class Code_Snippets_Edit_Menu extends Code_Snippets_Admin_Menu {
109
 
110
  /* Export the snippet if the button was clicked */
111
  if ( isset( $_POST['export_snippet'] ) ) {
112
- export_snippets( $_POST['snippet_id'] );
113
  }
114
 
115
  /* Download the snippet if the button was clicked */
116
  if ( isset( $_POST['download_snippet'] ) ) {
117
- export_snippets( $_POST['snippet_id'], null, 'php' );
118
  }
119
  }
120
  }
@@ -341,7 +341,7 @@ class Code_Snippets_Edit_Menu extends Code_Snippets_Admin_Menu {
341
 
342
  <script type="text/javascript">
343
  jQuery('#snippet_tags').tagit({
344
- availableTags: <?php echo json_encode( get_all_snippet_tags() ); ?>,
345
  allowSpaces: true,
346
  removeConfirmation: true
347
  });
109
 
110
  /* Export the snippet if the button was clicked */
111
  if ( isset( $_POST['export_snippet'] ) ) {
112
+ export_snippets( array( $_POST['snippet_id'] ) );
113
  }
114
 
115
  /* Download the snippet if the button was clicked */
116
  if ( isset( $_POST['download_snippet'] ) ) {
117
+ download_snippets( array( $_POST['snippet_id'] ) );
118
  }
119
  }
120
  }
341
 
342
  <script type="text/javascript">
343
  jQuery('#snippet_tags').tagit({
344
+ availableTags: <?php echo wp_json_encode( get_all_snippet_tags() ); ?>,
345
  allowSpaces: true,
346
  removeConfirmation: true
347
  });
php/admin-menus/class-import-menu.php CHANGED
@@ -54,26 +54,34 @@ class Code_Snippets_Import_Menu extends Code_Snippets_Admin_Menu {
54
 
55
  $count = 0;
56
  $network = is_network_admin();
 
57
  $dup_action = isset( $_POST['duplicate_action'] ) ? $_POST['duplicate_action'] : 'ignore';
 
58
 
59
  /* Loop through the uploaded files and import the snippets */
60
 
61
- foreach ( $_FILES['code_snippets_import_files']['tmp_name'] as $i => $import_file ) {
62
- $file_type = $_FILES['code_snippets_import_files']['type'][ $i ];
 
 
63
 
64
- if ( 'application/json' === $file_type ) {
65
  $result = import_snippets_json( $import_file, $network, $dup_action );
66
- } elseif ( 'text/xml' === $file_type ) {
67
  $result = import_snippets_xml( $import_file, $network, $dup_action );
68
  } else {
69
- continue;
70
  }
71
 
72
- $count += count( $result );
 
 
 
 
73
  }
74
 
75
  /* Send the amount of imported snippets to the page */
76
- $url = add_query_arg( $count > 0 ? array( 'imported' => $count ) : array( 'error' => true ) );
77
  wp_redirect( esc_url_raw( $url ) );
78
  exit;
79
  }
@@ -101,26 +109,34 @@ class Code_Snippets_Import_Menu extends Code_Snippets_Admin_Menu {
101
  * Print the status and error messages
102
  */
103
  protected function print_messages() {
104
- if ( isset( $_REQUEST['imported'] ) ) {
 
 
 
 
 
 
 
105
  echo '<div id="message" class="updated fade"><p>';
106
 
107
  $imported = intval( $_REQUEST['imported'] );
108
 
109
- printf(
110
- _n(
111
- 'Successfully imported <strong>%d</strong> snippet. <a href="%s">Have fun!</a>',
112
- 'Successfully imported <strong>%d</strong> snippets. <a href="%s">Have fun!</a>',
113
- $imported, 'code-snippets'
114
- ),
115
- $imported,
116
- code_snippets()->get_menu_url( 'manage' )
117
- );
118
 
119
- echo '</p></div>';
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- } elseif ( isset( $_REQUEST['error'] ) && $_REQUEST['error'] ) {
122
- echo '<div id="message" class="error fade"><p>';
123
- _e( 'An error occurred when processing the import file.', 'code-snippets' );
124
  echo '</p></div>';
125
  }
126
  }
54
 
55
  $count = 0;
56
  $network = is_network_admin();
57
+ $uploads = $_FILES['code_snippets_import_files'];
58
  $dup_action = isset( $_POST['duplicate_action'] ) ? $_POST['duplicate_action'] : 'ignore';
59
+ $error = false;
60
 
61
  /* Loop through the uploaded files and import the snippets */
62
 
63
+ foreach ( $uploads['tmp_name'] as $i => $import_file ) {
64
+ $ext = pathinfo( $uploads['name'][ $i ] );
65
+ $ext = $ext['extension'];
66
+ $mime_type = $uploads['type'][ $i ];
67
 
68
+ if ( 'json' === $ext || 'application/json' === $mime_type ) {
69
  $result = import_snippets_json( $import_file, $network, $dup_action );
70
+ } elseif ( 'xml' === $ext || 'text/xml' === $mime_type ) {
71
  $result = import_snippets_xml( $import_file, $network, $dup_action );
72
  } else {
73
+ $result = false;
74
  }
75
 
76
+ if ( false === $result || -1 === $result ) {
77
+ $error = true;
78
+ } else {
79
+ $count += count( $result );
80
+ }
81
  }
82
 
83
  /* Send the amount of imported snippets to the page */
84
+ $url = add_query_arg( $error ? array( 'error' => true ) : array( 'imported' => $count ) );
85
  wp_redirect( esc_url_raw( $url ) );
86
  exit;
87
  }
109
  * Print the status and error messages
110
  */
111
  protected function print_messages() {
112
+
113
+ if ( isset( $_REQUEST['error'] ) && $_REQUEST['error'] ) {
114
+ echo '<div id="message" class="error fade"><p>';
115
+ _e( 'An error occurred when processing the import files.', 'code-snippets' );
116
+ echo '</p></div>';
117
+ }
118
+
119
+ if ( isset( $_REQUEST['imported'] ) && intval( $_REQUEST['imported'] ) >= 0 ) {
120
  echo '<div id="message" class="updated fade"><p>';
121
 
122
  $imported = intval( $_REQUEST['imported'] );
123
 
124
+ if ( 0 === $imported ) {
125
+ esc_html_e( 'No snippets were imported.', 'code-snippets' );
 
 
 
 
 
 
 
126
 
127
+ } else {
128
+
129
+ printf(
130
+ _n(
131
+ 'Successfully imported <strong>%d</strong> snippet. <a href="%s">Have fun!</a>',
132
+ 'Successfully imported <strong>%d</strong> snippets. <a href="%s">Have fun!</a>',
133
+ $imported, 'code-snippets'
134
+ ),
135
+ $imported,
136
+ code_snippets()->get_menu_url( 'manage' )
137
+ );
138
+ }
139
 
 
 
 
140
  echo '</p></div>';
141
  }
142
  }
php/class-code-snippets.php CHANGED
@@ -57,6 +57,7 @@ class Code_Snippets {
57
 
58
  /* Snippet operation functions */
59
  require_once $includes_path . '/snippet-ops.php';
 
60
 
61
  /* Upgrade function */
62
  require_once $includes_path . '/upgrade.php';
57
 
58
  /* Snippet operation functions */
59
  require_once $includes_path . '/snippet-ops.php';
60
+ require_once $includes_path . '/import-export.php';
61
 
62
  /* Upgrade function */
63
  require_once $includes_path . '/upgrade.php';
php/class-list-table.php CHANGED
@@ -592,7 +592,6 @@ class Code_Snippets_List_Table extends WP_List_Table {
592
  * @uses activate_snippet() to activate snippets
593
  * @uses deactivate_snippet() to deactivate snippets
594
  * @uses delete_snippet() to delete snippets
595
- * @uses export_snippets() to export selected snippets
596
  * @uses wp_redirect() to pass the results to the current page
597
  * @uses add_query_arg() to append the results to the current URI
598
  */
@@ -637,10 +636,10 @@ class Code_Snippets_List_Table extends WP_List_Table {
637
  $result = 'deleted';
638
  }
639
  elseif ( 'export' === $action ) {
640
- export_snippets( array( $id ), $this->is_network );
641
  }
642
  elseif ( 'download' === $action ) {
643
- export_snippets( array( $id ), $this->is_network, 'php' );
644
  }
645
 
646
  if ( isset( $result ) ) {
@@ -698,11 +697,11 @@ class Code_Snippets_List_Table extends WP_List_Table {
698
  exit;
699
 
700
  case 'export-selected':
701
- export_snippets( $ids, $this->is_network );
702
  break;
703
 
704
  case 'download-selected':
705
- export_snippets( $ids, $this->is_network, 'php' );
706
  break;
707
 
708
  case 'delete-selected':
592
  * @uses activate_snippet() to activate snippets
593
  * @uses deactivate_snippet() to deactivate snippets
594
  * @uses delete_snippet() to delete snippets
 
595
  * @uses wp_redirect() to pass the results to the current page
596
  * @uses add_query_arg() to append the results to the current URI
597
  */
636
  $result = 'deleted';
637
  }
638
  elseif ( 'export' === $action ) {
639
+ export_snippets( array( $id ) );
640
  }
641
  elseif ( 'download' === $action ) {
642
+ download_snippets( array( $id ) );
643
  }
644
 
645
  if ( isset( $result ) ) {
697
  exit;
698
 
699
  case 'export-selected':
700
+ export_snippets( $ids );
701
  break;
702
 
703
  case 'download-selected':
704
+ download_snippets( $ids );
705
  break;
706
 
707
  case 'delete-selected':
php/import-export.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file includes functions for importing and exporting snippets
5
+ */
6
+
7
+
8
+ /**
9
+ *
10
+ * @access private
11
+ *
12
+ * @param $snippets
13
+ * @param null $multisite
14
+ * @param string $dup_action
15
+ *
16
+ * @return array
17
+ */
18
+ function _code_snippets_save_imported_snippets( $snippets, $multisite = null, $dup_action = 'ignore' ) {
19
+
20
+ /* Get a list of existing snippet names keyed to their IDs */
21
+ $existing_snippets = array();
22
+ if ( 'replace' == $dup_action || 'skip' === $dup_action ) {
23
+ $all_snippets = get_snippets( array(), $multisite );
24
+
25
+ foreach ( $all_snippets as $snippet ) {
26
+ if ( $snippet->name ) {
27
+ $existing_snippets[ $snippet->name ] = $snippet->id;
28
+ }
29
+ }
30
+ }
31
+
32
+ /* Save a record of the snippets which were imported */
33
+ $imported = array();
34
+
35
+ /* Loop through the provided snippets */
36
+ foreach ( $snippets as $snippet ) {
37
+
38
+ /* Check if the snippet already exists */
39
+ if ( 'ignore' !== $dup_action && isset( $existing_snippets[ $snippet->name ] ) ) {
40
+
41
+ /* If so, either overwrite the existing ID, or skip this import */
42
+ if ( 'replace' === $dup_action ) {
43
+ $snippet->id = $existing_snippets[ $snippet->name ];
44
+ } elseif ( 'skip' === $dup_action ) {
45
+ continue;
46
+ }
47
+ }
48
+
49
+ /* Save the snippet and increase the counter if successful */
50
+ if ( $snippet_id = save_snippet( $snippet ) ) {
51
+ $imported[] = $snippet_id;
52
+ }
53
+ }
54
+
55
+ return $imported;
56
+ }
57
+
58
+ /**
59
+ * Imports snippets from a JSON file
60
+ *
61
+ * @since 2.9.7
62
+ *
63
+ * @uses save_snippet() to add the snippets to the database
64
+ *
65
+ * @param string $file The path to the file to import
66
+ * @param bool|null $multisite Import into network-wide table or site-wide table?
67
+ * @param string $dup_action Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'
68
+ *
69
+ * @return array|bool An array of imported snippet IDs on success, false on failure
70
+ */
71
+ function import_snippets_json( $file, $multisite = null, $dup_action = 'ignore' ) {
72
+
73
+ if ( ! file_exists( $file ) || ! is_file( $file ) ) {
74
+ return false;
75
+ }
76
+
77
+ $raw_data = file_get_contents( $file );
78
+ $data = json_decode( $raw_data, true );
79
+ $snippets = array();
80
+
81
+ /* Reformat the data into snippet objects */
82
+ foreach ( $data['snippets'] as $snippet ) {
83
+ $snippet = new Code_Snippet( $snippet );
84
+ $snippet->network = $multisite;
85
+ $snippets[] = $snippet;
86
+ }
87
+
88
+ $imported = _code_snippets_save_imported_snippets( $snippets, $multisite, $dup_action );
89
+ do_action( 'code_snippets/import/json', $file, $multisite );
90
+ return $imported;
91
+ }
92
+
93
+ /**
94
+ * Imports snippets from an XML file
95
+ *
96
+ * @since 2.0
97
+ *
98
+ * @uses save_snippet() to add the snippets to the database
99
+ *
100
+ * @param string $file The path to the file to import
101
+ * @param bool|null $multisite Import into network-wide table or site-wide table?
102
+ * @param string $dup_action Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'
103
+ *
104
+ * @return array|bool An array of imported snippet IDs on success, false on failure
105
+ */
106
+ function import_snippets_xml( $file, $multisite = null, $dup_action = 'ignore' ) {
107
+
108
+ if ( ! file_exists( $file ) || ! is_file( $file ) ) {
109
+ return false;
110
+ }
111
+
112
+ $dom = new DOMDocument( '1.0', get_bloginfo( 'charset' ) );
113
+ $dom->load( $file );
114
+
115
+ $snippets_xml = $dom->getElementsByTagName( 'snippet' );
116
+ $fields = array( 'name', 'description', 'desc', 'code', 'tags', 'scope' );
117
+
118
+ $snippets = array();
119
+
120
+ /* Loop through all snippets */
121
+
122
+ /** @var DOMElement $snippet_xml */
123
+ foreach ( $snippets_xml as $snippet_xml ) {
124
+ $snippet = new Code_Snippet();
125
+ $snippet->network = $multisite;
126
+
127
+ /* Build a snippet object by looping through the field names */
128
+ foreach ( $fields as $field_name ) {
129
+
130
+ /* Fetch the field element from the document */
131
+ $field = $snippet_xml->getElementsByTagName( $field_name )->item( 0 );
132
+
133
+ /* If the field element exists, add it to the snippet object */
134
+ if ( isset( $field->nodeValue ) ) {
135
+ $snippet->set_field( $field_name, $field->nodeValue );
136
+ }
137
+ }
138
+
139
+ /* Get scope from attribute */
140
+ $scope = $snippet_xml->getAttribute( 'scope' );
141
+ if ( ! empty( $scope ) ) {
142
+ $snippet->scope = $scope;
143
+ }
144
+
145
+ $snippets[] = $snippet;
146
+ }
147
+
148
+ $imported = _code_snippets_save_imported_snippets( $snippets, $dup_action, $multisite );
149
+ do_action( 'code_snippets/import/xml', $file, $multisite );
150
+ return $imported;
151
+ }
152
+
153
+ /**
154
+ * Set up the current page to act like a downloadable file instead of being shown in the browser
155
+ *
156
+ * @param string $format
157
+ * @param array $ids
158
+ * @param string $table_name
159
+ * @param string $mime_type
160
+ *
161
+ * @return array
162
+ */
163
+ function code_snippets_prepare_export( $format, $ids, $table_name = '', $mime_type = '' ) {
164
+ global $wpdb;
165
+
166
+ /* Fetch the snippets from the database */
167
+ if ( '' === $table_name ) {
168
+ $table_name = code_snippets()->db->get_table_name();
169
+ }
170
+
171
+ if ( count( $ids ) ) {
172
+
173
+ $sql = sprintf(
174
+ 'SELECT * FROM %s WHERE id IN (%s)', $table_name,
175
+ implode( ',', array_fill( 0, count( $ids ), '%d' ) )
176
+ );
177
+
178
+ $snippets = $wpdb->get_results( $wpdb->prepare( $sql, $ids ), ARRAY_A );
179
+
180
+ } else {
181
+ $snippets = array();
182
+ }
183
+
184
+ /* Build the export filename */
185
+ if ( 1 == count( $ids ) ) {
186
+ /* If there is only snippet to export, use its name instead of the site name */
187
+ $first_snippet = new Code_Snippet( $snippets[0] );
188
+ $title = strtolower( $first_snippet->name );
189
+ } else {
190
+ /* Otherwise, use the site name as set in Settings > General */
191
+ $title = strtolower( get_bloginfo( 'name' ) );
192
+ }
193
+
194
+ $filename = "{$title}.code-snippets.{$format}";
195
+ $filename = apply_filters( 'code_snippets/export/filename', $filename, $title );
196
+
197
+ /* Set HTTP headers */
198
+ header( 'Content-Disposition: attachment; filename=' . sanitize_file_name( $filename ) );
199
+
200
+ if ( '' !== $mime_type ) {
201
+ header( "Content-Type: $mime_type; charset=" . get_bloginfo( 'charset' ) );
202
+ }
203
+
204
+ /* Return the retrieved snippets to build the rest of the export file */
205
+ return $snippets;
206
+ }
207
+
208
+ /**
209
+ * Export snippets to a downloadable PHP file
210
+ *
211
+ * @param $ids
212
+ * @param $table_name
213
+ */
214
+ function download_snippets( $ids, $table_name = '' ) {
215
+ $snippets = code_snippets_prepare_export( 'php', $ids, $table_name );
216
+
217
+ echo "<?php\n";
218
+
219
+ /* Loop through the snippets */
220
+ foreach ( $snippets as $snippet ) {
221
+ $snippet = new Code_Snippet( $snippet );
222
+
223
+ echo "\n/**\n * {$snippet->name}\n";
224
+
225
+ if ( ! empty( $snippet->desc ) ) {
226
+
227
+ /* Convert description to PhpDoc */
228
+ $desc = strip_tags( str_replace( "\n", "\n * ", $snippet->desc ) );
229
+
230
+ echo " *\n * $desc\n";
231
+ }
232
+
233
+ echo " */\n{$snippet->code}\n";
234
+ }
235
+
236
+ exit;
237
+ }
238
+
239
+ /**
240
+ * Export snippets in JSON format
241
+ *
242
+ * @param array $ids list of snippet IDs to export
243
+ * @param string $table_name name of the database table to fetch snippets from
244
+ */
245
+ function export_snippets( $ids, $table_name = '' ) {
246
+ $raw_snippets = code_snippets_prepare_export( 'json', $ids, $table_name, 'application/json' );
247
+ $final_snippets = array();
248
+
249
+ foreach ( $raw_snippets as $snippet ) {
250
+ $snippet = new Code_Snippet( $snippet );
251
+
252
+ $fields = array( 'name', 'desc', 'tags', 'scope', 'code' );
253
+ $final_snippet = array();
254
+
255
+ foreach ( $fields as $field ) {
256
+ if ( ! empty( $snippet->$field ) ) {
257
+ $final_snippet[ $field ] = $snippet->$field;
258
+ }
259
+ }
260
+
261
+ if ( $final_snippet ) {
262
+ $final_snippets[] = $final_snippet;
263
+ }
264
+ }
265
+
266
+ $data = array(
267
+ 'generator' => 'Code Snippets v' . CODE_SNIPPETS_VERSION,
268
+ 'date_created' => date( 'Y-m-d H:i' ),
269
+ 'snippets' => $final_snippets,
270
+ );
271
+
272
+ echo wp_json_encode( $data, apply_filters( 'code_snippets/export/json_encode_options', 0 ) );
273
+ exit;
274
+ }
php/snippet-ops.php CHANGED
@@ -325,171 +325,6 @@ function update_snippet_fields( $snippet_id, $fields, $network = null ) {
325
  do_action( 'code_snippets/update_snippet', $snippet->id, $table );
326
  }
327
 
328
- /**
329
- * Imports snippets from a JSON file
330
- *
331
- * @since 2.9.7
332
- *
333
- * @uses save_snippet() to add the snippets to the database
334
- *
335
- * @param string $file The path to the file to import
336
- * @param bool|null $multisite Import into network-wide table or site-wide table?
337
- * @param string $dup_action Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'
338
- *
339
- * @return array|bool An array of imported snippet IDs on success, false on failure
340
- */
341
- function import_snippets_json( $file, $multisite = null, $dup_action = 'ignore' ) {
342
-
343
- if ( ! file_exists( $file ) || ! is_file( $file ) ) {
344
- return false;
345
- }
346
-
347
- $raw_data = file_get_contents( $file );
348
- $data = json_decode( $raw_data, true );
349
-
350
- $imported = array();
351
-
352
- /* Get a list of existing snippet names keyed to their IDs */
353
- $existing_snippets = array();
354
- if ( 'replace' == $dup_action || 'skip' === $dup_action ) {
355
- $all_snippets = get_snippets( array(), $multisite );
356
-
357
- foreach ( $all_snippets as $snippet ) {
358
- if ( $snippet->name ) {
359
- $existing_snippets[ $snippet->name ] = $snippet->id;
360
- }
361
- }
362
- }
363
-
364
- /* Loop through all snippets */
365
-
366
- /** @var DOMElement $snippet_xml */
367
- foreach ( $data['snippets'] as $snippet ) {
368
- $snippet = new Code_Snippet( $snippet );
369
- $snippet->network = $multisite;
370
-
371
- if ( 'ignore' !== $dup_action && isset( $existing_snippets[ $snippet->name ] ) ) {
372
-
373
- if ( 'replace' === $dup_action ) {
374
- $snippet->id = $existing_snippets[ $snippet->name ];
375
- } elseif ( 'skip' === $dup_action ) {
376
- continue;
377
- }
378
- }
379
-
380
- /* Save the snippet and increase the counter if successful */
381
- if ( $snippet_id = save_snippet( $snippet ) ) {
382
- $imported[] = $snippet_id;
383
- }
384
- }
385
-
386
- do_action( 'code_snippets/import/json', $file, $multisite );
387
- return $imported;
388
- }
389
-
390
- /**
391
- * Imports snippets from an XML file
392
- *
393
- * @since 2.0
394
- *
395
- * @uses save_snippet() to add the snippets to the database
396
- *
397
- * @param string $file The path to the file to import
398
- * @param bool|null $multisite Import into network-wide table or site-wide table?
399
- * @param string $dup_action Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'
400
- *
401
- * @return array|bool An array of imported snippet IDs on success, false on failure
402
- */
403
- function import_snippets_xml( $file, $multisite = null, $dup_action = 'ignore' ) {
404
-
405
- if ( ! file_exists( $file ) || ! is_file( $file ) ) {
406
- return false;
407
- }
408
-
409
- $dom = new DOMDocument( '1.0', get_bloginfo( 'charset' ) );
410
- $dom->load( $file );
411
-
412
- $snippets_xml = $dom->getElementsByTagName( 'snippet' );
413
- $fields = array( 'name', 'description', 'desc', 'code', 'tags', 'scope' );
414
- $imported = array();
415
-
416
- /* Get a list of existing snippet names keyed to their IDs */
417
- $existing_snippets = array();
418
- if ( 'replace' == $dup_action || 'skip' === $dup_action ) {
419
- $all_snippets = get_snippets( array(), $multisite );
420
-
421
- foreach ( $all_snippets as $snippet ) {
422
- if ( $snippet->name ) {
423
- $existing_snippets[ $snippet->name ] = $snippet->id;
424
- }
425
- }
426
- }
427
-
428
- /* Loop through all snippets */
429
-
430
- /** @var DOMElement $snippet_xml */
431
- foreach ( $snippets_xml as $snippet_xml ) {
432
- $snippet = new Code_Snippet();
433
- $snippet->network = $multisite;
434
-
435
- /* Build a snippet object by looping through the field names */
436
- foreach ( $fields as $field_name ) {
437
-
438
- /* Fetch the field element from the document */
439
- $field = $snippet_xml->getElementsByTagName( $field_name )->item( 0 );
440
-
441
- /* If the field element exists, add it to the snippet object */
442
- if ( isset( $field->nodeValue ) ) {
443
- $snippet->set_field( $field_name, $field->nodeValue );
444
- }
445
- }
446
-
447
- /* Get scope from attribute */
448
- $scope = $snippet_xml->getAttribute( 'scope' );
449
- if ( ! empty( $scope ) ) {
450
- $snippet->scope = $scope;
451
- }
452
-
453
- if ( 'ignore' !== $dup_action && isset( $existing_snippets[ $snippet->name ] ) ) {
454
- if ( 'replace' === $dup_action ) {
455
- $snippet->id = $existing_snippets[ $snippet->name ];
456
- } elseif ( 'skip' === $dup_action ) {
457
- continue;
458
- }
459
- }
460
-
461
- /* Save the snippet and increase the counter if successful */
462
- if ( $snippet_id = save_snippet( $snippet ) ) {
463
- $imported[] = $snippet_id;
464
- }
465
- }
466
-
467
- do_action( 'code_snippets/import/xml', $file, $multisite );
468
- return $imported;
469
- }
470
-
471
- /**
472
- * Exports snippets as an XML, JSON or PHP file
473
- *
474
- * @since 2.0
475
- * @uses Code_Snippets_Export to export selected snippets
476
- * @uses code_snippets()->db->get_table_name() to dynamically retrieve the name of the snippet table
477
- *
478
- * @param array $ids The IDs of the snippets to export
479
- * @param bool|null $multisite Is the snippet a network-wide or site-wide snippet?
480
- * @param string $format Export to json, xml or php?
481
- */
482
- function export_snippets( $ids, $multisite = null, $format = 'json' ) {
483
- $table = code_snippets()->db->get_table_name( $multisite );
484
-
485
- if ( ! class_exists( 'Code_Snippets_Export' ) ) {
486
- require_once plugin_dir_path( CODE_SNIPPETS_FILE ) . 'php/class-export.php';
487
- }
488
-
489
- $class = new Code_Snippets_Export( $ids, $table, $format );
490
- $class->do_export();
491
- }
492
-
493
  /**
494
  * Execute a snippet
495
  *
325
  do_action( 'code_snippets/update_snippet', $snippet->id, $table );
326
  }
327
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  /**
329
  * Execute a snippet
330
  *
php/views/import.php CHANGED
@@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) {
35
 
36
  <label for="upload"><?php _e( 'Choose a file from your computer:', 'code-snippets' ); ?></label>
37
  <?php _e( '(Maximum size: 8MB)', 'code-snippets' ); ?>
38
- <input type="file" id="upload" name="code_snippets_import_files[]" size="25" accept="text/xml,application/json" multiple="multiple">
39
  </p>
40
 
41
  <h2>Duplicate Snippets</h2>
35
 
36
  <label for="upload"><?php _e( 'Choose a file from your computer:', 'code-snippets' ); ?></label>
37
  <?php _e( '(Maximum size: 8MB)', 'code-snippets' ); ?>
38
+ <input type="file" id="upload" name="code_snippets_import_files[]" size="25" accept="application/json,text/xml" multiple="multiple">
39
  </p>
40
 
41
  <h2>Duplicate Snippets</h2>
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: bungeshea
3
  Donate link: https://bungeshea.com/donate/
4
  Tags: code-snippets, snippets, code, php, network, multisite
5
  Requires at least: 3.6
6
- Tested up to: 4.9.2
7
- Stable tag: 2.10.0
8
  License: MIT
9
  License URI: license.txt
10
 
@@ -111,6 +111,11 @@ That's fantastic! Fork the [repository on GitHub](http://github.com/sheabunge/co
111
 
112
  == Changelog ==
113
 
 
 
 
 
 
114
  = 2.10.0 (18 Jan 2018) =
115
  * Improved: Added support for importing from multiple export files at once
116
  * Improved: Unbold the titles of inactive snippets for greater visual distinction
3
  Donate link: https://bungeshea.com/donate/
4
  Tags: code-snippets, snippets, code, php, network, multisite
5
  Requires at least: 3.6
6
+ Tested up to: 4.9.4
7
+ Stable tag: 2.10.1.1
8
  License: MIT
9
  License URI: license.txt
10
 
111
 
112
  == Changelog ==
113
 
114
+ = 2.10.1 (10 Feb 2018) =
115
+ * Fixed: Prevent errors when trying to export no snippets
116
+ * Fixed: Use wp_json_encode() to encode export data
117
+ * Fixed: Check both the file extension and MIME type of uploaded import files
118
+
119
  = 2.10.0 (18 Jan 2018) =
120
  * Improved: Added support for importing from multiple export files at once
121
  * Improved: Unbold the titles of inactive snippets for greater visual distinction