PluginProbe
Tag Groups is the Advanced Way to Display Your Taxonomy Terms / trunk
Tag Groups is the Advanced Way to Display Your Taxonomy Terms vtrunk
2.2.2 2.2.1 2.2.0 trunk 1.40.0 1.40.2 1.41.0 1.42.1 1.43.0 1.43.1 1.43.10 1.43.10.1 1.43.2 1.43.3 1.43.4 1.43.5 1.43.6 1.43.7 1.43.9 1.44.0 1.44.1 1.44.3 1.44.3.1 2.0.0 2.0.1 All 36 releases
tag-groups / include / admin / class.import.php

class.import.php in Tag Groups is the Advanced Way to Display Your Taxonomy Terms trunk, at include/admin/class.import.php

290 lines 13.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * @package Tag Groups
5 * @author Christoph Amthor
6 * @copyright 2020 Christoph Amthor (@ Chatty Mango, chattymango.com)
7 * @license GPL-3.0+
8 */
9
10 if (! class_exists('TagGroups_Import')) {
11 /**
12 *
13 * @since 1.38.0
14 */
15 // phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace, Squiz.Classes.ValidClassName.NotCamelCaps -- Legacy class structure
16 class TagGroups_Import
17 {
18 /**
19 * File contents for import
20 *
21 * @var string
22 */
23 private $contents;
24 /**
25 * type of data in the imported file
26 *
27 * @var string
28 */
29 private $file_type;
30 /**
31 * whether an error occured
32 *
33 * @var integer
34 */
35 private $error;
36
37 // phpcs:ignore Squiz.Scope.MethodScope.Missing -- Legacy code
38 function __construct()
39 {
40
41 $this->error = false;
42 }
43
44
45 /**
46 * Determines the type of imported file
47 *
48 * @return void
49 */
50 // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, Squiz.Scope.MethodScope.Missing -- Legacy method naming
51 function determine_file_type()
52 {
53
54 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- File upload verification
55 if (! isset($_FILES['settings_file'])) {
56 die("File missing");
57 }
58
59 // Check file name, but allow for some additional characters in file name since downloading multiple times may add something to the original name.
60 // Allow extension txt for backwards compatibility
61 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- File upload validation
62 preg_match('/^tag_groups_settings-\w{10}[\w,\s-]*\.((txt)|(json))$/', $_FILES['settings_file']['name'], $matches_settings);
63 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- File upload validation
64 preg_match('/^tag_groups_terms-\w{10}[\w,\s-]*\.json$/', $_FILES['settings_file']['name'], $matches_terms);
65 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- File upload validation
66 if (! empty($matches_settings) && ! empty($matches_settings[0]) && $matches_settings[0] == $_FILES['settings_file']['name']) {
67 $this->file_type = 'settings';
68 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- File upload validation
69 } elseif (! empty($matches_terms) && ! empty($matches_terms[0]) && $matches_terms[0] == $_FILES['settings_file']['name']) {
70 $this->file_type = 'terms';
71 } else {
72 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- File upload validation
73 if (! empty($_FILES['settings_file']['name'])) {
74 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- File upload validation
75 $file_info = ' ' . $_FILES['settings_file']['name'];
76 } else {
77 $file_info = '';
78 }
79
80 $this->error = true;
81 TagGroups_Admin_Notice::add('error', __('Error uploading the file.', 'tag-groups') . $file_info);
82 }
83 }
84
85
86 /**
87 * Reads the contents
88 *
89 * @return void
90 */
91 // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, Squiz.Scope.MethodScope.Missing -- Legacy method naming
92 function read_file()
93 {
94
95 if ($this->error) {
96 return;
97 }
98
99 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- File upload verification
100 if (! isset($_FILES['settings_file'])) {
101 die("File missing");
102 }
103
104 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown -- Reads PHP's local upload temporary file, not a remote URL.
105 $this->contents = @file_get_contents($_FILES['settings_file']['tmp_name']);
106 if (false === $this->contents) {
107 $this->error = true;
108 TagGroups_Admin_Notice::add('error', __('Error reading the file.', 'tag-groups'));
109 }
110 }
111
112
113 /**
114 * Parses the content and saves the imported data to the database, depending on the file type
115 *
116 * @return void
117 */
118 // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, Squiz.Scope.MethodScope.Missing -- Legacy method naming
119 function parse_and_save()
120 {
121
122 if ($this->error) {
123 return;
124 }
125
126 if ('settings' == $this->file_type) {
127 $this->parse_and_save_options();
128 } elseif ('terms' == $this->file_type) {
129 $this->parse_and_save_terms();
130 }
131 }
132
133
134 /**
135 * Parses the content and saves the imported data to the options
136 *
137 * @return void
138 */
139 // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, Squiz.Scope.MethodScope.Missing -- Legacy method naming
140 function parse_and_save_options()
141 {
142
143 $options = @json_decode($this->contents, true);
144 if (empty($options) || ! is_array($options) || $options['name'] != 'tag_groups_options') {
145 $this->error = true;
146 TagGroups_Admin_Notice::add('error', __('Error parsing the file.', 'tag-groups'));
147 return;
148 }
149
150 $available_options = TagGroups_Options::get_available_options();
151 $count_changed = 0;
152 // import only whitelisted options
153 foreach ($available_options as $key => $value) {
154 if ($available_options[ $key ]['export'] && isset($options[ $key ])) {
155 $result = TagGroups_Options::update_option($key, $options[ $key ]) ? 1 : 0;
156 if (1 == $result) {
157 TagGroups_Error::verbose_log('[Tag Groups] We updated ' . $key);
158 }
159
160 $count_changed += $result;
161 }
162 }
163
164 if (! isset($options['date'])) {
165 $options['date'] = ' - ' . __('date unknown', 'tag-groups') . ' - ';
166 }
167
168 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing -- File upload validation
169 TagGroups_Admin_Notice::add('success', sprintf(
170 /* translators: 1: Filename, 2: Plugin version, 3: Export file creation date. */
171 __('Your settings and groups have been imported from the file %1$s (created with plugin version %2$s on %3$s).', 'tag-groups'),
172 '<b>' . $_FILES['settings_file']['name'] . '</b>', //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing
173 $options['version'],
174 $options['date']
175 ) . '</p><p>' .
176 /* translators: %d is the number of options */
177 sprintf(_n('%d option was added or changed.', '%d options were added or changed.', $count_changed, 'tag-groups'), $count_changed));
178 do_action('tag_groups_settings_imported');
179 }
180
181
182 /**
183 * Parses the content and saves the imported data to the terms
184 *
185 * @return void
186 */
187 // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps, Squiz.Scope.MethodScope.Missing -- Legacy method naming
188 function parse_and_save_terms()
189 {
190
191 $terms = @json_decode($this->contents, true);
192 if (empty($terms) || ! is_array($terms) || $terms['name'] != 'tag_groups_terms') {
193 $this->error = true;
194 TagGroups_Admin_Notice::add('error', __('Error parsing the file.', 'tag-groups'));
195 return;
196 }
197
198 $count_processed = 0;
199 $count_changed = 0;
200 $count_saved = 0;
201 remove_all_filters('pre_insert_term');
202 remove_all_filters('wp_insert_term_data');
203 remove_all_actions('edit_terms');
204 remove_all_actions('edited_terms');
205 remove_all_actions('edit_term_taxonomy');
206 remove_all_actions('edited_term_taxonomy');
207 remove_all_actions('edit_term');
208 remove_all_actions('edited_term');
209 foreach ($terms['terms'] as $term) {
210 $is_term_saved = false;
211 $wp_term = get_term($term['term_id']);
212 // change only terms with the same name, else create new one
213 if (empty($wp_term)) {
214 // check by name - maybe it has a different ID
215 $term_by_name = get_term_by('name', $term['name'], $term['taxonomy']);
216 if ($term_by_name && is_object($term_by_name)) {
217 $term['term_id'] = $term_by_name->term_id;
218 } else {
219 $inserted_term = wp_insert_term($term['name'], $term['taxonomy']);
220 if (is_array($inserted_term)) {
221 $is_term_saved = true;
222 $term['term_id'] = $inserted_term['term_id'];
223 } else {
224 // an error occured
225
226 TagGroups_Error::log('[Tag Groups] Problem inserting ' . $term['name']);
227 continue;
228 }
229 }
230
231 $wp_term = get_term($term['term_id']);
232 }
233
234 $tg_term = new TagGroups_Term($term['term_id']);
235 if (! $tg_term->has_exactly_groups($term['term_group'])) {
236 $tg_term->set_group($term['term_group'])->save();
237 $count_changed++;
238 }
239
240
241 if (
242 $term['name'] != $wp_term->name ||
243 $term['slug'] != $wp_term->slug ||
244 $term['taxonomy'] != $wp_term->taxonomy ||
245 $term['description'] != $wp_term->description || // might lead to "false positives" if description contains invisible HTML
246 $term['parent'] != $wp_term->parent
247 ) {
248 // We update the default term data, except for term_group
249 unset($term['term_group']);
250 remove_all_actions("edit_{$term['taxonomy']}");
251 remove_all_actions("edited_{$term['taxonomy']}");
252 $result = wp_update_term($term['term_id'], $term['taxonomy'], $term);
253 if (is_array($result)) {
254 $is_term_saved = true;
255 }
256 }
257
258 if ($is_term_saved) {
259 $count_saved++;
260 }
261
262 $count_processed++;
263 }
264
265
266 if (! isset($terms['date'])) {
267 $terms['date'] = ' - ' . __('date unknown', 'tag-groups') . ' - ';
268 }
269
270 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- File upload validation
271 TagGroups_Admin_Notice::add('success', sprintf(
272 /* translators: 1: Filename, 2: Plugin version, 3: Export file creation date. */
273 __('Your terms have been imported from the file %1$s (created with plugin version %2$s on %3$s).', 'tag-groups'),
274 '<b>' . $_FILES['settings_file']['name'] . '</b>', //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.NonceVerification.Missing
275 $terms['version'],
276 $terms['date']
277 ) . '</p><p>' .
278 /* translators: %d is the number of terms processed */
279 sprintf(_n('We processed %d term.', 'We processed %d terms.', $count_processed, 'tag-groups'), $count_processed) . '</p><p>' .
280 /* translators: %d is the number of terms saved */
281 sprintf(_n('We saved %d term.', 'We saved %d terms.', $count_saved, 'tag-groups'), $count_saved) . '</p><p>' .
282 /* translators: %d is the number of terms updated */
283 sprintf(_n('The group info of %d term was updated.', 'The group info of %d terms was updated.', $count_changed, 'tag-groups'), $count_changed));
284 do_action('tag_groups_terms_imported');
285 }
286 }
287
288
289 }
290