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

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