PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.15.0
Import WP – CSV & XML Import Export for WordPress v2.15.0
2.15.1 2.15.0 2.14.24 2.14.23 2.7.0 2.7.1 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 2.9.1 All 144 releases
jc-importer / class / Common / Importer / Mapper / PostMapper.php

PostMapper.php in Import WP – CSV & XML Import Export for WordPress 2.15.0, at class/Common/Importer/Mapper/PostMapper.php

471 lines 14.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ImportWP\Common\Importer\Mapper;
4
5 use ImportWP\Common\Importer\Exception\MapperException;
6 use ImportWP\Common\Importer\MapperInterface;
7 use ImportWP\Common\Importer\ParsedData;
8 use ImportWP\Common\Util\Logger;
9
10 class PostMapper extends AbstractMapper implements MapperInterface
11 {
12 /**
13 * Reserved Field Names for post table
14 * @var array
15 */
16 protected $_post_fields = array(
17 'ID',
18 'menu_order',
19 'comment_status',
20 'ping_status',
21 'pinged',
22 'post_author',
23 'post_category',
24 'post_content',
25 'post_date',
26 'post_date_gmt',
27 'post_excerpt',
28 'post_name',
29 'post_parent',
30 'post_password',
31 'post_status',
32 'post_title',
33 'post_type',
34 'tags_input',
35 'to_ping',
36 'tax_input'
37 );
38
39 protected $_query_vars = array(
40 'post_name' => 'name',
41 'ID' => 'p'
42 );
43
44 public function setup()
45 {
46 wp_defer_term_counting(true);
47 wp_defer_comment_counting(true);
48 }
49
50 public function teardown()
51 {
52 wp_defer_term_counting(false);
53 wp_defer_comment_counting(false);
54 }
55
56 public function exists(ParsedData $data)
57 {
58 list($unique_fields, $meta_args, $has_unique_field) = $this->exists_get_identifier($data);
59 $unique_field_found = false;
60
61 $post_type = $this->importer->getSetting('post_type');
62 $post_status = 'any, trash, future';
63
64 $query_args = array(
65 'post_type' => $post_type,
66 'post_status' => $post_status,
67 'fields' => 'ids',
68 'cache_results' => false,
69 'update_post_meta_cache' => false,
70 'update_post_term_cache' => false,
71 'no_found_rows' => true,
72 );
73
74 if (!$has_unique_field) {
75 foreach ($unique_fields as $field) {
76
77 // check all groups for a unique value
78 $unique_value = $this->find_unique_field_in_data($data, $field);
79
80 if ($this->has_identifier_value($unique_value)) {
81 $has_unique_field = true;
82
83 if (in_array($field, $this->_post_fields, true)) {
84
85 if (array_key_exists($field, $this->_query_vars)) {
86 $query_args[$this->_query_vars[$field]] = $unique_value;
87 } else {
88 switch ($field) {
89 case 'post_title':
90 $query_args['title'] = $unique_value;
91 break;
92 default:
93 $query_args[$field] = $unique_value;
94 break;
95 }
96 }
97 } else {
98 $meta_args[] = array(
99 'key' => $field,
100 'value' => $unique_value
101 );
102 }
103 $unique_field_found = $field;
104 $this->set_unique_identifier_settings($unique_field_found, $unique_value);
105 break;
106 }
107 }
108 }
109
110
111
112
113 if (!$has_unique_field) {
114
115 // fallback to post_title
116 $unique_value = $data->getValue('post_title');
117 if (!$this->has_identifier_value($unique_value) || !$this->importer->has_legacy_unique_identifier()) {
118 throw new MapperException(__('No unique identifier value present. Check that Permissions has a unique identifier set and this row has a non-empty value. File column references are stored as _iwp_ref_uid.', 'jc-importer'));
119 }
120
121 $query_args['title'] = $unique_value;
122 $this->set_unique_identifier_settings('title', $unique_value);
123 }
124
125 if (!empty($meta_args)) {
126 $query_args['meta_query'] = $meta_args;
127 }
128
129 $query_args = apply_filters('iwp/importer/mapper/post_exists_query', $query_args);
130 Logger::debug("PostMapper::exists -query=" . wp_json_encode($query_args));
131
132 $query = new \WP_Query($query_args);
133 if ($query->post_count > 1) {
134 throw new MapperException(sprintf(__("Record is not unique: %s, Matching Ids: (%s).", 'jc-importer'), $unique_field_found, implode(', ', $query->posts)));
135 }
136
137 if ($query->post_count == 1) {
138 $this->ID = $query->posts[0];
139 return $this->ID;
140 }
141
142 return false;
143 }
144
145 public function insert(ParsedData $data)
146 {
147 $fields = $data->getData('default');
148
149 $post = array();
150 $meta = array();
151
152 // if we are trying to insert a post with a specific id then used import_id instead.
153 // if (isset($fields['ID']) && !empty($fields['ID'])) {
154 // $post['import_id'] = $fields['ID'];
155 // unset($fields['ID']);
156 // }
157
158 // we dont import the ID
159 if (isset($fields['ID'])) {
160 unset($fields['ID']);
161 }
162
163 $this->sortFields($fields, $post, $meta);
164
165 // set post_type
166 $post['post_type'] = $this->importer->getSetting('post_type');
167
168 Logger::debug('PostMapper::insert -wp_insert_post=' . wp_json_encode($post));
169
170 $this->ID = $this->create_post($post, $data);
171
172 if (is_wp_error($this->ID)) {
173 throw new MapperException($this->ID->get_error_message());
174 }
175
176 // TODO: Do we merge in the custom fields, or do we process that in post_process
177 $this->template->process($this->ID, $data, $this->importer);
178
179 $meta = array_merge($meta, $data->getData('custom_fields'));
180 Logger::debug('PostMapper::update -meta=' . wp_json_encode($meta));
181
182 // create post meta
183 if ($this->ID && !empty($meta)) {
184 foreach ($meta as $key => $value) {
185 if (is_array($value)) {
186 foreach ($value as $v) {
187 $this->add_custom_field($this->ID, $key, $v);
188 }
189 } else {
190 $this->update_custom_field($this->ID, $key, $value);
191 }
192 }
193 }
194
195 $this->add_version_tag();
196 $this->add_reference_tag($data);
197 $this->template->post_process($this->ID, $data);
198
199 clean_post_cache($this->ID);
200
201 return $this->ID;
202 }
203
204 public function create_post($post, ParsedData $data)
205 {
206 return wp_insert_post($post, true);
207 }
208
209 public function update(ParsedData $data)
210 {
211 $fields = $data->getData('default');
212
213 $post_type = $this->importer->getSetting('post_type');
214
215 $post = array();
216 $meta = array();
217
218 // we dont import the ID
219 if (isset($fields['ID'])) {
220 unset($fields['ID']);
221 }
222
223 $this->sortFields($fields, $post, $meta);
224
225 if (!$this->ID) {
226 return false;
227 }
228
229 // Check to see if trash flag is set, only the importer that removed it can restore it
230 $trash_status = get_post_meta($this->ID, '_iwp_trash_status', true);
231 if (!empty($trash_status)) {
232 $trash_importer_id = get_post_meta($this->ID, '_iwp_trash_importer', true);
233 if ($trash_importer_id == $this->importer->getId()) {
234 $post['post_status'] = $trash_status;
235 } else {
236 $trash_status = false;
237 }
238 }
239
240 // update post type
241 if (!empty($post)) {
242
243 // check to see if fields need updating
244 $query = new \WP_Query(array(
245 'post_type' => $post_type,
246 'p' => $this->ID,
247 'posts_per_page' => 1,
248 'cache_results' => false,
249 'update_post_meta_cache' => false,
250 'update_post_term_cache' => false,
251 'no_found_rows' => true,
252 'post_status' => 'any, trash, future'
253 ));
254 if ($query->found_posts == 1) {
255 $old_post = $query->post;
256
257 foreach ($post as $k => $p) {
258 if ($p == $old_post->$k) {
259 unset($post[$k]);
260 }
261 }
262 }
263
264 Logger::debug('PostMapper::update -wp_update_post=' . wp_json_encode($post));
265
266 if (!empty($post)) {
267 // update remaining
268 $post['ID'] = $this->ID;
269 $res = wp_update_post($post, true);
270 if (is_wp_error($res)) {
271 throw new MapperException($res->get_error_message());
272 }
273 }
274 }
275
276 // TODO: Do we merge in the custom fields, or do we process that in post_process
277 $this->template->process($this->ID, $data, $this->importer);
278
279 // update post meta
280 $meta = array_merge($meta, $data->getData('custom_fields'));
281 Logger::debug('PostMapper::update -meta=' . wp_json_encode($meta));
282
283 if (!empty($meta)) {
284 foreach ($meta as $key => $value) {
285 $this->clear_custom_field($this->ID, $key);
286 if (is_array($value)) {
287 foreach ($value as $v) {
288 $this->add_custom_field($this->ID, $key, $v);
289 }
290 } else {
291 $this->update_custom_field($this->ID, $key, $value);
292 }
293 }
294 }
295
296 $this->add_version_tag();
297 $this->add_reference_tag($data);
298
299 $this->template->post_process($this->ID, $data);
300
301 // Delete trash flag once post has been updated.
302 if (!empty($trash_status)) {
303 delete_post_meta($this->ID, '_iwp_trash_status');
304 delete_post_meta($this->ID, '_iwp_trash_importer');
305 }
306
307 clean_post_cache($this->ID);
308
309 return $this->ID;
310 }
311
312 public function get_objects_for_removal()
313 {
314 if ($this->is_session_tag_enabled()) {
315 return $this->get_ids_without_session_tag('pt-' . implode('|', (array)$this->importer->getSetting('post_type')));
316 } else {
317
318 $import_ids = apply_filters('iwp/mapper/session_importer_ids', [$this->importer->getId()], $this->importer->getId());
319 if (empty($import_ids)) {
320 return false;
321 }
322
323 $meta_query = [];
324 foreach ($import_ids as $import_id) {
325 $meta_query[] = array(
326 'key' => '_iwp_session_' . $import_id,
327 'value' => $this->importer->getStatusId(),
328 'compare' => '!='
329 );
330 }
331
332 if (count($meta_query) > 1) {
333 $meta_query['relation'] = 'AND';
334 }
335
336 $q = new \WP_Query(array(
337 'post_type' => $this->importer->getSetting('post_type'),
338 'meta_query' => $meta_query,
339 'fields' => 'ids',
340 'posts_per_page' => -1,
341 'cache_results' => false,
342 'update_post_meta_cache' => false,
343 'post_status' => 'any'
344 ));
345
346 if ($q->have_posts()) {
347 return $q->posts;
348 }
349 }
350
351 return false;
352 }
353
354 public function delete($id)
355 {
356 $permissions = $this->importer->getPermission('remove');
357 $force = isset($permissions['trash']) ? !$permissions['trash'] : true; // trash = true
358 if (!$force) {
359
360 // set trash flag
361 update_post_meta($id, '_iwp_trash_status', get_post_status($id));
362 update_post_meta($id, '_iwp_trash_importer', $this->importer->getId());
363 wp_trash_post($id);
364 } else {
365
366 // Remove connected attachments
367 $remove_media = isset($permissions['media']) ? $permissions['media'] : false;
368 if ($remove_media) {
369 $attachments = get_attached_media('', $id);
370 foreach ($attachments as $attachment) {
371 wp_delete_attachment($attachment->ID, 'true');
372 }
373 }
374
375 wp_delete_post($id, $force);
376 }
377
378 $this->remove_session_tag($id, 'pt-' . implode('|', (array)$this->importer->getSetting('post_type')));
379 }
380
381 /**
382 * Sort fields into post and meta array
383 *
384 * @param array $fields list of fields
385 * @param array $post post_data pointer array
386 * @param array $meta post_meta pointer array
387 *
388 * @return void
389 */
390 function sortFields($fields = array(), &$post = array(), &$meta = array())
391 {
392
393 foreach ($fields as $id => $value) {
394
395 if (in_array($id, $this->_post_fields, true)) {
396
397 // post field
398 $post[$id] = $value;
399 } else {
400
401 // meta field
402 $meta[$id] = $value;
403 }
404 }
405 }
406
407 /**
408 * Clear all post meta before adding custom field
409 */
410 public function clear_custom_field($post_id, $key)
411 {
412 delete_post_meta($post_id, $key);
413 }
414
415 /**
416 * Add custom field, allow for multiple records using the same key
417 *
418 * @param int $post_id
419 * @param string $key
420 * @param string $value
421 * @return void
422 */
423 public function add_custom_field($post_id, $key, $value)
424 {
425 // Stop double serialization
426 if (is_serialized($value)) {
427 $value = unserialize($value);
428 }
429
430 add_post_meta($post_id, $key, $value);
431 }
432
433 public function get_custom_field($id, $key = '', $single = false)
434 {
435 return get_post_meta($id, $key, $single);
436 }
437
438 public function update_custom_field($post_id, $key, $value, $unique = false, $skip_permissions = false)
439 {
440
441 $old_value = get_post_meta($post_id, $key, true);
442
443 // Stop double serialization
444 if (is_serialized($value)) {
445 $value = unserialize($value);
446 }
447
448 // check if new value
449 if ($old_value === $value) {
450 return;
451 }
452
453 if ($value !== '' && '' == $old_value) {
454 add_post_meta($post_id, $key, $value, $unique);
455 } elseif ($value !== '' && $value !== $old_value) {
456 update_post_meta($post_id, $key, $value);
457 } elseif ('' === $value && $old_value) {
458 delete_post_meta($post_id, $key, $value);
459 }
460 }
461
462 public function add_version_tag()
463 {
464 if ($this->is_session_tag_enabled()) {
465 $this->add_session_tag('pt-' . implode('|', (array)$this->importer->getSetting('post_type')));
466 } else {
467 update_post_meta($this->ID, '_iwp_session_' . $this->importer->getId(), $this->importer->getStatusId());
468 }
469 }
470 }
471