PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.8.3
Import WP – CSV & XML Import Export for WordPress v2.8.3
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 / Template / Template.php

Template.php in Import WP – CSV & XML Import Export for WordPress 2.8.3, at class/Common/Importer/Template/Template.php

1,018 lines 36.4 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\Template;
4
5 use ImportWP\Common\Attachment\Attachment;
6 use ImportWP\Common\Filesystem\Filesystem;
7 use ImportWP\Common\Ftp\Ftp;
8 use ImportWP\Common\Importer\File\XMLFile;
9 use ImportWP\Common\Importer\ParsedData;
10 use ImportWP\Common\Model\ImporterModel;
11 use ImportWP\Common\Util\Logger;
12 use ImportWP\Container;
13 use ImportWP\EventHandler;
14
15 class Template extends AbstractTemplate
16 {
17 /**
18 * Template name
19 *
20 * @var string
21 */
22 protected $name;
23 /**
24 * Mapper name
25 *
26 * @var string
27 */
28 protected $mapper;
29 /**
30 * @var ImporterModel
31 */
32 protected $importer;
33
34 /**
35 * Registered data groups
36 *
37 * @var string[]
38 */
39 protected $groups;
40
41 /**
42 * List of field option callbacks
43 *
44 * @var array
45 */
46 protected $field_options = [];
47
48 protected $default_template_options = [];
49
50 /**
51 * @var \WP_Error[] $errors
52 */
53 protected $errors = [];
54
55 /**
56 * @var EventHandler $event_handler
57 */
58 private $event_handler;
59
60 /**
61 * @var boolean
62 */
63 private $featured_set = false;
64
65 public function __construct(EventHandler $event_handler)
66 {
67 $this->event_handler = $event_handler;
68 $this->event_handler->run('template.init', [$this]);
69
70 $this->groups = $this->event_handler->run('template.data_groups', [$this->groups, $this]);
71
72 // Register field options callbacks
73 $this->field_options = [
74 '*.row_base' => [$this, 'get_row_base']
75 ];
76 $this->field_options = $this->event_handler->run('template.field_option_callbacks', [$this->field_options, $this]);
77 }
78
79 /**
80 * Get xml record base
81 *
82 * @param ImporterModel $importer_model
83 * @return array
84 */
85 public function get_row_base($importer_model)
86 {
87 /**
88 * @var ImporterManager $importer_manager
89 */
90 $importer_manager = Container::getInstance()->get('importer_manager');
91 $tmp = false;
92 $results = [];
93
94 if ($importer_model->getParser() !== 'xml') {
95 return $results;
96 }
97
98 $base_path = $importer_model->getFileSetting('base_path');
99 $nodes = $importer_model->getFileSetting('nodes');
100
101 $config = $importer_manager->get_config($importer_model->getId(), $tmp);
102
103 $filePath = $importer_model->getFile();
104 $file = new XMLFile($filePath, $config);
105 $file->setRecordPath($base_path);
106 $nodes = $file->get_node_list();
107
108 foreach ($nodes as $node) {
109 if (strpos($node, $base_path) !== 0) {
110 continue;
111 }
112
113 $sub_node = substr($node, strlen($base_path));
114
115 $results[] = [
116 'value' => $sub_node,
117 'label' => $sub_node
118 ];
119 }
120
121 return $results;
122 }
123
124 public function get_name()
125 {
126 return $this->name;
127 }
128
129 public function get_mapper()
130 {
131 return $this->mapper;
132 }
133
134 public function get_importer()
135 {
136 return $this->importer;
137 }
138
139 public function get_fields(ImporterModel $importer = null)
140 {
141 $fields = $this->register();
142 $fields = $this->event_handler->run('template.fields', [$fields, $this, $importer]);
143 return $fields;
144 }
145
146 public function register()
147 {
148 return [];
149 }
150
151 public function register_hooks(ImporterModel $importer)
152 {
153 $this->importer = $importer;
154
155 add_filter('iwp/importer/before_mapper', array($this, 'pre_process'));
156 add_filter('iwp/status/record_inserted', [$this, 'display_record_info'], 10, 3);
157 add_filter('iwp/status/record_updated', [$this, 'display_record_info'], 10, 3);
158 }
159
160 public function unregister_hooks()
161 {
162 remove_filter('iwp/importer/before_mapper', array($this, 'pre_process'));
163 remove_filter('iwp/status/record_inserted', [$this, 'display_record_info'], 10, 3);
164 remove_filter('iwp/status/record_updated', [$this, 'display_record_info'], 10, 3);
165 }
166
167 /**
168 * @param string $message
169 * @param int $id
170 * @param ParsedData $data
171 * @return $string
172 */
173 public function display_record_info($message, $id, $data)
174 {
175
176 $fields = $data->getData();
177 if (!empty($fields)) {
178 $message .= ' (' . implode(', ', array_keys($fields)) . ')';
179 }
180
181 if (!empty($this->errors)) {
182 $errors = [];
183 foreach ($this->errors as $error) {
184 $errors[] = $error->get_error_message();
185 }
186
187 $message .= ', Errors: (' . implode(', ', $errors) . ')';
188 }
189
190 $this->errors = [];
191
192 return $message;
193 }
194
195 public function register_group($label, $key, $fields, $args = [])
196 {
197 if (isset($args['row_base']) && true === $args['row_base']) {
198
199 $fields = array_merge(
200 [$this->register_field('Repeater Node', 'row_base', [
201 'type' => 'text',
202 'options' => 'callback',
203 'tooltip' => 'Select the path to the parent node containing values for this record, The preview when selecting data for each record should show a single record. Please note changing this will require updating references in this record.'
204 ])],
205 $fields
206 );
207 }
208
209 $tmp = [
210 'id' => $key,
211 'heading' => $label,
212 'type' => isset($args['type']) ? $args['type'] : 'group',
213 'fields' => $fields
214 ];
215
216 if (isset($args['condition']) && !empty($args['condition'])) {
217 $tmp['condition'] = $args['condition'];
218 }
219
220 return $tmp;
221 }
222
223 public function register_core_field($label, $key, $args = [])
224 {
225 $args['core'] = true;
226 return $this->register_field($label, $key, $args);
227 }
228
229 public function register_field($label, $key, $args = [])
230 {
231 $data = [
232 'id' => $key,
233 'label' => $label,
234 'type' => isset($args['type']) ? $args['type'] : 'field',
235 'core' => isset($args['core']) ? $args['core'] : false,
236 'tooltip' => isset($args['tooltip']) ? $args['tooltip'] : false
237 ];
238
239 if (isset($args['options'])) {
240 $data['options'] = $args['options'];
241 }
242
243 if (isset($args['default'])) {
244 $data['default'] = $args['default'];
245 }
246
247 if (isset($args['condition'])) {
248 $data['condition'] = $args['condition'];
249 }
250
251 return $data;
252 }
253
254 public function _register_attachment_setting_fields($display_conditions = [], $extra_fields = [], $disabled_fields = [])
255 {
256
257 $fields = [];
258
259 if (!in_array('_featured', $disabled_fields)) {
260 $fields[] = $this->register_field('Is Featured?', '_featured', [
261 'default' => 'no',
262 'options' => [
263 ['value' => 'no', 'label' => 'No'],
264 ['value' => 'yes', 'label' => 'Yes'],
265 ],
266 'tooltip' => __('Is the attachment the featured image for the current post.', 'importwp')
267 ]);
268 }
269
270 $fields = array_merge($fields, [
271 $this->register_field('Download', '_download', [
272 'default' => 'remote',
273 'options' => [
274 ['value' => 'remote', 'label' => 'Remote URL'],
275 ['value' => 'ftp', 'label' => 'FTP'],
276 ['value' => 'local', 'label' => 'Local Filesystem'],
277 ['value' => 'media', 'label' => 'Media Library'],
278 ],
279 'tooltip' => __('Select how the attachment is being downloaded.', 'importwp')
280 ]),
281 $this->register_field('Host', '_ftp_host', [
282 'condition' => ['_download', '==', 'ftp'],
283 'tooltip' => __('Enter the FTP hostname', 'importwp')
284 ]),
285 $this->register_field('Username', '_ftp_user', [
286 'condition' => ['_download', '==', 'ftp'],
287 'tooltip' => __('Enter the FTP username', 'importwp')
288 ]),
289 $this->register_field('Password', '_ftp_pass', [
290 'condition' => ['_download', '==', 'ftp'],
291 'tooltip' => __('Enter the FTP password', 'importwp')
292 ]),
293 $this->register_field('Path', '_ftp_path', [
294 'condition' => ['_download', '==', 'ftp'],
295 'tooltip' => __('Enter the FTP base path, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
296 ]),
297 $this->register_field('Base URL', '_remote_url', [
298 'condition' => ['_download', '==', 'remote'],
299 'tooltip' => __('Enter the base url, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
300 ]),
301 $this->register_field('Base URL', '_local_url', [
302 'condition' => ['_download', '==', 'local'],
303 'tooltip' => __('Enter the base path from this servers root file system, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
304 ]),
305
306 $this->register_field('Permissions', '_enable_image_hash', [
307 'condition' => ['_download', '!=', 'media'],
308 'default' => 'yes',
309 'options' => [
310 ['value' => 'no', 'label' => 'Always download new files'],
311 ['value' => 'yes', 'label' => 'Search media library before downloading new files'],
312 ],
313 'tooltip' => __('Enable to stop duplicate images by searching the media library before downloading new files.', 'importwp')
314 ]),
315 $this->register_field('Delimiter', '_delimiter', [
316 'type' => 'text',
317 'tooltip' => 'A single character used to seperate attachments when listing multiple, Leave empty to use default: ,'
318 ]),
319
320 ]);
321
322 if (!in_array('_meta', $disabled_fields)) {
323 $fields[] = $this->register_group('Attachment Meta', '_meta', [
324 $this->register_field('Enable Meta', '_enabled', [
325 'default' => 'no',
326 'options' => [
327 ['value' => 'no', 'label' => 'No'],
328 ['value' => 'yes', 'label' => 'Yes'],
329 ],
330 'type' => 'select',
331 'tooltip' => __('Enable/Disable the fields to import attachment meta data.', 'importwp')
332 ]),
333 $this->register_field('Alt Text', '_alt', [
334 'condition' => ['_enabled', '==', 'yes'],
335 'tooltip' => __('Image attachment alt text.', 'importwp'),
336 ]),
337 $this->register_field('Title Text', '_title', [
338 'condition' => ['_enabled', '==', 'yes'],
339 'tooltip' => __('Attachments title text.', 'importwp')
340 ]),
341 $this->register_field('Caption Text', '_caption', [
342 'condition' => ['_enabled', '==', 'yes'],
343 'tooltip' => __('Image attachments caption text.', 'importwp')
344 ]),
345 $this->register_field('Description Text', '_description', [
346 'condition' => ['_enabled', '==', 'yes'],
347 'tooltip' => __('Attachments description text.', 'importwp')
348 ])
349 ]);
350 }
351
352 return $this->register_group('Settings', 'settings', array_merge($extra_fields, $fields), ['type' => 'settings', 'condition' => $display_conditions]);
353 }
354
355 public function register_attachment_fields($label = 'Attachments', $name = 'attachments', $field_label = 'Location', $group_args = null, $attachment_args = [])
356 {
357 if (is_null($group_args)) {
358 $group_args = ['type' => 'repeatable', 'row_base' => true];
359 }
360
361 $display_conditions = isset($attachment_args['conditions']) ? $attachment_args['conditions'] : [];
362 $extra_fields = isset($attachment_args['extra_fields']) ? $attachment_args['extra_fields'] : [];
363 $disabled_fields = isset($attachment_args['disabled_fields']) ? $attachment_args['disabled_fields'] : [];
364
365 return $this->register_group($label, $name, [
366 $this->register_field($field_label, 'location', [
367 'tooltip' => __('The source location of the file being attached.', 'importwp')
368 ]),
369 $this->_register_attachment_setting_fields($display_conditions, $extra_fields, $disabled_fields)
370 ], $group_args);
371 }
372
373 public function get_field_options($field_name, $id)
374 {
375 $callback = false;
376 foreach ($this->field_options as $callback_field_name => $temp_callback) {
377 if (strpos($callback_field_name, '*') !== false) {
378
379 $callback_field_name = str_replace('.', '\.', $callback_field_name);
380
381 $pattern = str_replace('*', '[\S]+', $callback_field_name);
382 if (1 !== preg_match("/^{$pattern}/i", $field_name)) {
383 continue;
384 }
385
386 $callback = $temp_callback;
387 break;
388 }
389
390 if ($field_name !== $callback_field_name) {
391 continue;
392 }
393
394 $callback = $temp_callback;
395 break;
396 }
397
398 if (!$callback) {
399 return false;
400 }
401
402 if (!method_exists($callback[0], $callback[1])) {
403 return false;
404 }
405
406 if (!is_callable($callback)) {
407 return false;
408 }
409
410 return call_user_func_array($callback, [$id]);
411 }
412
413 public function get_default_template_options()
414 {
415 return $this->default_template_options;
416 }
417
418 /**
419 * Alter fields before they are parsed
420 *
421 * @param array $fields
422 * @return array
423 */
424 public function field_map($fields)
425 {
426 return $fields;
427 }
428
429 public function config_field_map($field_map)
430 {
431 $template_fields = $this->field_map($field_map);
432
433 $field_groups = [
434 'default' => [
435 'id' => 'default',
436 'fields' => []
437 ]
438 ];
439
440 foreach ($template_fields as $key => $value) {
441
442 if (empty($value) || preg_match('/\.row_base$/', $key) !== 1) {
443 continue;
444 }
445
446 $group_id = substr($key, 0, strlen($key) - strlen('.row_base'));
447
448 $field_groups[$group_id] = [
449 'id' => $group_id,
450 'base' => $value,
451 'fields' => []
452 ];
453 }
454
455 foreach ($template_fields as $field_id => $field_value) {
456
457 $found = false;
458
459 foreach ($field_groups as $group_prefix => $group_settings) {
460 if (false === strpos($field_id, $group_prefix) || preg_match('/\.row_base$/', $field_id) === 1) {
461 continue;
462 }
463
464 $field_groups[$group_prefix]['fields'][$field_id] = $field_value;
465 $found = true;
466 }
467
468 if (false === $found) {
469 $field_groups['default']['fields'][$field_id] = $field_value;
470 }
471 }
472
473 return $field_groups;
474 }
475
476 /**
477 * Process data before record is importer.
478 *
479 * Alter data that is passed to the mapper.
480 *
481 * @param ParsedData $data
482 * @return ParsedData
483 */
484 public function pre_process(ParsedData $data)
485 {
486 $data = $this->pre_process_groups($data);
487 $this->event_handler->run('template.pre_process', [$data, $this->importer, $this]);
488 return $data;
489 }
490
491 public function process($post_id, ParsedData $data, ImporterModel $importer_model)
492 {
493 $this->featured_set = false;
494 $this->event_handler->run('template.process', [$post_id, $data, $importer_model, $this]);
495 }
496
497 /**
498 * Process data after record is importer.
499 *
500 * Use data that is returned from the mapper.
501 *
502 * @param int $post_id
503 * @param ParsedData $data
504 * @return void
505 */
506 public function post_process($post_id, ParsedData $data)
507 {
508 $this->event_handler->run('template.post_process', [$post_id, $data, $this]);
509 }
510
511 public function pre_process_groups(ParsedData $data)
512 {
513 // Allows virtual groups to be registered
514 $this->groups = $this->event_handler->run('template.pre_process_groups', [$this->groups, $data, $this]);
515
516 $map = $data->getData('default');
517 foreach ($this->groups as $group) {
518 $group_map = [];
519
520 foreach ($map as $field_key => $fields_map) {
521 if (preg_match('/^' . $group . '\.(.*?)$/', $field_key) === 1) {
522 $group_map[$field_key] = $fields_map;
523 }
524 }
525
526 $data->replace($group_map, $group);
527 }
528
529 return $data;
530 }
531
532 /**
533 * Process attachment fields
534 *
535 * @param int $post_id
536 * @param array $row
537 * @param string $row_prefix
538 * @param Filesystem $filesystem
539 * @param Ftp $ftp
540 * @param Attachment $attachment
541 */
542 public function process_attachment($post_id, $row, $row_prefix, $filesystem, $ftp, $attachment)
543 {
544 $delimiter = apply_filters('iwp/value_delimiter', ',');
545 $delimiter = apply_filters('iwp/attachment/value_delimiter', $delimiter);
546
547 if (isset($row[$row_prefix . 'settings._delimiter'])) {
548
549 if (strlen(trim($row[$row_prefix . 'settings._delimiter'])) === 1) {
550 $delimiter = trim($row[$row_prefix . 'settings._delimiter']);
551 }
552 } elseif (isset($row[$row_prefix . '_delimiter'])) {
553
554 if (strlen(trim($row[$row_prefix . '_delimiter'])) === 1) {
555 $delimiter = trim($row[$row_prefix . '_delimiter']);
556 }
557 }
558
559 $meta_delimiter = apply_filters('iwp/attachment/meta_delimiter', $delimiter);
560
561 $locations = isset($row[$row_prefix . 'location']) ? $row[$row_prefix . 'location'] : null;
562 $location_parts = explode($delimiter, $locations);
563 $location_parts = array_filter(array_map('trim', $location_parts));
564
565 if (isset($row[$row_prefix . 'settings._meta._title'])) {
566 $attachment_titles = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._title']);
567 } elseif ($row[$row_prefix . '_meta._title']) {
568 $attachment_titles = explode($meta_delimiter, $row[$row_prefix . '_meta._title']);
569 } else {
570 $attachment_titles = null;
571 }
572
573 if (isset($row[$row_prefix . 'settings._meta._alt'])) {
574 $attachment_alts = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._alt']);
575 } elseif (isset($row[$row_prefix . '_meta._alt'])) {
576 $attachment_alts = explode($meta_delimiter, $row[$row_prefix . '_meta._alt']);
577 } else {
578 $attachment_alts = null;
579 }
580
581 if (isset($row[$row_prefix . 'settings._meta._caption'])) {
582 $attachment_captions = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._caption']);
583 } elseif (isset($row[$row_prefix . '_meta._caption'])) {
584 $attachment_captions = explode($meta_delimiter, $row[$row_prefix . '_meta._caption']);
585 } else {
586 $attachment_captions = null;
587 }
588
589 if (isset($row[$row_prefix . 'settings._meta._description'])) {
590 $attachment_descriptions = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._description']);
591 } elseif (isset($row[$row_prefix . '_meta._description'])) {
592 $attachment_descriptions = explode($meta_delimiter, $row[$row_prefix . '_meta._description']);
593 } else {
594 $attachment_descriptions = null;
595 }
596
597 if (isset($row[$row_prefix . 'settings._enable_image_hash'])) {
598 $attachment_enable_image_hash = $row[$row_prefix . 'settings._enable_image_hash'];
599 } elseif (isset($row[$row_prefix . '_enable_image_hash'])) {
600 $attachment_enable_image_hash = $row[$row_prefix . '_enable_image_hash'];
601 } else {
602 $attachment_enable_image_hash = 'yes';
603 }
604
605 $attachment_ids = [];
606 $location_counter = 0;
607 foreach ($location_parts as $location) {
608
609 if (empty($location)) {
610 continue;
611 }
612
613 if (isset($row[$row_prefix . 'settings._download'])) {
614 $download = $row[$row_prefix . 'settings._download'];
615 } elseif (isset($row[$row_prefix . '_download'])) {
616 $download = $row[$row_prefix . '_download'];
617 } else {
618 $download = null;
619 }
620
621 if (isset($row[$row_prefix . 'settings._featured'])) {
622 $featured = $row[$row_prefix . 'settings._featured'];
623 } elseif (isset($row[$row_prefix . '_featured'])) {
624 $featured = $row[$row_prefix . '_featured'];
625 } else {
626 $featured = null;
627 }
628
629
630 $source = null;
631 $result = false;
632 $attachment_id = null;
633 $attachment_salt = '';
634
635 $location = trim($location);
636
637 switch ($download) {
638 case 'remote':
639
640 if (isset($row[$row_prefix . 'settings._remote_url'])) {
641 $base_url = $row[$row_prefix . 'settings._remote_url'];
642 } elseif (isset($row[$row_prefix . '_remote_url'])) {
643 $base_url = $row[$row_prefix . '_remote_url'];
644 } else {
645 $base_url = null;
646 }
647
648 // check if file hash is already stored
649 $source = $base_url . $location;
650 if (empty($source)) {
651 continue 2;
652 }
653
654
655 $attachment_salt = file_exists($source) ? md5_file($source) : '';
656 $attachment_id = 0;
657 if ($attachment_enable_image_hash == 'yes') {
658 $attachment_id = $attachment->get_attachment_by_hash($source);
659 }
660
661 if ($attachment_id <= 0) {
662
663 $main_zip_file = false;
664 if ($base_url === 'iwp_zip') {
665 $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
666 if ($main_zip && file_exists($main_zip)) {
667 $base_url .= '://' . $main_zip;
668 $main_zip_file = $main_zip;
669 }
670 }
671
672 $zip = $this->get_zip_source($base_url, $filesystem);
673 if ($zip !== false) {
674
675 if (!$main_zip_file && isset($zip['src'])) {
676
677 /**
678 * @var \ImportWP\Common\Http\Http $http
679 */
680 $http = Container::getInstance()->get('http');
681 $result = $http->download_file($zip['src'], $zip['name']);
682 if (is_wp_error($result)) {
683 break;
684 }
685
686 if (!$result) {
687 $result = new \WP_Error('IWP_HTTP_2', 'Error downloading zip file');
688 break;
689 }
690 }
691
692 $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
693 if (!$result) {
694 continue 2;
695 }
696
697 break;
698 }
699 }
700
701 $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
702 if ($attachment_id <= 0) {
703 Logger::write(__CLASS__ . '::process__attachments -remote=' . $source . ' -filename=' . $custom_filename);
704 $result = $filesystem->download_file($source, null, null, $custom_filename);
705 }
706 break;
707 case 'ftp':
708
709 if (isset($row[$row_prefix . 'settings._ftp_user'])) {
710 $ftp_user = $row[$row_prefix . 'settings._ftp_user'];
711 } elseif (isset($row[$row_prefix . '_ftp_user'])) {
712 $ftp_user = $row[$row_prefix . '_ftp_user'];
713 } else {
714 $ftp_user = null;
715 }
716
717 if (isset($row[$row_prefix . 'settings._ftp_host'])) {
718 $ftp_host = $row[$row_prefix . 'settings._ftp_host'];
719 } elseif (isset($row[$row_prefix . '_ftp_host'])) {
720 $ftp_host = $row[$row_prefix . '_ftp_host'];
721 } else {
722 $ftp_host = null;
723 }
724
725 if (isset($row[$row_prefix . 'settings._ftp_pass'])) {
726 $ftp_pass = $row[$row_prefix . 'settings._ftp_pass'];
727 } elseif (isset($row[$row_prefix . '_ftp_pass'])) {
728 $ftp_pass = $row[$row_prefix . '_ftp_pass'];
729 } else {
730 $ftp_pass = null;
731 }
732
733 if (isset($row[$row_prefix . 'settings._ftp_path'])) {
734 $base_url = $row[$row_prefix . 'settings._ftp_path'];
735 } elseif (isset($row[$row_prefix . '_ftp_path'])) {
736 $base_url = $row[$row_prefix . '_ftp_path'];
737 } else {
738 $base_url = null;
739 }
740
741 // check if file hash is already stored
742 $source = $base_url . $location;
743 if (empty($source)) {
744 continue 2;
745 }
746
747 $attachment_salt = file_exists($source) ? md5_file($source) : '';
748 $attachment_id = 0;
749 if ($attachment_enable_image_hash == 'yes') {
750 $attachment_id = $attachment->get_attachment_by_hash($source, $attachment_salt);
751 }
752
753 if ($attachment_id <= 0) {
754
755 $main_zip_file = false;
756 if ($base_url === 'iwp_zip') {
757 $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
758 if ($main_zip && file_exists($main_zip)) {
759 $base_url .= '://' . $main_zip;
760 $main_zip_file = $main_zip;
761 }
762 }
763
764 $zip = $this->get_zip_source($base_url, $filesystem);
765 if ($zip !== false) {
766
767 if (!$main_zip_file && isset($zip['src'])) {
768 $result = $ftp->download_file($zip['src'], $ftp_host, $ftp_user, $ftp_pass, $zip['name']);
769 if (is_wp_error($result)) {
770 break;
771 }
772 }
773
774 $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
775 if (!$result) {
776 continue 2;
777 }
778
779 break;
780 }
781 }
782
783 $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
784 if ($attachment_id <= 0) {
785 Logger::write(__CLASS__ . '::process__attachments -ftp=' . $source . ' -filename=' . $custom_filename);
786 $result = $ftp->download_file($source, $ftp_host, $ftp_user, $ftp_pass, $custom_filename);
787 }
788 break;
789 case 'local':
790
791 if (isset($row[$row_prefix . 'settings._local_url'])) {
792 $base_url = $row[$row_prefix . 'settings._local_url'];
793 } elseif (isset($row[$row_prefix . '_local_url'])) {
794 $base_url = $row[$row_prefix . '_local_url'];
795 } else {
796 $base_url = null;
797 }
798
799 // check if file hash is already stored
800 $source = $base_url . $location;
801 if (empty($source)) {
802 continue 2;
803 }
804
805 $attachment_salt = file_exists($source) ? md5_file($source) : '';
806 $attachment_id = 0;
807 if ($attachment_enable_image_hash == 'yes') {
808 $attachment_id = $attachment->get_attachment_by_hash($source, $attachment_salt);
809 }
810
811 if ($attachment_id <= 0) {
812
813 $main_zip_file = false;
814 if ($base_url === 'iwp_zip') {
815 $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
816 if ($main_zip && file_exists($main_zip)) {
817 $base_url .= '://' . $main_zip;
818 $main_zip_file = $main_zip;
819 }
820 }
821
822 $zip = $this->get_zip_source($base_url, $filesystem);
823 if ($zip !== false) {
824
825 if (!$main_zip_file && isset($zip['src'])) {
826 $result = $filesystem->copy($zip['src'], $zip['name']);
827 if (is_wp_error($result)) {
828 break;
829 }
830 }
831
832 $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
833 if (!$result) {
834 continue 2;
835 }
836
837 break;
838 }
839 }
840
841 $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
842 if ($attachment_id <= 0) {
843 Logger::write(__CLASS__ . '::process__attachments -local=' . $source . ' -filename=' . $custom_filename);
844 $result = $filesystem->copy_file($source, null, $custom_filename);
845 }
846 break;
847 case 'media':
848 $source = $location;
849 if (empty($source)) {
850 continue 2;
851 }
852
853 $attachment_id = $attachment->attachment_partial_url_to_postid($source);
854 Logger::write(__CLASS__ . '::process__attachments -media=' . $source);
855
856 break;
857 }
858
859 if (isset($row[$row_prefix . 'settings._meta._enabled'])) {
860 $meta_enabled = $row[$row_prefix . 'settings._meta._enabled'] === 'yes' ? true : false;
861 } elseif (isset($row[$row_prefix . '_meta._enabled'])) {
862 $meta_enabled = $row[$row_prefix . '_meta._enabled'] === 'yes' ? true : false;
863 } else {
864 $meta_enabled = false;
865 }
866
867 // insert attachment
868 if ($attachment_id <= 0) {
869
870 if (is_wp_error($result)) {
871 Logger::write(__CLASS__ . '::process__attachments -error=' . $result->get_error_message());
872 $this->errors[] = $result;
873 continue;
874 }
875
876 if (!$result) {
877 continue;
878 }
879
880 $attachment_args = [];
881 if ($meta_enabled) {
882 $attachment_args['title'] = isset($attachment_titles[$location_counter]) ? $attachment_titles[$location_counter] : null;
883 $attachment_args['alt'] = isset($attachment_alts[$location_counter]) ? $attachment_alts[$location_counter] : null;
884 $attachment_args['caption'] = isset($attachment_captions[$location_counter]) ? $attachment_captions[$location_counter] : null;
885 $attachment_args['description'] = isset($attachment_descriptions[$location_counter]) ? $attachment_descriptions[$location_counter] : null;;
886 }
887
888 $attachment_id = $attachment->insert_attachment($post_id, $result['dest'], $result['mime'], $attachment_args);
889 if (is_wp_error($attachment_id)) {
890 Logger::write(__CLASS__ . '::process__attachments -error=' . $attachment_id->get_error_message());
891 continue;
892 }
893
894 $attachment->generate_image_sizes($attachment_id, $result['dest']);
895 $attachment->store_attachment_hash($attachment_id, $source, $attachment_salt);
896 } else {
897 // Update existing attachment meta
898 if ($meta_enabled) {
899 $post_data = [];
900
901 if (isset($attachment_titles[$location_counter])) {
902 $post_data['post_title'] = $attachment_titles[$location_counter];
903 }
904
905 if (isset($attachment_descriptions[$location_counter])) {
906 $post_data['post_content'] = $attachment_descriptions[$location_counter];
907 }
908
909 if (isset($attachment_captions[$location_counter])) {
910 $post_data['post_excerpt'] = $attachment_captions[$location_counter];
911 }
912
913 if (!empty($post_data)) {
914 $post_data['ID'] = $attachment_id;
915 wp_update_post($post_data);
916 }
917
918 if (isset($attachment_alts[$location_counter])) {
919 update_post_meta($attachment_id, '_wp_attachment_image_alt', $attachment_alts[$location_counter]);
920 }
921 }
922 }
923
924 $attachment_ids[] = $attachment_id;
925 $attachment_url = wp_get_attachment_url($attachment_id);
926 $this->_attachments[] = $attachment_url;
927
928 Logger::write(__CLASS__ . '::process__attachments -id=' . $attachment_id . ' -url=' . $attachment_url);
929
930 // set featured
931 if ('yes' === $featured && false === $this->featured_set) {
932 update_post_meta($post_id, '_thumbnail_id', $attachment_id);
933 $this->featured_set = true;
934 }
935
936 $location_counter++;
937 }
938
939 return $attachment_ids;
940 }
941
942 /**
943 * Add error message
944 *
945 * @param string|\WP_Error $error
946 * @return void
947 */
948 public function add_error($error)
949 {
950 if (!is_wp_error($error)) {
951 $error = new \WP_Error('IWP_TEMP_ERR', $error);
952 }
953
954 $this->errors[] = $error;
955 }
956
957 /**
958 * Convert fields/headings to data map
959 *
960 * @param mixed $fields
961 * @param ImporterModel $importer
962 * @return array
963 */
964 public function generate_field_map($fields, $importer)
965 {
966 return ['enabled' => [], 'map' => []];
967 }
968
969 public function get_zip_source($base_url, $filesystem)
970 {
971 $zip_parts = [];
972 if (preg_match('/^iwp_zip:\/\/(.*?)$/', $base_url, $zip_parts) === 1) {
973
974 $iwp_tmp = $filesystem->get_temp_directory();
975
976 $iwp_tmp .= DIRECTORY_SEPARATOR . 'zip';
977 if (!is_dir($iwp_tmp)) {
978 mkdir($iwp_tmp);
979 }
980
981 $hash = md5($base_url);
982 $iwp_tmp .= DIRECTORY_SEPARATOR . $hash . '.zip';
983 if (!file_exists($iwp_tmp)) {
984 return ['src' => $zip_parts[1], 'name' => $iwp_tmp];
985 }
986
987 return ['name' => $iwp_tmp];
988 }
989
990 return false;
991 }
992
993 public function get_file_from_zip($zip_path, $filename, $filesystem)
994 {
995 $zip = new \ZipArchive();
996 if ($zip->open($zip_path) === true) {
997 $output_data = $zip->getFromName($filename);
998 if ($output_data === false) {
999 return false;
1000 }
1001
1002 return $filesystem->string_to_file($output_data, $filename);
1003 }
1004
1005 return false;
1006 }
1007
1008 public function try_use_main_zip($base_url, $location)
1009 {
1010 if ($base_url === 'iwp_zip') {
1011
1012 $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
1013 $source = $main_zip . $location;
1014 $base_url .= $main_zip;
1015 }
1016 }
1017 }
1018