PluginProbe
Code Snippets / 3.8.1
Code Snippets v3.8.1
3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 3.0.1 All 64 releases
code-snippets / php / export / class-import.php

class-import.php in Code Snippets 3.8.1, at php/export/class-import.php

209 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Code_Snippets;
4
5 use DOMDocument;
6
7 /**
8 * Handles importing snippets from export files into the site
9 *
10 * @package Code_Snippets
11 * @since 3.0.0
12 *
13 * phpcs:disable WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
14 * phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
15 */
16 class Import {
17
18 /**
19 * Path to file to import.
20 *
21 * @var string
22 */
23 private string $file;
24
25 /**
26 * Whether snippets should be imported into the network-wide or site-wide table.
27 *
28 * @var bool
29 */
30 private bool $multisite;
31
32 /**
33 * Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'.
34 *
35 * @var string
36 */
37 private string $dup_action;
38
39 /**
40 * Class constructor.
41 *
42 * @param string $file The path to the file to import.
43 * @param bool|null $network Import into network-wide table (true) or site-wide table (false).
44 * @param string $dup_action Action to take if duplicate snippets are detected. Can be 'skip', 'ignore', or 'replace'.
45 */
46 public function __construct( string $file, ?bool $network = null, string $dup_action = 'ignore' ) {
47 $this->file = $file;
48 $this->multisite = DB::validate_network_param( $network );
49 $this->dup_action = $dup_action;
50 }
51
52 /**
53 * Imports snippets from a JSON file.
54 *
55 * @return array<integer>|bool An array of imported snippet IDs on success, false on failure
56 */
57 public function import_json() {
58 if ( ! file_exists( $this->file ) || ! is_file( $this->file ) ) {
59 return false;
60 }
61
62 $raw_data = file_get_contents( $this->file );
63 $data = json_decode( $raw_data, true );
64 $snippets = array();
65
66 // Reformat the data into snippet objects.
67 foreach ( $data['snippets'] as $snippet_data ) {
68 $snippet = new Snippet();
69 $snippet->network = $this->multisite;
70
71 $import_fields = [
72 'name',
73 'desc',
74 'description',
75 'code',
76 'tags',
77 'scope',
78 'priority',
79 'shared_network',
80 'modified',
81 'cloud_id',
82 ];
83
84 foreach ( $import_fields as $field ) {
85 if ( isset( $snippet_data[ $field ] ) ) {
86 $snippet->set_field( $field, $snippet_data[ $field ] );
87 }
88 }
89
90 $snippets[] = $snippet;
91 }
92
93 $imported = $this->save_snippets( $snippets );
94
95 do_action( 'code_snippets/import/json', $this->file, $this->multisite );
96 return $imported;
97 }
98
99 /**
100 * Imports snippets from an XML file
101 *
102 * @return array<integer>|bool An array of imported snippet IDs on success, false on failure
103 */
104 public function import_xml() {
105 if ( ! file_exists( $this->file ) || ! is_file( $this->file ) ) {
106 return false;
107 }
108
109 $dom = new DOMDocument( '1.0', get_bloginfo( 'charset' ) );
110 $dom->load( $this->file );
111
112 $snippets_xml = $dom->getElementsByTagName( 'snippet' );
113 $fields = array( 'name', 'description', 'desc', 'code', 'tags', 'scope' );
114
115 $snippets = array();
116
117 foreach ( $snippets_xml as $snippet_xml ) {
118 $snippet = new Snippet();
119 $snippet->network = $this->multisite;
120
121 // Build a snippet object by looping through the field names.
122 foreach ( $fields as $field_name ) {
123
124 // Fetch the field element from the document.
125 $field = $snippet_xml->getElementsByTagName( $field_name )->item( 0 );
126
127 // If the field element exists, add it to the snippet object.
128 if ( isset( $field->nodeValue ) ) {
129 $snippet->set_field( $field_name, $field->nodeValue );
130 }
131 }
132
133 // Get scope from attribute.
134 $scope = $snippet_xml->getAttribute( 'scope' );
135 if ( ! empty( $scope ) ) {
136 $snippet->scope = $scope;
137 }
138
139 $snippets[] = $snippet;
140 }
141
142 $imported = $this->save_snippets( $snippets );
143 do_action( 'code_snippets/import/xml', $this->file, $this->multisite );
144
145 return $imported;
146 }
147
148 /**
149 * Fetch a list of existing snippets for checking duplicates.
150 *
151 * @return array<string, integer>
152 */
153 private function fetch_existing_snippets(): array {
154 $existing_snippets = array();
155
156 if ( 'replace' === $this->dup_action || 'skip' === $this->dup_action ) {
157 $all_snippets = get_snippets( array(), $this->multisite );
158
159 foreach ( $all_snippets as $snippet ) {
160 if ( $snippet->name ) {
161 $existing_snippets[ $snippet->name ] = $snippet->id;
162 }
163 }
164 }
165
166 return $existing_snippets;
167 }
168
169 /**
170 * Save imported snippets to the database
171 *
172 * @access private
173 *
174 * @param array<Snippet> $snippets List of snippets to save.
175 *
176 * @return array<integer> IDs of imported snippets.
177 */
178 private function save_snippets( array $snippets ): array {
179 $existing_snippets = $this->fetch_existing_snippets();
180 $imported = array();
181
182 foreach ( $snippets as $snippet ) {
183
184 // Check if the snippet already exists.
185 if ( 'ignore' !== $this->dup_action && isset( $existing_snippets[ $snippet->name ] ) ) {
186
187 // If so, either overwrite the existing ID, or skip this import.
188 if ( 'replace' === $this->dup_action ) {
189 $snippet->id = $existing_snippets[ $snippet->name ];
190 } elseif ( 'skip' === $this->dup_action ) {
191 continue;
192 }
193 }
194
195 // Save the snippet and increase the counter if successful.
196 $saved_snippet = save_snippet( $snippet );
197
198 // Get ID of the saved snippet as save_snippet() returns complete snippet object.
199 $snippet_id = $saved_snippet->id;
200
201 if ( $snippet_id ) {
202 $imported[] = $snippet_id;
203 }
204 }
205
206 return $imported;
207 }
208 }
209