PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.9.0
Import WP – CSV & XML Import Export for WordPress v2.9.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.9.0, at class/Common/Importer/Mapper/PostMapper.php

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