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
← All changes | class/Common/Importer/Template/Template.php +603 -79 2.7.1 → 2.15.0 View file →
@@ -5,8 +5,9 @@
5 5 use ImportWP\Common\Attachment\Attachment;
6 6 use ImportWP\Common\Filesystem\Filesystem;
7 7 use ImportWP\Common\Ftp\Ftp;
8 8 use ImportWP\Common\Importer\File\XMLFile;
9 +use ImportWP\Common\Importer\Mapper\AbstractMapper;
9 10 use ImportWP\Common\Importer\ParsedData;
10 11 use ImportWP\Common\Model\ImporterModel;
11 12 use ImportWP\Common\Util\Logger;
12 13 use ImportWP\Container;
@@ -47,8 +48,15 @@
47 48
48 49 protected $default_template_options = [];
49 50
50 51 /**
52 + *
53 + * List of optional fields that are enabled by default
54 + * @var string[]
55 + */
56 + protected $default_enabled_fields = [];
57 +
58 + /**
51 59 * @var \WP_Error[] $errors
52 60 */
53 61 protected $errors = [];
54 62
@@ -104,13 +112,28 @@
104 112 $file = new XMLFile($filePath, $config);
105 113 $file->setRecordPath($base_path);
106 114 $nodes = $file->get_node_list();
107 115
116 + // Nodes that appear as a parent of another path have selectable children.
117 + $parents = [];
108 118 foreach ($nodes as $node) {
119 + $parent = $node;
120 + while (($pos = strrpos($parent, '/')) !== false && $pos > 0) {
121 + $parent = substr($parent, 0, $pos);
122 + $parents[$parent] = true;
123 + }
124 + }
125 +
126 + foreach ($nodes as $node) {
109 127 if (strpos($node, $base_path) !== 0) {
110 128 continue;
111 129 }
112 130
131 + // Skip leaf nodes (e.g. /categories/category) — they have no selectable child nodes.
132 + if (!isset($parents[$node])) {
133 + continue;
134 + }
135 +
113 136 $sub_node = substr($node, strlen($base_path));
114 137
115 138 $results[] = [
116 139 'value' => $sub_node,
@@ -196,23 +219,44 @@
196 219 {
197 220 if (isset($args['row_base']) && true === $args['row_base']) {
198 221
199 222 $fields = array_merge(
200 - [$this->register_field('Repeater Node', 'row_base', [
223 + [$this->register_field(__('Repeater Node', 'jc-importer'), 'row_base', [
201 224 'type' => 'text',
202 225 '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.'
226 + '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.', 'jc-importer')
204 227 ])],
205 228 $fields
206 229 );
207 230 }
208 231
209 - return [
232 + $tmp = [
210 233 'id' => $key,
211 234 'heading' => $label,
212 235 'type' => isset($args['type']) ? $args['type'] : 'group',
213 - 'fields' => $fields
236 + 'fields' => $fields,
214 237 ];
238 +
239 + if (isset($args['link']) && !empty($args['link'])) {
240 + $tmp['link'] = $args['link'];
241 + }
242 +
243 + if (isset($args['condition']) && !empty($args['condition'])) {
244 + $tmp['condition'] = $args['condition'];
245 + }
246 +
247 + // Allow for setting fields to be registered for the group
248 + // currently only supporting toggle fields.
249 + if (isset($args['settings']) && !empty($args['settings'])) {
250 + $tmp['settings'] = $args['settings'];
251 + }
252 +
253 + // Field ids used to build the collapsed repeater row summary in the UI.
254 + if (isset($args['row_summary']) && !empty($args['row_summary'])) {
255 + $tmp['row_summary'] = array_values((array) $args['row_summary']);
256 + }
257 +
258 + return $tmp;
215 259 }
216 260
217 261 public function register_core_field($label, $key, $args = [])
218 262 {
@@ -244,95 +288,126 @@
244 288
245 289 return $data;
246 290 }
247 291
248 - public function register_attachment_fields($label = 'Attachments', $name = 'attachments', $field_label = 'Location', $group_args = null)
292 + public function _register_attachment_setting_fields($display_conditions = [], $extra_fields = [], $disabled_fields = [])
249 293 {
250 - if (is_null($group_args)) {
251 - $group_args = ['type' => 'repeatable', 'row_base' => true];
252 - }
253 - return $this->register_group($label, $name, [
254 - $this->register_field($field_label, 'location', [
255 - 'tooltip' => __('The source location of the file being attached.', 'importwp')
256 - ]),
257 - $this->register_field('Is Featured?', '_featured', [
294 +
295 + $fields = [];
296 +
297 + if (!in_array('_featured', $disabled_fields)) {
298 + $fields[] = $this->register_field(__('Is Featured?', 'jc-importer'), '_featured', [
258 299 'default' => 'no',
259 300 'options' => [
260 - ['value' => 'no', 'label' => 'No'],
261 - ['value' => 'yes', 'label' => 'Yes'],
301 + ['value' => 'no', 'label' => __('No', 'jc-importer')],
302 + ['value' => 'yes', 'label' => __('Yes', 'jc-importer')],
262 303 ],
263 - 'tooltip' => __('Is the attachment the featured image for the current post.', 'importwp')
264 - ]),
265 - $this->register_field('Download', '_download', [
304 + 'tooltip' => __('Is the attachment the featured image for the current post.', 'jc-importer')
305 + ]);
306 + }
307 +
308 + $fields = array_merge($fields, [
309 + $this->register_field(__('Download', 'jc-importer'), '_download', [
266 310 'default' => 'remote',
267 311 'options' => [
268 - ['value' => 'remote', 'label' => 'Remote URL'],
269 - ['value' => 'ftp', 'label' => 'FTP'],
270 - ['value' => 'local', 'label' => 'Local Filesystem'],
271 - ['value' => 'media', 'label' => 'Media Library'],
312 + ['value' => 'remote', 'label' => __('Remote URL', 'jc-importer')],
313 + ['value' => 'ftp', 'label' => __('FTP', 'jc-importer')],
314 + ['value' => 'local', 'label' => __('Local Filesystem', 'jc-importer')],
315 + ['value' => 'media', 'label' => __('Media Library', 'jc-importer')],
272 316 ],
273 - 'tooltip' => __('Select how the attachment is being downloaded.', 'importwp')
317 + 'tooltip' => __('Select how the attachment is being downloaded.', 'jc-importer')
274 318 ]),
275 - $this->register_field('Host', '_ftp_host', [
319 + $this->register_field(__('Host', 'jc-importer'), '_ftp_host', [
276 320 'condition' => ['_download', '==', 'ftp'],
277 - 'tooltip' => __('Enter the FTP hostname', 'importwp')
321 + 'tooltip' => __('Enter the FTP hostname', 'jc-importer')
278 322 ]),
279 - $this->register_field('Username', '_ftp_user', [
323 + $this->register_field(__('Username', 'jc-importer'), '_ftp_user', [
280 324 'condition' => ['_download', '==', 'ftp'],
281 - 'tooltip' => __('Enter the FTP username', 'importwp')
325 + 'tooltip' => __('Enter the FTP username', 'jc-importer')
282 326 ]),
283 - $this->register_field('Password', '_ftp_pass', [
327 + $this->register_field(__('Password', 'jc-importer'), '_ftp_pass', [
284 328 'condition' => ['_download', '==', 'ftp'],
285 - 'tooltip' => __('Enter the FTP password', 'importwp')
329 + 'tooltip' => __('Enter the FTP password', 'jc-importer')
286 330 ]),
287 - $this->register_field('Path', '_ftp_path', [
331 + $this->register_field(__('Path', 'jc-importer'), '_ftp_path', [
288 332 'condition' => ['_download', '==', 'ftp'],
289 - 'tooltip' => __('Enter the FTP base path, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
333 + 'tooltip' => __('Enter the FTP base path, this is prefixed onto the Location field, leave empty to be ignore', 'jc-importer')
290 334 ]),
291 - $this->register_field('Base URL', '_remote_url', [
335 + $this->register_field(__('Base URL', 'jc-importer'), '_remote_url', [
292 336 'condition' => ['_download', '==', 'remote'],
293 - 'tooltip' => __('Enter the base url, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
337 + 'tooltip' => __('Enter the base url, this is prefixed onto the Location field, leave empty to be ignore', 'jc-importer')
294 338 ]),
295 - $this->register_field('Base URL', '_local_url', [
339 + $this->register_field(__('Base URL', 'jc-importer'), '_local_url', [
296 340 'condition' => ['_download', '==', 'local'],
297 - 'tooltip' => __('Enter the base path from this servers root file system, this is prefixed onto the Location field, leave empty to be ignore', 'importwp')
341 + 'tooltip' => __('Enter the base path from this servers root file system, this is prefixed onto the Location field, leave empty to be ignore', 'jc-importer')
298 342 ]),
299 - $this->register_field('Permissions', '_enable_image_hash', [
343 +
344 + $this->register_field(__('Permissions', 'jc-importer'), '_enable_image_hash', [
300 345 'condition' => ['_download', '!=', 'media'],
301 346 'default' => 'yes',
302 347 'options' => [
303 - ['value' => 'no', 'label' => 'Always download new files'],
304 - ['value' => 'yes', 'label' => 'Search media library before downloading new files'],
348 + ['value' => 'no', 'label' => __('Always download new files', 'jc-importer')],
349 + ['value' => 'yes', 'label' => __('Search media library before downloading new files', 'jc-importer')],
305 350 ],
306 - 'tooltip' => __('Enable to stop duplicate images by searching the media library before downloading new files.', 'importwp')
351 + 'tooltip' => __('Enable to stop duplicate images by searching the media library before downloading new files.', 'jc-importer')
307 352 ]),
308 - $this->register_group('Attachment Meta', '_meta', [
309 - $this->register_field('Enable Meta', '_enabled', [
353 + $this->register_field(__('Delimiter', 'jc-importer'), '_delimiter', [
354 + 'type' => 'text',
355 + 'tooltip' => sprintf(__('A single character used to seperate attachments when listing multiple, Leave empty to use the default: %s', 'jc-importer'), ',')
356 + ]),
357 +
358 + ]);
359 +
360 + if (!in_array('_meta', $disabled_fields)) {
361 + $fields[] = $this->register_group(__('Attachment Meta', 'jc-importer'), '_meta', [
362 + $this->register_field(__('Enable Meta', 'jc-importer'), '_enabled', [
310 363 'default' => 'no',
311 364 'options' => [
312 - ['value' => 'no', 'label' => 'No'],
313 - ['value' => 'yes', 'label' => 'Yes'],
365 + ['value' => 'no', 'label' => __('No', 'jc-importer')],
366 + ['value' => 'yes', 'label' => __('Yes', 'jc-importer')],
314 367 ],
315 368 'type' => 'select',
316 - 'tooltip' => __('Enable/Disable the fields to import attachment meta data.', 'importwp')
369 + 'tooltip' => __('Enable/Disable the fields to import attachment meta data.', 'jc-importer')
317 370 ]),
318 - $this->register_field('Alt Text', '_alt', [
371 + $this->register_field(__('Alt Text', 'jc-importer'), '_alt', [
319 372 'condition' => ['_enabled', '==', 'yes'],
320 - 'tooltip' => __('Image attachment alt text.', 'importwp'),
373 + 'tooltip' => __('Image attachment alt text.', 'jc-importer'),
321 374 ]),
322 - $this->register_field('Title Text', '_title', [
375 + $this->register_field(__('Title Text', 'jc-importer'), '_title', [
323 376 'condition' => ['_enabled', '==', 'yes'],
324 - 'tooltip' => __('Attachments title text.', 'importwp')
377 + 'tooltip' => __('Attachments title text.', 'jc-importer')
325 378 ]),
326 - $this->register_field('Caption Text', '_caption', [
379 + $this->register_field(__('Caption Text', 'jc-importer'), '_caption', [
327 380 'condition' => ['_enabled', '==', 'yes'],
328 - 'tooltip' => __('Image attachments caption text.', 'importwp')
381 + 'tooltip' => __('Image attachments caption text.', 'jc-importer')
329 382 ]),
330 - $this->register_field('Description Text', '_description', [
383 + $this->register_field(__('Description Text', 'jc-importer'), '_description', [
331 384 'condition' => ['_enabled', '==', 'yes'],
332 - 'tooltip' => __('Attachments description text.', 'importwp')
385 + 'tooltip' => __('Attachments description text.', 'jc-importer')
333 386 ])
387 + ]);
388 + }
389 +
390 + return $this->register_group(__('Settings', 'jc-importer'), 'settings', array_merge($extra_fields, $fields), ['type' => 'settings', 'condition' => $display_conditions]);
391 + }
392 +
393 + public function register_attachment_fields($label = 'Images & Attachments', $name = 'attachments', $field_label = 'Location', $group_args = null, $attachment_args = [])
394 + {
395 + if (is_null($group_args)) {
396 + $group_args = ['type' => 'repeatable', 'row_base' => true, 'row_summary' => ['location'], 'link' => 'https://www.importwp.com/docs/how-to-import-wordpress-attachments-onto-a-post-type/'];
397 + } else if (!isset($group_args['row_summary'])) {
398 + $group_args['row_summary'] = ['location'];
399 + }
400 +
401 + $display_conditions = isset($attachment_args['conditions']) ? $attachment_args['conditions'] : [];
402 + $extra_fields = isset($attachment_args['extra_fields']) ? $attachment_args['extra_fields'] : [];
403 + $disabled_fields = isset($attachment_args['disabled_fields']) ? $attachment_args['disabled_fields'] : [];
404 +
405 + return $this->register_group($label, $name, [
406 + $this->register_field($field_label, 'location', [
407 + 'tooltip' => __('The source location of the file being attached.', 'jc-importer')
334 408 ]),
409 + $this->_register_attachment_setting_fields($display_conditions, $extra_fields, $disabled_fields)
335 410 ], $group_args);
336 411 }
337 412
338 413 public function get_field_options($field_name, $id)
@@ -434,8 +509,20 @@
434 509 $field_groups['default']['fields'][$field_id] = $field_value;
435 510 }
436 511 }
437 512
513 + if ($this->importer->has_custom_unique_identifier()) {
514 +
515 + $ref = $this->importer->getSetting('unique_identifier_ref');
516 +
517 + $field_groups['iwp'] = [
518 + 'id' => 'iwp',
519 + 'fields' => [
520 + $this->importer->get_iwp_reference_meta_key() => (!is_null($ref) ? $ref : '')
521 + ]
522 + ];
523 + }
524 +
438 525 return $field_groups;
439 526 }
440 527
441 528 /**
@@ -477,19 +564,21 @@
477 564 {
478 565 // Allows virtual groups to be registered
479 566 $this->groups = $this->event_handler->run('template.pre_process_groups', [$this->groups, $data, $this]);
480 567
481 - $map = $data->getData('default');
482 - foreach ($this->groups as $group) {
483 - $group_map = [];
568 + if (is_array($this->groups) && !empty($this->groups)) {
569 + $map = $data->getData('default');
570 + foreach ($this->groups as $group) {
571 + $group_map = [];
484 572
485 - foreach ($map as $field_key => $fields_map) {
486 - if (preg_match('/^' . $group . '\.(.*?)$/', $field_key) === 1) {
487 - $group_map[$field_key] = $fields_map;
573 + foreach ($map as $field_key => $fields_map) {
574 + if (preg_match('/^' . $group . '\.(.*?)$/', $field_key) === 1) {
575 + $group_map[$field_key] = $fields_map;
576 + }
488 577 }
578 +
579 + $data->replace($group_map, $group);
489 580 }
490 -
491 - $data->replace($group_map, $group);
492 581 }
493 582
494 583 return $data;
495 584 }
@@ -507,8 +596,21 @@
507 596 public function process_attachment($post_id, $row, $row_prefix, $filesystem, $ftp, $attachment)
508 597 {
509 598 $delimiter = apply_filters('iwp/value_delimiter', ',');
510 599 $delimiter = apply_filters('iwp/attachment/value_delimiter', $delimiter);
600 +
601 + if (isset($row[$row_prefix . 'settings._delimiter'])) {
602 +
603 + if (strlen(trim($row[$row_prefix . 'settings._delimiter'])) === 1) {
604 + $delimiter = trim($row[$row_prefix . 'settings._delimiter']);
605 + }
606 + } elseif (isset($row[$row_prefix . '_delimiter'])) {
607 +
608 + if (strlen(trim($row[$row_prefix . '_delimiter'])) === 1) {
609 + $delimiter = trim($row[$row_prefix . '_delimiter']);
610 + }
611 + }
612 +
511 613 $meta_delimiter = apply_filters('iwp/attachment/meta_delimiter', $delimiter);
512 614
513 615 $locations = isset($row[$row_prefix . 'location']) ? $row[$row_prefix . 'location'] : null;
514 616 $location_parts = explode($delimiter, $locations);
@@ -513,15 +615,48 @@
513 615 $locations = isset($row[$row_prefix . 'location']) ? $row[$row_prefix . 'location'] : null;
514 616 $location_parts = explode($delimiter, $locations);
515 617 $location_parts = array_filter(array_map('trim', $location_parts));
516 618
517 - $attachment_titles = isset($row[$row_prefix . '_meta._title']) ? explode($meta_delimiter, $row[$row_prefix . '_meta._title']) : null;
518 - $attachment_alts = isset($row[$row_prefix . '_meta._alt']) ? explode($meta_delimiter, $row[$row_prefix . '_meta._alt']) : null;
519 - $attachment_captions = isset($row[$row_prefix . '_meta._caption']) ? explode($meta_delimiter, $row[$row_prefix . '_meta._caption']) : null;
520 - $attachment_descriptions = isset($row[$row_prefix . '_meta._description']) ? explode($meta_delimiter, $row[$row_prefix . '_meta._description']) : null;
619 + if (isset($row[$row_prefix . 'settings._meta._title'])) {
620 + $attachment_titles = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._title']);
621 + } elseif ($row[$row_prefix . '_meta._title']) {
622 + $attachment_titles = explode($meta_delimiter, $row[$row_prefix . '_meta._title']);
623 + } else {
624 + $attachment_titles = null;
625 + }
521 626
522 - $attachment_enable_image_hash = isset($row[$row_prefix . '_enable_image_hash']) ? $row[$row_prefix . '_enable_image_hash'] : 'yes';
627 + if (isset($row[$row_prefix . 'settings._meta._alt'])) {
628 + $attachment_alts = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._alt']);
629 + } elseif (isset($row[$row_prefix . '_meta._alt'])) {
630 + $attachment_alts = explode($meta_delimiter, $row[$row_prefix . '_meta._alt']);
631 + } else {
632 + $attachment_alts = null;
633 + }
523 634
635 + if (isset($row[$row_prefix . 'settings._meta._caption'])) {
636 + $attachment_captions = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._caption']);
637 + } elseif (isset($row[$row_prefix . '_meta._caption'])) {
638 + $attachment_captions = explode($meta_delimiter, $row[$row_prefix . '_meta._caption']);
639 + } else {
640 + $attachment_captions = null;
641 + }
642 +
643 + if (isset($row[$row_prefix . 'settings._meta._description'])) {
644 + $attachment_descriptions = explode($meta_delimiter, $row[$row_prefix . 'settings._meta._description']);
645 + } elseif (isset($row[$row_prefix . '_meta._description'])) {
646 + $attachment_descriptions = explode($meta_delimiter, $row[$row_prefix . '_meta._description']);
647 + } else {
648 + $attachment_descriptions = null;
649 + }
650 +
651 + if (isset($row[$row_prefix . 'settings._enable_image_hash'])) {
652 + $attachment_enable_image_hash = $row[$row_prefix . 'settings._enable_image_hash'];
653 + } elseif (isset($row[$row_prefix . '_enable_image_hash'])) {
654 + $attachment_enable_image_hash = $row[$row_prefix . '_enable_image_hash'];
655 + } else {
656 + $attachment_enable_image_hash = 'yes';
657 + }
658 +
524 659 $attachment_ids = [];
525 660 $location_counter = 0;
526 661 foreach ($location_parts as $location) {
527 662
@@ -528,10 +663,25 @@
528 663 if (empty($location)) {
529 664 continue;
530 665 }
531 666
532 - $download = isset($row[$row_prefix . '_download']) ? $row[$row_prefix . '_download'] : null;
533 - $featured = isset($row[$row_prefix . '_featured']) ? $row[$row_prefix . '_featured'] : null;
667 + if (isset($row[$row_prefix . 'settings._download'])) {
668 + $download = $row[$row_prefix . 'settings._download'];
669 + } elseif (isset($row[$row_prefix . '_download'])) {
670 + $download = $row[$row_prefix . '_download'];
671 + } else {
672 + $download = null;
673 + }
674 +
675 + if (isset($row[$row_prefix . 'settings._featured'])) {
676 + $featured = $row[$row_prefix . 'settings._featured'];
677 + } elseif (isset($row[$row_prefix . '_featured'])) {
678 + $featured = $row[$row_prefix . '_featured'];
679 + } else {
680 + $featured = null;
681 + }
682 +
683 +
534 684 $source = null;
535 685 $result = false;
536 686 $attachment_id = null;
537 687 $attachment_salt = '';
@@ -539,10 +689,17 @@
539 689 $location = trim($location);
540 690
541 691 switch ($download) {
542 692 case 'remote':
543 - $base_url = isset($row[$row_prefix . '_remote_url']) ? $row[$row_prefix . '_remote_url'] : null;
544 693
694 + if (isset($row[$row_prefix . 'settings._remote_url'])) {
695 + $base_url = $row[$row_prefix . 'settings._remote_url'];
696 + } elseif (isset($row[$row_prefix . '_remote_url'])) {
697 + $base_url = $row[$row_prefix . '_remote_url'];
698 + } else {
699 + $base_url = null;
700 + }
701 +
545 702 // check if file hash is already stored
546 703 $source = $base_url . $location;
547 704 if (empty($source)) {
548 705 continue 2;
@@ -547,26 +704,135 @@
547 704 if (empty($source)) {
548 705 continue 2;
549 706 }
550 707
551 - $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
552 708
709 + $attachment_salt = file_exists($source) ? md5_file($source) : '';
553 710 $attachment_id = 0;
554 711 if ($attachment_enable_image_hash == 'yes') {
555 712 $attachment_id = $attachment->get_attachment_by_hash($source);
556 713 }
557 714
715 + // check to see if remote url matches file existing in media library
558 716 if ($attachment_id <= 0) {
717 + $dir = wp_get_upload_dir();
718 + if (str_starts_with($source, $dir['baseurl'] . '/')) {
719 + $attachment_id = attachment_url_to_postid($source);
720 + }
721 + }
722 +
723 + if ($attachment_id <= 0) {
724 +
725 + $main_zip_file = false;
726 + if ($base_url === 'iwp_zip') {
727 + $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
728 + if ($main_zip && file_exists($main_zip)) {
729 + $base_url .= '://' . $main_zip;
730 + $main_zip_file = $main_zip;
731 + }
732 + }
733 +
734 + $zip = $this->get_zip_source($base_url, $filesystem);
735 + if ($zip !== false) {
736 +
737 + if (!$main_zip_file && isset($zip['src'])) {
738 +
739 + /**
740 + * @var \ImportWP\Common\Http\Http $http
741 + */
742 + $http = Container::getInstance()->get('http');
743 + $result = $http->download_file($zip['src'], $zip['name']);
744 + if (is_wp_error($result)) {
745 + break;
746 + }
747 +
748 + if (!$result) {
749 + $result = new \WP_Error('IWP_HTTP_2', __('Error downloading zip file', 'jc-importer'));
750 + break;
751 + }
752 + }
753 +
754 + $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
755 + if (!$result) {
756 + continue 2;
757 + }
758 +
759 + break;
760 + }
761 + }
762 +
763 + if (apply_filters('iwp/template/process_attachment/enable_file_size_hash', false) === true) {
764 +
765 + // check to see if the remote url image is the same size as the one on disk.
766 + if ($attachment_id > 0 && $attachment_enable_image_hash == 'yes') {
767 +
768 + $existing_file = get_attached_file($attachment_id, true);
769 +
770 + // Remove -scaled from the file name if it exists
771 + if ($existing_file && file_exists($existing_file)) {
772 + $existing_file = str_replace('-scaled.', '.', $existing_file);
773 + }
774 +
775 + if ($existing_file && file_exists($existing_file)) {
776 + $head = wp_remote_head($source);
777 + if (!is_wp_error($head)) {
778 +
779 + // get file size from the header
780 + $header_key = apply_filters('iwp/template/process_attachment/remote_file_size_header_key', 'content-length');
781 + $size = wp_remote_retrieve_header($head, $header_key);
782 + $existing_file_size = filesize($existing_file);
783 +
784 + if ($size != $existing_file_size) {
785 +
786 + // append the size to the attachment salt
787 + $attachment_salt .= $size;
788 + $attachment_id = $attachment->get_attachment_by_hash($source, $attachment_salt);
789 + }
790 + }
791 + }
792 + }
793 + }
794 +
795 + $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
796 + if ($attachment_id <= 0) {
559 797 Logger::write(__CLASS__ . '::process__attachments -remote=' . $source . ' -filename=' . $custom_filename);
560 798 $result = $filesystem->download_file($source, null, null, $custom_filename);
561 799 }
562 800 break;
563 801 case 'ftp':
564 - $ftp_user = isset($row[$row_prefix . '_ftp_user']) ? $row[$row_prefix . '_ftp_user'] : null;
565 - $ftp_host = isset($row[$row_prefix . '_ftp_host']) ? $row[$row_prefix . '_ftp_host'] : null;
566 - $ftp_pass = isset($row[$row_prefix . '_ftp_pass']) ? $row[$row_prefix . '_ftp_pass'] : null;
567 - $base_url = isset($row[$row_prefix . '_ftp_path']) ? $row[$row_prefix . '_ftp_path'] : null;
568 802
803 + if (isset($row[$row_prefix . 'settings._ftp_user'])) {
804 + $ftp_user = $row[$row_prefix . 'settings._ftp_user'];
805 + } elseif (isset($row[$row_prefix . '_ftp_user'])) {
806 + $ftp_user = $row[$row_prefix . '_ftp_user'];
807 + } else {
808 + $ftp_user = null;
809 + }
810 +
811 + if (isset($row[$row_prefix . 'settings._ftp_host'])) {
812 + $ftp_host = $row[$row_prefix . 'settings._ftp_host'];
813 + } elseif (isset($row[$row_prefix . '_ftp_host'])) {
814 + $ftp_host = $row[$row_prefix . '_ftp_host'];
815 + } else {
816 + $ftp_host = null;
817 + }
818 +
819 + if (isset($row[$row_prefix . 'settings._ftp_pass'])) {
820 + $ftp_pass = $row[$row_prefix . 'settings._ftp_pass'];
821 + } elseif (isset($row[$row_prefix . '_ftp_pass'])) {
822 + $ftp_pass = $row[$row_prefix . '_ftp_pass'];
823 + } else {
824 + $ftp_pass = null;
825 + }
826 +
827 + if (isset($row[$row_prefix . 'settings._ftp_path'])) {
828 + $base_url = $row[$row_prefix . 'settings._ftp_path'];
829 + } elseif (isset($row[$row_prefix . '_ftp_path'])) {
830 + $base_url = $row[$row_prefix . '_ftp_path'];
831 + } else {
832 + $base_url = null;
833 + }
834 +
569 835 // check if file hash is already stored
570 836 $source = $base_url . $location;
571 837 if (empty($source)) {
572 838 continue 2;
@@ -571,23 +837,60 @@
571 837 if (empty($source)) {
572 838 continue 2;
573 839 }
574 840
575 - $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
576 -
841 + $attachment_salt = file_exists($source) ? md5_file($source) : '';
577 842 $attachment_id = 0;
578 843 if ($attachment_enable_image_hash == 'yes') {
579 - $attachment_id = $attachment->get_attachment_by_hash($source);
844 + $attachment_id = $attachment->get_attachment_by_hash($source, $attachment_salt);
580 845 }
581 846
582 847 if ($attachment_id <= 0) {
848 +
849 + $main_zip_file = false;
850 + if ($base_url === 'iwp_zip') {
851 + $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
852 + if ($main_zip && file_exists($main_zip)) {
853 + $base_url .= '://' . $main_zip;
854 + $main_zip_file = $main_zip;
855 + }
856 + }
857 +
858 + $zip = $this->get_zip_source($base_url, $filesystem);
859 + if ($zip !== false) {
860 +
861 + if (!$main_zip_file && isset($zip['src'])) {
862 + $result = $ftp->download_file($zip['src'], $ftp_host, $ftp_user, $ftp_pass, $zip['name']);
863 + if (is_wp_error($result)) {
864 + break;
865 + }
866 + }
867 +
868 + $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
869 + if (!$result) {
870 + continue 2;
871 + }
872 +
873 + break;
874 + }
875 + }
876 +
877 + $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
878 + if ($attachment_id <= 0) {
583 879 Logger::write(__CLASS__ . '::process__attachments -ftp=' . $source . ' -filename=' . $custom_filename);
584 880 $result = $ftp->download_file($source, $ftp_host, $ftp_user, $ftp_pass, $custom_filename);
585 881 }
586 882 break;
587 883 case 'local':
588 - $base_url = isset($row[$row_prefix . '_local_url']) ? $row[$row_prefix . '_local_url'] : null;
589 884
885 + if (isset($row[$row_prefix . 'settings._local_url'])) {
886 + $base_url = $row[$row_prefix . 'settings._local_url'];
887 + } elseif (isset($row[$row_prefix . '_local_url'])) {
888 + $base_url = $row[$row_prefix . '_local_url'];
889 + } else {
890 + $base_url = null;
891 + }
892 +
590 893 // check if file hash is already stored
591 894 $source = $base_url . $location;
592 895 if (empty($source)) {
593 896 continue 2;
@@ -592,15 +895,46 @@
592 895 if (empty($source)) {
593 896 continue 2;
594 897 }
595 898
596 - $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
597 899 $attachment_salt = file_exists($source) ? md5_file($source) : '';
598 900 $attachment_id = 0;
599 901 if ($attachment_enable_image_hash == 'yes') {
600 902 $attachment_id = $attachment->get_attachment_by_hash($source, $attachment_salt);
601 903 }
904 +
602 905 if ($attachment_id <= 0) {
906 +
907 + $main_zip_file = false;
908 + if ($base_url === 'iwp_zip') {
909 + $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
910 + if ($main_zip && file_exists($main_zip)) {
911 + $base_url .= '://' . $main_zip;
912 + $main_zip_file = $main_zip;
913 + }
914 + }
915 +
916 + $zip = $this->get_zip_source($base_url, $filesystem);
917 + if ($zip !== false) {
918 +
919 + if (!$main_zip_file && isset($zip['src'])) {
920 + $result = $filesystem->copy($zip['src'], $zip['name']);
921 + if (is_wp_error($result)) {
922 + break;
923 + }
924 + }
925 +
926 + $result = $this->get_file_from_zip($main_zip_file ? $main_zip_file : $zip['name'], $location, $filesystem);
927 + if (!$result) {
928 + continue 2;
929 + }
930 +
931 + break;
932 + }
933 + }
934 +
935 + $custom_filename = apply_filters('iwp/attachment/filename', null, $source);
936 + if ($attachment_id <= 0) {
603 937 Logger::write(__CLASS__ . '::process__attachments -local=' . $source . ' -filename=' . $custom_filename);
604 938 $result = $filesystem->copy_file($source, null, $custom_filename);
605 939 }
606 940 break;
@@ -615,9 +949,15 @@
615 949
616 950 break;
617 951 }
618 952
619 - $meta_enabled = isset($row[$row_prefix . '_meta._enabled']) && $row[$row_prefix . '_meta._enabled'] === 'yes' ? true : false;
953 + if (isset($row[$row_prefix . 'settings._meta._enabled'])) {
954 + $meta_enabled = $row[$row_prefix . 'settings._meta._enabled'] === 'yes' ? true : false;
955 + } elseif (isset($row[$row_prefix . '_meta._enabled'])) {
956 + $meta_enabled = $row[$row_prefix . '_meta._enabled'] === 'yes' ? true : false;
957 + } else {
958 + $meta_enabled = false;
959 + }
620 960
621 961 // insert attachment
622 962 if ($attachment_id <= 0) {
623 963
@@ -638,8 +978,32 @@
638 978 $attachment_args['caption'] = isset($attachment_captions[$location_counter]) ? $attachment_captions[$location_counter] : null;
639 979 $attachment_args['description'] = isset($attachment_descriptions[$location_counter]) ? $attachment_descriptions[$location_counter] : null;;
640 980 }
641 981
982 + // resize attachment
983 + if ($crop_details = apply_filters('iwp/importer/template/process_attachment/resize', '__return_false')) {
984 +
985 + if (is_array($crop_details) && count($crop_details) == 3 && file_exists($result['dest'])) {
986 +
987 + list($max_w, $max_h, $crop) = $crop_details;
988 +
989 + if (!is_null($max_w)) {
990 + $max_w = absint($max_w);
991 + }
992 + if (!is_null($max_h)) {
993 + $max_h = absint($max_h);
994 + }
995 +
996 + $editor = wp_get_image_editor($result['dest']);
997 + if (!is_wp_error($editor)) {
998 + $editor->resize($max_w, $max_h, (bool)$crop);
999 + $editor->save($result['dest']);
1000 + } else {
1001 + Logger::write(__CLASS__ . '::process__attachments -resize -error=' . $editor->get_error_message());
1002 + }
1003 + }
1004 + }
1005 +
642 1006 $attachment_id = $attachment->insert_attachment($post_id, $result['dest'], $result['mime'], $attachment_args);
643 1007 if (is_wp_error($attachment_id)) {
644 1008 Logger::write(__CLASS__ . '::process__attachments -error=' . $attachment_id->get_error_message());
645 1009 continue;
@@ -693,8 +1057,47 @@
693 1057 return $attachment_ids;
694 1058 }
695 1059
696 1060 /**
1061 + * Remove custom field meta fields from the provided array based on importer permissions.
1062 + *
1063 + * @param string[string] $custom_fields
1064 + * @param ParsedData $data
1065 + * @param string $group_name
1066 + * @param string $permission_key
1067 + * @param string $prefix
1068 + * @return string[string]
1069 + */
1070 + public function process_attachment_meta_permissions($custom_fields, $data, $group_name, $permission_key, $prefix)
1071 + {
1072 + $allowed = $data->permission()->validate([
1073 + $permission_key . '._alt' => '',
1074 + $permission_key . '._title' => '',
1075 + $permission_key . '._caption' => '',
1076 + $permission_key . '._description' => ''
1077 + ], $data->getMethod(), $group_name);
1078 +
1079 + if (!isset($allowed[$permission_key . '._alt'])) {
1080 + // remove alt
1081 + unset($custom_fields[$prefix . 'settings._meta._alt']);
1082 + }
1083 + if (!isset($allowed[$permission_key . '._title'])) {
1084 + // remove title
1085 + unset($custom_fields[$prefix . 'settings._meta._title']);
1086 + }
1087 + if (!isset($allowed[$permission_key . '._caption'])) {
1088 + // remove caption
1089 + unset($custom_fields[$prefix . 'settings._meta._caption']);
1090 + }
1091 + if (!isset($allowed[$permission_key . '._description'])) {
1092 + // remove description
1093 + unset($custom_fields[$prefix . 'settings._meta._description']);
1094 + }
1095 +
1096 + return $custom_fields;
1097 + }
1098 +
1099 + /**
697 1100 * Add error message
698 1101 *
699 1102 * @param string|\WP_Error $error
700 1103 * @return void
@@ -705,6 +1108,127 @@
705 1108 $error = new \WP_Error('IWP_TEMP_ERR', $error);
706 1109 }
707 1110
708 1111 $this->errors[] = $error;
1112 + }
1113 +
1114 + /**
1115 + * Convert fields/headings to data map
1116 + *
1117 + * @param mixed $fields
1118 + * @param ImporterModel $importer
1119 + * @return array
1120 + */
1121 + public function generate_field_map($fields, $importer)
1122 + {
1123 + return ['enabled' => [], 'map' => []];
1124 + }
1125 +
1126 + public function get_zip_source($base_url, $filesystem)
1127 + {
1128 + $zip_parts = [];
1129 + if (preg_match('/^iwp_zip:\/\/(.*?)$/', $base_url, $zip_parts) === 1) {
1130 +
1131 + $iwp_tmp = $filesystem->get_temp_directory();
1132 +
1133 + $iwp_tmp .= DIRECTORY_SEPARATOR . 'zip';
1134 + if (!is_dir($iwp_tmp)) {
1135 + mkdir($iwp_tmp);
1136 + }
1137 +
1138 + $hash = md5($base_url);
1139 + $iwp_tmp .= DIRECTORY_SEPARATOR . $hash . '.zip';
1140 + if (!file_exists($iwp_tmp)) {
1141 + return ['src' => $zip_parts[1], 'name' => $iwp_tmp];
1142 + }
1143 +
1144 + return ['name' => $iwp_tmp];
1145 + }
1146 +
1147 + return false;
1148 + }
1149 +
1150 + public function get_file_from_zip($zip_path, $filename, $filesystem)
1151 + {
1152 + $zip = new \ZipArchive();
1153 + if ($zip->open($zip_path) === true) {
1154 + $output_data = $zip->getFromName($filename);
1155 + if ($output_data === false) {
1156 + return false;
1157 + }
1158 +
1159 + return $filesystem->string_to_file($output_data, $filename);
1160 + }
1161 +
1162 + return false;
1163 + }
1164 +
1165 + public function try_use_main_zip($base_url, $location)
1166 + {
1167 + if ($base_url === 'iwp_zip') {
1168 +
1169 + $main_zip = get_post_meta($this->importer->getId(), '_iwp_zip', true);
1170 + $source = $main_zip . $location;
1171 + $base_url .= $main_zip;
1172 + }
1173 + }
1174 +
1175 + public function get_permission_fields($importer_model)
1176 + {
1177 + return [];
1178 + }
1179 +
1180 + public function register_settings() {}
1181 +
1182 + public function register_options()
1183 + {
1184 + return [];
1185 + }
1186 +
1187 + public function get_default_enabled_fields()
1188 + {
1189 + return $this->default_enabled_fields;
1190 + }
1191 +
1192 +
1193 + public function get_unique_identifier_options($importer_model, $unique_fields = [])
1194 + {
1195 + $output = [];
1196 + return $output;
1197 + }
1198 +
1199 + public function get_unique_identifier_options_from_map($importer_model, $unique_fields, $field_map, $optional_fields)
1200 + {
1201 + $output = [];
1202 + $mapped_data = $importer_model->getMap();
1203 +
1204 + foreach ($field_map as $field_id => $field_map_key) {
1205 +
1206 + if (isset($output[$field_id])) {
1207 + continue;
1208 + }
1209 +
1210 + $output[$field_id] = [
1211 + 'value' => $field_id,
1212 + 'label' => $field_id,
1213 + 'uid' => false,
1214 + 'active' => false,
1215 + ];
1216 +
1217 + if (in_array($field_id, $unique_fields)) {
1218 + $output[$field_id]['uid'] = true;
1219 + }
1220 +
1221 + if (!isset($mapped_data[$field_map_key]) || empty($mapped_data[$field_map_key])) {
1222 + continue;
1223 + }
1224 +
1225 + if (in_array($field_id, $optional_fields) && true !== $importer_model->isEnabledField($field_map_key)) {
1226 + continue;
1227 + }
1228 +
1229 + $output[$field_id]['active'] = true;
1230 + }
1231 +
1232 + return $output;
709 1233 }
710 1234 }