Import any XML or CSV File to WordPress - Version 3.4.8

Version Description

  • improvement: various import speed optimizations
  • bug fix: remove deprecated function calls for PHP 7.2 compatibility
  • bug fix: delete db tables when mu blog deleted
  • bug fix: remove BOM from import templates
  • bug fix: saving CSV delimiter when changing import file
Download this release

Release Info

Developer soflyy
Plugin Icon 128x128 Import any XML or CSV File to WordPress
Version 3.4.8
Comparing to
See all releases

Code changes from version 3.4.7 to 3.4.8

Files changed (50) hide show
  1. actions/add_attachment.php +25 -0
  2. actions/admin_notices.php +10 -12
  3. actions/attachment_updated.php +25 -0
  4. actions/delete_post.php +10 -3
  5. actions/pmxi_after_xml_import.php +20 -0
  6. actions/pmxi_before_xml_import.php +10 -0
  7. actions/wp_ajax_test_images.php +2 -2
  8. classes/PHPExcel/Worksheet/AutoFilter/Column.php +7 -7
  9. classes/api.php +42 -9
  10. classes/chunk.php +0 -6
  11. classes/config.php +4 -9
  12. classes/error.php +82 -0
  13. classes/render.php +1 -1
  14. controllers/admin/addons.php +151 -140
  15. controllers/admin/import.php +72 -18
  16. controllers/controller/admin.php +7 -2
  17. filters/wpmu_drop_tables.php +10 -0
  18. helpers/functions.php +10 -2
  19. helpers/get_file_curl.php +1 -1
  20. helpers/pmxi_findDuplicates.php +2 -2
  21. helpers/wp_all_import_get_feed_type.php +0 -0
  22. helpers/wp_all_import_get_gz.php +0 -0
  23. helpers/wp_all_import_get_image_from_gallery.php +16 -7
  24. helpers/wp_all_import_get_url.php +126 -0
  25. helpers/wp_all_import_remove_source.php +4 -2
  26. helpers/wp_delete_attachments.php +17 -27
  27. libraries/XmlImportTemplateCodeGenerator.php +3 -5
  28. models/image/list.php +52 -0
  29. models/image/record.php +15 -0
  30. models/import/record.php +1090 -709
  31. plugin.php +83 -30
  32. readme.txt +9 -2
  33. schema.php +10 -1
  34. static/css/admin.css +8 -2
  35. static/img/help.png +0 -0
  36. static/js/admin.js +21 -11
  37. static/js/jquery/chosen.jquery.js +1269 -0
  38. static/js/jquery/chosen.jquery.min.js +2 -0
  39. static/js/jquery/css/chosen/chosen-sprite.png +0 -0
  40. static/js/jquery/css/chosen/chosen-sprite@2x.png +0 -0
  41. static/js/jquery/css/chosen/chosen.css +450 -0
  42. views/admin/import/index.php +17 -3
  43. views/admin/import/options.php +6 -0
  44. views/admin/import/options/_settings_template.php +17 -3
  45. views/admin/import/options/scheduling/_scheduling_ui.php +15 -0
  46. views/admin/import/process.php +14 -8
  47. views/admin/import/template/_featured_template.php +22 -2
  48. views/admin/import/template/_other_template.php +2 -2
  49. views/admin/import/template/_taxonomies_template.php +1 -1
  50. views/admin/manage/index.php +4 -5
actions/add_attachment.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fires once an attachment has been added.
4
+ *
5
+ * @since 2.0.0
6
+ *
7
+ * @param int $post_ID Attachment ID.
8
+ */
9
+ function pmxi_add_attachment($post_ID){
10
+ // add image filename to pmxi_images table
11
+ if (wp_attachment_is_image($post_ID)){
12
+ $imageRecord = new PMXI_Image_Record();
13
+ $imageRecord->getBy(array(
14
+ 'attachment_id' => $post_ID
15
+ ));
16
+ if ($imageRecord->isEmpty()){
17
+ $image_name = basename(wp_get_attachment_url( $post_ID ));
18
+ $imageRecord->set(array(
19
+ 'attachment_id' => $post_ID,
20
+ 'image_url' => '',
21
+ 'image_filename' => $image_name
22
+ ))->insert();
23
+ }
24
+ }
25
+ }
actions/admin_notices.php CHANGED
@@ -1,15 +1,13 @@
1
  <?php
2
 
3
- function pmxi_admin_notices() {
4
- // notify user if history folder is not writable
5
- $uploads = wp_upload_dir();
6
 
7
  // compare woocommerce add-on version
8
  if ( class_exists( 'PMWI_Plugin' ) and ( defined('PMWI_VERSION') and version_compare(PMWI_VERSION, '2.1.4') < 0 and PMWI_EDITION == 'paid' or defined('PMWI_FREE_VERSION') and version_compare(PMWI_FREE_VERSION, '1.2.2') < 0 and PMWI_EDITION == 'free') ) {
9
  ?>
10
  <div class="error"><p>
11
  <?php printf(
12
- __('<b>%s Plugin</b>: Please update your WP All Import WooCommerce add-on to the latest version', 'pmwi_plugin'),
13
  PMWI_Plugin::getInstance()->getName()
14
  ) ?>
15
  </p></div>
@@ -36,7 +34,7 @@ function pmxi_admin_notices() {
36
  ?>
37
  <div class="error"><p>
38
  <?php printf(
39
- __('<b>%s Plugin</b>: Please update your WP All Import ACF add-on to the latest version', 'pmwi_plugin'),
40
  PMAI_Plugin::getInstance()->getName()
41
  ) ?>
42
  </p></div>
@@ -53,7 +51,7 @@ function pmxi_admin_notices() {
53
  ?>
54
  <div class="error"><p>
55
  <?php printf(
56
- __('<b>%s Plugin</b>: Please update your WP All Import Linkcloak add-on to the latest version', 'pmwi_plugin'),
57
  PMLCA_Plugin::getInstance()->getName()
58
  ) ?>
59
  </p></div>
@@ -70,7 +68,7 @@ function pmxi_admin_notices() {
70
  ?>
71
  <div class="error"><p>
72
  <?php printf(
73
- __('<b>%s Plugin</b>: Please update your WP All Import User add-on to the latest version', 'pmwi_plugin'),
74
  PMUI_Plugin::getInstance()->getName()
75
  ) ?>
76
  </p></div>
@@ -87,7 +85,7 @@ function pmxi_admin_notices() {
87
  ?>
88
  <div class="error"><p>
89
  <?php printf(
90
- __('<b>%s Plugin</b>: Please update your WP All Import WPML add-on to the latest version', 'pmwi_plugin'),
91
  PMLI_Plugin::getInstance()->getName()
92
  ) ?>
93
  </p></div>
@@ -116,16 +114,16 @@ function pmxi_admin_notices() {
116
  foreach ($warnings as $code) {
117
  switch ($code) {
118
  case 1:
119
- $m = __('<strong>Warning:</strong> your title is blank.', 'pmxi_plugin');
120
  break;
121
  case 2:
122
- $m = __('<strong>Warning:</strong> your content is blank.', 'pmxi_plugin');
123
  break;
124
  case 3:
125
- $m = __('<strong>Warning:</strong> You must <a href="http://www.wpallimport.com/upgrade-to-pro/?utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=images" target="_blank">upgrade to the Pro edition of WP All Import</a> to import images. The settings you configured in the images section will be ignored.', 'pmxi_plugin');
126
  break;
127
  case 4:
128
- $m = __('<strong>Warning:</strong> You must <a href="https://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=1748&edd_options%5Bprice_id%5D=0&utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=custom-fields" target="_blank">upgrade to the Pro edition of WP All Import</a> to import data to Custom Fields. The settings you configured in the Custom Fields section will be ignored.', 'pmxi_plugin');
129
  break;
130
  default:
131
  $m = false;
1
  <?php
2
 
3
+ function pmxi_admin_notices() {
 
 
4
 
5
  // compare woocommerce add-on version
6
  if ( class_exists( 'PMWI_Plugin' ) and ( defined('PMWI_VERSION') and version_compare(PMWI_VERSION, '2.1.4') < 0 and PMWI_EDITION == 'paid' or defined('PMWI_FREE_VERSION') and version_compare(PMWI_FREE_VERSION, '1.2.2') < 0 and PMWI_EDITION == 'free') ) {
7
  ?>
8
  <div class="error"><p>
9
  <?php printf(
10
+ __('<b>%s Plugin</b>: Please update your WP All Import WooCommerce add-on to the latest version', 'wp_all_import_plugin'),
11
  PMWI_Plugin::getInstance()->getName()
12
  ) ?>
13
  </p></div>
34
  ?>
35
  <div class="error"><p>
36
  <?php printf(
37
+ __('<b>%s Plugin</b>: Please update your WP All Import ACF add-on to the latest version', 'wp_all_import_plugin'),
38
  PMAI_Plugin::getInstance()->getName()
39
  ) ?>
40
  </p></div>
51
  ?>
52
  <div class="error"><p>
53
  <?php printf(
54
+ __('<b>%s Plugin</b>: Please update your WP All Import Linkcloak add-on to the latest version', 'wp_all_import_plugin'),
55
  PMLCA_Plugin::getInstance()->getName()
56
  ) ?>
57
  </p></div>
68
  ?>
69
  <div class="error"><p>
70
  <?php printf(
71
+ __('<b>%s Plugin</b>: Please update your WP All Import User add-on to the latest version', 'wp_all_import_plugin'),
72
  PMUI_Plugin::getInstance()->getName()
73
  ) ?>
74
  </p></div>
85
  ?>
86
  <div class="error"><p>
87
  <?php printf(
88
+ __('<b>%s Plugin</b>: Please update your WP All Import WPML add-on to the latest version', 'wp_all_import_plugin'),
89
  PMLI_Plugin::getInstance()->getName()
90
  ) ?>
91
  </p></div>
114
  foreach ($warnings as $code) {
115
  switch ($code) {
116
  case 1:
117
+ $m = __('<strong>Warning:</strong> your title is blank.', 'wp_all_import_plugin');
118
  break;
119
  case 2:
120
+ $m = __('<strong>Warning:</strong> your content is blank.', 'wp_all_import_plugin');
121
  break;
122
  case 3:
123
+ $m = __('<strong>Warning:</strong> You must <a href="http://www.wpallimport.com/upgrade-to-pro/?utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=images" target="_blank">upgrade to the Pro edition of WP All Import</a> to import images. The settings you configured in the images section will be ignored.', 'wp_all_import_plugin');
124
  break;
125
  case 4:
126
+ $m = __('<strong>Warning:</strong> You must <a href="https://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=1748&edd_options%5Bprice_id%5D=0&utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=custom-fields" target="_blank">upgrade to the Pro edition of WP All Import</a> to import data to Custom Fields. The settings you configured in the Custom Fields section will be ignored.', 'wp_all_import_plugin');
127
  break;
128
  default:
129
  $m = false;
actions/attachment_updated.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fires once an existing attachment has been updated.
4
+ *
5
+ * @since 4.4.0
6
+ *
7
+ * @param int $post_ID Post ID.
8
+ * @param WP_Post $post_after Post object following the update.
9
+ * @param WP_Post $post_before Post object before the update.
10
+ */
11
+ function pmxi_attachment_updated($post_ID, $post_after, $post_before){
12
+ // update image filename in pmxi_images table
13
+ if (wp_attachment_is_image($post_ID)){
14
+ $imageRecord = new PMXI_Image_Record();
15
+ $imageRecord->getBy(array(
16
+ 'attachment_id' => $post_ID
17
+ ));
18
+ if (!$imageRecord->isEmpty()){
19
+ $image_name = basename(wp_get_attachment_url( $post_ID ));
20
+ $imageRecord->set(array(
21
+ 'image_filename' => $image_name
22
+ ))->update();
23
+ }
24
+ }
25
+ }
actions/delete_post.php CHANGED
@@ -1,8 +1,15 @@
1
  <?php
2
 
3
  function pmxi_delete_post($post_id) {
4
- if (is_numeric($post_id)){
5
- $post = new PMXI_Post_Record();
6
- $post->getBy('post_id', $post_id)->isEmpty() or $post->delete();
 
 
 
 
 
 
 
7
  }
8
  }
1
  <?php
2
 
3
  function pmxi_delete_post($post_id) {
4
+ if (!empty($post_id) && is_numeric($post_id)){
5
+ $post = new PMXI_Post_Record();
6
+ $is_post = ! $post->getBy( 'post_id', $post_id )->isEmpty();
7
+
8
+ if ( $is_post ) {
9
+ $post->delete();
10
+ } else {
11
+ $image = new PMXI_Image_Record();
12
+ $image->getBy( 'attachment_id', $post_id )->isEmpty() or $image->delete();
13
+ }
14
  }
15
  }
actions/pmxi_after_xml_import.php CHANGED
@@ -17,6 +17,26 @@ function pmxi_pmxi_after_xml_import( $import_id, $import )
17
  }
18
  }
19
  delete_option('wp_all_import_posts_hierarchy_' . $import_id);
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
 
 
 
21
  }
 
 
 
 
 
22
  }
17
  }
18
  }
19
  delete_option('wp_all_import_posts_hierarchy_' . $import_id);
20
+
21
+ // Update term count after import process is complete.
22
+ foreach ( (array) get_object_taxonomies( $import->options['custom_type'] ) as $taxonomy ) {
23
+ $term_ids = get_terms(
24
+ array(
25
+ 'taxonomy' => $taxonomy,
26
+ 'hide_empty' => false,
27
+ 'fields' => 'ids',
28
+ )
29
+ );
30
+ wp_update_term_count_now( $term_ids, $taxonomy );
31
+ }
32
  }
33
+
34
+ // Update post count only once after import process is completed.
35
+ wp_all_import_update_post_count();
36
  }
37
+
38
+ // Add removed action during import.
39
+ add_action( 'transition_post_status', '_update_term_count_on_transition_post_status', 10, 3 );
40
+ add_action( 'transition_post_status', '_update_posts_count_on_transition_post_status', 10, 3 );
41
+ add_action( 'post_updated', 'wp_save_post_revision', 10, 1 );
42
  }
actions/pmxi_before_xml_import.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function pmxi_pmxi_before_xml_import( $import_id )
3
+ {
4
+ delete_option('wp_all_import_taxonomies_hierarchy_' . $import_id);
5
+
6
+ // Remove some costly unnecessary actions during import.
7
+ remove_action( 'transition_post_status', '_update_term_count_on_transition_post_status', 10 );
8
+ remove_action( 'transition_post_status', '_update_posts_count_on_transition_post_status', 10 );
9
+ remove_action( 'post_updated', 'wp_save_post_revision', 10 );
10
+ }
actions/wp_ajax_test_images.php CHANGED
@@ -99,11 +99,11 @@ function pmxi_wp_ajax_test_images(){
99
 
100
  if ((int)$success_images === 1)
101
  {
102
- $success_msg = sprintf(__('%d image was successfully founded in media gallery', 'wp_all_import_plugin'), $success_images);
103
  }
104
  elseif ((int)$success_images > 1)
105
  {
106
- $success_msg = sprintf(__('%d images were successfully founded in media gallery', 'wp_all_import_plugin'), $success_images);
107
  }
108
 
109
  break;
99
 
100
  if ((int)$success_images === 1)
101
  {
102
+ $success_msg = sprintf(__('%d image was successfully found in media gallery', 'wp_all_import_plugin'), $success_images);
103
  }
104
  elseif ((int)$success_images > 1)
105
  {
106
+ $success_msg = sprintf(__('%d images were successfully found in media gallery', 'wp_all_import_plugin'), $success_images);
107
  }
108
 
109
  break;
classes/PHPExcel/Worksheet/AutoFilter/Column.php CHANGED
@@ -261,7 +261,7 @@ class PHPExcel_Worksheet_AutoFilter_Column
261
  */
262
  public function setAttribute($pName, $pValue)
263
  {
264
- $this->attributes[$pName] = $pValue;
265
 
266
  return $this;
267
  }
@@ -284,8 +284,8 @@ class PHPExcel_Worksheet_AutoFilter_Column
284
  */
285
  public function getAttribute($pName)
286
  {
287
- if (isset($this->attributes[$pName])) {
288
- return $this->attributes[$pName];
289
  }
290
  return null;
291
  }
@@ -310,9 +310,9 @@ class PHPExcel_Worksheet_AutoFilter_Column
310
  public function getRule($pIndex)
311
  {
312
  if (!isset($this->ruleset[$pIndex])) {
313
- $this->ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);
314
  }
315
- return $this->ruleset[$pIndex];
316
  }
317
 
318
  /**
@@ -351,8 +351,8 @@ class PHPExcel_Worksheet_AutoFilter_Column
351
  */
352
  public function deleteRule($pIndex)
353
  {
354
- if (isset($this->ruleset[$pIndex])) {
355
- unset($this->ruleset[$pIndex]);
356
  // If we've just deleted down to a single rule, then reset And/Or joining to Or
357
  if (count($this->ruleset) <= 1) {
358
  $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
261
  */
262
  public function setAttribute($pName, $pValue)
263
  {
264
+ $this->{attributes[$pName]} = $pValue;
265
 
266
  return $this;
267
  }
284
  */
285
  public function getAttribute($pName)
286
  {
287
+ if (isset($this->{attributes[$pName]})) {
288
+ return $this->{attributes[$pName]};
289
  }
290
  return null;
291
  }
310
  public function getRule($pIndex)
311
  {
312
  if (!isset($this->ruleset[$pIndex])) {
313
+ $this->{ruleset[$pIndex]} = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);
314
  }
315
+ return $this->{ruleset[$pIndex]};
316
  }
317
 
318
  /**
351
  */
352
  public function deleteRule($pIndex)
353
  {
354
+ if (isset($this->{ruleset[$pIndex]})) {
355
+ unset($this->{ruleset[$pIndex]});
356
  // If we've just deleted down to a single rule, then reset And/Or joining to Or
357
  if (count($this->ruleset) <= 1) {
358
  $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
classes/api.php CHANGED
@@ -376,7 +376,7 @@ class PMXI_API
376
 
377
  }
378
 
379
- $uploads = wp_upload_dir();
380
 
381
  $uploads = apply_filters('wp_all_import_images_uploads_dir', $uploads, false, false, false);
382
 
@@ -385,15 +385,37 @@ class PMXI_API
385
  $download_image = true;
386
  $result = false;
387
  $wp_filetype = false;
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
- global $wpdb;
390
-
391
- $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $file_type);
 
392
 
393
- if ( $attch != null ){
 
 
 
 
 
 
 
 
 
 
394
 
395
  return $attch->ID;
396
-
397
  }
398
 
399
  $image_filename = wp_unique_filename($targetDir, $image_name);
@@ -562,14 +584,25 @@ class PMXI_API
562
  if (trim($image_meta['caption']))
563
  $attachment['post_content'] = $image_meta['caption'];
564
  }
565
-
566
  $attid = wp_insert_attachment($attachment, $image_filepath, $pid);
567
 
568
  if (is_wp_error($attid)) {
569
  $logger and call_user_func($logger, __('- <b>WARNING</b>', 'wp_all_import_plugin') . ': ' . $attid->get_error_message());
570
  return false;
571
- } else {
572
- wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $image_filepath));
 
 
 
 
 
 
 
 
 
 
 
573
  $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully created for image `%s`', 'wp_all_import_plugin'), $targetUrl . '/' . $image_filename));
574
  return $attid;
575
  }
376
 
377
  }
378
 
379
+ $uploads = wp_upload_dir();
380
 
381
  $uploads = apply_filters('wp_all_import_images_uploads_dir', $uploads, false, false, false);
382
 
385
  $download_image = true;
386
  $result = false;
387
  $wp_filetype = false;
388
+ $attch = false;
389
+
390
+ // trying to find existing image in hash table
391
+ if ("yes" == $download_images){
392
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by URL...', 'wp_all_import_plugin'), rawurldecode($img_url)));
393
+ $imageList = new PMXI_Image_List();
394
+ $attch = $imageList->getExistingImageByUrl($img_url);
395
+ if ($attch){
396
+ $logger and call_user_func($logger, sprintf(__('Existing image was found by URL `%s`...', 'wp_all_import_plugin'), $img_url));
397
+ return $attch->ID;
398
+ }
399
+ }
400
 
401
+ if (empty($attch)){
402
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by `_wp_attached_file` `%s`...', 'wp_all_import_plugin'), $img_url, $image_name));
403
+ $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $file_type);
404
+ }
405
 
406
+ if ( ! empty($attch) ){
407
+ $logger and call_user_func($logger, sprintf(__('- Existing image was found by `_wp_attached_file` ...', 'wp_all_import_plugin'), $img_url));
408
+ $imageRecord = new PMXI_Image_Record();
409
+ $imageRecord->getBy(array(
410
+ 'attachment_id' => $attch->ID
411
+ ));
412
+ $imageRecord->isEmpty() and $imageRecord->set(array(
413
+ 'attachment_id' => $attch->ID,
414
+ 'image_url' => $img_url,
415
+ 'image_filename' => $image_name
416
+ ))->insert();
417
 
418
  return $attch->ID;
 
419
  }
420
 
421
  $image_filename = wp_unique_filename($targetDir, $image_name);
584
  if (trim($image_meta['caption']))
585
  $attachment['post_content'] = $image_meta['caption'];
586
  }
587
+ remove_all_actions('add_attachment');
588
  $attid = wp_insert_attachment($attachment, $image_filepath, $pid);
589
 
590
  if (is_wp_error($attid)) {
591
  $logger and call_user_func($logger, __('- <b>WARNING</b>', 'wp_all_import_plugin') . ': ' . $attid->get_error_message());
592
  return false;
593
+ } else {
594
+ /** Fires once an attachment has been added. */
595
+ do_action( 'wp_all_import_add_attachment', $attid );
596
+ wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $image_filepath));
597
+ $imageRecord = new PMXI_Image_Record();
598
+ $imageRecord->getBy(array(
599
+ 'attachment_id' => $attid
600
+ ));
601
+ $imageRecord->isEmpty() and $imageRecord->set(array(
602
+ 'attachment_id' => $attid,
603
+ 'image_url' => $img_url,
604
+ 'image_filename' => $image_filename
605
+ ))->insert();
606
  $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully created for image `%s`', 'wp_all_import_plugin'), $targetUrl . '/' . $image_filename));
607
  return $attid;
608
  }
classes/chunk.php CHANGED
@@ -171,12 +171,6 @@ class PMXI_Chunk {
171
  );
172
  // Works like an XmlReader, and walks the XML tree node by node. Captures by node depth setting.
173
  $parser = new Parser\StringWalker($parseroptions);
174
- // Create the streamer
175
- $streamer = new XmlStringStreamer($parser, $streamProvider);
176
- while ($node = $streamer->getNode()) {
177
- // $simpleXmlNode = simplexml_load_string($node);
178
- // echo (string)$simpleXmlNode->firstName;
179
- }
180
 
181
  $this->cloud = $parser->cloud;
182
 
171
  );
172
  // Works like an XmlReader, and walks the XML tree node by node. Captures by node depth setting.
173
  $parser = new Parser\StringWalker($parseroptions);
 
 
 
 
 
 
174
 
175
  $this->cloud = $parser->cloud;
176
 
classes/config.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  /**
3
  * Class to load config files
4
- *
5
- * @author Maksym Tsypliakov <maksym.tsypliakov@gmail.com>
6
  */
7
  class PMXI_Config implements IteratorAggregate {
8
  /**
@@ -39,13 +39,8 @@ class PMXI_Config implements IteratorAggregate {
39
  } else {
40
  $filePath = realpath($filePath);
41
  if ($filePath and ! in_array($filePath, $this->loaded)) {
42
- require $filePath;
43
- //handle unc paths for the anonymous function
44
- if(substr($filePath, 0, 2) == "\\\\"){
45
- $filePath = str_replace('\\','\\\\',$filePath);
46
- }
47
- $sandbox = create_function('', "require '$filePath'; if(array_keys(get_defined_vars()) != array('config')) return array(); return \$config;");
48
- $config = $sandbox();
49
  $this->loaded[] = $filePath;
50
  $this->config = array_merge($this->config, $config);
51
  }
1
  <?php
2
  /**
3
  * Class to load config files
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
  */
7
  class PMXI_Config implements IteratorAggregate {
8
  /**
39
  } else {
40
  $filePath = realpath($filePath);
41
  if ($filePath and ! in_array($filePath, $this->loaded)) {
42
+ require $filePath;
43
+ $config = (!isset($config)) ? array() : $config;
 
 
 
 
 
44
  $this->loaded[] = $filePath;
45
  $this->config = array_merge($this->config, $config);
46
  }
classes/error.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PMXI_Error{
4
+
5
+ public $recordNumber;
6
+
7
+ public function __construct($recordNumber = false) {
8
+ $this->recordNumber = $recordNumber;
9
+ }
10
+
11
+ public function handle(){
12
+
13
+ $error = $this->getLastError();
14
+ $trace = $this->trace();
15
+ if($error && strpos($error['file'], 'functions.php') !== false){
16
+ $wp_uploads = $this->getUploadsDir();
17
+ $functions = 'in '.$wp_uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'functions.php:'.$error['line'];
18
+ $error['message'] = str_replace($functions, '', $error['message']);
19
+ $error['message'] = str_replace("\\n",'',$error['message']);
20
+ $errorParts = explode('Stack trace', $error['message']);
21
+ $error['message'] = $errorParts[0];
22
+ $error['message'] .=' on line '.$error['line'];
23
+ $error['message'] = str_replace("\n",'',$error['message']);
24
+ $error['message'] = str_replace("Uncaught Error:", '', $error['message']);
25
+ $error['message'] = 'PHP Error: ' . $error['message'];
26
+ $error['message'] = str_replace(' ', ' ', $error['message']);
27
+ echo "[[ERROR]]";
28
+ if($error['message'] == '') {
29
+ $error['message'] = __('An unknown error occured', 'wp_all_import_plugin');
30
+ }
31
+ $this->terminate(json_encode(array('error' => '<span class="error">'.$error['message'].' of the Functions Editor'.'</span>', 'line' => $error['line'], 'title' => __('PHP Error','wp_all_import_plugin'))));
32
+ } else if(strpos($error['file'], 'XMLWriter.php') !== false ) {
33
+ if(strpos($error['message'],'syntax error, unexpected') !== false) {
34
+ echo "[[ERROR]]";
35
+ $this->terminate(json_encode(array('error'=>__('You probably forgot to close a quote', 'wp_all_import_plugin'),'title' => __('PHP Error','wp_all_import_plugin'))));
36
+ }
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @return array
42
+ */
43
+ protected function getLastError()
44
+ {
45
+ return error_get_last();
46
+ }
47
+
48
+ /**
49
+ * @return mixed
50
+ */
51
+ protected function getUploadsDir()
52
+ {
53
+ return wp_upload_dir();
54
+ }
55
+
56
+ /**
57
+ * Hack to be able to test the class in isolation
58
+ *
59
+ * @param $message
60
+ */
61
+ protected function terminate($message)
62
+ {
63
+ exit($message);
64
+ }
65
+
66
+ protected function trace(){
67
+ $e = new Exception();
68
+ return $e->getTraceAsString();
69
+ // return debug_backtrace();
70
+ }
71
+
72
+ public function import_data_handler($errno, $errstr, $errfile, $errline) {
73
+ error_log('Found import exception: ' . $errstr . ' ' . $errno . ' ' . $errfile . ' ' . $errline . ' for record #' . $this->recordNumber);
74
+ // trigger_error('TEST');
75
+ // throw new XmlImportException($errstr, $errno, 0, $errfile, $errline);
76
+ }
77
+
78
+ public function parse_data_handler($errno, $errstr, $errfile, $errline) {
79
+ error_log('Found parse exception: ' . $errstr . ' ' . $errno . ' ' . $errfile . ' ' . $errline);
80
+ throw new XmlImportException($errstr, $errno);
81
+ }
82
+ }
classes/render.php CHANGED
@@ -56,7 +56,7 @@ if ( ! class_exists('PMXI_Render')){
56
  if (!empty($child->wholeText)){
57
  self::render_csv_text(trim($child->wholeText), $shorten, $is_render_collapsed);
58
  }
59
- elseif (is_callable(array($child, 'nodeValue'), true) && !empty($child->nodeValue)){
60
  self::render_csv_text(trim($child->nodeValue), $shorten, $is_render_collapsed);
61
  }
62
  } else {
56
  if (!empty($child->wholeText)){
57
  self::render_csv_text(trim($child->wholeText), $shorten, $is_render_collapsed);
58
  }
59
+ elseif (is_callable(array($child, 'nodeValue'), true) && isset($child->nodeValue)){
60
  self::render_csv_text(trim($child->nodeValue), $shorten, $is_render_collapsed);
61
  }
62
  } else {
controllers/admin/addons.php CHANGED
@@ -1,144 +1,155 @@
1
- <?php
2
  /**
3
  * Admin Add-ons page
4
- *
5
- * @author Max Tsiplyakov <makstsiplyakov@gmail.com>
6
  */
7
- class PMXI_Admin_Addons extends PMXI_Controller_Admin {
8
-
9
- public static $addons = array('PMWI_Plugin' => 0, 'PMAI_Plugin' => 0, 'PMWITabs_Plugin' => 0, 'PMLI_Plugin' => 0, 'PMLCA_Plugin' => 0, 'PMUI_Plugin' => 0); // inactive by default
10
-
11
- public static $premium = array();
12
-
13
- public static $free = array();
14
-
15
- public function __construct() {
16
-
17
- parent::__construct();
18
-
19
- // Woocommerce add-on
20
- self::$premium['PMWI_Plugin'] = array(
21
- 'title' => __("WooCommerce Addon",'wp_all_import_plugin'),
22
- 'description' => __("Import Products from any XML or CSV to WooCommerce",'wp_all_import_plugin'),
23
- 'thumbnail' => 'http://placehold.it/220x220',
24
- 'active' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'paid'),
25
- 'free_installed' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'free'),
26
- 'required_plugins' => false,
27
- 'url' => 'http://www.wpallimport.com/woocommerce-product-import'
28
- );
29
-
30
- // ACF add-on
31
- self::$premium['PMAI_Plugin'] = array(
32
- 'title' => __("ACF Addon",'wp_all_import_plugin'),
33
- 'description' => __("Import to advanced custom fields",'wp_all_import_plugin'),
34
- 'thumbnail' => 'http://placehold.it/220x220',
35
- 'active' => (class_exists('PMAI_Plugin') and defined('PMAI_EDITION') and PMAI_EDITION == 'paid'),
36
- 'free_installed' => (class_exists('PMAI_Plugin') and defined('PMAI_EDITION') and PMAI_EDITION == 'free'),
37
- 'required_plugins' => array('Advanced Custom Fields' => class_exists('acf')),
38
- 'url' => 'http://www.wpallimport.com/advanced-custom-fields/'
39
- );
40
-
41
- // WPML add-on
42
- self::$premium['PMLI_Plugin'] = array(
43
- 'title' => __("WPML Addon",'wp_all_import_plugin'),
44
- 'description' => __("Import to WPML",'wp_all_import_plugin'),
45
- 'thumbnail' => 'http://placehold.it/220x220',
46
- 'active' => (class_exists('PMLI_Plugin') and defined('PMLI_EDITION') and PMLI_EDITION == 'paid'),
47
- 'free_installed' => (class_exists('PMLI_Plugin') and defined('PMLI_EDITION') and PMLI_EDITION == 'free'),
48
- 'required_plugins' => array('WPML' => class_exists('SitePress')),
49
- 'url' => 'http://www.wpallimport.com/add-ons/wpml/'
50
- );
51
-
52
- // User add-on
53
- self::$premium['PMUI_Plugin'] = array(
54
- 'title' => __("User Addon",'wp_all_import_plugin'),
55
- 'description' => __("Import Users",'wp_all_import_plugin'),
56
- 'thumbnail' => 'http://placehold.it/220x220',
57
- 'active' => (class_exists('PMUI_Plugin') and defined('PMUI_EDITION') and PMUI_EDITION == 'paid'),
58
- 'free_installed' => (class_exists('PMUI_Plugin') and defined('PMUI_EDITION') and PMUI_EDITION == 'free'),
59
- 'required_plugins' => false,
60
- 'url' => 'http://www.wpallimport.com/add-ons/user-import/'
61
- );
62
-
63
- // Affiliate link cloaking add-on
64
- self::$premium['PMLCA_Plugin'] = array(
65
- 'title' => __("Link cloaking Addon",'wp_all_import_plugin'),
66
- 'description' => __("Affiliate link cloaking",'wp_all_import_plugin'),
67
- 'thumbnail' => 'http://placehold.it/220x220',
68
- 'active' => (class_exists('PMLCA_Plugin') and defined('PMLCA_EDITION') and PMLCA_EDITION == 'paid'),
69
- 'free_installed' => (class_exists('PMLCA_Plugin') and defined('PMLCA_EDITION') and PMLCA_EDITION == 'free'),
70
- 'required_plugins' => false,
71
- 'url' => 'http://www.wpallimport.com/add-ons/link-cloaking/'
72
- );
73
-
74
- self::$free['PMWI_Plugin'] = array(
75
- 'title' => __("WooCommerce Addon - free edition",'wp_all_import_plugin'),
76
- 'description' => __("Import Products from any XML or CSV to WooCommerce",'wp_all_import_plugin'),
77
- 'thumbnail' => 'http://placehold.it/220x220',
78
- 'active' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'free'),
79
- 'paid_installed' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'paid'),
80
- 'required_plugins' => false,
81
- 'url' => 'http://wordpress.org/plugins/woocommerce-xml-csv-product-import'
82
- );
83
- self::$free['PMWITabs_Plugin'] = array(
84
- 'title' => __("WooCommerce Tabs Addon",'wp_all_import_plugin'),
85
- 'description' => __("Import data to WooCommerce tabs",'wp_all_import_plugin'),
86
- 'thumbnail' => 'http://placehold.it/220x220',
87
- 'active' => class_exists('PMWITabs_Plugin'),
88
- 'paid_installed' => false,
89
- 'required_plugins' => array('WooCommerce Addon' => class_exists('PMWI_Plugin')),
90
- 'url' => 'http://www.wpallimport.com'
91
- );
92
-
93
-
94
- }
95
-
96
- public function index() {
97
-
98
- $this->data['premium'] = self::$premium;
99
-
100
- $this->data['free'] = self::$free;
101
-
102
- $this->render();
103
- }
104
-
105
- public function get_premium_addons(){
106
- return self::$premium;
107
- }
108
-
109
- public function get_free_addons(){
110
- return self::$free;
111
- }
112
-
113
- protected static function set_addons_status(){
114
- foreach (self::$addons as $class => $active)
115
- self::$addons[$class] = class_exists($class);
116
-
117
- self::$addons = apply_filters('pmxi_addons', self::$addons);
118
-
119
- }
120
-
121
- public static function get_all_addons(){
122
-
123
- self::set_addons_status();
124
-
125
- return self::$addons;
126
- }
127
-
128
- public static function get_addon($addon = false){
129
-
130
- self::set_addons_status();
131
-
132
- return ($addon) ? self::$addons[$addon] : false;
133
- }
134
-
135
- public static function get_active_addons(){
136
-
137
- self::set_addons_status();
138
- $active_addons = array();
139
- foreach (self::$addons as $class => $active) if ($active) $active_addons[] = $class;
140
-
141
- return $active_addons;
142
- }
143
-
 
 
 
 
 
 
 
 
 
 
 
144
  }
1
+ <?php
2
  /**
3
  * Admin Add-ons page
4
+ *
5
+ * @author Maksym Tsypliakov <maksym.tsypliakov@gmail.com>
6
  */
7
+ class PMXI_Admin_Addons extends PMXI_Controller_Admin {
8
+
9
+ public static $addons = array('PMWI_Plugin' => 0, 'PMAI_Plugin' => 0, 'PMWITabs_Plugin' => 0, 'PMLI_Plugin' => 0, 'PMLCA_Plugin' => 0, 'PMUI_Plugin' => 0, 'PMTI_Plugin' => 0); // inactive by default
10
+
11
+ public static $premium = array();
12
+
13
+ public static $free = array();
14
+
15
+ public function __construct() {
16
+
17
+ parent::__construct();
18
+
19
+ // Woocommerce add-on
20
+ self::$premium['PMWI_Plugin'] = array(
21
+ 'title' => __("WooCommerce Addon",'wp_all_import_plugin'),
22
+ 'description' => __("Import Products from any XML or CSV to WooCommerce",'wp_all_import_plugin'),
23
+ 'thumbnail' => 'http://placehold.it/220x220',
24
+ 'active' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'paid'),
25
+ 'free_installed' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'free'),
26
+ 'required_plugins' => false,
27
+ 'url' => 'http://www.wpallimport.com/woocommerce-product-import'
28
+ );
29
+
30
+ // ACF add-on
31
+ self::$premium['PMAI_Plugin'] = array(
32
+ 'title' => __("ACF Addon",'wp_all_import_plugin'),
33
+ 'description' => __("Import to advanced custom fields",'wp_all_import_plugin'),
34
+ 'thumbnail' => 'http://placehold.it/220x220',
35
+ 'active' => (class_exists('PMAI_Plugin') and defined('PMAI_EDITION') and PMAI_EDITION == 'paid'),
36
+ 'free_installed' => (class_exists('PMAI_Plugin') and defined('PMAI_EDITION') and PMAI_EDITION == 'free'),
37
+ 'required_plugins' => array('Advanced Custom Fields' => class_exists('acf')),
38
+ 'url' => 'http://www.wpallimport.com/advanced-custom-fields/'
39
+ );
40
+
41
+ // Toolset Types add-on
42
+ self::$premium['PMTI_Plugin'] = array(
43
+ 'title' => __("Toolset Types Addon",'wp_all_import_plugin'),
44
+ 'description' => __("Import to toolset types",'wp_all_import_plugin'),
45
+ 'thumbnail' => 'http://placehold.it/220x220',
46
+ 'active' => (class_exists('PMTI_Plugin') and defined('PMTI_EDITION') and PMTI_EDITION == 'paid'),
47
+ 'free_installed' => (class_exists('PMTI_Plugin') and defined('PMTI_EDITION') and PMTI_EDITION == 'free'),
48
+ 'required_plugins' => array('Toolset Types' => defined(TYPES_VERSION)),
49
+ 'url' => 'http://www.wpallimport.com/advanced-custom-fields/'
50
+ );
51
+
52
+ // WPML add-on
53
+ self::$premium['PMLI_Plugin'] = array(
54
+ 'title' => __("WPML Addon",'wp_all_import_plugin'),
55
+ 'description' => __("Import to WPML",'wp_all_import_plugin'),
56
+ 'thumbnail' => 'http://placehold.it/220x220',
57
+ 'active' => (class_exists('PMLI_Plugin') and defined('PMLI_EDITION') and PMLI_EDITION == 'paid'),
58
+ 'free_installed' => (class_exists('PMLI_Plugin') and defined('PMLI_EDITION') and PMLI_EDITION == 'free'),
59
+ 'required_plugins' => array('WPML' => class_exists('SitePress')),
60
+ 'url' => 'http://www.wpallimport.com/add-ons/wpml/'
61
+ );
62
+
63
+ // User add-on
64
+ self::$premium['PMUI_Plugin'] = array(
65
+ 'title' => __("User Addon",'wp_all_import_plugin'),
66
+ 'description' => __("Import Users",'wp_all_import_plugin'),
67
+ 'thumbnail' => 'http://placehold.it/220x220',
68
+ 'active' => (class_exists('PMUI_Plugin') and defined('PMUI_EDITION') and PMUI_EDITION == 'paid'),
69
+ 'free_installed' => (class_exists('PMUI_Plugin') and defined('PMUI_EDITION') and PMUI_EDITION == 'free'),
70
+ 'required_plugins' => false,
71
+ 'url' => 'http://www.wpallimport.com/add-ons/user-import/'
72
+ );
73
+
74
+ // Affiliate link cloaking add-on
75
+ self::$premium['PMLCA_Plugin'] = array(
76
+ 'title' => __("Link cloaking Addon",'wp_all_import_plugin'),
77
+ 'description' => __("Affiliate link cloaking",'wp_all_import_plugin'),
78
+ 'thumbnail' => 'http://placehold.it/220x220',
79
+ 'active' => (class_exists('PMLCA_Plugin') and defined('PMLCA_EDITION') and PMLCA_EDITION == 'paid'),
80
+ 'free_installed' => (class_exists('PMLCA_Plugin') and defined('PMLCA_EDITION') and PMLCA_EDITION == 'free'),
81
+ 'required_plugins' => false,
82
+ 'url' => 'http://www.wpallimport.com/add-ons/link-cloaking/'
83
+ );
84
+
85
+ self::$free['PMWI_Plugin'] = array(
86
+ 'title' => __("WooCommerce Addon - free edition",'wp_all_import_plugin'),
87
+ 'description' => __("Import Products from any XML or CSV to WooCommerce",'wp_all_import_plugin'),
88
+ 'thumbnail' => 'http://placehold.it/220x220',
89
+ 'active' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'free'),
90
+ 'paid_installed' => (class_exists('PMWI_Plugin') and defined('PMWI_EDITION') and PMWI_EDITION == 'paid'),
91
+ 'required_plugins' => false,
92
+ 'url' => 'http://wordpress.org/plugins/woocommerce-xml-csv-product-import'
93
+ );
94
+ self::$free['PMWITabs_Plugin'] = array(
95
+ 'title' => __("WooCommerce Tabs Addon",'wp_all_import_plugin'),
96
+ 'description' => __("Import data to WooCommerce tabs",'wp_all_import_plugin'),
97
+ 'thumbnail' => 'http://placehold.it/220x220',
98
+ 'active' => class_exists('PMWITabs_Plugin'),
99
+ 'paid_installed' => false,
100
+ 'required_plugins' => array('WooCommerce Addon' => class_exists('PMWI_Plugin')),
101
+ 'url' => 'http://www.wpallimport.com'
102
+ );
103
+
104
+
105
+ }
106
+
107
+ public function index() {
108
+
109
+ $this->data['premium'] = self::$premium;
110
+
111
+ $this->data['free'] = self::$free;
112
+
113
+ $this->render();
114
+ }
115
+
116
+ public function get_premium_addons(){
117
+ return self::$premium;
118
+ }
119
+
120
+ public function get_free_addons(){
121
+ return self::$free;
122
+ }
123
+
124
+ protected static function set_addons_status(){
125
+ foreach (self::$addons as $class => $active)
126
+ self::$addons[$class] = class_exists($class);
127
+
128
+ self::$addons = apply_filters('pmxi_addons', self::$addons);
129
+
130
+ }
131
+
132
+ public static function get_all_addons(){
133
+
134
+ self::set_addons_status();
135
+
136
+ return self::$addons;
137
+ }
138
+
139
+ public static function get_addon($addon = false){
140
+
141
+ self::set_addons_status();
142
+
143
+ return ($addon) ? self::$addons[$addon] : false;
144
+ }
145
+
146
+ public static function get_active_addons(){
147
+
148
+ self::set_addons_status();
149
+ $active_addons = array();
150
+ foreach (self::$addons as $class => $active) if ($active) $active_addons[] = $class;
151
+
152
+ return $active_addons;
153
+ }
154
+
155
  }
controllers/admin/import.php CHANGED
@@ -1497,7 +1497,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1497
  }
1498
  // validate images meta data
1499
  foreach (array('title', 'caption', 'alt', 'decription') as $section) {
1500
- if ( $post['set_image_meta_' . $section] )
1501
  {
1502
  if ( ! empty($post['image_meta_' . $section])) $this->_validate_template($post['image_meta_' . $section], __('Images meta ' . $section, 'wp_all_import_plugin'));
1503
  }
@@ -1542,7 +1542,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1542
  /*if ('page' == $post['type'] and ! preg_match('%^(-?\d+)?$%', $post['order'])) {
1543
  $this->errors->add('form-validation', __('Order must be an integer number', 'wp_all_import_plugin'));
1544
  }*/
1545
- if ('post' == $post['type']) {
1546
  /*'' == $post['categories'] or $this->_validate_template($post['categories'], __('Categories', 'wp_all_import_plugin'));*/
1547
  '' == $post['tags'] or $this->_validate_template($post['tags'], __('Tags', 'wp_all_import_plugin'));
1548
  }
@@ -1556,7 +1556,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1556
  $this->errors->add('form-validation', __('Tag list delimiter must cannot be empty', 'wp_all_import_plugin'));
1557
  }*/
1558
 
1559
- $this->errors = apply_filters('pmxi_options_validation', $this->errors, $post, $this->data['import']);
1560
 
1561
  if ( ! $this->errors->get_error_codes()) { // no validation errors found
1562
  // assign some defaults
@@ -1600,9 +1600,9 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1600
 
1601
  PMXI_Plugin::$session->save_data();
1602
 
1603
- if ( ! in_array($post['custom_type'], array('import_users')) ){
1604
 
1605
- global $wpdb;
1606
 
1607
  // Get all meta keys for requested post type
1608
  $this->data['meta_keys'] = array();
@@ -1637,7 +1637,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1637
  // Get All meta keys in the system
1638
  $this->data['meta_keys'] = array();
1639
  $meta_keys = new PMXI_Model_List();
1640
- $meta_keys->setTable(PMXI_Plugin::getInstance()->getWPPrefix() . 'usermeta');
1641
  $meta_keys->setColumns('umeta_id', 'meta_key')->getBy(NULL, "umeta_id", NULL, NULL, "meta_key");
1642
  $hide_fields = array('first_name', 'last_name', 'nickname', 'description', PMXI_Plugin::getInstance()->getWPPrefix() . 'capabilities');
1643
  if ( ! empty($meta_keys) and $meta_keys->count() ){
@@ -1824,6 +1824,13 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1824
 
1825
  if ( ! $this->isWizard) {
1826
 
 
 
 
 
 
 
 
1827
  // File Path validation
1828
  switch ($this->input->post('new_type')){
1829
  case 'upload':
@@ -1938,7 +1945,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1938
 
1939
  }
1940
 
1941
- $this->errors = apply_filters('pmxi_options_validation', $this->errors, $post, $this->data['import']);
1942
 
1943
  if ( ! $this->errors->get_error_codes()) { // no validation errors found
1944
 
@@ -2379,17 +2386,17 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2379
  }
2380
 
2381
  if ($ajax_processing)
2382
- {
2383
- $logger = create_function('$m', 'printf("<div class=\\"progress-msg\\">[%s] $m</div>\\n", date("H:i:s")); flush();');
2384
  }
2385
  else
2386
  {
2387
- $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(wp_all_import_strip_tags_content($m))) { PMXI_Plugin::$session->log .= "<p>".strip_tags(wp_all_import_strip_tags_content($m))."</p>"; flush(); }');
2388
  }
2389
 
2390
  PMXI_Plugin::$session->set('start_time', (empty(PMXI_Plugin::$session->start_time)) ? time() : PMXI_Plugin::$session->start_time);
2391
 
2392
- $is_reset_cache = apply_filters('wp_all_import_reset_cache_before_import', true, $import_id);
2393
 
2394
  if ($is_reset_cache){
2395
  wp_cache_flush();
@@ -2429,7 +2436,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2429
  }
2430
  }
2431
 
2432
- $records_to_import = (empty($records)) ? $import->count : $records[count($records) -1];
2433
 
2434
  $failures = $input->get('failures', 0);
2435
 
@@ -2444,7 +2451,9 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2444
 
2445
  if ( ! empty(PMXI_Plugin::$session->local_paths) ) {
2446
 
2447
- if (!empty($records) && $import->queue_chunk_number < $records[0] && strpos($import->xpath, "[") === false) $pointer = $records[0];
 
 
2448
 
2449
  $chunk_records_count = PMXI_Plugin::getInstance()->getOption('large_feed_limit');
2450
 
@@ -2464,7 +2473,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2464
  }
2465
 
2466
  // set XMLReader pointer to first value of specified records option
2467
- if ( ! empty($records) && $import->queue_chunk_number < $records[0] && strpos($import->xpath, "[") === false){
2468
 
2469
  if ($import->options['chuncking'] && $pointer > $chunk_records_count)
2470
  {
@@ -2588,7 +2597,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2588
  'errors' => PMXI_Plugin::$session->errors,
2589
  'log' => $log_data,
2590
  'done' => false,
2591
- 'records_per_request' => $import->options['records_per_request'],
2592
  'iteration_execution_time' => $iteration_execution_time
2593
  ));
2594
  }
@@ -2644,7 +2653,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2644
  'errors' => PMXI_Plugin::$session->errors,
2645
  'log' => $log_data,
2646
  'done' => false,
2647
- 'records_per_request' => $import->options['records_per_request'],
2648
  'iteration_execution_time' => $iteration_execution_time
2649
  ));
2650
  }
@@ -2671,8 +2680,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
2671
  @fclose($log);
2672
  }
2673
  }
2674
-
2675
- wp_cache_flush();
2676
  foreach ( get_taxonomies() as $tax ) {
2677
  delete_option( "{$tax}_children" );
2678
  _get_term_hierarchy( $tax );
@@ -2805,4 +2813,50 @@ COMPLETE;
2805
  }
2806
  return $xml;
2807
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2808
  }
1497
  }
1498
  // validate images meta data
1499
  foreach (array('title', 'caption', 'alt', 'decription') as $section) {
1500
+ if ( !empty($post['set_image_meta_' . $section]) )
1501
  {
1502
  if ( ! empty($post['image_meta_' . $section])) $this->_validate_template($post['image_meta_' . $section], __('Images meta ' . $section, 'wp_all_import_plugin'));
1503
  }
1542
  /*if ('page' == $post['type'] and ! preg_match('%^(-?\d+)?$%', $post['order'])) {
1543
  $this->errors->add('form-validation', __('Order must be an integer number', 'wp_all_import_plugin'));
1544
  }*/
1545
+ if ('post' == $post['type'] && isset($post['tags'])) {
1546
  /*'' == $post['categories'] or $this->_validate_template($post['categories'], __('Categories', 'wp_all_import_plugin'));*/
1547
  '' == $post['tags'] or $this->_validate_template($post['tags'], __('Tags', 'wp_all_import_plugin'));
1548
  }
1556
  $this->errors->add('form-validation', __('Tag list delimiter must cannot be empty', 'wp_all_import_plugin'));
1557
  }*/
1558
 
1559
+ $this->errors = apply_filters('pmxi_options_validation', $this->errors, $post, isset($this->data['import']) ? $this->data['import'] : false);
1560
 
1561
  if ( ! $this->errors->get_error_codes()) { // no validation errors found
1562
  // assign some defaults
1600
 
1601
  PMXI_Plugin::$session->save_data();
1602
 
1603
+ global $wpdb;
1604
 
1605
+ if ( ! in_array($post['custom_type'], array('import_users')) ){
1606
 
1607
  // Get all meta keys for requested post type
1608
  $this->data['meta_keys'] = array();
1637
  // Get All meta keys in the system
1638
  $this->data['meta_keys'] = array();
1639
  $meta_keys = new PMXI_Model_List();
1640
+ $meta_keys->setTable($wpdb->usermeta);
1641
  $meta_keys->setColumns('umeta_id', 'meta_key')->getBy(NULL, "umeta_id", NULL, NULL, "meta_key");
1642
  $hide_fields = array('first_name', 'last_name', 'nickname', 'description', PMXI_Plugin::getInstance()->getWPPrefix() . 'capabilities');
1643
  if ( ! empty($meta_keys) and $meta_keys->count() ){
1824
 
1825
  if ( ! $this->isWizard) {
1826
 
1827
+ // updating csv delimiter
1828
+ if ( $post['delimiter'] != $this->data['import']->options['delimiter'] ){
1829
+ $import_options = $this->data['import']->options;
1830
+ $import_options['delimiter'] = $post['delimiter'];
1831
+ $this->data['import']->set('options', $import_options)->save();
1832
+ }
1833
+
1834
  // File Path validation
1835
  switch ($this->input->post('new_type')){
1836
  case 'upload':
1945
 
1946
  }
1947
 
1948
+ $this->errors = apply_filters('pmxi_options_validation', $this->errors, $post, isset($this->data['import']) ? $this->data['import'] : false);
1949
 
1950
  if ( ! $this->errors->get_error_codes()) { // no validation errors found
1951
 
2386
  }
2387
 
2388
  if ($ajax_processing)
2389
+ {
2390
+ $logger = function($m) {printf("<div class='progress-msg'>[%s] $m</div>\n", date("H:i:s"));flush();};
2391
  }
2392
  else
2393
  {
2394
+ $logger = function($m) {echo "<div class='progress-msg'>$m</div>\n"; if ( "" != strip_tags(wp_all_import_strip_tags_content($m))) { PMXI_Plugin::$session->log .= "<p>".strip_tags(wp_all_import_strip_tags_content($m))."</p>"; flush(); }};
2395
  }
2396
 
2397
  PMXI_Plugin::$session->set('start_time', (empty(PMXI_Plugin::$session->start_time)) ? time() : PMXI_Plugin::$session->start_time);
2398
 
2399
+ $is_reset_cache = apply_filters('wp_all_import_reset_cache_before_import', false, $import->id);
2400
 
2401
  if ($is_reset_cache){
2402
  wp_cache_flush();
2436
  }
2437
  }
2438
 
2439
+ $records_to_import = (empty($records) || $import->options['is_delete_missing']) ? $import->count : $records[count($records) -1];
2440
 
2441
  $failures = $input->get('failures', 0);
2442
 
2451
 
2452
  if ( ! empty(PMXI_Plugin::$session->local_paths) ) {
2453
 
2454
+ if (!empty($records) && $import->queue_chunk_number < $records[0] && strpos($import->xpath, "[") === false && ! $import->options['is_delete_missing']) {
2455
+ $pointer = $records[0];
2456
+ }
2457
 
2458
  $chunk_records_count = PMXI_Plugin::getInstance()->getOption('large_feed_limit');
2459
 
2473
  }
2474
 
2475
  // set XMLReader pointer to first value of specified records option
2476
+ if ( ! empty($records) && $import->queue_chunk_number < $records[0] && strpos($import->xpath, "[") === false && ! $import->options['is_delete_missing']){
2477
 
2478
  if ($import->options['chuncking'] && $pointer > $chunk_records_count)
2479
  {
2597
  'errors' => PMXI_Plugin::$session->errors,
2598
  'log' => $log_data,
2599
  'done' => false,
2600
+ 'records_per_request' => $records_per_request,
2601
  'iteration_execution_time' => $iteration_execution_time
2602
  ));
2603
  }
2653
  'errors' => PMXI_Plugin::$session->errors,
2654
  'log' => $log_data,
2655
  'done' => false,
2656
+ 'records_per_request' => $records_per_request,
2657
  'iteration_execution_time' => $iteration_execution_time
2658
  ));
2659
  }
2680
  @fclose($log);
2681
  }
2682
  }
2683
+
 
2684
  foreach ( get_taxonomies() as $tax ) {
2685
  delete_option( "{$tax}_children" );
2686
  _get_term_hierarchy( $tax );
2813
  }
2814
  return $xml;
2815
  }
2816
+
2817
+ /**
2818
+ * @return string
2819
+ */
2820
+ private function findUniqueKey()
2821
+ {
2822
+ $uniqueKey = '';
2823
+
2824
+ if (empty(PMXI_Plugin::$session->options['unique_key'])) {
2825
+
2826
+ $keys_black_list = array('programurl');
2827
+
2828
+ if (empty(PMXI_Plugin::$session->deligate))
2829
+ $uniqueKey = PMXI_Plugin::$session->options['title'];
2830
+
2831
+ // auto searching ID element
2832
+ if (!empty($this->data['dom']) and empty(PMXI_Plugin::$session->deligate)) {
2833
+ $dom = empty($this->data['dom']->documentElement) ? $this->data['dom'] : $this->data['dom']->documentElement;
2834
+ $this->find_unique_key($dom);
2835
+ if (!empty($this->_unique_key)) {
2836
+ foreach ($keys_black_list as $key => $value) {
2837
+ $uniqueKey = str_replace('{' . $value . '[1]}', "", $uniqueKey);
2838
+ }
2839
+ foreach ($this->_unique_key as $key) {
2840
+ if (stripos($key, 'id') !== false) {
2841
+ $uniqueKey .= ' - {' . $key . '[1]}';
2842
+ break;
2843
+ }
2844
+ }
2845
+ foreach ($this->_unique_key as $key) {
2846
+ if (stripos($key, 'url') !== false or stripos($key, 'sku') !== false or stripos($key, 'ref') !== false) {
2847
+ if (!in_array($key, $keys_black_list)) {
2848
+ $uniqueKey .= ' - {' . $key . '[1]}';
2849
+ break;
2850
+ }
2851
+ }
2852
+ }
2853
+ }
2854
+ $uniqueKey = apply_filters('pmxi_unique_key', $uniqueKey, PMXI_Plugin::$session->options);
2855
+ }
2856
+ } else {
2857
+ $uniqueKey = PMXI_Plugin::$session->options['unique_key'];
2858
+ }
2859
+
2860
+ return $uniqueKey;
2861
+ }
2862
  }
controllers/controller/admin.php CHANGED
@@ -55,8 +55,11 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
55
 
56
  parent::__construct();
57
 
58
- // add special filter for url fields
59
- $this->input->addFilter(create_function('$str', 'return "http://" == $str || "ftp://" == $str ? "" : $str;'));
 
 
 
60
 
61
  // enqueue required sripts and styles
62
  global $wp_styles;
@@ -69,6 +72,7 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
69
  wp_enqueue_style('pmxi-admin-style-ie', WP_ALL_IMPORT_ROOT_URL . '/static/css/admin-ie.css');
70
  wp_enqueue_style('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/css/select2/select2.css');
71
  wp_enqueue_style('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/css/select2/select2-bootstrap.css');
 
72
  add_editor_style( WP_ALL_IMPORT_ROOT_URL . '/static/css/custom-editor-style.css' );
73
  wp_enqueue_style('jquery-codemirror', WP_ALL_IMPORT_ROOT_URL . '/static/codemirror/codemirror.css', array(), PMXI_VERSION);
74
 
@@ -96,6 +100,7 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
96
  wp_enqueue_script('jquery-nestable', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'jquery-ui-progressbar'));
97
  wp_enqueue_script('jquery-moment', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/moment.js', 'jquery', PMXI_VERSION);
98
  wp_enqueue_script('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/select2.min.js', 'jquery');
 
99
  wp_enqueue_script('jquery-ddslick', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.ddslick.min.js', 'jquery');
100
  wp_enqueue_script('jquery-contextmenu', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.ui-contextmenu.min.js', array('jquery', 'jquery-ui-menu'));
101
  wp_enqueue_script('jquery-codemirror', WP_ALL_IMPORT_ROOT_URL . '/static/codemirror/codemirror.js', array(), PMXI_VERSION);
55
 
56
  parent::__construct();
57
 
58
+ if (version_compare(phpversion(), '7.2' , "<")){
59
+ $filter = create_function('$str', 'return "http://" == $str || "ftp://" == $str ? "" : $str;');
60
+ // add special filter for url fields
61
+ $this->input->addFilter($filter);
62
+ }
63
 
64
  // enqueue required sripts and styles
65
  global $wp_styles;
72
  wp_enqueue_style('pmxi-admin-style-ie', WP_ALL_IMPORT_ROOT_URL . '/static/css/admin-ie.css');
73
  wp_enqueue_style('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/css/select2/select2.css');
74
  wp_enqueue_style('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/css/select2/select2-bootstrap.css');
75
+ wp_enqueue_style('jquery-chosen', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/css/chosen/chosen.css');
76
  add_editor_style( WP_ALL_IMPORT_ROOT_URL . '/static/css/custom-editor-style.css' );
77
  wp_enqueue_style('jquery-codemirror', WP_ALL_IMPORT_ROOT_URL . '/static/codemirror/codemirror.css', array(), PMXI_VERSION);
78
 
100
  wp_enqueue_script('jquery-nestable', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'jquery-ui-progressbar'));
101
  wp_enqueue_script('jquery-moment', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/moment.js', 'jquery', PMXI_VERSION);
102
  wp_enqueue_script('jquery-select2', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/select2.min.js', 'jquery');
103
+ wp_enqueue_script('jquery-chosen', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/chosen.jquery.min.js', 'jquery');
104
  wp_enqueue_script('jquery-ddslick', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.ddslick.min.js', 'jquery');
105
  wp_enqueue_script('jquery-contextmenu', WP_ALL_IMPORT_ROOT_URL . '/static/js/jquery/jquery.ui-contextmenu.min.js', array('jquery', 'jquery-ui-menu'));
106
  wp_enqueue_script('jquery-codemirror', WP_ALL_IMPORT_ROOT_URL . '/static/codemirror/codemirror.js', array(), PMXI_VERSION);
filters/wpmu_drop_tables.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function pmxi_wpmu_drop_tables($tables){
3
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'templates';
4
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'imports';
5
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'posts';
6
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'files';
7
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'history';
8
+ $tables[] = PMXI_Plugin::getInstance()->getTablePrefix() . 'images';
9
+ return $tables;
10
+ }
helpers/functions.php CHANGED
@@ -17,8 +17,8 @@
17
  if (!function_exists('pmxi_human_filesize')){
18
  function pmxi_human_filesize($bytes, $decimals = 2) {
19
  $sz = 'BKMGTP';
20
- $factor = floor((strlen($bytes) - 1) / 3);
21
- return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
22
  }
23
  }
24
 
@@ -214,3 +214,11 @@
214
  return end($a);
215
  }
216
  }
 
 
 
 
 
 
 
 
17
  if (!function_exists('pmxi_human_filesize')){
18
  function pmxi_human_filesize($bytes, $decimals = 2) {
19
  $sz = 'BKMGTP';
20
+ $factor = (int) floor((strlen($bytes) - 1) / 3);
21
+ return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . (isset($sz[$factor]) ? $sz[$factor] : '');
22
  }
23
  }
24
 
214
  return end($a);
215
  }
216
  }
217
+
218
+ if ( ! function_exists('wp_all_import_update_post_count')) {
219
+ function wp_all_import_update_post_count() {
220
+ global $wpdb;
221
+ update_option( 'post_count', (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_status = 'publish' and post_type = 'post'" ) );
222
+ }
223
+ }
224
+
helpers/get_file_curl.php CHANGED
@@ -90,7 +90,7 @@ if ( ! function_exists('pmxi_curl_download') ) {
90
  fclose($fp);
91
  }
92
 
93
- if ( ! ($image_info = apply_filters('pmxi_getimagesize', @getimagesize($fullpath), $fullpath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP)) ){
94
  return false;
95
  }
96
 
90
  fclose($fp);
91
  }
92
 
93
+ if ( preg_match('%\W(jpg|jpeg|gif|png)$%i', basename($fullpath)) and ( ! ($image_info = apply_filters('pmxi_getimagesize', @getimagesize($fullpath), $fullpath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) ) ){
94
  return false;
95
  }
96
 
helpers/pmxi_findDuplicates.php CHANGED
@@ -44,7 +44,7 @@ function pmxi_findDuplicates($articleData, $custom_duplicate_name = '', $custom_
44
  'product_variation'
45
  ) : array($articleData['post_type']);
46
 
47
- $sql = $wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS " . $wpdb->posts . ".ID FROM " . $wpdb->posts . " INNER JOIN " . $wpdb->postmeta . " ON ( " . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".post_id ) WHERE 1=1 AND ( ( " . $wpdb->postmeta . ".meta_key = %s AND (" . $wpdb->postmeta . ".meta_value = %s OR " . $wpdb->postmeta . ".meta_value = %s OR REPLACE(REPLACE(REPLACE(" . $wpdb->postmeta . ".meta_value, ' ', ''), '\\t', ''), '\\n', '') = %s) ) ) AND " . $wpdb->posts . ".post_type IN ('" . implode("','", $post_types) . "') AND ((" . $wpdb->posts . ".post_status <> 'trash' AND " . $wpdb->posts . ".post_status <> 'auto-draft')) GROUP BY " . $wpdb->posts . ".ID ORDER BY " . $wpdb->posts . ".ID ASC LIMIT 0, 15", trim($custom_duplicate_name), trim($custom_duplicate_value), htmlspecialchars(trim($custom_duplicate_value)), preg_replace('%[ \\t\\n]%', '', trim($custom_duplicate_value)));
48
 
49
  $query = $wpdb->get_results($sql);
50
 
@@ -56,7 +56,7 @@ function pmxi_findDuplicates($articleData, $custom_duplicate_name = '', $custom_
56
 
57
  if (empty($duplicate_ids)) {
58
 
59
- $query = $wpdb->get_results($wpdb->prepare("SELECT SQL_CALC_FOUND_ROWS " . $wpdb->posts . ".ID FROM " . $wpdb->posts . " INNER JOIN " . $wpdb->postmeta . " ON (" . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".post_id) WHERE 1=1 AND " . $wpdb->posts . ".post_type IN ('" . implode("','", $post_types) . "') AND (" . $wpdb->posts . ".post_status = 'publish' OR " . $wpdb->posts . ".post_status = 'future' OR " . $wpdb->posts . ".post_status = 'draft' OR " . $wpdb->posts . ".post_status = 'pending' OR " . $wpdb->posts . ".post_status = 'trash' OR " . $wpdb->posts . ".post_status = 'private') AND ( (" . $wpdb->postmeta . ".meta_key = '%s' AND (" . $wpdb->postmeta . ".meta_value = '%s' OR " . $wpdb->postmeta . ".meta_value = '%s' OR " . $wpdb->postmeta . ".meta_value = '%s') ) ) GROUP BY " . $wpdb->posts . ".ID ORDER BY " . $wpdb->posts . ".ID ASC LIMIT 0, 20", trim($custom_duplicate_name), trim($custom_duplicate_value), htmlspecialchars(trim($custom_duplicate_value)), esc_attr(trim($custom_duplicate_value))));
60
 
61
  if (!empty($query)) {
62
  foreach ($query as $p) {
44
  'product_variation'
45
  ) : array($articleData['post_type']);
46
 
47
+ $sql = $wpdb->prepare("SELECT " . $wpdb->posts . ".ID FROM " . $wpdb->posts . " INNER JOIN " . $wpdb->postmeta . " ON ( " . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".post_id ) WHERE 1=1 AND ( ( " . $wpdb->postmeta . ".meta_key = %s AND (" . $wpdb->postmeta . ".meta_value = %s OR " . $wpdb->postmeta . ".meta_value = %s OR REPLACE(REPLACE(REPLACE(" . $wpdb->postmeta . ".meta_value, ' ', ''), '\\t', ''), '\\n', '') = %s) ) ) AND " . $wpdb->posts . ".post_type IN ('" . implode("','", $post_types) . "') AND ((" . $wpdb->posts . ".post_status <> 'trash' AND " . $wpdb->posts . ".post_status <> 'auto-draft')) GROUP BY " . $wpdb->posts . ".ID ORDER BY " . $wpdb->posts . ".ID ASC LIMIT 0, 15", trim($custom_duplicate_name), trim($custom_duplicate_value), htmlspecialchars(trim($custom_duplicate_value)), preg_replace('%[ \\t\\n]%', '', trim($custom_duplicate_value)));
48
 
49
  $query = $wpdb->get_results($sql);
50
 
56
 
57
  if (empty($duplicate_ids)) {
58
 
59
+ $query = $wpdb->get_results($wpdb->prepare("SELECT " . $wpdb->posts . ".ID FROM " . $wpdb->posts . " INNER JOIN " . $wpdb->postmeta . " ON (" . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".post_id) WHERE 1=1 AND " . $wpdb->posts . ".post_type IN ('" . implode("','", $post_types) . "') AND (" . $wpdb->posts . ".post_status = 'publish' OR " . $wpdb->posts . ".post_status = 'future' OR " . $wpdb->posts . ".post_status = 'draft' OR " . $wpdb->posts . ".post_status = 'pending' OR " . $wpdb->posts . ".post_status = 'trash' OR " . $wpdb->posts . ".post_status = 'private') AND ( (" . $wpdb->postmeta . ".meta_key = '%s' AND (" . $wpdb->postmeta . ".meta_value = '%s' OR " . $wpdb->postmeta . ".meta_value = '%s' OR " . $wpdb->postmeta . ".meta_value = '%s') ) ) GROUP BY " . $wpdb->posts . ".ID ORDER BY " . $wpdb->posts . ".ID ASC LIMIT 0, 20", trim($custom_duplicate_name), trim($custom_duplicate_value), htmlspecialchars(trim($custom_duplicate_value)), esc_attr(trim($custom_duplicate_value))));
60
 
61
  if (!empty($query)) {
62
  foreach ($query as $p) {
helpers/wp_all_import_get_feed_type.php CHANGED
File without changes
helpers/wp_all_import_get_gz.php CHANGED
File without changes
helpers/wp_all_import_get_image_from_gallery.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
- function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $bundle_type = 'images') {
 
4
  global $wpdb;
5
 
6
  $original_image_name = $image_name;
@@ -15,14 +16,11 @@ function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $
15
  // search attachment by attached file
16
  $attachment_metas = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . $wpdb->postmeta . " WHERE meta_key = %s AND (meta_value = %s OR meta_value LIKE %s);", '_wp_attached_file', $image_name, "%/" . $image_name));
17
 
18
- // if (empty($attachment_metas)){
19
- // $attachment_metas = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->postmeta . " WHERE meta_key = %s AND (meta_value = %s OR meta_value LIKE %s);", '_wp_attached_file', sanitize_file_name($image_name), "%/" . sanitize_file_name($image_name) ) );
20
- // }
21
-
22
  if (!empty($attachment_metas)) {
23
  foreach ($attachment_metas as $attachment_meta) {
24
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE ID = %d;", $attachment_meta->post_id));
25
  if (!empty($attch)) {
 
26
  break;
27
  }
28
  }
@@ -35,6 +33,7 @@ function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $
35
  foreach ($attachment_metas as $attachment_meta) {
36
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE ID = %d;", $attachment_meta->post_id));
37
  if (!empty($attch)) {
 
38
  break;
39
  }
40
  }
@@ -49,14 +48,21 @@ function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $
49
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE (post_title = %s OR post_title = %s OR post_name = %s) AND post_type = %s AND post_mime_type = %s;", $image_name, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name), sanitize_title($image_name), "attachment", $wp_filetype['type']));
50
  }
51
 
 
 
 
 
52
  // search attachment by file name without extension
53
- if (empty($attch)) {
54
  $attachment_title = explode(".", $image_name);
55
  if (is_array($attachment_title) and count($attachment_title) > 1) {
56
  array_pop($attachment_title);
57
  }
58
  $image_name = implode(".", $attachment_title);
59
- $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE (post_title = %s OR post_title = %s OR post_name = %s) AND post_type = %s AND post_mime_type LIKE %s;", $image_name, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name), sanitize_title($image_name), "attachment", "image%"));
 
 
 
60
  }
61
  }
62
 
@@ -66,6 +72,9 @@ function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $
66
  if (trim($img_meta['title']) && !is_numeric(sanitize_title($img_meta['title']))) {
67
  $img_title = $img_meta['title'];
68
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE post_title = %s AND post_type = %s AND post_mime_type LIKE %s;", $img_title, "attachment", "image%"));
 
 
 
69
  }
70
  }
71
  if (empty($attch)){
1
  <?php
2
 
3
+ function wp_all_import_get_image_from_gallery($image_name, $targetDir = FALSE, $bundle_type = 'images', $logger = false) {
4
+
5
  global $wpdb;
6
 
7
  $original_image_name = $image_name;
16
  // search attachment by attached file
17
  $attachment_metas = $wpdb->get_results($wpdb->prepare("SELECT * FROM " . $wpdb->postmeta . " WHERE meta_key = %s AND (meta_value = %s OR meta_value LIKE %s);", '_wp_attached_file', $image_name, "%/" . $image_name));
18
 
 
 
 
 
19
  if (!empty($attachment_metas)) {
20
  foreach ($attachment_metas as $attachment_meta) {
21
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE ID = %d;", $attachment_meta->post_id));
22
  if (!empty($attch)) {
23
+ $logger and call_user_func($logger, sprintf(__('- Found existing image with ID `%s` by meta key _wp_attached_file equals to `%s`...', 'wp_all_import_plugin'), $attch->ID, trim($image_name)));
24
  break;
25
  }
26
  }
33
  foreach ($attachment_metas as $attachment_meta) {
34
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE ID = %d;", $attachment_meta->post_id));
35
  if (!empty($attch)) {
36
+ $logger and call_user_func($logger, sprintf(__('- Found existing image with ID `%s` by meta key _wp_attached_file equals to `%s`...', 'wp_all_import_plugin'), $attch->ID, sanitize_file_name($image_name)));
37
  break;
38
  }
39
  }
48
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE (post_title = %s OR post_title = %s OR post_name = %s) AND post_type = %s AND post_mime_type = %s;", $image_name, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name), sanitize_title($image_name), "attachment", $wp_filetype['type']));
49
  }
50
 
51
+ if (!empty($attch)){
52
+ $logger and call_user_func($logger, sprintf(__('- Found existing image with ID `%s` by post_title or post_name equals to `%s`...', 'wp_all_import_plugin'), $attch->ID, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name)));
53
+ }
54
+
55
  // search attachment by file name without extension
56
+ if (empty($attch) and !empty($wp_filetype['type'])) {
57
  $attachment_title = explode(".", $image_name);
58
  if (is_array($attachment_title) and count($attachment_title) > 1) {
59
  array_pop($attachment_title);
60
  }
61
  $image_name = implode(".", $attachment_title);
62
+ $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE (post_title = %s OR post_title = %s OR post_name = %s) AND post_type = %s AND post_mime_type LIKE %s;", $image_name, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name), sanitize_title($image_name), "attachment", $wp_filetype['type']));
63
+ if (!empty($attch)){
64
+ $logger and call_user_func($logger, sprintf(__('- Found existing image with ID `%s` by post_title or post_name equals to `%s`...', 'wp_all_import_plugin'), $attch->ID, preg_replace('/\\.[^.\\s]{3,4}$/', '', $image_name)));
65
+ }
66
  }
67
  }
68
 
72
  if (trim($img_meta['title']) && !is_numeric(sanitize_title($img_meta['title']))) {
73
  $img_title = $img_meta['title'];
74
  $attch = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . $wpdb->posts . " WHERE post_title = %s AND post_type = %s AND post_mime_type LIKE %s;", $img_title, "attachment", "image%"));
75
+ if (!empty($attch)){
76
+ $logger and call_user_func($logger, sprintf(__('- Found existing image with ID `%s` by post_title equals to `%s`...', 'wp_all_import_plugin'), $attch->ID, $img_title));
77
+ }
78
  }
79
  }
80
  if (empty($attch)){
helpers/wp_all_import_get_url.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reading large files from remote server
4
+ * @ $filePath - file URL
5
+ * return local path of copied file
6
+ */
7
+
8
+ if (!function_exists('wp_all_import_get_url')) {
9
+
10
+ function wp_all_import_get_url($filePath, $targetDir = FALSE, $contentType = FALSE, $contentEncoding = FALSE, $detect = FALSE) {
11
+
12
+ $type = $contentType;
13
+
14
+ $uploads = wp_upload_dir();
15
+
16
+ $targetDir = (!$targetDir) ? wp_all_import_secure_file($uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::UPLOADS_DIRECTORY) : $targetDir;
17
+
18
+ $tmpname = wp_unique_filename($targetDir, ($type and strlen(basename($filePath)) < 30) ? basename($filePath) : time());
19
+
20
+ $localPath = $targetDir . '/' . urldecode(sanitize_file_name($tmpname)) . ((!$type) ? '.tmp' : '');
21
+
22
+ $is_valid = FALSE;
23
+
24
+ $is_curl_download_only = apply_filters('wp_all_import_curl_download_only', false, $filePath);
25
+
26
+ if ( ! $is_curl_download_only ){
27
+
28
+ $file = ($contentEncoding == 'gzip') ? @fopen($filePath) : @fopen($filePath, "rb");
29
+
30
+ if (is_resource($file)) {
31
+
32
+ $fp = @fopen($localPath, 'w');
33
+ $first_chunk = TRUE;
34
+ while (!@feof($file)) {
35
+ $chunk = @fread($file, 1024);
36
+ if (!$type and $first_chunk and (strpos($chunk, "<?") !== FALSE or strpos($chunk, "<rss") !== FALSE) or strpos($chunk, "xmlns") !== FALSE) {
37
+ $type = 'xml';
38
+ }
39
+ elseif (!$type and $first_chunk) {
40
+ $type = 'csv';
41
+ } // if it's a 1st chunk, then chunk <? symbols to detect XML file
42
+ $first_chunk = FALSE;
43
+ @fwrite($fp, $chunk);
44
+ }
45
+ @fclose($file);
46
+ @fclose($fp);
47
+
48
+ $chunk = new PMXI_Chunk($localPath);
49
+
50
+ if (!empty($chunk->options['element'])) {
51
+ $defaultXpath = "/" . $chunk->options['element'];
52
+ $is_valid = TRUE;
53
+ }
54
+
55
+ if ($is_valid) {
56
+
57
+ while ($xml = $chunk->read()) {
58
+
59
+ if (!empty($xml)) {
60
+
61
+ //PMXI_Import_Record::preprocessXml($xml);
62
+ $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . "\n" . $xml;
63
+
64
+ $dom = new DOMDocument('1.0', 'UTF-8');
65
+ $old = libxml_use_internal_errors(TRUE);
66
+ $dom->loadXML($xml);
67
+ libxml_use_internal_errors($old);
68
+ $xpath = new DOMXPath($dom);
69
+ if (($elements = $xpath->query($defaultXpath)) and $elements->length) {
70
+ break;
71
+ }
72
+ }
73
+ }
74
+
75
+ if (empty($xml)) {
76
+ $is_valid = FALSE;
77
+ }
78
+ }
79
+ unset($chunk);
80
+ }
81
+ }
82
+
83
+ if (!$is_valid) {
84
+
85
+ $request = get_file_curl($filePath, $localPath);
86
+
87
+ if ( ! is_wp_error($request) ) {
88
+
89
+ if ( ! $type ) {
90
+ if ($contentEncoding == 'gzip') {
91
+ $file = @fopen($localPath);
92
+ }
93
+ else {
94
+ $file = @fopen($localPath, "rb");
95
+ }
96
+ while (!@feof($file)) {
97
+ $chunk = @fread($file, 1024);
98
+ if (strpos($chunk, "<?") !== FALSE or strpos($chunk, "<rss") !== FALSE or strpos($chunk, "xmlns") !== FALSE) {
99
+ $type = 'xml';
100
+ }
101
+ else {
102
+ $type = 'csv';
103
+ } // if it's a 1st chunk, then chunk <? symbols to detect XML file
104
+ break;
105
+ }
106
+ @fclose($file);
107
+ }
108
+ }
109
+ else {
110
+ return $request;
111
+ }
112
+
113
+ }
114
+
115
+ if (!preg_match('%\W(' . $type . ')$%i', basename($localPath))) {
116
+ if (@rename($localPath, $localPath . '.' . $type)) {
117
+ $localPath = $localPath . '.' . $type;
118
+ }
119
+ }
120
+
121
+ return ($detect) ? array(
122
+ 'type' => $type,
123
+ 'localPath' => $localPath
124
+ ) : $localPath;
125
+ }
126
+ }
helpers/wp_all_import_remove_source.php CHANGED
@@ -11,8 +11,10 @@ if ( ! function_exists('wp_all_import_remove_source')){
11
  $dirname = array_pop($path_all_parts);
12
 
13
  if ( wp_all_import_isValidMd5($dirname)){
14
- if ($remove_dir or file_exists($path_parts['dirname'] . DIRECTORY_SEPARATOR . 'index.php') && count(@scandir($path_parts['dirname'])) == 3){
15
- @unlink($path_parts['dirname'] . DIRECTORY_SEPARATOR . 'index.php' );
 
 
16
  }
17
  if ($remove_dir or count(@scandir($path_parts['dirname'])) == 2){
18
  wp_all_import_rmdir($path_parts['dirname']);
11
  $dirname = array_pop($path_all_parts);
12
 
13
  if ( wp_all_import_isValidMd5($dirname)){
14
+ if ($remove_dir or count(@scandir($path_parts['dirname'])) == 3){
15
+ if (file_exists($path_parts['dirname'] . DIRECTORY_SEPARATOR . 'index.php')){
16
+ @unlink($path_parts['dirname'] . DIRECTORY_SEPARATOR . 'index.php' );
17
+ }
18
  }
19
  if ($remove_dir or count(@scandir($path_parts['dirname'])) == 2){
20
  wp_all_import_rmdir($path_parts['dirname']);
helpers/wp_delete_attachments.php CHANGED
@@ -11,33 +11,23 @@ function wp_delete_attachments($parent_id, $unlink = true, $type = 'images') {
11
 
12
  $attachments = get_posts(array('post_parent' => $parent_id, 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null));
13
 
14
- foreach ($attachments as $attach) {
15
-
16
- if ($type == 'files' and ! wp_attachment_is_image( $attach->ID ) ){
17
-
18
- if ($unlink)
19
- {
20
- wp_delete_attachment($attach->ID, true);
21
- }
22
- else
23
- {
24
- $ids[] = $attach->ID;
25
- }
26
- }
27
- elseif ($type == 'images' and wp_attachment_is_image( $attach->ID )) {
28
-
29
- if ($unlink)
30
- {
31
- wp_delete_attachment($attach->ID, true);
32
- }
33
- else
34
- {
35
- $ids[] = $attach->ID;
36
- }
37
- }
38
- }
39
-
40
- global $wpdb;
41
 
42
  if ( ! empty( $ids ) ) {
43
 
11
 
12
  $attachments = get_posts(array('post_parent' => $parent_id, 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null));
13
 
14
+ foreach ($attachments as $attach) {
15
+ if ( ($type == 'files' && ! wp_attachment_is_image( $attach->ID )) || ($type == 'images' && wp_attachment_is_image( $attach->ID ))) {
16
+ if ($unlink) {
17
+ if (!empty($attach->ID)) {
18
+ $file = get_attached_file($attach->ID);
19
+ if (@file_exists($file)) {
20
+ wp_delete_attachment($attach->ID, TRUE);
21
+ }
22
+ }
23
+ }
24
+ else {
25
+ $ids[] = $attach->ID;
26
+ }
27
+ }
28
+ }
29
+
30
+ global $wpdb;
 
 
 
 
 
 
 
 
 
 
31
 
32
  if ( ! empty( $ids ) ) {
33
 
libraries/XmlImportTemplateCodeGenerator.php CHANGED
@@ -98,17 +98,15 @@ class XmlImportTemplateCodeGenerator
98
  if (count($this->sequence->getVariables()))
99
  {
100
  array_pop($this->xmlStack);
101
- }
102
- if (is_null($filename))
103
- {
104
- $filename = @tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
105
  }
106
  if ( ! $filename or ! @is_writable($filename) ){
107
  $uploads = wp_upload_dir();
108
  $targetDir = $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::TEMP_DIRECTORY;
109
  $filename = $targetDir . DIRECTORY_SEPARATOR . wp_unique_filename($targetDir, 'tmpfile');
110
  }
111
-
 
 
112
  file_put_contents($filename, $result);
113
  $sleep = apply_filters( 'wp_all_import_shard_delay', 0 );
114
  usleep($sleep);
98
  if (count($this->sequence->getVariables()))
99
  {
100
  array_pop($this->xmlStack);
 
 
 
 
101
  }
102
  if ( ! $filename or ! @is_writable($filename) ){
103
  $uploads = wp_upload_dir();
104
  $targetDir = $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::TEMP_DIRECTORY;
105
  $filename = $targetDir . DIRECTORY_SEPARATOR . wp_unique_filename($targetDir, 'tmpfile');
106
  }
107
+ // if ( ! $filename or ! @is_writable($filename)) {
108
+ // $filename = @tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
109
+ // }
110
  file_put_contents($filename, $result);
111
  $sleep = apply_filters( 'wp_all_import_shard_delay', 0 );
112
  usleep($sleep);
models/image/list.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class PMXI_Image_List
5
+ */
6
+ class PMXI_Image_List extends PMXI_Model_List {
7
+
8
+ /**
9
+ * PMXI_Image_List constructor.
10
+ */
11
+ public function __construct() {
12
+ parent::__construct();
13
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'images');
14
+ }
15
+
16
+ /**
17
+ * @param $url
18
+ * @return array|bool|null|\WP_Post
19
+ */
20
+ public function getExistingImageByUrl($url) {
21
+ $args = array(
22
+ 'image_url' => $url,
23
+ );
24
+ return $this->getExistingImage($args);
25
+ }
26
+
27
+ /**
28
+ * @param $image
29
+ * @return array|bool|null|\WP_Post
30
+ */
31
+ public function getExistingImageByFilename($image) {
32
+ $args = array(
33
+ 'image_filename' => $image,
34
+ );
35
+ return $this->getExistingImage($args);
36
+ }
37
+
38
+ /**
39
+ * @param $args
40
+ * @return array|bool|null|\WP_Post
41
+ */
42
+ public function getExistingImage($args){
43
+ $attid = false;
44
+ foreach($this->getBy($args)->convertRecords() as $imageRecord) {
45
+ if ( ! $imageRecord->isEmpty() ) {
46
+ $attid = $imageRecord->attachment_id;
47
+ break;
48
+ }
49
+ }
50
+ return $attid ? get_post($attid) : false;
51
+ }
52
+ }
models/image/record.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PMXI_Image_Record extends PMXI_Model_Record {
4
+ protected $primary = array('attachment_id');
5
+
6
+ /**
7
+ * Initialize model instance
8
+ * @param array[optional] $data Array of record data to initialize object with
9
+ */
10
+ public function __construct($data = array()) {
11
+ parent::__construct($data);
12
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'images');
13
+ }
14
+
15
+ }
models/import/record.php CHANGED
@@ -19,15 +19,15 @@ class PMXI_Import_Record extends PMXI_Model_Record {
19
  $is_preprocess_enabled = apply_filters('is_xml_preprocess_enabled', true);
20
 
21
  if ($is_preprocess_enabled)
22
- {
23
- $xml = preg_replace_callback('/<!\[CDATA\[.*?\]\]>/s', 'wp_all_import_cdata_filter', $xml );
24
- //$xml = preg_replace('/&(?![a-z#]+;)/i', '&amp;', $xml);
25
- $xml = preg_replace('/&([^amp;|^gt;|^lt;]+)/i', '&amp;$1', $xml);
26
-
27
- if ( ! empty(self::$cdata) ){
28
- foreach (self::$cdata as $key => $val) {
29
- $xml = str_replace('{{CPLACE_' . ($key + 1) . '}}', $val, $xml);
30
- }
31
  }
32
  }
33
  }
@@ -111,11 +111,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
111
  * @chainable
112
  */
113
  public function process($xml, $logger = NULL, $chunk = false, $is_cron = false, $xpath_prefix = '', $loop = 0) {
 
114
  add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
115
-
116
- kses_remove_filters();
117
 
118
- $cxpath = $xpath_prefix . $this->xpath;
119
 
120
  $this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
121
 
@@ -135,9 +134,13 @@ class PMXI_Import_Record extends PMXI_Model_Record {
135
 
136
  try {
137
 
 
 
 
 
138
  $chunk == 1 and $logger and printf("<div class='progress-msg'>%s</div>\n", date("r")) and flush();
139
-
140
- $chunk == 1 and $logger and call_user_func($logger, __('Composing titles...', 'wp_all_import_plugin'));
141
  if ( ! empty($this->options['title'])){
142
  $titles = XmlImportParser::factory($xml, $cxpath, $this->options['title'], $file)->parse($records); $tmp_files[] = $file;
143
  }
@@ -145,16 +148,39 @@ class PMXI_Import_Record extends PMXI_Model_Record {
145
  $loop and $titles = array_fill(0, $loop, '');
146
  }
147
 
148
- $chunk == 1 and $logger and call_user_func($logger, __('Composing excerpts...', 'wp_all_import_plugin'));
149
- $post_excerpt = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  if ( ! empty($this->options['post_excerpt']) && $this->is_parsing_required('is_update_excerpt')){
151
- $post_excerpt = XmlImportParser::factory($xml, $cxpath, $this->options['post_excerpt'], $file)->parse($records); $tmp_files[] = $file;
152
- }
153
- else{
154
- count($titles) and $post_excerpt = array_fill(0, count($titles), '');
155
- }
 
156
 
157
- if ( "xpath" == $this->options['status'] ){
158
  $chunk == 1 and $logger and call_user_func($logger, __('Composing statuses...', 'wp_all_import_plugin'));
159
  $post_status = array();
160
  if ( ! empty($this->options['status_xpath']) && $this->is_parsing_required('is_update_status') ){
@@ -198,16 +224,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
198
  }
199
  }
200
 
201
- if ( "pid" == $this->options['duplicate_indicator'] ){
202
- $chunk == 1 and $logger and call_user_func($logger, __('Composing post IDs...', 'wp_all_import_plugin'));
203
- $post_ids = array();
204
- if (!empty($this->options['pid_xpath'])){
205
- $post_ids = XmlImportParser::factory($xml, $cxpath, $this->options['pid_xpath'], $file)->parse($records); $tmp_files[] = $file;
206
  }
207
  else{
208
- count($titles) and $post_ids = array_fill(0, count($titles), '');
209
  }
210
  }
 
 
 
211
 
212
  if ( "no" == $this->options['is_multiple_page_template'] ){
213
  $chunk == 1 and $logger and call_user_func($logger, __('Composing page templates...', 'wp_all_import_plugin'));
@@ -220,19 +249,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
220
  }
221
  }
222
 
223
- if ( $this->options['is_override_post_type'] and ! empty($this->options['post_type_xpath']) ){
224
- $chunk == 1 and $logger and call_user_func($logger, __('Composing post types...', 'wp_all_import_plugin'));
225
- $post_type = array();
226
- $post_type = XmlImportParser::factory($xml, $cxpath, $this->options['post_type_xpath'], $file)->parse($records); $tmp_files[] = $file;
227
- }
228
- else{
229
- if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
230
- $pType = $this->options['custom_type'];
231
- } else {
232
- $pType = $this->options['type'];
233
- }
234
- count($titles) and $post_type = array_fill(0, count($titles), $pType);
235
- }
236
 
237
  if ( "no" == $this->options['is_multiple_page_parent'] ){
238
  $chunk == 1 and $logger and call_user_func($logger, __('Composing page parent...', 'wp_all_import_plugin'));
@@ -246,46 +275,46 @@ class PMXI_Import_Record extends PMXI_Model_Record {
246
  }
247
 
248
  if ( $this->is_parsing_required('is_update_author') ){
249
- $chunk == 1 and $logger and call_user_func($logger, __('Composing authors...', 'wp_all_import_plugin'));
250
- $post_author = array();
251
- $current_user = wp_get_current_user();
252
-
253
- if (!empty($this->options['author'])){
254
- $post_author = XmlImportParser::factory($xml, $cxpath, $this->options['author'], $file)->parse($records); $tmp_files[] = $file;
255
- foreach ($post_author as $key => $author) {
256
- $user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
257
- if (!empty($user))
258
- {
259
- $post_author[$key] = $user->ID;
260
- }
261
- else{
262
- if ($current_user->ID){
263
- $post_author[$key] = $current_user->ID;
264
- }
265
- else{
266
- $super_admins = get_super_admins();
267
- if ( ! empty($super_admins)){
268
- $sauthor = array_shift($super_admins);
269
- $user = get_user_by('login', $sauthor) or $user = get_user_by('slug', $sauthor) or $user = get_user_by('email', $sauthor) or ctype_digit($sauthor) and $user = get_user_by('id', $sauthor);
270
- $post_author[$key] = (!empty($user)) ? $user->ID : $current_user->ID;
271
- }
272
- }
273
- }
274
- }
275
- }
276
- else{
277
- if ($current_user->ID){
278
- count($titles) and $post_author = array_fill(0, count($titles), $current_user->ID);
279
- }
280
- else{
281
- $super_admins = get_super_admins();
282
- if ( ! empty($super_admins)){
283
- $author = array_shift($super_admins);
284
- $user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
285
- count($titles) and $post_author = array_fill(0, count($titles), (!empty($user)) ? $user->ID : $current_user->ID);
286
- }
287
- }
288
- }
289
  }
290
  else{
291
  $current_user = wp_get_current_user();
@@ -301,6 +330,14 @@ class PMXI_Import_Record extends PMXI_Model_Record {
301
  count($titles) and $post_slug = array_fill(0, count($titles), '');
302
  }
303
 
 
 
 
 
 
 
 
 
304
  $chunk == 1 and $logger and call_user_func($logger, __('Composing menu order...', 'wp_all_import_plugin'));
305
  $menu_order = array();
306
  if (!empty($this->options['order']) && $this->is_parsing_required('is_update_menu_order')){
@@ -325,39 +362,39 @@ class PMXI_Import_Record extends PMXI_Model_Record {
325
 
326
  $chunk == 1 and $logger and call_user_func($logger, __('Composing dates...', 'wp_all_import_plugin'));
327
  if ( $this->is_parsing_required('is_update_dates') ){
328
- if ('specific' == $this->options['date_type']) {
329
- $dates = XmlImportParser::factory($xml, $cxpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
330
- $warned = array(); // used to prevent the same notice displaying several times
331
- foreach ($dates as $i => $d) {
332
- if ($d == 'now') $d = current_time('mysql'); // Replace 'now' with the WordPress local time to account for timezone offsets (WordPress references its local time during publishing rather than the server’s time so it should use that)
333
- $time = strtotime($d);
334
- if (FALSE === $time) {
335
- in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $d));
336
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
337
- $time = time();
338
- }
339
- $dates[$i] = date('Y-m-d H:i:s', $time);
340
- }
341
- } else {
342
- $dates_start = XmlImportParser::factory($xml, $cxpath, $this->options['date_start'], $file)->parse($records); $tmp_files[] = $file;
343
- $dates_end = XmlImportParser::factory($xml, $cxpath, $this->options['date_end'], $file)->parse($records); $tmp_files[] = $file;
344
- $warned = array(); // used to prevent the same notice displaying several times
345
- foreach ($dates_start as $i => $d) {
346
- $time_start = strtotime($dates_start[$i]);
347
- if (FALSE === $time_start) {
348
- in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $dates_start[$i]));
349
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
350
- $time_start = time();
351
- }
352
- $time_end = strtotime($dates_end[$i]);
353
- if (FALSE === $time_end) {
354
- in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $dates_end[$i]));
355
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
356
- $time_end = time();
357
- }
358
- $dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
359
- }
360
- }
361
  }
362
  else{
363
  count($titles) and $dates = array_fill(0, count($titles), date('Y-m-d H:i:s', strtotime(current_time('mysql'))));
@@ -582,9 +619,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
582
  }
583
  endforeach;
584
  endif;
585
- // [/custom taxonomies]
586
 
587
- // Composing featured images
588
  $image_sections = apply_filters('wp_all_import_image_sections', array(
589
  array(
590
  'slug' => '',
@@ -685,29 +722,28 @@ class PMXI_Import_Record extends PMXI_Model_Record {
685
  $image_meta_descriptions_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $image_meta_descriptions;
686
  }
687
 
688
- if ( "yes" == $this->options[$section['slug'] . 'download_images'] ){
689
- // Composing images suffix
690
- $chunk == 1 and $this->options[$section['slug'] . 'auto_rename_images'] and $logger and call_user_func($logger, __('Composing ' . strtolower($section['title']) . ' suffix...', 'wp_all_import_plugin'));
691
- $auto_rename_images = array();
692
- if ( $this->options[$section['slug'] . 'auto_rename_images'] and ! empty($this->options[$section['slug'] . 'auto_rename_images_suffix'])){
693
- $auto_rename_images = XmlImportParser::factory($xml, $cxpath, $this->options[$section['slug'] . 'auto_rename_images_suffix'], $file)->parse($records); $tmp_files[] = $file;
694
- }
695
- else{
696
- count($titles) and $auto_rename_images = array_fill(0, count($titles), '');
697
- }
698
- $auto_rename_images_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $auto_rename_images;
699
 
700
- // Composing images extensions
701
- $chunk == 1 and $this->options[$section['slug'] . 'auto_set_extension'] and $logger and call_user_func($logger, __('Composing ' . strtolower($section['title']) . ' extensions...', 'wp_all_import_plugin'));
702
- $auto_extensions = array();
703
- if ( $this->options[$section['slug'] . 'auto_set_extension'] and ! empty($this->options[$section['slug'] . 'new_extension'])){
704
- $auto_extensions = XmlImportParser::factory($xml, $cxpath, $this->options[$section['slug'] . 'new_extension'], $file)->parse($records); $tmp_files[] = $file;
705
- }
706
- else{
707
- count($titles) and $auto_extensions = array_fill(0, count($titles), '');
708
- }
709
- $auto_extensions_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $auto_extensions;
710
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
 
712
  }
713
  }
@@ -724,7 +760,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
724
 
725
  if ($this->options['attachments'] && $this->is_parsing_required('is_update_attachments') ) {
726
  // Detect if attachments is separated by comma
727
- $atchs = empty($this->options['atch_delim']) ? explode(',', $this->options['attachments']) : explode($this->options['atch_delim'], $this->options['attachments']);
728
  if (!empty($atchs)){
729
  $parse_multiple = true;
730
  foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
@@ -755,7 +791,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
755
  else{
756
  count($titles) and $unique_keys = array_fill(0, count($titles), '');
757
  }
758
-
759
  $chunk == 1 and $logger and call_user_func($logger, __('Processing posts...', 'wp_all_import_plugin'));
760
 
761
  $addons = array();
@@ -806,7 +842,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
806
 
807
  if ($this->options['is_import_specified']) {
808
  $chunk == 1 and $logger and call_user_func($logger, __('Calculate specified records to import...', 'wp_all_import_plugin'));
809
- $import_specified_option = apply_filters('wp_all_import_specified_records', $this->options['import_specified'], $this->id, $rootNodes);
810
  foreach (preg_split('% *, *%', $import_specified_option, -1, PREG_SPLIT_NO_EMPTY) as $chank) {
811
  if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
812
  $specified_records = array_merge($specified_records, range(intval($mtch[1]), intval($mtch[2])));
@@ -815,17 +851,32 @@ class PMXI_Import_Record extends PMXI_Model_Record {
815
  }
816
  }
817
 
818
- }
819
 
820
- foreach ($titles as $i => $void) {
821
 
822
- $custom_type_details = get_post_type_object( $post_type[$i] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823
 
824
  if ($is_cron and $cron_sleep) sleep($cron_sleep);
825
 
826
  $logger and call_user_func($logger, __('---', 'wp_all_import_plugin'));
827
  $logger and call_user_func($logger, sprintf(__('Record #%s', 'wp_all_import_plugin'), $this->imported + $this->skipped + $i + 1));
828
-
829
  if ( "manual" == $this->options['duplicate_matching']
830
  and ! empty($specified_records)
831
  and ! in_array($created + $updated + $skipped + 1, $specified_records) )
@@ -834,11 +885,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
834
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'wp_all_import_plugin'));
835
  $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
836
  $logger and !$is_cron and PMXI_Plugin::$session->chunk_number++;
837
- $logger and !$is_cron and PMXI_Plugin::$session->save_data();
838
  continue;
839
- }
840
-
841
- wp_cache_flush();
842
 
843
  $logger and call_user_func($logger, __('<b>ACTION</b>: pmxi_before_post_import ...', 'wp_all_import_plugin'));
844
  do_action('pmxi_before_post_import', $this->id);
@@ -857,58 +906,79 @@ class PMXI_Import_Record extends PMXI_Model_Record {
857
  $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
858
  }
859
  }
860
-
861
- if ( $this->options['custom_type'] == 'import_users' ){
862
- $articleData = apply_filters('wp_all_import_combine_article_data', array(
863
- 'user_pass' => $addons_data['PMUI_Plugin']['pmui_pass'][$i],
864
- 'user_login' => $addons_data['PMUI_Plugin']['pmui_logins'][$i],
865
- 'user_nicename' => $addons_data['PMUI_Plugin']['pmui_nicename'][$i],
866
- 'user_url' => $addons_data['PMUI_Plugin']['pmui_url'][$i],
867
- 'user_email' => $addons_data['PMUI_Plugin']['pmui_email'][$i],
868
- 'display_name' => $addons_data['PMUI_Plugin']['pmui_display_name'][$i],
869
- 'user_registered' => $addons_data['PMUI_Plugin']['pmui_registered'][$i],
870
- 'first_name' => $addons_data['PMUI_Plugin']['pmui_first_name'][$i],
871
- 'last_name' => $addons_data['PMUI_Plugin']['pmui_last_name'][$i],
872
- 'description' => $addons_data['PMUI_Plugin']['pmui_description'][$i],
873
- 'nickname' => $addons_data['PMUI_Plugin']['pmui_nickname'][$i],
874
- 'role' => ('' == $addons_data['PMUI_Plugin']['pmui_role'][$i]) ? 'subscriber' : strtolower($addons_data['PMUI_Plugin']['pmui_role'][$i]),
875
- ), $this->options['custom_type'], $this->id, $i);
876
- $logger and call_user_func($logger, sprintf(__('Combine all data for user %s...', 'wp_all_import_plugin'), $articleData['user_login']));
877
- }
878
- else {
879
- $articleData = apply_filters('wp_all_import_combine_article_data', array(
880
- 'post_type' => $post_type[$i],
881
- 'post_status' => ("xpath" == $this->options['status']) ? $post_status[$i] : $this->options['status'],
882
- 'comment_status' => ("xpath" == $this->options['comment_status']) ? $comment_status[$i] : $this->options['comment_status'],
883
- 'ping_status' => ("xpath" == $this->options['ping_status']) ? $ping_status[$i] : $this->options['ping_status'],
884
- 'post_title' => (!empty($this->options['is_leave_html'])) ? html_entity_decode($titles[$i]) : $titles[$i],
885
- 'post_excerpt' => apply_filters('pmxi_the_excerpt', ((!empty($this->options['is_leave_html'])) ? html_entity_decode($post_excerpt[$i]) : $post_excerpt[$i]), $this->id),
886
- 'post_name' => $post_slug[$i],
887
- 'post_content' => apply_filters('pmxi_the_content', ((!empty($this->options['is_leave_html'])) ? html_entity_decode($contents[$i]) : $contents[$i]), $this->id),
888
- 'post_date' => $dates[$i],
889
- 'post_date_gmt' => get_gmt_from_date($dates[$i]),
890
- 'post_author' => $post_author[$i],
891
- 'menu_order' => (int) $menu_order[$i],
892
- 'post_parent' => ("no" == $this->options['is_multiple_page_parent']) ? wp_all_import_get_parent_post($page_parent[$i], $post_type[$i], $this->options['type']) : (int) $this->options['parent'],
893
- 'page_template' => ("no" == $this->options['is_multiple_page_template']) ? $page_template[$i] : $this->options['page_template']
894
- ), $this->options['custom_type'], $this->id, $i);
895
- if ( 'shop_coupon' == $post_type[$i] ){
896
- $articleData['post_excerpt'] = $articleData['post_content'];
897
- }
898
- $logger and call_user_func($logger, sprintf(__('Combine all data for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
899
-
900
- // if ( "xpath" == $this->options['status'] )
901
- // {
902
- // $status_object = get_post_status_object($post_status[$i]);
903
-
904
- // if ( empty($status_object) )
905
- // {
906
- // $articleData['post_status'] = 'draft';
907
- // $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Post status `%s` is not supported, post `%s` will be saved in draft.', 'wp_all_import_plugin'), $post_status[$i], $articleData['post_title']));
908
- // $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
909
- // }
910
- // }
911
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
912
 
913
  // Re-import Records Matching
914
  $post_to_update = false; $post_to_update_id = false;
@@ -917,32 +987,46 @@ class PMXI_Import_Record extends PMXI_Model_Record {
917
  $current_xml_node = wp_all_import_xml2array($rootNodes[$i]);
918
 
919
  $check_for_duplicates = apply_filters('wp_all_import_is_check_duplicates', true, $this->id);
920
-
921
  if ( $check_for_duplicates )
922
  {
923
  // if Auto Matching re-import option selected
924
  if ( "manual" != $this->options['duplicate_matching'] ){
925
 
926
  // find corresponding article among previously imported
927
- $logger and call_user_func($logger, sprintf(__('Find corresponding article among previously imported for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
928
- $postRecord->clear();
929
- $postRecord->getBy(array(
930
- 'unique_key' => $unique_keys[$i],
931
- 'import_id' => $this->id,
932
- ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
933
 
934
- if ( ! $postRecord->isEmpty() ) {
935
- $logger and call_user_func($logger, sprintf(__('Duplicate post was found for post %s with unique key `%s`...', 'wp_all_import_plugin'), $articleData['post_title'], $unique_keys[$i]));
936
- if ( $this->options['custom_type'] == 'import_users'){
937
- $post_to_update = get_user_by('id', $post_to_update_id = $postRecord->post_id);
938
- }
939
- else{
940
- $post_to_update = get_post($post_to_update_id = $postRecord->post_id);
941
- }
942
- }
943
- else{
944
- $logger and call_user_func($logger, sprintf(__('Duplicate post wasn\'t found with unique key `%s`...', 'wp_all_import_plugin'), $unique_keys[$i]));
945
- }
946
 
947
  // if Manual Matching re-import option seleted
948
  } else {
@@ -955,36 +1039,40 @@ class PMXI_Import_Record extends PMXI_Model_Record {
955
  count($titles) and $custom_duplicate_name = $custom_duplicate_value = array_fill(0, count($titles), '');
956
  }
957
 
958
- $logger and call_user_func($logger, sprintf(__('Find corresponding article among database for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
959
 
 
960
  if ('pid' == $this->options['duplicate_indicator']) {
961
- $duplicate_id = $post_ids[$i];
962
  }
963
  // handle duplicates according to import settings
964
  else
965
  {
966
- $duplicates = pmxi_findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i], $this->options['duplicate_indicator']);
967
  $duplicate_id = ( ! empty($duplicates)) ? array_shift($duplicates) : false;
968
  }
969
 
970
- if ( ! empty($duplicate_id)) {
971
- $duplicate_id = apply_filters('wp_all_import_manual_matching_duplicate_id', $duplicate_id, $duplicates, $articleData, $this->id);
972
  if (class_exists('WPAI_WPML') && ! empty($this->options['wpml_addon']['lng'])){
973
  // trying to find needed translation for update
974
  $duplicate_id = apply_filters('wpml_object_id', $duplicate_id, get_post_type($duplicate_id), true, $this->options['wpml_addon']['lng']);
975
  }
976
- $logger and call_user_func($logger, sprintf(__('Duplicate post was found for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
977
  switch ($this->options['custom_type']){
978
  case 'import_users':
979
  $post_to_update = get_user_by('id', $post_to_update_id = $duplicate_id);
980
- break;
 
 
 
981
  default:
982
  $post_to_update = get_post($post_to_update_id = $duplicate_id);
983
  break;
984
  }
985
  }
986
  else{
987
- $logger and call_user_func($logger, sprintf(__('Duplicate post wasn\'t found for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
988
  }
989
  }
990
  }
@@ -1020,7 +1108,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1020
 
1021
  $continue_import = true;
1022
 
1023
- $continue_import = apply_filters('wp_all_import_is_post_to_update', $continue_import, $post_to_update_id, $current_xml_node, $this->id);
1024
 
1025
  if ( ! $continue_import ){
1026
 
@@ -1057,134 +1145,177 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1057
  // Choose which data to update
1058
  if ( $this->options['update_all_data'] == 'no' ){
1059
 
1060
- if ( ! in_array($this->options['custom_type'], array('import_users'))){
1061
-
1062
- // preserve date of already existing article when duplicate is found
1063
- if ( ( ! $this->options['is_update_categories'] and ( is_object_in_taxonomy( $post_type[$i], 'category' ) or is_object_in_taxonomy( $post_type[$i], 'post_tag' ) ) ) or ($this->options['is_update_categories'] and $this->options['update_categories_logic'] != "full_update")) {
1064
- $logger and call_user_func($logger, sprintf(__('Preserve taxonomies of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1065
- $existing_taxonomies = array();
1066
- foreach (array_keys($taxonomies) as $tx_name) {
1067
- $txes_list = get_the_terms($articleData['ID'], $tx_name);
1068
- if (is_wp_error($txes_list)) {
1069
- $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'wp_all_import_plugin'), $articleData['ID']));
1070
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1071
- } else {
1072
- $txes_new = array();
1073
- if (!empty($txes_list)):
1074
- foreach ($txes_list as $t) {
1075
- $txes_new[] = $t->term_taxonomy_id;
1076
- }
1077
- endif;
1078
- $existing_taxonomies[$tx_name][$i] = $txes_new;
1079
- }
1080
- }
1081
- }
1082
-
1083
- if ( ! $this->options['is_update_dates']) { // preserve date of already existing article when duplicate is found
1084
- $articleData['post_date'] = $post_to_update->post_date;
1085
- $articleData['post_date_gmt'] = $post_to_update->post_date_gmt;
1086
- $logger and call_user_func($logger, sprintf(__('Preserve date of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1087
- }
1088
- if ( ! $this->options['is_update_status']) { // preserve status and trashed flag
1089
- $articleData['post_status'] = $post_to_update->post_status;
1090
- $logger and call_user_func($logger, sprintf(__('Preserve status of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1091
- }
1092
- if ( ! $this->options['is_update_content']){
1093
- $articleData['post_content'] = $post_to_update->post_content;
1094
- $logger and call_user_func($logger, sprintf(__('Preserve content of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1095
- }
1096
- if ( ! $this->options['is_update_title']){
1097
- $articleData['post_title'] = $post_to_update->post_title;
1098
- $logger and call_user_func($logger, sprintf(__('Preserve title of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1099
- }
1100
- if ( ! $this->options['is_update_slug']){
1101
- $articleData['post_name'] = $post_to_update->post_name;
1102
- $logger and call_user_func($logger, sprintf(__('Preserve slug of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1103
- }
1104
- // Check for changed slugs for published post objects and save the old slug.
1105
- if( ! empty($articleData['post_name']) and $articleData['post_name'] != $post_to_update->post_name)
1106
- {
1107
- $old_slugs = (array) get_post_meta( $post_to_update_id, '_wp_old_slug' );
 
 
 
 
 
 
 
 
 
 
1108
 
1109
- // If we haven't added this old slug before, add it now.
1110
- if ( ! empty( $post_to_update->post_name ) && ! in_array( $post_to_update->post_name, $old_slugs ) ) {
1111
- add_post_meta( $post_to_update_id, '_wp_old_slug', $post_to_update->post_name );
1112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1113
 
1114
- // If the new slug was used previously, delete it from the list.
1115
- if ( in_array( $articleData['post_name'], $old_slugs ) ) {
1116
- delete_post_meta( $post_to_update_id, '_wp_old_slug', $articleData['post_name'] );
1117
- }
1118
- }
1119
-
1120
- if ( ! $this->options['is_update_excerpt']){
1121
- $articleData['post_excerpt'] = $post_to_update->post_excerpt;
1122
- $logger and call_user_func($logger, sprintf(__('Preserve excerpt of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1123
- }
1124
- if ( ! $this->options['is_update_menu_order']){
1125
- $articleData['menu_order'] = $post_to_update->menu_order;
1126
- $logger and call_user_func($logger, sprintf(__('Preserve menu order of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1127
- }
1128
- if ( ! $this->options['is_update_parent']){
1129
- $articleData['post_parent'] = $post_to_update->post_parent;
1130
- $logger and call_user_func($logger, sprintf(__('Preserve post parent of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1131
- }
1132
- if ( ! $this->options['is_update_post_type']){
1133
- $articleData['post_type'] = $post_to_update->post_type;
1134
- $logger and call_user_func($logger, sprintf(__('Preserve post type of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1135
- }
1136
- if ( ! $this->options['is_update_comment_status']){
1137
- $articleData['comment_status'] = $post_to_update->comment_status;
1138
- $logger and call_user_func($logger, sprintf(__('Preserve comment status of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1139
- }
1140
- if ( ! $this->options['is_update_author']){
1141
- $articleData['post_author'] = $post_to_update->post_author;
1142
- $logger and call_user_func($logger, sprintf(__('Preserve post author of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1143
- }
1144
- }
1145
- else {
1146
- if ( ! $this->options['is_update_first_name'] ) $articleData['first_name'] = $post_to_update->first_name;
1147
- if ( ! $this->options['is_update_last_name'] ) $articleData['last_name'] = $post_to_update->last_name;
1148
- if ( ! $this->options['is_update_role'] ) unset($articleData['role']);
1149
- if ( ! $this->options['is_update_nickname'] ) $articleData['nickname'] = get_user_meta($post_to_update->ID, 'nickname', true);
1150
- if ( ! $this->options['is_update_description'] ) $articleData['description'] = get_user_meta($post_to_update->ID, 'description', true);
1151
- if ( ! $this->options['is_update_login'] ) $articleData['user_login'] = $post_to_update->user_login;
1152
- if ( ! $this->options['is_update_password'] ) unset($articleData['user_pass']);
1153
- if ( ! $this->options['is_update_nicename'] ) $articleData['user_nicename'] = $post_to_update->user_nicename;
1154
- if ( ! $this->options['is_update_email'] ) $articleData['user_email'] = $post_to_update->user_email;
1155
- if ( ! $this->options['is_update_registered'] ) $articleData['user_registered'] = $post_to_update->user_registered;
1156
- if ( ! $this->options['is_update_display_name'] ) $articleData['display_name'] = $post_to_update->display_name;
1157
- if ( ! $this->options['is_update_url'] ) $articleData['user_url'] = $post_to_update->user_url;
1158
- }
1159
-
1160
- }
1161
 
1162
- if ( ! in_array($this->options['custom_type'], array('import_users'))){
 
 
 
 
1163
 
1164
- $is_images_to_delete = apply_filters('pmxi_delete_images', true, $articleData, $current_xml_node);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1165
 
1166
- if ( $is_images_to_delete ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1167
 
1168
- if ( $this->options['update_all_data'] == 'yes' or ( $this->options['update_all_data'] == 'no' and $this->options['is_update_attachments'])) {
1169
- $logger and call_user_func($logger, sprintf(__('Deleting attachments for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1170
- wp_delete_attachments($articleData['ID'], true, 'files');
1171
- }
1172
- // handle obsolete attachments (i.e. delete or keep) according to import settings
1173
- if ($this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_images'] and $this->options['update_images_logic'] == "full_update")) {
1174
- $logger and call_user_func($logger, sprintf(__('Deleting images for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1175
- if (!empty($images_bundle)) {
1176
- foreach ($images_bundle as $slug => $bundle_data) {
1177
- $option_slug = ($slug == 'pmxi_gallery_image') ? '' : $slug;
1178
- if (count($images_bundle) > 1 && $slug == 'pmxi_gallery_image') {
1179
- continue;
 
 
 
 
 
1180
  }
1181
- $do_not_remove_images = ($this->options[$option_slug . 'download_images'] == 'gallery' or $this->options[$option_slug . 'do_not_remove_images']) ? FALSE : TRUE;
1182
- $missing_images = wp_delete_attachments($articleData['ID'], $do_not_remove_images, 'images');
1183
  }
1184
  }
1185
- }
1186
- }
1187
- }
1188
  }
1189
  elseif ( ! $postRecord->isEmpty() ){
1190
 
@@ -1193,7 +1324,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1193
 
1194
  }
1195
 
1196
- $logger and call_user_func($logger, sprintf(__('Applying filter `pmxi_article_data` for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1197
  $articleData = apply_filters('pmxi_article_data', $articleData, $this, $post_to_update);
1198
 
1199
  // no new records are created. it will only update posts it finds matching duplicates for
@@ -1291,13 +1422,13 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1291
  if ($this->options['is_fast_mode']){
1292
  foreach (array('transition_post_status', 'save_post', 'pre_post_update', 'add_attachment', 'edit_attachment', 'edit_post', 'post_updated', 'wp_insert_post', 'save_post_' . $post_type[$i]) as $act) {
1293
  remove_all_actions($act);
1294
- }
1295
  }
1296
 
1297
  if ( empty($articleData['ID']) )
1298
  {
1299
  $continue_import = true;
1300
- $continue_import = apply_filters('wp_all_import_is_post_to_create', $continue_import, $current_xml_node, $this->id);
1301
 
1302
  if ( ! $continue_import ){
1303
  $skipped++;
@@ -1309,30 +1440,64 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1309
  continue;
1310
  }
1311
  }
1312
-
1313
- if ( ! in_array($this->options['custom_type'], array('import_users'))){
1314
- if (empty($articleData['ID'])){
1315
- $logger and call_user_func($logger, sprintf(__('<b>CREATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1316
- }
1317
- else{
1318
- $logger and call_user_func($logger, sprintf(__('<b>UPDATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1319
- }
1320
- $pid = (empty($articleData['ID'])) ? wp_insert_post($articleData, true) : wp_update_post($articleData, true);
1321
- }
1322
- else{
1323
- if (empty($articleData['ID']) && email_exists( $articleData['user_email'] )){
1324
- $logger and call_user_func($logger, sprintf(__('<b>ERROR</b> Sorry, that email address `%s` is already used!', 'wp_all_import_plugin'), $articleData['user_email']));
1325
- $logger and !$is_cron and PMXI_Plugin::$session->errors++;
1326
- $skipped++;
1327
- continue;
1328
- }
1329
- $pid = (empty($articleData['ID'])) ? wp_insert_user( $articleData ) : wp_update_user( $articleData );
1330
- // update user login using direct sql query
1331
- if (!empty($articleData['ID'])){
1332
- $this->wpdb->update($this->wpdb->users, array('user_login' => $articleData['user_login']), array('ID' => $articleData['ID']));
1333
- }
1334
- $articleData['post_title'] = $articleData['user_login'];
1335
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1336
 
1337
  if (empty($pid))
1338
  {
@@ -1346,33 +1511,36 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1346
  $skipped++;
1347
  } else {
1348
 
1349
- if (empty($articleData['post_parent']) && !empty($page_parent[$i])){
1350
  $parent_posts = get_option('wp_all_import_posts_hierarchy_' . $this->id);
1351
  if (empty($parent_posts)) $parent_posts = array();
1352
  $parent_posts[$pid] = $page_parent[$i];
1353
  update_option('wp_all_import_posts_hierarchy_' . $this->id, $parent_posts);
1354
- }
1355
-
1356
- if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
1357
  // associate post with import
1358
  $product_key = (($post_type[$i] == "product" and PMXI_Admin_Addons::get_addon('PMWI_Plugin')) ? $addons_data['PMWI_Plugin']['single_product_ID'][$i] : '');
1359
- $postRecord->isEmpty() and $postRecord->set(array(
 
 
 
1360
  'post_id' => $pid,
1361
  'import_id' => $this->id,
1362
  'unique_key' => $unique_keys[$i],
1363
  'product_key' => $product_key
1364
  ))->insert();
1365
 
1366
- $postRecordData = array(
1367
  'iteration' => $this->iteration,
1368
  'specified' => empty($specified_records) ? 0 : 1
1369
  );
1370
 
1371
  if ( ! empty($product_key) ){
1372
  $postRecordData['product_key'] = $product_key;
1373
- }
1374
 
1375
- $postRecord->set($postRecordData)->update();
1376
 
1377
  $logger and call_user_func($logger, sprintf(__('Associate post `%s` with current import ...', 'wp_all_import_plugin'), $articleData['post_title']));
1378
  }
@@ -1417,106 +1585,218 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1417
  }
1418
  }
1419
  }
 
 
 
 
 
 
 
 
1420
 
1421
- // [/addons import]
1422
 
1423
- if (empty($articleData['ID']) or $this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_custom_fields']) or ($this->options['update_all_data'] == 'no' and $this->options['is_update_attributes'] and $post_type[$i] == "product" and class_exists('PMWI_Plugin'))) {
 
1424
 
1425
- $encoded_meta = array();
1426
-
1427
- if ( ! empty($serialized_meta)){
1428
 
1429
- $processed_custom_fields = array();
1430
 
1431
- foreach ($serialized_meta as $m_keys) {
1432
 
1433
- foreach ($m_keys as $m_key => $values) {
1434
-
1435
- if (!empty($articleData['ID'])){
1436
-
1437
- if ($this->options['update_all_data'] != 'yes'){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1438
 
1439
- $field_to_update = false;
 
 
 
1440
 
1441
- if ($this->options['is_update_custom_fields'] and $this->options['update_custom_fields_logic'] == "only" and ! empty($this->options['custom_fields_list']) and is_array($this->options['custom_fields_list']) and in_array($m_key, $this->options['custom_fields_list']) ) $field_to_update = true;
1442
- if ($this->options['is_update_custom_fields'] and $this->options['update_custom_fields_logic'] == "all_except" and ( empty($this->options['custom_fields_list']) or ! in_array($m_key, $this->options['custom_fields_list']) )) $field_to_update = true;
1443
-
1444
- if ( $this->options['update_custom_fields_logic'] == "full_update" ) $field_to_update = true;
1445
 
1446
- // apply addons filters
1447
- $field_to_update = apply_filters('pmxi_custom_field_to_update', $field_to_update, $post_type[$i], $this->options, $m_key);
1448
 
1449
- if ( ! $field_to_update ) {
1450
- $logger and call_user_func($logger, sprintf(__('- Custom field `%s` has been skipped attempted to record matching options ...', 'wp_all_import_plugin'), $m_key));
1451
- continue;
1452
- }
1453
 
1454
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1455
 
1456
- }
1457
-
1458
- $logger and call_user_func($logger, __('- <b>ACTION</b>: pmxi_custom_field', 'wp_all_import_plugin'));
1459
- $cf_value = apply_filters('pmxi_custom_field', (is_serialized($values[$i])) ? unserialize($values[$i]) : $values[$i], $pid, $m_key, $existing_meta_keys, $this->id);
1460
-
1461
- //$this->pushmeta($pid, $m_key, $cf_value);
1462
- if ( $this->options['custom_type'] == 'import_users')
1463
- {
1464
- if (in_array($m_key, $processed_custom_fields))
1465
- {
1466
- add_user_meta($pid, $m_key, $cf_value);
1467
- }
1468
- else
1469
- {
1470
- update_user_meta($pid, $m_key, $cf_value);
1471
- }
1472
- }
1473
- else
1474
- {
1475
- if (in_array($m_key, $processed_custom_fields))
1476
- {
1477
- add_post_meta($pid, $m_key, $cf_value);
1478
- }
1479
- else
1480
- {
1481
- update_post_meta($pid, $m_key, $cf_value);
1482
- }
1483
- }
1484
- if ( ! in_array($m_key, $processed_custom_fields)) $processed_custom_fields[] = $m_key;
1485
 
1486
- $logger and call_user_func($logger, sprintf(__('- Custom field `%s` has been updated with value `%s` for post `%s` ...', 'wp_all_import_plugin'), $m_key, esc_attr(maybe_serialize($cf_value)), $articleData['post_title']));
1487
- $logger and call_user_func($logger, __('- <b>ACTION</b>: pmxi_update_post_meta', 'wp_all_import_plugin'));
1488
- do_action( 'pmxi_update_post_meta', $pid, $m_key, (is_serialized($values[$i])) ? unserialize($values[$i]) : $values[$i]); // hook that was triggered after post meta data updated
1489
- }
1490
- }
1491
 
1492
- //$this->executeSQL();
1493
- }
1494
- }
1495
- // [/custom fields]
 
 
1496
 
1497
- // Page Template
1498
- global $wp_version;
1499
- if ( ! empty($articleData['post_type']) and ('page' == $articleData['post_type'] || version_compare($wp_version, '4.7.0', '>=')) and wp_all_import_is_update_cf('_wp_page_template', $this->options) and ( !empty($this->options['page_template']) or "no" == $this->options['is_multiple_page_template']) ){
1500
- update_post_meta($pid, '_wp_page_template', ("no" == $this->options['is_multiple_page_template']) ? $page_template[$i] : $this->options['page_template']);
1501
- }
1502
-
1503
- // [featured image]
1504
 
1505
- $is_images_to_update = apply_filters('pmxi_is_images_to_update', true, $articleData, $current_xml_node);
1506
 
1507
- $is_allow_import_images = apply_filters('wp_all_import_is_allow_import_images', false, empty($articleData['post_type']) ? '' : $articleData['post_type']);
 
1508
 
1509
- $images_uploads = apply_filters('wp_all_import_images_uploads_dir', $uploads, $articleData, $current_xml_node, $this->id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1510
 
1511
  if ( $is_images_to_update and ! empty($images_uploads) and false === $images_uploads['error'] and ( ! empty($articleData['post_type']) and $articleData['post_type'] == "product" and class_exists('PMWI_Plugin') or $is_allow_import_images) and (empty($articleData['ID']) or $this->options['update_all_data'] == "yes" or ( $this->options['update_all_data'] == "no" and $this->options['is_update_images'])) ) {
1512
 
1513
- if ( ! empty($images_bundle) ){
1514
 
1515
  require_once(ABSPATH . 'wp-admin/includes/image.php');
1516
 
1517
- $is_show_add_new_images = apply_filters('wp_all_import_is_show_add_new_images', true, $post_type[$i]);
 
 
1518
 
1519
  foreach ($images_bundle as $slug => $bundle_data) {
 
 
1520
 
1521
  $featured_images = $bundle_data['files'];
1522
 
@@ -1529,12 +1809,8 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1529
  $targetDir = $images_uploads['path'];
1530
  $targetUrl = $images_uploads['url'];
1531
 
1532
- $logger and call_user_func($logger, __('<b>IMAGES:</b>', 'wp_all_import_plugin'));
1533
-
1534
  if ( ! @is_writable($targetDir) ){
1535
-
1536
  $logger and call_user_func($logger, sprintf(__('<b>ERROR</b>: Target directory %s is not writable', 'wp_all_import_plugin'), $targetDir));
1537
-
1538
  }
1539
  else{
1540
 
@@ -1654,7 +1930,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1654
  // generate local file name
1655
  $image_name = urldecode(($this->options[$option_slug . 'auto_rename_images'] and !empty($auto_rename_images_bundle[$slug][$i])) ? sanitize_file_name(($img_ext) ? str_replace("." . $default_extension, "", $auto_rename_images_bundle[$slug][$i]) : $auto_rename_images_bundle[$slug][$i]) : (($img_ext) ? str_replace("." . $default_extension, "", $bn) : $bn)) . (("" != $img_ext) ? '.' . $img_ext : '');
1656
  $image_name = apply_filters("wp_all_import_image_filename", $image_name, empty($img_titles[$k]) ? '' : $img_titles[$k], empty($img_captions[$k]) ? '' : $img_captions[$k], empty($img_alts[$k]) ? '' : $img_alts[$k], $articleData, $this->id, $img_url);
1657
-
1658
  // if wizard store image data to custom field
1659
  $create_image = false;
1660
  $download_image = true;
@@ -1669,18 +1945,16 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1669
  $image_filename = $image_name;
1670
 
1671
  // search existing attachment
1672
- if ($this->options[$option_slug . 'search_existing_images'] or "gallery" == $this->options[$option_slug . 'download_images']){
1673
 
1674
- $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $bundle_data['type']);
1675
 
1676
  if ("gallery" == $this->options[$option_slug . 'download_images']) $download_image = false;
1677
 
1678
- if (empty($attch))
1679
- {
1680
  $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Image %s not found in media gallery.', 'wp_all_import_plugin'), trim($image_name)));
1681
  }
1682
- else
1683
- {
1684
  $logger and call_user_func($logger, sprintf(__('- Using existing image `%s` for post `%s` ...', 'wp_all_import_plugin'), trim($image_name), $articleData['post_title']));
1685
  $download_image = false;
1686
  $create_image = false;
@@ -1709,10 +1983,8 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1709
 
1710
  if ( ! $create_image ) {
1711
 
1712
- if ($this->options[$option_slug . 'auto_rename_images'] and !empty($auto_rename_images_bundle[$slug][$i]))
1713
- {
1714
- if ($k)
1715
- {
1716
  $image_name = str_replace('.' . pmxi_getExtension($image_name), '', $image_name) . '-' . $k . '.' . pmxi_getExtension($image_name);
1717
  }
1718
  }
@@ -1741,7 +2013,6 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1741
  }
1742
  }
1743
  }
1744
-
1745
  }
1746
 
1747
  // search existing attachment
@@ -1749,21 +2020,74 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1749
 
1750
  $image_filename = $image_name;
1751
 
1752
- $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $bundle_data['type']);
 
 
 
 
 
 
 
 
 
 
 
 
 
1753
 
1754
- if ("gallery" == $this->options[$option_slug . 'download_images']) $download_image = false;
1755
 
1756
- if (empty($attch))
1757
- {
1758
- $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Image %s not found in media gallery.', 'wp_all_import_plugin'), trim($image_name)));
1759
- }
1760
- else
1761
- {
1762
- $logger and call_user_func($logger, sprintf(__('- Using existing image `%s` for post `%s` ...', 'wp_all_import_plugin'), trim($image_name), $articleData['post_title']));
1763
- $download_image = false;
1764
- $create_image = false;
1765
- $attid = $attch->ID;
1766
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1767
  }
1768
 
1769
  if ($download_image && "gallery" != $this->options[$option_slug . 'download_images']){
@@ -1777,11 +2101,11 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1777
  $wpai_uploads = $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR;
1778
  $wpai_image_path = $wpai_uploads . str_replace('%20', ' ', $url);
1779
 
1780
- $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s`', 'wp_all_import_plugin'), $wpai_image_path));
1781
 
1782
  if ( @file_exists($wpai_image_path) and @copy( $wpai_image_path, $image_filepath )){
1783
  $download_image = false;
1784
- // valdate import attachments
1785
  if ($bundle_data['type'] == 'files'){
1786
  if( ! $wp_filetype = wp_check_filetype(wp_all_import_basename($image_filepath), null )) {
1787
  $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Can\'t detect attachment file type %s', 'wp_all_import_plugin'), trim($image_filepath)));
@@ -1795,7 +2119,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1795
  }
1796
  // validate import images
1797
  elseif($bundle_data['type'] == 'images'){
1798
- if( preg_match('%\W(svg)$%i', wp_all_import_basename($image_filepath)) or $image_info = apply_filters('pmxi_getimagesize', @getimagesize($image_filepath), $image_filepath) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)) ) {
1799
  $create_image = true;
1800
  $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully found', 'wp_all_import_plugin'), $wpai_image_path));
1801
  }
@@ -1808,101 +2132,36 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1808
  }
1809
  }
1810
  }
1811
- else {
1812
-
1813
- $logger and call_user_func($logger, sprintf(__('- Downloading image from `%s`', 'wp_all_import_plugin'), $url));
1814
-
1815
- $request = get_file_curl($url, $image_filepath);
1816
-
1817
- $get_ctx = stream_context_create(array('http' => array('timeout' => 5)));
1818
-
1819
- if ( (is_wp_error($request) or $request === false) and ! @file_put_contents($image_filepath, @file_get_contents($url, false, $get_ctx))) {
1820
- @unlink($image_filepath); // delete file since failed upload may result in empty file created
1821
- } else{
1822
-
1823
- if($bundle_data['type'] == 'images'){
1824
- if( preg_match('%\W(svg)$%i', wp_all_import_basename($image_filepath)) or $image_info = apply_filters('pmxi_getimagesize', @getimagesize($image_filepath), $image_filepath) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP))) {
1825
- $create_image = true;
1826
- $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url));
1827
- }
1828
- else
1829
- {
1830
- $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'wp_all_import_plugin'), $url));
1831
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1832
- }
1833
- }
1834
- elseif($bundle_data['type'] == 'files'){
1835
- if( $wp_filetype = wp_check_filetype(wp_all_import_basename($image_filepath), null )) {
1836
- $create_image = true;
1837
- $logger and call_user_func($logger, sprintf(__('- File `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url));
1838
- }
1839
- }
1840
-
1841
- }
1842
-
1843
- if ( ! $create_image )
1844
- {
1845
- if ( $img_url !== pmxi_convert_encoding($img_url) )
1846
- {
1847
- $url = trim(pmxi_convert_encoding($img_url));
1848
-
1849
- $request = get_file_curl($url, $image_filepath);
1850
-
1851
- $get_ctx = stream_context_create(array('http' => array('timeout' => 5)));
1852
-
1853
- if ( (is_wp_error($request) or $request === false) and ! @file_put_contents($image_filepath, @file_get_contents($url, false, $get_ctx))) {
1854
- $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s cannot be saved locally as %s', 'wp_all_import_plugin'), $url, $image_filepath));
1855
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1856
- @unlink($image_filepath); // delete file since failed upload may result in empty file created
1857
- }
1858
- else{
1859
- if($bundle_data['type'] == 'images'){
1860
- if( preg_match('%\W(svg)$%i', wp_all_import_basename($image_filepath)) or $image_info = apply_filters('pmxi_getimagesize', @getimagesize($image_filepath), $image_filepath) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP))) {
1861
- $create_image = true;
1862
- $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url));
1863
- } else {
1864
- $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'wp_all_import_plugin'), $url));
1865
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1866
- @unlink($image_filepath);
1867
- }
1868
- }
1869
- elseif($bundle_data['type'] == 'files'){
1870
- if( ! $wp_filetype = wp_check_filetype(wp_all_import_basename($image_filepath), null )) {
1871
- $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Can\'t detect attachment file type %s', 'wp_all_import_plugin'), trim($url)));
1872
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1873
- @unlink($image_filepath);
1874
- }
1875
- else {
1876
- $create_image = true;
1877
- $logger and call_user_func($logger, sprintf(__('- File `%s` has been successfully found', 'wp_all_import_plugin'), $url));
1878
- }
1879
- }
1880
- }
1881
- }
1882
- else{
1883
- @unlink($image_filepath);
1884
- }
1885
- }
1886
  }
1887
  }
1888
  }
1889
 
1890
  $handle_image = false;
1891
 
 
1892
  if ($create_image){
1893
 
1894
  $file_mime_type = '';
1895
 
1896
- if ($bundle_data['type'] == 'images')
1897
- {
1898
- if ( ! empty($image_info) )
1899
- {
1900
  $file_mime_type = image_type_to_mime_type($image_info[2]);
1901
  }
1902
  $file_mime_type = apply_filters('wp_all_import_image_mime_type', $file_mime_type, $image_filepath);
1903
  }
1904
- else
1905
- {
1906
  $file_mime_type = $wp_filetype['type'];
1907
  }
1908
 
@@ -1912,43 +2171,47 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1912
  'type' => $file_mime_type
1913
  ));
1914
 
1915
- $logger and call_user_func($logger, sprintf(__('- Creating an attachment for image `%s`', 'wp_all_import_plugin'), $handle_image['url']));
1916
-
1917
- $attachment_title = explode(".", $image_name);
1918
- if (is_array($attachment_title) and count($attachment_title) > 1) array_pop($attachment_title);
1919
-
1920
- $attachment = array(
1921
- 'post_mime_type' => $handle_image['type'],
1922
- 'guid' => $handle_image['url'],
1923
- 'post_title' => implode(".", $attachment_title),
1924
- 'post_content' => '',
1925
- 'post_author' => $post_author[$i],
1926
- );
1927
- if ($bundle_data['type'] == 'images' and ($image_meta = wp_read_image_metadata($handle_image['file']))) {
1928
- if (trim($image_meta['title']) && ! is_numeric(sanitize_title($image_meta['title'])))
1929
- $attachment['post_title'] = $image_meta['title'];
1930
- if (trim($image_meta['caption']))
1931
- $attachment['post_content'] = $image_meta['caption'];
1932
- }
1933
-
1934
- if ( in_array($post_type[$i], array('taxonomies')) ){
1935
- $attid = wp_insert_attachment($attachment, $handle_image['file'], 0);
1936
- }
1937
- else{
1938
- $attid = wp_insert_attachment($attachment, $handle_image['file'], $pid);
 
 
 
 
 
 
 
 
 
 
 
 
1939
  }
1940
-
1941
- if (is_wp_error($attid)) {
1942
- $logger and call_user_func($logger, __('- <b>WARNING</b>', 'wp_all_import_plugin') . ': ' . $attid->get_error_message());
1943
- $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1944
- } else {
1945
- wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $handle_image['file']));
1946
- }
1947
-
1948
  }
1949
 
1950
  if ($attid && ! is_wp_error($attid))
1951
- {
1952
  if ($attch != null && empty($attch->post_parent) && ! in_array($post_type[$i], array('taxonomies'))){
1953
  wp_update_post(
1954
  array(
@@ -1974,7 +2237,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1974
  switch ($post_type[$i]){
1975
  case 'taxonomies':
1976
  $post_thumbnail_id = get_term_meta( $pid, 'thumbnail_id', true );
1977
- if ($bundle_data['type'] == 'images' and empty($post_thumbnail_id) and $this->options[$option_slug . 'is_featured'] ) {
1978
  update_term_meta($pid, 'thumbnail_id', $attid);
1979
  }
1980
  elseif(!in_array($attid, $gallery_attachment_ids) and $post_thumbnail_id != $attid){
@@ -1984,7 +2247,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1984
  default:
1985
  $post_thumbnail_id = get_post_thumbnail_id( $pid );
1986
 
1987
- if ($bundle_data['type'] == 'images' and empty($post_thumbnail_id) and $this->options[$option_slug . 'is_featured'] ) {
1988
  set_post_thumbnail($pid, $attid);
1989
  }
1990
  elseif(!in_array($attid, $gallery_attachment_ids) and $post_thumbnail_id != $attid){
@@ -1993,13 +2256,11 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1993
  break;
1994
  }
1995
 
1996
- if ($attch != null and empty($attch->post_parent))
1997
- {
1998
- $logger and call_user_func($logger, sprintf(__('- Attachment with ID: `%s` has been successfully updated for image `%s`', 'wp_all_import_plugin'), $attid, ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename));
1999
  }
2000
- elseif(empty($attch))
2001
- {
2002
- $logger and call_user_func($logger, sprintf(__('- Attachment with ID: `%s` has been successfully created for image `%s`', 'wp_all_import_plugin'), $attid, ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename));
2003
  }
2004
  }
2005
  }
@@ -2054,7 +2315,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2054
 
2055
  foreach ($imgs as $img) {
2056
  do_action( $slug, $pid, false, $img, false);
2057
- }
2058
  }
2059
  }
2060
  }
@@ -2069,7 +2330,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2069
  // [attachments]
2070
  $is_attachments_to_update = apply_filters('pmxi_is_attachments_to_update', true, $articleData, $current_xml_node);
2071
 
2072
- $attachments_uploads = apply_filters('wp_all_import_attachments_uploads_dir', $uploads, $articleData, $current_xml_node, $this->id);
2073
 
2074
  if ( $is_attachments_to_update and ! empty($attachments_uploads) and false === $attachments_uploads['error'] and !empty($attachments[$i]) and (empty($articleData['ID']) or $this->options['update_all_data'] == "yes" or ($this->options['update_all_data'] == "no" and $this->options['is_update_attachments']))) {
2075
 
@@ -2106,9 +2367,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2106
  $attachment_filepath = $targetDir . '/' . sanitize_file_name($attachment_filename);
2107
 
2108
  if ($this->options['is_search_existing_attach']){
2109
- // search existing attachment
2110
- $attch = wp_all_import_get_image_from_gallery($attachment_filename, $targetDir, 'files');
2111
-
 
2112
  if ( $attch != null ){
2113
  $download_file = false;
2114
  $attach_id = $attch->ID;
@@ -2185,9 +2447,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2185
  {
2186
  $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully created for file `%s`', 'wp_all_import_plugin'), ($handle_attachment) ? $handle_attachment['url'] : $targetUrl . '/' . $attachment_filename));
2187
  }
2188
- $logger and call_user_func($logger, __('- <b>ACTION</b>: pmxi_attachment_uploaded', 'wp_all_import_plugin'));
2189
- do_action( 'pmxi_attachment_uploaded', $pid, $attach_id, $attachment_filepath);
2190
- }
2191
  }
2192
  }
2193
  }
@@ -2199,7 +2461,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2199
  $logger and call_user_func($logger, sprintf(__('Attachments import skipped for post `%s` according to \'pmxi_is_attachments_to_update\' filter...', 'wp_all_import_plugin'), $articleData['post_title']));
2200
  }
2201
  // [/attachments]
2202
-
2203
  // [custom taxonomies]
2204
  if ( ! empty($taxonomies) ){
2205
 
@@ -2241,8 +2503,6 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2241
  unset($existing_taxonomies[$tx_name][$i]);
2242
  }
2243
 
2244
- $assign_taxes = apply_filters('wp_all_import_set_post_terms', $assign_taxes, $tx_name, $pid, $this->id);
2245
-
2246
  // create term if not exists
2247
  if ( ! empty($txes[$i]) ):
2248
  foreach ($txes[$i] as $key => $single_tax) {
@@ -2317,10 +2577,12 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2317
  }
2318
  }
2319
  }
2320
- endif;
 
 
2321
 
2322
  // associate taxes with post
2323
- $this->associate_terms($pid, ( empty($assign_taxes) ? false : $assign_taxes ), $tx_name, $logger, $is_cron, $articleData['post_status']);
2324
 
2325
  }
2326
  else
@@ -2336,7 +2598,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2336
  if ( PMXI_Admin_Addons::get_addon('PMWI_Plugin') and strpos($tx_name, "pa_") === 0 ) continue;
2337
 
2338
  if (!empty($txes[$i]))
2339
- $this->associate_terms($pid, $txes[$i], $tx_name, $logger, $is_cron, $articleData['post_status']);
2340
  }
2341
  }
2342
  }
@@ -2356,7 +2618,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2356
  $_post = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID = %d LIMIT 1", $pid ) );
2357
  $_post = sanitize_post( $_post, 'raw' );
2358
  $post_object = new WP_Post( $_post );
2359
- do_action( "save_post_" . $articleData['post_type'], $pid, $post_object, $is_update );
2360
  do_action( 'save_post', $pid, $post_object, $is_update );
2361
  do_action( 'wp_insert_post', $pid, $post_object, $is_update );
2362
  }
@@ -2405,10 +2667,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2405
  $logger and call_user_func($logger, __('<b>ACTION</b>: pmxi_after_post_import', 'wp_all_import_plugin'));
2406
  do_action('pmxi_after_post_import', $this->id);
2407
 
2408
- $logger and !$is_cron and PMXI_Plugin::$session->chunk_number++;
2409
- }
2410
 
2411
- wp_cache_flush();
 
2412
 
2413
  $this->set(array(
2414
  'imported' => $created + $updated,
@@ -2429,7 +2691,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2429
  $is_import_complete = ($records_count == $records_to_import);
2430
 
2431
  // Set out of stock status for missing records [Woocommerce add-on option]
2432
- if ( $is_import_complete and empty($this->options['is_delete_missing']) and $post_type[$i] == "product" and class_exists('PMWI_Plugin') and !empty($this->options['missing_records_stock_status'])) {
2433
 
2434
  $logger and call_user_func($logger, __('Update stock status previously imported posts which are no longer actual...', 'wp_all_import_plugin'));
2435
  $args = array('import_id' => $this->id, 'iteration !=' => $this->iteration);
@@ -2440,6 +2702,14 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2440
  foreach ($missingPosts as $missingPost) {
2441
  update_post_meta( $missingPost['post_id'], '_stock_status', 'outofstock' );
2442
  update_post_meta( $missingPost['post_id'], '_stock', 0 );
 
 
 
 
 
 
 
 
2443
  $missingPostRecord = new PMXI_Post_Record();
2444
  $missingPostRecord->getBy('id', $missingPost['id']);
2445
  if ( ! $missingPostRecord->isEmpty())
@@ -2465,18 +2735,100 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2465
  return $this;
2466
  }
2467
 
2468
- private function getRecordTitle($articleData){
2469
- $title = $articleData['post_title'];
2470
  switch ($this->options['custom_type']){
2471
  case 'import_users':
2472
  $title = $articleData['user_login'];
2473
  break;
2474
  default:
 
2475
  break;
2476
  }
2477
  return $title;
2478
  }
2479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2480
  public function delete_source($logger = false)
2481
  {
2482
  if ($this->options['is_delete_source'])
@@ -2634,10 +2986,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2634
  switch ($this->options['custom_type']){
2635
  case 'import_users':
2636
  do_action('pmxi_delete_post', $ids, $this);
 
 
 
 
2637
  $sql = "delete a,b
2638
  FROM ".$this->wpdb->users." a
2639
  LEFT JOIN ".$this->wpdb->usermeta." b ON ( a.ID = b.user_id )
2640
  WHERE a.ID IN (" . implode(',', $ids) . ");";
 
 
 
 
 
2641
  break;
2642
  case 'taxonomies':
2643
  do_action('pmxi_delete_taxonomy_term', $ids, $this);
@@ -2721,7 +3082,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2721
  {
2722
  $caps['unfiltered_html'] = true;
2723
  return $caps;
2724
- }
2725
 
2726
  protected function recount_terms($pid, $post_type){
2727
 
@@ -2739,51 +3100,42 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2739
  }
2740
  }
2741
  }
2742
-
2743
- protected function associate_terms($pid, $assign_taxes, $tx_name, $logger, $is_cron = false, $post_status = 'publish'){
2744
- wp_cache_flush();
2745
- $terms = wp_get_object_terms( $pid, $tx_name );
2746
- $term_ids = array();
2747
-
2748
- $assign_taxes = (is_array($assign_taxes)) ? array_filter($assign_taxes) : false;
2749
-
2750
- if ( ! empty($terms) ){
2751
- if ( ! is_wp_error( $terms ) ) {
2752
- foreach ($terms as $term_info) {
2753
- $term_ids[] = $term_info->term_taxonomy_id;
2754
- $this->wpdb->query( $this->wpdb->prepare("UPDATE {$this->wpdb->term_taxonomy} SET count = count - 1 WHERE term_taxonomy_id = %d AND count > 0", $term_info->term_taxonomy_id) );
2755
- }
2756
- $in_tt_ids = "'" . implode( "', '", $term_ids ) . "'";
2757
- $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $pid ) );
2758
- }
2759
  }
2760
 
2761
- if (empty($assign_taxes)) return;
2762
 
2763
- // foreach ($assign_taxes as $tt) {
2764
- // $this->wpdb->insert( $this->wpdb->term_relationships, array( 'object_id' => $pid, 'term_taxonomy_id' => $tt ) );
2765
- // $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" );
2766
- // }
2767
 
2768
- $values = array();
2769
- $term_order = 0;
2770
- foreach ( $assign_taxes as $tt )
2771
- {
2772
- do_action('wp_all_import_associate_term', $pid, $tt, $tx_name);
2773
- $values[] = $this->wpdb->prepare( "(%d, %d, %d)", $pid, $tt, ++$term_order);
2774
- if ( ! in_array($post_status, array('draft'))){
2775
- $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" );
2776
- }
2777
- }
2778
-
2779
 
2780
- if ( $values ){
2781
- if ( false === $this->wpdb->query( "INSERT INTO {$this->wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)" ) ){
2782
- $logger and call_user_func($logger, __('<b>ERROR</b> Could not insert term relationship into the database', 'wp_all_import_plugin') . ': '. $this->wpdb->last_error);
2783
- }
2784
- }
 
 
 
 
 
2785
 
2786
- wp_cache_delete( $pid, $tx_name . '_relationships' );
2787
  }
2788
 
2789
  /**
@@ -2799,12 +3151,17 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2799
  if ( ! $keepPosts) {
2800
 
2801
  $missing_ids = array();
2802
- $missingPosts = $postList->getBy(array('import_id' => $this->id));
2803
- if ( ! $missingPosts->isEmpty() ):
 
 
 
 
 
2804
 
2805
  foreach ($missingPosts as $missingPost) {
2806
 
2807
- $missing_ids[] = $missingPost['post_id'];
2808
 
2809
  }
2810
 
@@ -2868,44 +3225,63 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2868
  protected function deleteRecords( $is_delete_attachments, $is_deleted_images, $ids = array() )
2869
  {
2870
  foreach ( $ids as $k => $id ) {
2871
- // Remove attachments
2872
- if ($is_delete_attachments == 'yes' or $is_delete_attachments == 'auto' and empty($this->options['is_keep_attachments']))
2873
- {
2874
- wp_delete_attachments($id, true, 'files');
2875
- }
2876
- else
2877
- {
2878
- wp_delete_attachments($id, false, 'files');
2879
- }
2880
- // Remove images
2881
- if ($is_deleted_images == 'yes' or $is_deleted_images == 'auto' and empty($this->options['is_keep_imgs']))
2882
- {
2883
- wp_delete_attachments($id, true, 'images');
2884
- }
2885
- else
2886
- {
2887
- wp_delete_attachments($id, false, 'images');
2888
- }
2889
-
2890
- do_action('pmxi_delete_post', $id, $this);
 
2891
 
2892
- if ( $this->options['custom_type'] != 'import_users' ) wp_delete_object_term_relationships($id, get_object_taxonomies('' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post'));
2893
  }
2894
 
2895
- if ( $this->options['custom_type'] == 'import_users' ){
2896
- $sql = "delete a,b
2897
- FROM ".$this->wpdb->users." a
2898
- LEFT JOIN ".$this->wpdb->usermeta." b ON ( a.ID = b.user_id )
2899
- WHERE a.ID IN (".implode(',', $ids).");";
2900
- }
2901
- else {
2902
- $sql = "delete a,b,c
2903
- FROM ".$this->wpdb->posts." a
2904
- LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
2905
- LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
2906
- LEFT JOIN ".$this->wpdb->posts." d ON ( a.ID = d.post_parent )
2907
- WHERE a.ID IN (".implode(',', $ids).");";
2908
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2909
 
2910
  $this->wpdb->query(
2911
  $sql
@@ -2967,5 +3343,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
2967
  }
2968
  return ($is_delete_import) ? parent::delete() : true;
2969
  }
 
 
 
 
 
2970
 
2971
  }
19
  $is_preprocess_enabled = apply_filters('is_xml_preprocess_enabled', true);
20
 
21
  if ($is_preprocess_enabled)
22
+ {
23
+ $xml = preg_replace_callback('/<!\[CDATA\[.*?\]\]>/s', 'wp_all_import_cdata_filter', $xml );
24
+
25
+ $xml = preg_replace('/&([^amp;|^gt;|^lt;]+)/i', '&amp;$1', $xml);
26
+
27
+ if ( ! empty(self::$cdata) ){
28
+ foreach (self::$cdata as $key => $val) {
29
+ $xml = str_replace('{{CPLACE_' . ($key + 1) . '}}', $val, $xml);
30
+ }
31
  }
32
  }
33
  }
111
  * @chainable
112
  */
113
  public function process($xml, $logger = NULL, $chunk = false, $is_cron = false, $xpath_prefix = '', $loop = 0) {
114
+
115
  add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
 
 
116
 
117
+ $cxpath = $xpath_prefix . $this->xpath;
118
 
119
  $this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
120
 
134
 
135
  try {
136
 
137
+ //$errorHandler = new PMXI_Error();
138
+
139
+ //set_error_handler( array($errorHandler, 'parse_data_handler'), E_ALL | E_STRICT | E_WARNING );
140
+
141
  $chunk == 1 and $logger and printf("<div class='progress-msg'>%s</div>\n", date("r")) and flush();
142
+
143
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing titles...', 'wp_all_import_plugin'));
144
  if ( ! empty($this->options['title'])){
145
  $titles = XmlImportParser::factory($xml, $cxpath, $this->options['title'], $file)->parse($records); $tmp_files[] = $file;
146
  }
148
  $loop and $titles = array_fill(0, $loop, '');
149
  }
150
 
151
+ if ( in_array($this->options['custom_type'], array('taxonomies')) ){
152
+ // Composing parent terms
153
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing parent terms...', 'wp_all_import_plugin'));
154
+ $taxonomy_parent = array();
155
+ if ( ! empty($this->options['taxonomy_parent']) && $this->is_parsing_required('is_update_parent') ){
156
+ $taxonomy_parent = XmlImportParser::factory($xml, $cxpath, $this->options['taxonomy_parent'], $file)->parse($records); $tmp_files[] = $file;
157
+ }
158
+ else{
159
+ count($titles) and $taxonomy_parent = array_fill(0, count($titles), 0);
160
+ }
161
+ // Composing terms slug
162
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing terms slug...', 'wp_all_import_plugin'));
163
+ $taxonomy_slug = array();
164
+ if ( 'xpath' == $this->options['taxonomy_slug'] && ! empty($this->options['taxonomy_slug_xpath']) && $this->is_parsing_required('is_update_slug')){
165
+ $taxonomy_slug = XmlImportParser::factory($xml, $cxpath, $this->options['taxonomy_slug_xpath'], $file)->parse($records); $tmp_files[] = $file;
166
+ }
167
+ else{
168
+ count($titles) and $taxonomy_slug = array_fill(0, count($titles), '');
169
+ }
170
+ }
171
+
172
+ if ( ! in_array($this->options['custom_type'], array('taxonomies')) ){
173
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing excerpts...', 'wp_all_import_plugin'));
174
+ $post_excerpt = array();
175
  if ( ! empty($this->options['post_excerpt']) && $this->is_parsing_required('is_update_excerpt')){
176
+ $post_excerpt = XmlImportParser::factory($xml, $cxpath, $this->options['post_excerpt'], $file)->parse($records); $tmp_files[] = $file;
177
+ }
178
+ else{
179
+ count($titles) and $post_excerpt = array_fill(0, count($titles), '');
180
+ }
181
+ }
182
 
183
+ if ( "xpath" == $this->options['status'] ){
184
  $chunk == 1 and $logger and call_user_func($logger, __('Composing statuses...', 'wp_all_import_plugin'));
185
  $post_status = array();
186
  if ( ! empty($this->options['status_xpath']) && $this->is_parsing_required('is_update_status') ){
224
  }
225
  }
226
 
227
+ $duplicate_indicator_values = array();
228
+ if ( in_array($this->options['duplicate_indicator'], array("pid", "title", "slug")) ){
229
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing duplicate indicators...', 'wp_all_import_plugin'));
230
+ if (!empty($this->options[$this->options['duplicate_indicator'] . '_xpath'])){
231
+ $duplicate_indicator_values = XmlImportParser::factory($xml, $cxpath, $this->options[$this->options['duplicate_indicator'] . '_xpath'], $file)->parse($records); $tmp_files[] = $file;
232
  }
233
  else{
234
+ count($titles) and $duplicate_indicator_values = array_fill(0, count($titles), '');
235
  }
236
  }
237
+ else{
238
+ count($titles) and $duplicate_indicator_values = array_fill(0, count($titles), '');
239
+ }
240
 
241
  if ( "no" == $this->options['is_multiple_page_template'] ){
242
  $chunk == 1 and $logger and call_user_func($logger, __('Composing page templates...', 'wp_all_import_plugin'));
249
  }
250
  }
251
 
252
+ if ( $this->options['is_override_post_type'] and ! empty($this->options['post_type_xpath']) ){
253
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing post types...', 'wp_all_import_plugin'));
254
+ $post_type = array();
255
+ $post_type = XmlImportParser::factory($xml, $cxpath, $this->options['post_type_xpath'], $file)->parse($records); $tmp_files[] = $file;
256
+ }
257
+ else{
258
+ if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
259
+ $pType = $this->options['custom_type'];
260
+ } else {
261
+ $pType = $this->options['type'];
262
+ }
263
+ count($titles) and $post_type = array_fill(0, count($titles), $pType);
264
+ }
265
 
266
  if ( "no" == $this->options['is_multiple_page_parent'] ){
267
  $chunk == 1 and $logger and call_user_func($logger, __('Composing page parent...', 'wp_all_import_plugin'));
275
  }
276
 
277
  if ( $this->is_parsing_required('is_update_author') ){
278
+ $chunk == 1 and $logger and call_user_func($logger, __('Composing authors...', 'wp_all_import_plugin'));
279
+ $post_author = array();
280
+ $current_user = wp_get_current_user();
281
+
282
+ if (!empty($this->options['author'])){
283
+ $post_author = XmlImportParser::factory($xml, $cxpath, $this->options['author'], $file)->parse($records); $tmp_files[] = $file;
284
+ foreach ($post_author as $key => $author) {
285
+ $user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
286
+ if (!empty($user))
287
+ {
288
+ $post_author[$key] = $user->ID;
289
+ }
290
+ else{
291
+ if ($current_user->ID){
292
+ $post_author[$key] = $current_user->ID;
293
+ }
294
+ else{
295
+ $super_admins = get_super_admins();
296
+ if ( ! empty($super_admins)){
297
+ $sauthor = array_shift($super_admins);
298
+ $user = get_user_by('login', $sauthor) or $user = get_user_by('slug', $sauthor) or $user = get_user_by('email', $sauthor) or ctype_digit($sauthor) and $user = get_user_by('id', $sauthor);
299
+ $post_author[$key] = (!empty($user)) ? $user->ID : $current_user->ID;
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ else{
306
+ if ($current_user->ID){
307
+ count($titles) and $post_author = array_fill(0, count($titles), $current_user->ID);
308
+ }
309
+ else{
310
+ $super_admins = get_super_admins();
311
+ if ( ! empty($super_admins)){
312
+ $author = array_shift($super_admins);
313
+ $user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
314
+ count($titles) and $post_author = array_fill(0, count($titles), (!empty($user)) ? $user->ID : $current_user->ID);
315
+ }
316
+ }
317
+ }
318
  }
319
  else{
320
  $current_user = wp_get_current_user();
330
  count($titles) and $post_slug = array_fill(0, count($titles), '');
331
  }
332
 
333
+ $is_image_featured = array();
334
+ if (!empty($this->options['is_featured_xpath'])){
335
+ $is_image_featured = XmlImportParser::factory($xml, $cxpath, $this->options['is_featured_xpath'], $file)->parse($records); $tmp_files[] = $file;
336
+ }
337
+ else{
338
+ count($titles) and $is_image_featured = array_fill(0, count($titles), '');
339
+ }
340
+
341
  $chunk == 1 and $logger and call_user_func($logger, __('Composing menu order...', 'wp_all_import_plugin'));
342
  $menu_order = array();
343
  if (!empty($this->options['order']) && $this->is_parsing_required('is_update_menu_order')){
362
 
363
  $chunk == 1 and $logger and call_user_func($logger, __('Composing dates...', 'wp_all_import_plugin'));
364
  if ( $this->is_parsing_required('is_update_dates') ){
365
+ if ('specific' == $this->options['date_type']) {
366
+ $dates = XmlImportParser::factory($xml, $cxpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
367
+ $warned = array(); // used to prevent the same notice displaying several times
368
+ foreach ($dates as $i => $d) {
369
+ if ($d == 'now') $d = current_time('mysql'); // Replace 'now' with the WordPress local time to account for timezone offsets (WordPress references its local time during publishing rather than the server’s time so it should use that)
370
+ $time = strtotime($d);
371
+ if (FALSE === $time) {
372
+ in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $d));
373
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
374
+ $time = time();
375
+ }
376
+ $dates[$i] = date('Y-m-d H:i:s', $time);
377
+ }
378
+ } else {
379
+ $dates_start = XmlImportParser::factory($xml, $cxpath, $this->options['date_start'], $file)->parse($records); $tmp_files[] = $file;
380
+ $dates_end = XmlImportParser::factory($xml, $cxpath, $this->options['date_end'], $file)->parse($records); $tmp_files[] = $file;
381
+ $warned = array(); // used to prevent the same notice displaying several times
382
+ foreach ($dates_start as $i => $d) {
383
+ $time_start = strtotime($dates_start[$i]);
384
+ if (FALSE === $time_start) {
385
+ in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $dates_start[$i]));
386
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
387
+ $time_start = time();
388
+ }
389
+ $time_end = strtotime($dates_end[$i]);
390
+ if (FALSE === $time_end) {
391
+ in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'wp_all_import_plugin'), $warned[] = $dates_end[$i]));
392
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
393
+ $time_end = time();
394
+ }
395
+ $dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
396
+ }
397
+ }
398
  }
399
  else{
400
  count($titles) and $dates = array_fill(0, count($titles), date('Y-m-d H:i:s', strtotime(current_time('mysql'))));
619
  }
620
  endforeach;
621
  endif;
622
+ // [/custom taxonomies]
623
 
624
+ // Composing featured images
625
  $image_sections = apply_filters('wp_all_import_image_sections', array(
626
  array(
627
  'slug' => '',
722
  $image_meta_descriptions_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $image_meta_descriptions;
723
  }
724
 
 
 
 
 
 
 
 
 
 
 
 
725
 
726
+ // Composing images suffix
727
+ $chunk == 1 and $this->options[$section['slug'] . 'auto_rename_images'] and $logger and call_user_func($logger, __('Composing ' . strtolower($section['title']) . ' suffix...', 'wp_all_import_plugin'));
728
+ $auto_rename_images = array();
729
+ if ( $this->options[$section['slug'] . 'auto_rename_images'] and ! empty($this->options[$section['slug'] . 'auto_rename_images_suffix'])){
730
+ $auto_rename_images = XmlImportParser::factory($xml, $cxpath, $this->options[$section['slug'] . 'auto_rename_images_suffix'], $file)->parse($records); $tmp_files[] = $file;
 
 
 
 
 
731
  }
732
+ else{
733
+ count($titles) and $auto_rename_images = array_fill(0, count($titles), '');
734
+ }
735
+ $auto_rename_images_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $auto_rename_images;
736
+
737
+ // Composing images extensions
738
+ $chunk == 1 and $this->options[$section['slug'] . 'auto_set_extension'] and $logger and call_user_func($logger, __('Composing ' . strtolower($section['title']) . ' extensions...', 'wp_all_import_plugin'));
739
+ $auto_extensions = array();
740
+ if ( $this->options[$section['slug'] . 'auto_set_extension'] and ! empty($this->options[$section['slug'] . 'new_extension'])){
741
+ $auto_extensions = XmlImportParser::factory($xml, $cxpath, $this->options[$section['slug'] . 'new_extension'], $file)->parse($records); $tmp_files[] = $file;
742
+ }
743
+ else{
744
+ count($titles) and $auto_extensions = array_fill(0, count($titles), '');
745
+ }
746
+ $auto_extensions_bundle[ empty($section['slug']) ? 'pmxi_gallery_image' : $section['slug']] = $auto_extensions;
747
 
748
  }
749
  }
760
 
761
  if ($this->options['attachments'] && $this->is_parsing_required('is_update_attachments') ) {
762
  // Detect if attachments is separated by comma
763
+ $atchs = empty($this->options['atch_delim']) ? explode(',', $this->options['attachments']) : explode($this->options['atch_delim'], $this->options['attachments']);
764
  if (!empty($atchs)){
765
  $parse_multiple = true;
766
  foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
791
  else{
792
  count($titles) and $unique_keys = array_fill(0, count($titles), '');
793
  }
794
+
795
  $chunk == 1 and $logger and call_user_func($logger, __('Processing posts...', 'wp_all_import_plugin'));
796
 
797
  $addons = array();
842
 
843
  if ($this->options['is_import_specified']) {
844
  $chunk == 1 and $logger and call_user_func($logger, __('Calculate specified records to import...', 'wp_all_import_plugin'));
845
+ $import_specified_option = apply_filters('wp_all_import_specified_records', $this->options['import_specified'], $this->id, $rootNodes);
846
  foreach (preg_split('% *, *%', $import_specified_option, -1, PREG_SPLIT_NO_EMPTY) as $chank) {
847
  if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
848
  $specified_records = array_merge($specified_records, range(intval($mtch[1]), intval($mtch[2])));
851
  }
852
  }
853
 
854
+ }
855
 
856
+ //restore_error_handler();
857
 
858
+ foreach ($titles as $i => $void) {
859
+
860
+ //$errorHandler = new PMXI_Error($this->imported + $this->skipped + $i + 1);
861
+
862
+ //set_error_handler( array($errorHandler, 'import_data_handler'), E_ALL | E_STRICT | E_WARNING );
863
+
864
+ switch ($this->options['custom_type']) {
865
+ case 'taxonomies':
866
+ $custom_type_details = new stdClass();
867
+ $custom_type_details->labels = new stdClass();
868
+ $custom_type_details->labels->singular_name = __('Taxonomy Term', 'wp_all_import_plugin');
869
+ break;
870
+ default:
871
+ $custom_type_details = get_post_type_object($post_type[$i]);
872
+ break;
873
+ }
874
 
875
  if ($is_cron and $cron_sleep) sleep($cron_sleep);
876
 
877
  $logger and call_user_func($logger, __('---', 'wp_all_import_plugin'));
878
  $logger and call_user_func($logger, sprintf(__('Record #%s', 'wp_all_import_plugin'), $this->imported + $this->skipped + $i + 1));
879
+
880
  if ( "manual" == $this->options['duplicate_matching']
881
  and ! empty($specified_records)
882
  and ! in_array($created + $updated + $skipped + 1, $specified_records) )
885
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'wp_all_import_plugin'));
886
  $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
887
  $logger and !$is_cron and PMXI_Plugin::$session->chunk_number++;
888
+ $logger and !$is_cron and PMXI_Plugin::$session->save_data();
889
  continue;
890
+ }
 
 
891
 
892
  $logger and call_user_func($logger, __('<b>ACTION</b>: pmxi_before_post_import ...', 'wp_all_import_plugin'));
893
  do_action('pmxi_before_post_import', $this->id);
906
  $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
907
  }
908
  }
909
+
910
+ switch ($this->options['custom_type']){
911
+ case 'import_users':
912
+ $articleData = apply_filters('wp_all_import_combine_article_data', array(
913
+ 'user_pass' => $addons_data['PMUI_Plugin']['pmui_pass'][$i],
914
+ 'user_login' => $addons_data['PMUI_Plugin']['pmui_logins'][$i],
915
+ 'user_nicename' => $addons_data['PMUI_Plugin']['pmui_nicename'][$i],
916
+ 'user_url' => $addons_data['PMUI_Plugin']['pmui_url'][$i],
917
+ 'user_email' => $addons_data['PMUI_Plugin']['pmui_email'][$i],
918
+ 'display_name' => $addons_data['PMUI_Plugin']['pmui_display_name'][$i],
919
+ 'user_registered' => $addons_data['PMUI_Plugin']['pmui_registered'][$i],
920
+ 'first_name' => $addons_data['PMUI_Plugin']['pmui_first_name'][$i],
921
+ 'last_name' => $addons_data['PMUI_Plugin']['pmui_last_name'][$i],
922
+ 'description' => $addons_data['PMUI_Plugin']['pmui_description'][$i],
923
+ 'nickname' => $addons_data['PMUI_Plugin']['pmui_nickname'][$i],
924
+ 'role' => ('' == $addons_data['PMUI_Plugin']['pmui_role'][$i]) ? 'subscriber' : $addons_data['PMUI_Plugin']['pmui_role'][$i],
925
+ ), $this->options['custom_type'], $this->id, $i);
926
+ $logger and call_user_func($logger, sprintf(__('Combine all data for user %s...', 'wp_all_import_plugin'), $articleData['user_login']));
927
+ break;
928
+ case 'taxonomies':
929
+ $taxonomy_type = get_taxonomy( $this->options['taxonomy_type'] );
930
+ $parent_term_id = 0;
931
+ if ( ! empty($taxonomy_parent[$i]) && $taxonomy_type->hierarchical){
932
+ $parent_term = get_term_by('slug', $taxonomy_parent[$i], $this->options['taxonomy_type']) or $parent_term = get_term_by('name', $taxonomy_parent[$i], $this->options['taxonomy_type']) or ctype_digit($taxonomy_parent[$i]) and $parent_term = get_term_by('id', $taxonomy_parent[$i], $this->options['taxonomy_type']);
933
+ if (!empty($parent_term) && !is_wp_error($parent_term)){
934
+ $parent_term_id = $parent_term->term_id;
935
+ }
936
+ }
937
+ $articleData = apply_filters('wp_all_import_combine_article_data', array(
938
+ 'post_type' => $post_type[$i],
939
+ 'post_title' => (!empty($this->options['is_leave_html'])) ? html_entity_decode($titles[$i]) : $titles[$i],
940
+ 'post_parent' => $parent_term_id,
941
+ 'post_content' => apply_filters('pmxi_the_content', ((!empty($this->options['is_leave_html'])) ? html_entity_decode($contents[$i]) : $contents[$i]), $this->id),
942
+ 'menu_order' => (int) $menu_order[$i],
943
+ 'slug' => $taxonomy_slug[$i],
944
+ 'taxonomy' => $this->options['taxonomy_type']
945
+ ), $this->options['custom_type'], $this->id, $i);
946
+ $logger and call_user_func($logger, sprintf(__('Combine all data for term %s...', 'wp_all_import_plugin'), $articleData['post_title']));
947
+ break;
948
+ default:
949
+ $articleData = apply_filters('wp_all_import_combine_article_data', array(
950
+ 'post_type' => $post_type[$i],
951
+ 'post_status' => ("xpath" == $this->options['status']) ? $post_status[$i] : $this->options['status'],
952
+ 'comment_status' => ("xpath" == $this->options['comment_status']) ? $comment_status[$i] : $this->options['comment_status'],
953
+ 'ping_status' => ("xpath" == $this->options['ping_status']) ? $ping_status[$i] : $this->options['ping_status'],
954
+ 'post_title' => (!empty($this->options['is_leave_html'])) ? html_entity_decode($titles[$i]) : $titles[$i],
955
+ 'post_excerpt' => apply_filters('pmxi_the_excerpt', ((!empty($this->options['is_leave_html'])) ? html_entity_decode($post_excerpt[$i]) : $post_excerpt[$i]), $this->id),
956
+ 'post_name' => $post_slug[$i],
957
+ 'post_content' => apply_filters('pmxi_the_content', ((!empty($this->options['is_leave_html'])) ? html_entity_decode($contents[$i]) : $contents[$i]), $this->id),
958
+ 'post_date' => $dates[$i],
959
+ 'post_date_gmt' => get_gmt_from_date($dates[$i]),
960
+ 'post_author' => $post_author[$i],
961
+ 'menu_order' => (int) $menu_order[$i],
962
+ 'post_parent' => ("no" == $this->options['is_multiple_page_parent']) ? wp_all_import_get_parent_post($page_parent[$i], $post_type[$i], $this->options['type']) : (int) $this->options['parent'],
963
+ 'page_template' => ("no" == $this->options['is_multiple_page_template']) ? $page_template[$i] : $this->options['page_template']
964
+ ), $this->options['custom_type'], $this->id, $i);
965
+ if ( 'shop_coupon' == $post_type[$i] ){
966
+ $articleData['post_excerpt'] = $articleData['post_content'];
967
+ }
968
+ $logger and call_user_func($logger, sprintf(__('Combine all data for post `%s`...', 'wp_all_import_plugin'), $articleData['post_title']));
969
+ // if ( "xpath" == $this->options['status'] )
970
+ // {
971
+ // $status_object = get_post_status_object($post_status[$i]);
972
+
973
+ // if ( empty($status_object) )
974
+ // {
975
+ // $articleData['post_status'] = 'draft';
976
+ // $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Post status `%s` is not supported, post `%s` will be saved in draft.', 'wp_all_import_plugin'), $post_status[$i], $articleData['post_title']));
977
+ // $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
978
+ // }
979
+ // }
980
+ break;
981
+ }
982
 
983
  // Re-import Records Matching
984
  $post_to_update = false; $post_to_update_id = false;
987
  $current_xml_node = wp_all_import_xml2array($rootNodes[$i]);
988
 
989
  $check_for_duplicates = apply_filters('wp_all_import_is_check_duplicates', true, $this->id);
990
+
991
  if ( $check_for_duplicates )
992
  {
993
  // if Auto Matching re-import option selected
994
  if ( "manual" != $this->options['duplicate_matching'] ){
995
 
996
  // find corresponding article among previously imported
997
+ $logger and call_user_func($logger, sprintf(__('Find corresponding article among previously imported for post `%s`...', 'wp_all_import_plugin'), $this->getRecordTitle($articleData)));
998
+ $postList = new PMXI_Post_List();
999
+ $args = array(
1000
+ 'unique_key' => $unique_keys[$i],
1001
+ 'import_id' => $this->id,
1002
+ );
1003
+ $postRecord->clear();
1004
+ foreach($postList->getBy($args)->convertRecords() as $postRecord) {
1005
+ if ( ! $postRecord->isEmpty() ) {
1006
+ switch ($this->options['custom_type']){
1007
+ case 'import_users':
1008
+ $post_to_update = get_user_by('id', $post_to_update_id = $postRecord->post_id);
1009
+ break;
1010
+ case 'taxonomies':
1011
+ $post_to_update = get_term_by('id', $post_to_update_id = $postRecord->post_id, $this->options['taxonomy_type']);
1012
+ break;
1013
+ default:
1014
+ $post_to_update = get_post($post_to_update_id = $postRecord->post_id);
1015
+ break;
1016
+ }
1017
+ }
1018
+ if ($post_to_update){
1019
+ $logger and call_user_func($logger, sprintf(__('Duplicate post was found for post %s with unique key `%s`...', 'wp_all_import_plugin'), $this->getRecordTitle($articleData), $unique_keys[$i]));
1020
+ break;
1021
+ }
1022
+ else{
1023
+ $postRecord->delete();
1024
+ }
1025
+ }
1026
 
1027
+ if (empty($post_to_update)) {
1028
+ $logger and call_user_func($logger, sprintf(__('Duplicate post wasn\'t found with unique key `%s`...', 'wp_all_import_plugin'), $unique_keys[$i]));
1029
+ }
 
 
 
 
 
 
 
 
 
1030
 
1031
  // if Manual Matching re-import option seleted
1032
  } else {
1039
  count($titles) and $custom_duplicate_name = $custom_duplicate_value = array_fill(0, count($titles), '');
1040
  }
1041
 
1042
+ $logger and call_user_func($logger, sprintf(__('Find corresponding article among database for post `%s`...', 'wp_all_import_plugin'), $this->getRecordTitle($articleData)));
1043
 
1044
+ $duplicates = array();
1045
  if ('pid' == $this->options['duplicate_indicator']) {
1046
+ $duplicate_id = $duplicate_indicator_values[$i];
1047
  }
1048
  // handle duplicates according to import settings
1049
  else
1050
  {
1051
+ $duplicates = pmxi_findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i], $this->options['duplicate_indicator'], $duplicate_indicator_values[$i]);
1052
  $duplicate_id = ( ! empty($duplicates)) ? array_shift($duplicates) : false;
1053
  }
1054
 
1055
+ if ( ! empty($duplicate_id)) {
1056
+ $duplicate_id = apply_filters('wp_all_import_manual_matching_duplicate_id', $duplicate_id, $duplicates, $articleData, $this->id);
1057
  if (class_exists('WPAI_WPML') && ! empty($this->options['wpml_addon']['lng'])){
1058
  // trying to find needed translation for update
1059
  $duplicate_id = apply_filters('wpml_object_id', $duplicate_id, get_post_type($duplicate_id), true, $this->options['wpml_addon']['lng']);
1060
  }
1061
+ $logger and call_user_func($logger, sprintf(__('Duplicate post was found for post `%s`...', 'wp_all_import_plugin'), $this->getRecordTitle($articleData)));
1062
  switch ($this->options['custom_type']){
1063
  case 'import_users':
1064
  $post_to_update = get_user_by('id', $post_to_update_id = $duplicate_id);
1065
+ break;
1066
+ case 'taxonomies':
1067
+ $post_to_update = get_term_by('id', $post_to_update_id = $duplicate_id, $this->options['taxonomy_type']);
1068
+ break;
1069
  default:
1070
  $post_to_update = get_post($post_to_update_id = $duplicate_id);
1071
  break;
1072
  }
1073
  }
1074
  else{
1075
+ $logger and call_user_func($logger, sprintf(__('Duplicate post wasn\'t found for post `%s`...', 'wp_all_import_plugin'), $this->getRecordTitle($articleData)));
1076
  }
1077
  }
1078
  }
1108
 
1109
  $continue_import = true;
1110
 
1111
+ $continue_import = apply_filters('wp_all_import_is_post_to_update', $continue_import, $post_to_update_id, $current_xml_node, $this->id);
1112
 
1113
  if ( ! $continue_import ){
1114
 
1145
  // Choose which data to update
1146
  if ( $this->options['update_all_data'] == 'no' ){
1147
 
1148
+ switch ($this->options['custom_type']){
1149
+ case 'import_users':
1150
+ if ( ! $this->options['is_update_first_name'] ) $articleData['first_name'] = $post_to_update->first_name;
1151
+ if ( ! $this->options['is_update_last_name'] ) $articleData['last_name'] = $post_to_update->last_name;
1152
+ if ( ! $this->options['is_update_role'] ) unset($articleData['role']);
1153
+ if ( ! $this->options['is_update_nickname'] ) $articleData['nickname'] = get_user_meta($post_to_update->ID, 'nickname', true);
1154
+ if ( ! $this->options['is_update_description'] ) $articleData['description'] = get_user_meta($post_to_update->ID, 'description', true);
1155
+ if ( ! $this->options['is_update_login'] ) $articleData['user_login'] = $post_to_update->user_login;
1156
+ if ( ! $this->options['is_update_password'] ) unset($articleData['user_pass']);
1157
+ if ( ! $this->options['is_update_nicename'] ) $articleData['user_nicename'] = $post_to_update->user_nicename;
1158
+ if ( ! $this->options['is_update_email'] ) $articleData['user_email'] = $post_to_update->user_email;
1159
+ if ( ! $this->options['is_update_registered'] ) $articleData['user_registered'] = $post_to_update->user_registered;
1160
+ if ( ! $this->options['is_update_display_name'] ) $articleData['display_name'] = $post_to_update->display_name;
1161
+ if ( ! $this->options['is_update_url'] ) $articleData['user_url'] = $post_to_update->user_url;
1162
+ break;
1163
+ case 'taxonomies':
1164
+ if ( ! $this->options['is_update_content']){
1165
+ $articleData['post_content'] = $post_to_update->description;
1166
+ $logger and call_user_func($logger, sprintf(__('Preserve description of already existing taxonomy term for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1167
+ }
1168
+ if ( ! $this->options['is_update_title']){
1169
+ $articleData['post_title'] = $post_to_update->name;
1170
+ $logger and call_user_func($logger, sprintf(__('Preserve name of already existing taxonomy term for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1171
+ }
1172
+ if ( ! $this->options['is_update_slug']){
1173
+ $articleData['slug'] = $post_to_update->slug;
1174
+ $logger and call_user_func($logger, sprintf(__('Preserve slug of already existing taxonomy term for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1175
+ }
1176
+ // if ( ! $this->options['is_update_menu_order']){
1177
+ // $articleData['post_name'] = $post_to_update->post_name;
1178
+ // $logger and call_user_func($logger, sprintf(__('Preserve menu order of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1179
+ // }
1180
+ if ( ! $this->options['is_update_parent']){
1181
+ $articleData['post_parent'] = $post_to_update->parent;
1182
+ $logger and call_user_func($logger, sprintf(__('Preserve parent of already existing taxonomy term for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1183
+ }
1184
+ break;
1185
+ default:
1186
+ // preserve date of already existing article when duplicate is found
1187
+ if ( ( ! $this->options['is_update_categories'] and ( is_object_in_taxonomy( $post_type[$i], 'category' ) or is_object_in_taxonomy( $post_type[$i], 'post_tag' ) ) ) or ($this->options['is_update_categories'] and $this->options['update_categories_logic'] != "full_update")) {
1188
+ $logger and call_user_func($logger, sprintf(__('Preserve taxonomies of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1189
+ $existing_taxonomies = array();
1190
+ foreach (array_keys($taxonomies) as $tx_name) {
1191
+ $txes_list = get_the_terms($articleData['ID'], $tx_name);
1192
+ if (is_wp_error($txes_list)) {
1193
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'wp_all_import_plugin'), $articleData['ID']));
1194
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1195
+ } else {
1196
+ $txes_new = array();
1197
+ if (!empty($txes_list)):
1198
+ foreach ($txes_list as $t) {
1199
+ $txes_new[] = $t->term_taxonomy_id;
1200
+ }
1201
+ endif;
1202
+ $existing_taxonomies[$tx_name][$i] = $txes_new;
1203
+ }
1204
+ }
1205
+ }
1206
 
1207
+ if ( ! $this->options['is_update_dates']) { // preserve date of already existing article when duplicate is found
1208
+ $articleData['post_date'] = $post_to_update->post_date;
1209
+ $articleData['post_date_gmt'] = $post_to_update->post_date_gmt;
1210
+ $logger and call_user_func($logger, sprintf(__('Preserve date of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1211
+ }
1212
+ if ( ! $this->options['is_update_status']) { // preserve status and trashed flag
1213
+ $articleData['post_status'] = $post_to_update->post_status;
1214
+ $logger and call_user_func($logger, sprintf(__('Preserve status of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1215
+ }
1216
+ if ( ! $this->options['is_update_content']){
1217
+ $articleData['post_content'] = $post_to_update->post_content;
1218
+ $logger and call_user_func($logger, sprintf(__('Preserve content of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1219
+ }
1220
+ if ( ! $this->options['is_update_title']){
1221
+ $articleData['post_title'] = $post_to_update->post_title;
1222
+ $logger and call_user_func($logger, sprintf(__('Preserve title of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1223
+ }
1224
+ if ( ! $this->options['is_update_slug']){
1225
+ $articleData['post_name'] = $post_to_update->post_name;
1226
+ $logger and call_user_func($logger, sprintf(__('Preserve slug of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1227
+ }
1228
+ // Check for changed slugs for published post objects and save the old slug.
1229
+ if( ! empty($articleData['post_name']) and $articleData['post_name'] != $post_to_update->post_name)
1230
+ {
1231
+ $old_slugs = (array) get_post_meta( $post_to_update_id, '_wp_old_slug' );
1232
 
1233
+ // If we haven't added this old slug before, add it now.
1234
+ if ( ! empty( $post_to_update->post_name ) && ! in_array( $post_to_update->post_name, $old_slugs ) ) {
1235
+ add_post_meta( $post_to_update_id, '_wp_old_slug', $post_to_update->post_name );
1236
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1237
 
1238
+ // If the new slug was used previously, delete it from the list.
1239
+ if ( in_array( $articleData['post_name'], $old_slugs ) ) {
1240
+ delete_post_meta( $post_to_update_id, '_wp_old_slug', $articleData['post_name'] );
1241
+ }
1242
+ }
1243
 
1244
+ if ( ! $this->options['is_update_excerpt']){
1245
+ $articleData['post_excerpt'] = $post_to_update->post_excerpt;
1246
+ $logger and call_user_func($logger, sprintf(__('Preserve excerpt of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1247
+ }
1248
+ if ( ! $this->options['is_update_menu_order']){
1249
+ $articleData['menu_order'] = $post_to_update->menu_order;
1250
+ $logger and call_user_func($logger, sprintf(__('Preserve menu order of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1251
+ }
1252
+ if ( ! $this->options['is_update_parent']){
1253
+ $articleData['post_parent'] = $post_to_update->post_parent;
1254
+ $logger and call_user_func($logger, sprintf(__('Preserve post parent of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1255
+ }
1256
+ if ( ! $this->options['is_update_post_type']){
1257
+ $articleData['post_type'] = $post_to_update->post_type;
1258
+ $logger and call_user_func($logger, sprintf(__('Preserve post type of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1259
+ }
1260
+ if ( ! $this->options['is_update_comment_status']){
1261
+ $articleData['comment_status'] = $post_to_update->comment_status;
1262
+ $logger and call_user_func($logger, sprintf(__('Preserve comment status of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1263
+ }
1264
+ if ( ! $this->options['is_update_author']){
1265
+ $articleData['post_author'] = $post_to_update->post_author;
1266
+ $logger and call_user_func($logger, sprintf(__('Preserve post author of already existing article for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1267
+ }
1268
+ if ( ! wp_all_import_is_update_cf('_wp_page_template', $this->options) ){
1269
+ $articleData['page_template'] = get_post_meta($post_to_update_id, '_wp_page_template', true);
1270
+ }
1271
+ break;
1272
+ }
1273
+ }
1274
 
1275
+ $is_images_to_delete = apply_filters('pmxi_delete_images', true, $articleData, $current_xml_node);
1276
+ if ( $is_images_to_delete ) {
1277
+ switch ($this->options['custom_type']) {
1278
+ case 'import_users':
1279
+
1280
+ break;
1281
+ case 'taxonomies':
1282
+
1283
+ // handle obsolete attachments (i.e. delete or keep) according to import settings
1284
+ if ($this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_images'] and $this->options['update_images_logic'] == "full_update")) {
1285
+ $logger and call_user_func($logger, sprintf(__('Deleting images for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1286
+ $term_thumbnail_id = get_term_meta($articleData['ID'], 'thumbnail_id', TRUE);
1287
+ if (!empty($term_thumbnail_id)) {
1288
+ delete_term_meta($articleData['ID'], 'thumbnail_id');
1289
+ $remove_images = ($this->options['download_images'] == 'gallery' or $this->options['do_not_remove_images']) ? FALSE : TRUE;
1290
+ if ($remove_images){
1291
+ wp_delete_attachment($term_thumbnail_id, true);
1292
+ }
1293
+ }
1294
+ }
1295
 
1296
+ break;
1297
+ default:
1298
+ if ($this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_attachments'])) {
1299
+ $logger and call_user_func($logger, sprintf(__('Deleting attachments for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1300
+ wp_delete_attachments($articleData['ID'], ! $this->options['is_search_existing_attach'], 'files');
1301
+ }
1302
+ // handle obsolete attachments (i.e. delete or keep) according to import settings
1303
+ if ($this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_images'] and $this->options['update_images_logic'] == "full_update")) {
1304
+ $logger and call_user_func($logger, sprintf(__('Deleting images for `%s`', 'wp_all_import_plugin'), $articleData['post_title']));
1305
+ if (!empty($images_bundle)) {
1306
+ foreach ($images_bundle as $slug => $bundle_data) {
1307
+ $option_slug = ($slug == 'pmxi_gallery_image') ? '' : $slug;
1308
+ if (count($images_bundle) > 1 && $slug == 'pmxi_gallery_image') {
1309
+ continue;
1310
+ }
1311
+ $do_not_remove_images = ($this->options[$option_slug . 'download_images'] == 'gallery' or $this->options[$option_slug . 'do_not_remove_images']) ? FALSE : TRUE;
1312
+ $missing_images = wp_delete_attachments($articleData['ID'], $do_not_remove_images, 'images');
1313
  }
 
 
1314
  }
1315
  }
1316
+ break;
1317
+ }
1318
+ }
1319
  }
1320
  elseif ( ! $postRecord->isEmpty() ){
1321
 
1324
 
1325
  }
1326
 
1327
+ $logger and call_user_func($logger, sprintf(__('Applying filter `pmxi_article_data` for `%s`', 'wp_all_import_plugin'), $this->getRecordTitle($articleData)));
1328
  $articleData = apply_filters('pmxi_article_data', $articleData, $this, $post_to_update);
1329
 
1330
  // no new records are created. it will only update posts it finds matching duplicates for
1422
  if ($this->options['is_fast_mode']){
1423
  foreach (array('transition_post_status', 'save_post', 'pre_post_update', 'add_attachment', 'edit_attachment', 'edit_post', 'post_updated', 'wp_insert_post', 'save_post_' . $post_type[$i]) as $act) {
1424
  remove_all_actions($act);
1425
+ }
1426
  }
1427
 
1428
  if ( empty($articleData['ID']) )
1429
  {
1430
  $continue_import = true;
1431
+ $continue_import = apply_filters('wp_all_import_is_post_to_create', $continue_import, $current_xml_node, $this->id);
1432
 
1433
  if ( ! $continue_import ){
1434
  $skipped++;
1440
  continue;
1441
  }
1442
  }
1443
+
1444
+ switch ($this->options['custom_type']){
1445
+ case 'import_users':
1446
+ if (empty($articleData['ID']) && email_exists( $articleData['user_email'] )){
1447
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b> Sorry, that email address `%s` is already used!', 'wp_all_import_plugin'), $articleData['user_email']));
1448
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
1449
+ $logger and !$is_cron and PMXI_Plugin::$session->chunk_number++;
1450
+ $logger and !$is_cron and PMXI_Plugin::$session->save_data();
1451
+ $skipped++;
1452
+ continue 2;
1453
+ }
1454
+ $pid = (empty($articleData['ID'])) ? wp_insert_user( $articleData ) : wp_update_user( $articleData );
1455
+ // update user login using direct sql query
1456
+ if (!empty($articleData['ID'])){
1457
+ $this->wpdb->update($this->wpdb->users, array('user_login' => $articleData['user_login']), array('ID' => $articleData['ID']));
1458
+ }
1459
+ $articleData['post_title'] = $articleData['user_login'];
1460
+ break;
1461
+ case 'taxonomies':
1462
+ if (empty($articleData['ID'])){
1463
+ $logger and call_user_func($logger, sprintf(__('<b>CREATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1464
+ }
1465
+ else{
1466
+ $logger and call_user_func($logger, sprintf(__('<b>UPDATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1467
+ }
1468
+ $term = (empty($articleData['ID'])) ? wp_insert_term($articleData['post_title'], $this->options['taxonomy_type'], array(
1469
+ 'parent' => empty($articleData['post_parent']) ? 0 : $articleData['post_parent'],
1470
+ 'slug' => $articleData['slug'],
1471
+ 'description' => $articleData['post_content']
1472
+ )) : wp_update_term($articleData['ID'], $this->options['taxonomy_type'], array(
1473
+ 'name' => $articleData['post_title'],
1474
+ 'parent' => empty($articleData['post_parent']) ? 0 : $articleData['post_parent'],
1475
+ 'slug' => $articleData['slug'],
1476
+ 'description' => $articleData['post_content']
1477
+ ));
1478
+ if (is_wp_error($term)){
1479
+ $logger and call_user_func($logger, __('<b>ERROR</b>', 'wp_all_import_plugin') . ': ' . $term->get_error_message());
1480
+ }
1481
+ else{
1482
+ $pid = $term['term_id'];
1483
+ if (empty($articleData['post_parent']) && !empty($taxonomy_parent[$i])){
1484
+ $parent_terms = get_option('wp_all_import_taxonomies_hierarchy_' . $this->id);
1485
+ if (empty($parent_terms)) $parent_terms = array();
1486
+ $parent_terms[$pid] = $taxonomy_parent[$i];
1487
+ update_option('wp_all_import_taxonomies_hierarchy_' . $this->id, $parent_terms);
1488
+ }
1489
+ }
1490
+ break;
1491
+ default:
1492
+ if (empty($articleData['ID'])){
1493
+ $logger and call_user_func($logger, sprintf(__('<b>CREATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1494
+ }
1495
+ else{
1496
+ $logger and call_user_func($logger, sprintf(__('<b>UPDATING</b> `%s` `%s`', 'wp_all_import_plugin'), $articleData['post_title'], $custom_type_details->labels->singular_name));
1497
+ }
1498
+ $pid = (empty($articleData['ID'])) ? wp_insert_post($articleData, true) : wp_update_post($articleData, true);
1499
+ break;
1500
+ }
1501
 
1502
  if (empty($pid))
1503
  {
1511
  $skipped++;
1512
  } else {
1513
 
1514
+ if (empty($articleData['post_parent']) && !empty($page_parent[$i])){
1515
  $parent_posts = get_option('wp_all_import_posts_hierarchy_' . $this->id);
1516
  if (empty($parent_posts)) $parent_posts = array();
1517
  $parent_posts[$pid] = $page_parent[$i];
1518
  update_option('wp_all_import_posts_hierarchy_' . $this->id, $parent_posts);
1519
+ }
1520
+
1521
+ if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
1522
  // associate post with import
1523
  $product_key = (($post_type[$i] == "product" and PMXI_Admin_Addons::get_addon('PMWI_Plugin')) ? $addons_data['PMWI_Plugin']['single_product_ID'][$i] : '');
1524
+ if ($post_type[$i] == "taxonomies"){
1525
+ $product_key = 'taxonomy_term';
1526
+ }
1527
+ $postRecord->isEmpty() and $postRecord->set(array(
1528
  'post_id' => $pid,
1529
  'import_id' => $this->id,
1530
  'unique_key' => $unique_keys[$i],
1531
  'product_key' => $product_key
1532
  ))->insert();
1533
 
1534
+ $postRecordData = array(
1535
  'iteration' => $this->iteration,
1536
  'specified' => empty($specified_records) ? 0 : 1
1537
  );
1538
 
1539
  if ( ! empty($product_key) ){
1540
  $postRecordData['product_key'] = $product_key;
1541
+ }
1542
 
1543
+ $postRecord->set($postRecordData)->update();
1544
 
1545
  $logger and call_user_func($logger, sprintf(__('Associate post `%s` with current import ...', 'wp_all_import_plugin'), $articleData['post_title']));
1546
  }
1585
  }
1586
  }
1587
  }
1588
+
1589
+ // [/addons import]
1590
+
1591
+ // Page Template
1592
+ global $wp_version;
1593
+ if ( ! empty($articleData['post_type']) and ('page' == $articleData['post_type'] || version_compare($wp_version, '4.7.0', '>=')) and wp_all_import_is_update_cf('_wp_page_template', $this->options) and ( !empty($this->options['page_template']) or "no" == $this->options['is_multiple_page_template']) ){
1594
+ update_post_meta($pid, '_wp_page_template', ("no" == $this->options['is_multiple_page_template']) ? $page_template[$i] : $this->options['page_template']);
1595
+ }
1596
 
1597
+ // [featured image]
1598
 
1599
+ $is_allow_import_images = apply_filters('wp_all_import_is_allow_import_images', false, empty($articleData['post_type']) ? '' : $articleData['post_type']);
1600
+ $images_uploads = apply_filters('wp_all_import_images_uploads_dir', $uploads, $articleData, $current_xml_node, $this->id);
1601
 
1602
+ if (!empty($articleData['post_content']) && $this->options['is_update_content'] && $this->options['import_img_tags'] && ( ! empty($articleData['post_type']) && $articleData['post_type'] == "product" && class_exists('PMWI_Plugin') || $is_allow_import_images)){
 
 
1603
 
1604
+ require_once(ABSPATH . 'wp-admin/includes/image.php');
1605
 
1606
+ $logger and call_user_func($logger, __('<b>CONTENT IMAGES:</b>', 'wp_all_import_plugin'));
1607
 
1608
+ // search for images in galleries
1609
+ $galleries = array();
1610
+ if (preg_match_all('%\[gallery[^\]]*ids="([^\]]*)"[^\]]*\]%is', $articleData['post_content'], $matches, PREG_PATTERN_ORDER)) {
1611
+ $galleries = array_unique(array_filter($matches[1]));
1612
+ }
1613
+ $gallery_images = array();
1614
+ if ( ! empty($galleries) ){
1615
+ foreach ($galleries as $key => $gallery) {
1616
+ $imgs = array_unique(array_filter(explode(",", $gallery)));
1617
+ if (!empty($imgs)){
1618
+ foreach ($imgs as $img) {
1619
+ if ( ! is_numeric($img) ){
1620
+ $gallery_images[] = json_decode(base64_decode($img), true);
1621
+ }
1622
+ }
1623
+ }
1624
+ }
1625
+ }
1626
+ // search for images in <img> tags
1627
+ $tag_images = array();
1628
+ if (preg_match_all('%<img\s[^>]*src=(?(?=")"([^"]*)"|(?(?=\')\'([^\']*)\'|([^\s>]*)))%is', $articleData['post_content'], $matches, PREG_PATTERN_ORDER)) {
1629
+ $tag_images = array_unique(array_merge(array_filter($matches[1]), array_filter($matches[2]), array_filter($matches[3])));
1630
+ }
1631
 
1632
+ $images_sources = array(
1633
+ 'gallery' => $gallery_images,
1634
+ 'tag' => $tag_images
1635
+ );
1636
 
1637
+ $targetDir = $images_uploads['path'];
1638
+ $targetUrl = $images_uploads['url'];
1639
+ foreach ($images_sources as $source_type => $images){
 
1640
 
1641
+ if ( empty($images) ) continue;
 
1642
 
1643
+ foreach ( $images as $image ){
 
 
 
1644
 
1645
+ if ($source_type == 'gallery'){
1646
+ $image_data = $image;
1647
+ $image = $image_data['url'];
1648
+ $image_title = $image_data['title'];
1649
+ $image_caption = $image_data['caption'];
1650
+ $image_alt = $image_data['alt'];
1651
+ $image_description = $image_data['description'];
1652
+ }
1653
+ // trying to get image full size
1654
+ $original_image_url = $image;
1655
+ $full_size = preg_replace('%-\d{2,4}x\d{2,4}%', '', $image);
1656
+ if ($full_size != $image){
1657
+ // check if full size image exists
1658
+ $full_size_headers = get_headers($full_size, true);
1659
+ if (!empty($full_size_headers['Content-Type']) && strpos($full_size_headers['Content-Type'], 'image') !== false){
1660
+ $image = $full_size;
1661
+ }
1662
+ }
1663
 
1664
+ $attid = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1665
 
1666
+ // trying to find existing image in images table
1667
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by URL...', 'wp_all_import_plugin'), rawurldecode($image)));
1668
+ $imageList = new PMXI_Image_List();
1669
+ $attch = $imageList->getExistingImageByUrl($image);
 
1670
 
1671
+ // trying to find existing image in media library using old logic
1672
+ if (empty($attch)){
1673
+ $image_name = wp_all_import_sanitize_filename(urldecode(wp_all_import_basename($image)));
1674
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by `_wp_attached_file` `%s`...', 'wp_all_import_plugin'), $image, $image_name));
1675
+ $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, 'images', $logger);
1676
+ }
1677
 
1678
+ // exisitng image founded
1679
+ if ($attch) {
1680
+ $attid = $attch->ID;
1681
+ $logger and call_user_func($logger, sprintf(__('- Existing image was found for post content `%s`...', 'wp_all_import_plugin'), rawurldecode($image)));
1682
+ }
1683
+ else {
 
1684
 
1685
+ $logger and call_user_func($logger, sprintf(__('- Image `%s` was not found...', 'wp_all_import_plugin'), rawurldecode($image)));
1686
 
1687
+ // Download remote image and save it in images table
1688
+ $url = html_entity_decode(trim($image), ENT_QUOTES);
1689
 
1690
+ if (empty($url)) continue;
1691
+
1692
+ $bn = wp_all_import_sanitize_filename(urldecode(wp_all_import_basename($url)));
1693
+
1694
+ $img_ext = pmxi_getExtensionFromStr($url);
1695
+ $default_extension = pmxi_getExtension($bn);
1696
+ if ($img_ext == "") $img_ext = pmxi_get_remote_image_ext($url);
1697
+
1698
+ // generate local file name
1699
+ $image_name = urldecode(("" != $img_ext) ? str_replace("." . $default_extension, "", $bn) : $bn) . (("" != $img_ext) ? '.' . $img_ext : '');
1700
+
1701
+ $image_filename = wp_unique_filename($targetDir, $image_name);
1702
+ $image_filepath = $targetDir . '/' . $image_filename;
1703
+
1704
+ $image_info = $this->downloadFile($url, $image_filepath, $is_cron, $logger);
1705
+
1706
+ if ($image_info){
1707
+ // create an attachment
1708
+ $file_mime_type = '';
1709
+
1710
+ if ( ! empty($image_info) )
1711
+ {
1712
+ $file_mime_type = image_type_to_mime_type($image_info[2]);
1713
+ }
1714
+ $file_mime_type = apply_filters('wp_all_import_image_mime_type', $file_mime_type, $image_filepath);
1715
+
1716
+ $handle_image = array(
1717
+ 'file' => $image_filepath,
1718
+ 'url' => $targetUrl . '/' . $image_filename,
1719
+ 'type' => $file_mime_type
1720
+ );
1721
+
1722
+ $attid = $this->createAttachment($pid, $handle_image, $image_name, $post_author[$i], $post_type[$i], $is_cron, $logger, $bundle_data['type']);
1723
+ }
1724
+ }
1725
+
1726
+ // attachment founded or successfully created
1727
+ if ($attid){
1728
+
1729
+ $imageRecord = new PMXI_Image_Record();
1730
+ $imageRecord->getBy(array(
1731
+ 'attachment_id' => $attid
1732
+ ));
1733
+ if ($imageRecord->isEmpty()){
1734
+ $imageRecord->set(array(
1735
+ 'attachment_id' => $attid,
1736
+ 'image_url' => $image,
1737
+ 'image_filename' => $image_name
1738
+ ))->insert();
1739
+ }
1740
+ elseif (empty($imageRecord->image_url)){
1741
+ // update image URL if record already exist
1742
+ $imageRecord->set(array(
1743
+ 'attachment_id' => $attid,
1744
+ 'image_url' => $image
1745
+ ))->update();
1746
+ }
1747
+
1748
+ if ($source_type == 'gallery') {
1749
+ $articleData['post_content'] = str_replace(base64_encode(json_encode($image_data)), $attid, $articleData['post_content']);
1750
+ }
1751
+ $attachmentURL = wp_get_attachment_url($attid);
1752
+ if ($attachmentURL){
1753
+ preg_match('%-\d{2,4}x\d{2,4}%', $original_image_url, $matches);
1754
+ if (!empty($matches)){
1755
+ $attachment_thumbnail_url = preg_replace('%\.(\D{2,4})$%', $matches[0] . '.$1', $attachmentURL);
1756
+ // check is thumbnail exists
1757
+ $attachment_thumbnail_path = str_replace($targetUrl, $uploads['path'], $attachment_thumbnail_url);
1758
+ if (file_exists($attachment_thumbnail_path)){
1759
+ $articleData['post_content'] = str_replace($original_image_url, $attachment_thumbnail_url, $articleData['post_content']);
1760
+ }
1761
+ else{
1762
+ $articleData['post_content'] = str_replace($original_image_url, $attachmentURL, $articleData['post_content']);
1763
+ }
1764
+ }
1765
+ $articleData['post_content'] = str_replace($image, $attachmentURL, $articleData['post_content']);
1766
+ }
1767
+
1768
+ if ($source_type == 'gallery'){
1769
+ $update_attachment_meta = array();
1770
+ $update_attachment_meta['post_title'] = trim($image_title);
1771
+ $update_attachment_meta['post_excerpt'] = trim($image_caption);
1772
+ $update_attachment_meta['post_content'] = trim($image_description);
1773
+ update_post_meta($attid, '_wp_attachment_image_alt', trim($image_alt));
1774
+ $this->wpdb->update( $this->wpdb->posts, $update_attachment_meta, array('ID' => $attid) );
1775
+ }
1776
+ }
1777
+ }
1778
+ // Update post content
1779
+ $this->wpdb->update( $this->wpdb->posts, array('post_content' => $articleData['post_content']), array('ID' => $pid) );
1780
+ }
1781
+ }
1782
+
1783
+ $is_images_to_update = apply_filters('pmxi_is_images_to_update', true, $articleData, $current_xml_node);
1784
+
1785
+ $logger and call_user_func($logger, __('<b>IMAGES:</b>', 'wp_all_import_plugin'));
1786
 
1787
  if ( $is_images_to_update and ! empty($images_uploads) and false === $images_uploads['error'] and ( ! empty($articleData['post_type']) and $articleData['post_type'] == "product" and class_exists('PMWI_Plugin') or $is_allow_import_images) and (empty($articleData['ID']) or $this->options['update_all_data'] == "yes" or ( $this->options['update_all_data'] == "no" and $this->options['is_update_images'])) ) {
1788
 
1789
+ if ( ! empty($images_bundle) ){
1790
 
1791
  require_once(ABSPATH . 'wp-admin/includes/image.php');
1792
 
1793
+ $is_show_add_new_images = apply_filters('wp_all_import_is_show_add_new_images', true, $post_type[$i]);
1794
+
1795
+ $is_images_section_enabled = apply_filters('wp_all_import_is_images_section_enabled', true, $post_type[$i]);
1796
 
1797
  foreach ($images_bundle as $slug => $bundle_data) {
1798
+
1799
+ if ( ! $is_images_section_enabled && $slug == 'pmxi_gallery_image' ) continue;
1800
 
1801
  $featured_images = $bundle_data['files'];
1802
 
1809
  $targetDir = $images_uploads['path'];
1810
  $targetUrl = $images_uploads['url'];
1811
 
 
 
1812
  if ( ! @is_writable($targetDir) ){
 
1813
  $logger and call_user_func($logger, sprintf(__('<b>ERROR</b>: Target directory %s is not writable', 'wp_all_import_plugin'), $targetDir));
 
1814
  }
1815
  else{
1816
 
1930
  // generate local file name
1931
  $image_name = urldecode(($this->options[$option_slug . 'auto_rename_images'] and !empty($auto_rename_images_bundle[$slug][$i])) ? sanitize_file_name(($img_ext) ? str_replace("." . $default_extension, "", $auto_rename_images_bundle[$slug][$i]) : $auto_rename_images_bundle[$slug][$i]) : (($img_ext) ? str_replace("." . $default_extension, "", $bn) : $bn)) . (("" != $img_ext) ? '.' . $img_ext : '');
1932
  $image_name = apply_filters("wp_all_import_image_filename", $image_name, empty($img_titles[$k]) ? '' : $img_titles[$k], empty($img_captions[$k]) ? '' : $img_captions[$k], empty($img_alts[$k]) ? '' : $img_alts[$k], $articleData, $this->id, $img_url);
1933
+
1934
  // if wizard store image data to custom field
1935
  $create_image = false;
1936
  $download_image = true;
1945
  $image_filename = $image_name;
1946
 
1947
  // search existing attachment
1948
+ if ($this->options[$option_slug . 'search_existing_images'] or "gallery" == $this->options[$option_slug . 'download_images']){
1949
 
1950
+ $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $bundle_data['type'], $logger);
1951
 
1952
  if ("gallery" == $this->options[$option_slug . 'download_images']) $download_image = false;
1953
 
1954
+ if (empty($attch)) {
 
1955
  $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Image %s not found in media gallery.', 'wp_all_import_plugin'), trim($image_name)));
1956
  }
1957
+ else {
 
1958
  $logger and call_user_func($logger, sprintf(__('- Using existing image `%s` for post `%s` ...', 'wp_all_import_plugin'), trim($image_name), $articleData['post_title']));
1959
  $download_image = false;
1960
  $create_image = false;
1983
 
1984
  if ( ! $create_image ) {
1985
 
1986
+ if ($this->options[$option_slug . 'auto_rename_images'] and !empty($auto_rename_images_bundle[$slug][$i])) {
1987
+ if ($k) {
 
 
1988
  $image_name = str_replace('.' . pmxi_getExtension($image_name), '', $image_name) . '-' . $k . '.' . pmxi_getExtension($image_name);
1989
  }
1990
  }
2013
  }
2014
  }
2015
  }
 
2016
  }
2017
 
2018
  // search existing attachment
2020
 
2021
  $image_filename = $image_name;
2022
 
2023
+ // trying to find existing image in images table
2024
+ if ($this->options[$option_slug . 'download_images'] === "yes"){
2025
+ $imageList = new PMXI_Image_List();
2026
+ switch ($this->options['search_existing_images_logic']){
2027
+ case 'by_url':
2028
+ $attch = $imageList->getExistingImageByUrl($url);
2029
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by URL...', 'wp_all_import_plugin'), rawurldecode($url)));
2030
+ break;
2031
+ default:
2032
+ $attch = $imageList->getExistingImageByFilename($image_name);
2033
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` by Filename...', 'wp_all_import_plugin'), $image_name));
2034
+ break;
2035
+ }
2036
+ }
2037
 
2038
+ if ("gallery" == $this->options[$option_slug . 'download_images']) $download_image = false;
2039
 
2040
+ // search for existing images using old logic
2041
+ if ( empty($attch) && ($this->options[$option_slug . 'download_images'] !== "yes" || $this->options['search_existing_images_logic'] == 'by_filename')){
2042
+
2043
+ $logger and call_user_func($logger, sprintf(__('- Search for existing image `%s` by `_wp_attached_file` ...', 'wp_all_import_plugin'), rawurldecode($image_name)));
2044
+
2045
+ $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, $bundle_data['type'], $logger);
2046
+ }
2047
+
2048
+ if (empty($attch)) {
2049
+ $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Image %s not found in media gallery.', 'wp_all_import_plugin'), rawurldecode($image_name)));
2050
+ }
2051
+ else {
2052
+ $logger and call_user_func($logger, sprintf(__('- Using existing image `%s` for post `%s` ...', 'wp_all_import_plugin'), rawurldecode($image_name), $articleData['post_title']));
2053
+ $download_image = false;
2054
+ $create_image = false;
2055
+ $attid = $attch->ID;
2056
+ // save image into images table
2057
+ if ("yes" === $this->options[$option_slug . 'download_images']){
2058
+ $imageRecord = new PMXI_Image_Record();
2059
+ $imageRecord->getBy(array(
2060
+ 'attachment_id' => $attid
2061
+ ));
2062
+ if ($imageRecord->isEmpty()){
2063
+ $imageRecord->set(array(
2064
+ 'attachment_id' => $attid,
2065
+ 'image_url' => $url,
2066
+ 'image_filename' => $image_name
2067
+ ))->insert();
2068
+ }
2069
+ else{
2070
+ switch ($this->options['search_existing_images_logic']){
2071
+ case 'by_url':
2072
+ // update image URL if it was not set
2073
+ if (empty($imageRecord->image_url)){
2074
+ $imageRecord->set(array(
2075
+ 'image_url' => $url
2076
+ ))->update();
2077
+ }
2078
+ break;
2079
+ default:
2080
+ // update image Filename if it was not set
2081
+ if (empty($imageRecord->image_filename)){
2082
+ $imageRecord->set(array(
2083
+ 'image_filename' => $image_name
2084
+ ))->update();
2085
+ }
2086
+ break;
2087
+ }
2088
+ }
2089
+ }
2090
+ }
2091
  }
2092
 
2093
  if ($download_image && "gallery" != $this->options[$option_slug . 'download_images']){
2101
  $wpai_uploads = $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR;
2102
  $wpai_image_path = $wpai_uploads . str_replace('%20', ' ', $url);
2103
 
2104
+ $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s`', 'wp_all_import_plugin'), $wpai_image_path));
2105
 
2106
  if ( @file_exists($wpai_image_path) and @copy( $wpai_image_path, $image_filepath )){
2107
  $download_image = false;
2108
+ // validate import attachments
2109
  if ($bundle_data['type'] == 'files'){
2110
  if( ! $wp_filetype = wp_check_filetype(wp_all_import_basename($image_filepath), null )) {
2111
  $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Can\'t detect attachment file type %s', 'wp_all_import_plugin'), trim($image_filepath)));
2119
  }
2120
  // validate import images
2121
  elseif($bundle_data['type'] == 'images'){
2122
+ if( preg_match('%\W(svg)$%i', wp_all_import_basename($image_filepath)) or $image_info = apply_filters('pmxi_getimagesize', @getimagesize($image_filepath), $image_filepath) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP)) ) {
2123
  $create_image = true;
2124
  $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully found', 'wp_all_import_plugin'), $wpai_image_path));
2125
  }
2132
  }
2133
  }
2134
  }
2135
+ else {
2136
+ $image_info = $this->downloadFile($url, $image_filepath, $is_cron, $logger, $bundle_data['type']);
2137
+ if ( ! $image_info ) {
2138
+ if ( $img_url !== pmxi_convert_encoding($img_url) ) {
2139
+ $url = trim(pmxi_convert_encoding($img_url));
2140
+ $image_info = $this->downloadFile($url, $image_filepath, $is_cron, $logger, $bundle_data['type']);
2141
+ }
2142
+ else{
2143
+ @unlink($image_filepath);
2144
+ }
2145
+ }
2146
+ $create_image = empty($image_info) ? false : true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2147
  }
2148
  }
2149
  }
2150
 
2151
  $handle_image = false;
2152
 
2153
+ // existing image not founded, create new attachment
2154
  if ($create_image){
2155
 
2156
  $file_mime_type = '';
2157
 
2158
+ if ($bundle_data['type'] == 'images') {
2159
+ if ( ! empty($image_info) ) {
 
 
2160
  $file_mime_type = image_type_to_mime_type($image_info[2]);
2161
  }
2162
  $file_mime_type = apply_filters('wp_all_import_image_mime_type', $file_mime_type, $image_filepath);
2163
  }
2164
+ else {
 
2165
  $file_mime_type = $wp_filetype['type'];
2166
  }
2167
 
2171
  'type' => $file_mime_type
2172
  ));
2173
 
2174
+ $attid = $this->createAttachment($pid, $handle_image, $image_name, $post_author[$i], $post_type[$i], $is_cron, $logger, $bundle_data['type']);
2175
+
2176
+ // save image into images table
2177
+ if ( $attid && "yes" === $this->options[$option_slug . 'download_images']){
2178
+ $imageRecord = new PMXI_Image_Record();
2179
+ $imageRecord->getBy(array(
2180
+ 'attachment_id' => $attid
2181
+ ));
2182
+ if ($imageRecord->isEmpty()){
2183
+ $imageRecord->set(array(
2184
+ 'attachment_id' => $attid,
2185
+ 'image_url' => $url,
2186
+ 'image_filename' => $image_name
2187
+ ))->insert();
2188
+ }
2189
+ else{
2190
+ // image already in image table, but was not founded, so updating it with new data
2191
+ switch ($this->options['search_existing_images_logic']){
2192
+ case 'by_url':
2193
+ // update image URL if it was not set
2194
+ if (empty($imageRecord->image_url)){
2195
+ $imageRecord->set(array(
2196
+ 'image_url' => $url
2197
+ ))->update();
2198
+ }
2199
+ break;
2200
+ default:
2201
+ // update image Filename if it was not set
2202
+ if (empty($imageRecord->image_filename)){
2203
+ $imageRecord->set(array(
2204
+ 'image_filename' => $image_name
2205
+ ))->update();
2206
+ }
2207
+ break;
2208
+ }
2209
+ }
2210
  }
 
 
 
 
 
 
 
 
2211
  }
2212
 
2213
  if ($attid && ! is_wp_error($attid))
2214
+ {
2215
  if ($attch != null && empty($attch->post_parent) && ! in_array($post_type[$i], array('taxonomies'))){
2216
  wp_update_post(
2217
  array(
2237
  switch ($post_type[$i]){
2238
  case 'taxonomies':
2239
  $post_thumbnail_id = get_term_meta( $pid, 'thumbnail_id', true );
2240
+ if ($bundle_data['type'] == 'images' and empty($post_thumbnail_id) and ($this->options[$option_slug . 'is_featured'] or !empty($is_image_featured[$i])) ) {
2241
  update_term_meta($pid, 'thumbnail_id', $attid);
2242
  }
2243
  elseif(!in_array($attid, $gallery_attachment_ids) and $post_thumbnail_id != $attid){
2247
  default:
2248
  $post_thumbnail_id = get_post_thumbnail_id( $pid );
2249
 
2250
+ if ($bundle_data['type'] == 'images' and empty($post_thumbnail_id) and ($this->options[$option_slug . 'is_featured'] or !empty($is_image_featured[$i])) ) {
2251
  set_post_thumbnail($pid, $attid);
2252
  }
2253
  elseif(!in_array($attid, $gallery_attachment_ids) and $post_thumbnail_id != $attid){
2256
  break;
2257
  }
2258
 
2259
+ if ($attch != null and empty($attch->post_parent)) {
2260
+ $logger and call_user_func($logger, sprintf(__('- Attachment with ID: `%s` has been successfully updated for image `%s`', 'wp_all_import_plugin'), $attid, ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename));
 
2261
  }
2262
+ elseif(empty($attch)) {
2263
+ $logger and call_user_func($logger, sprintf(__('- Attachment with ID: `%s` has been successfully created for image `%s`', 'wp_all_import_plugin'), $attid, ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename));
 
2264
  }
2265
  }
2266
  }
2315
 
2316
  foreach ($imgs as $img) {
2317
  do_action( $slug, $pid, false, $img, false);
2318
+ }
2319
  }
2320
  }
2321
  }
2330
  // [attachments]
2331
  $is_attachments_to_update = apply_filters('pmxi_is_attachments_to_update', true, $articleData, $current_xml_node);
2332
 
2333
+ $attachments_uploads = apply_filters('wp_all_import_attachments_uploads_dir', $uploads, $articleData, $current_xml_node, $this->id);
2334
 
2335
  if ( $is_attachments_to_update and ! empty($attachments_uploads) and false === $attachments_uploads['error'] and !empty($attachments[$i]) and (empty($articleData['ID']) or $this->options['update_all_data'] == "yes" or ($this->options['update_all_data'] == "no" and $this->options['is_update_attachments']))) {
2336
 
2367
  $attachment_filepath = $targetDir . '/' . sanitize_file_name($attachment_filename);
2368
 
2369
  if ($this->options['is_search_existing_attach']){
2370
+
2371
+ // search existing attachment
2372
+ $attch = wp_all_import_get_image_from_gallery($attachment_filename, $targetDir, 'files', $logger);
2373
+
2374
  if ( $attch != null ){
2375
  $download_file = false;
2376
  $attach_id = $attch->ID;
2447
  {
2448
  $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully created for file `%s`', 'wp_all_import_plugin'), ($handle_attachment) ? $handle_attachment['url'] : $targetUrl . '/' . $attachment_filename));
2449
  }
2450
+ $logger and call_user_func($logger, __('- <b>ACTION</b>: pmxi_attachment_uploaded', 'wp_all_import_plugin'));
2451
+ do_action( 'pmxi_attachment_uploaded', $pid, $attach_id, $attachment_filepath);
2452
+ }
2453
  }
2454
  }
2455
  }
2461
  $logger and call_user_func($logger, sprintf(__('Attachments import skipped for post `%s` according to \'pmxi_is_attachments_to_update\' filter...', 'wp_all_import_plugin'), $articleData['post_title']));
2462
  }
2463
  // [/attachments]
2464
+
2465
  // [custom taxonomies]
2466
  if ( ! empty($taxonomies) ){
2467
 
2503
  unset($existing_taxonomies[$tx_name][$i]);
2504
  }
2505
 
 
 
2506
  // create term if not exists
2507
  if ( ! empty($txes[$i]) ):
2508
  foreach ($txes[$i] as $key => $single_tax) {
2577
  }
2578
  }
2579
  }
2580
+ endif;
2581
+
2582
+ $assign_taxes = apply_filters('wp_all_import_set_post_terms', $assign_taxes, $tx_name, $pid, $this->id);
2583
 
2584
  // associate taxes with post
2585
+ $this->associate_terms($pid, ( empty($assign_taxes) ? false : $assign_taxes ), $tx_name, $logger, $is_cron, $articleData['post_status']);
2586
 
2587
  }
2588
  else
2598
  if ( PMXI_Admin_Addons::get_addon('PMWI_Plugin') and strpos($tx_name, "pa_") === 0 ) continue;
2599
 
2600
  if (!empty($txes[$i]))
2601
+ $this->associate_terms($pid, $txes[$i], $tx_name, $logger, $is_cron, $articleData['post_status']);
2602
  }
2603
  }
2604
  }
2618
  $_post = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID = %d LIMIT 1", $pid ) );
2619
  $_post = sanitize_post( $_post, 'raw' );
2620
  $post_object = new WP_Post( $_post );
2621
+ do_action( "save_post_" . $articleData['post_type'], $pid, $post_object, $is_update );
2622
  do_action( 'save_post', $pid, $post_object, $is_update );
2623
  do_action( 'wp_insert_post', $pid, $post_object, $is_update );
2624
  }
2667
  $logger and call_user_func($logger, __('<b>ACTION</b>: pmxi_after_post_import', 'wp_all_import_plugin'));
2668
  do_action('pmxi_after_post_import', $this->id);
2669
 
2670
+ $logger and !$is_cron and PMXI_Plugin::$session->chunk_number++;
 
2671
 
2672
+ //restore_error_handler();
2673
+ }
2674
 
2675
  $this->set(array(
2676
  'imported' => $created + $updated,
2691
  $is_import_complete = ($records_count == $records_to_import);
2692
 
2693
  // Set out of stock status for missing records [Woocommerce add-on option]
2694
+ if ( $is_import_complete and empty($this->options['is_delete_missing']) and $post_type[$i] == "product" and class_exists('PMWI_Plugin') and !empty($this->options['missing_records_stock_status']) and "manual" != $this->options['duplicate_matching']) {
2695
 
2696
  $logger and call_user_func($logger, __('Update stock status previously imported posts which are no longer actual...', 'wp_all_import_plugin'));
2697
  $args = array('import_id' => $this->id, 'iteration !=' => $this->iteration);
2702
  foreach ($missingPosts as $missingPost) {
2703
  update_post_meta( $missingPost['post_id'], '_stock_status', 'outofstock' );
2704
  update_post_meta( $missingPost['post_id'], '_stock', 0 );
2705
+
2706
+ $term_ids = wp_get_object_terms($missingPost['post_id'], 'product_visibility', array('fields' => 'ids'));
2707
+ $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' );
2708
+ if (!empty($outofstock_term) && !is_wp_error($outofstock_term) && !in_array($outofstock_term->term_taxonomy_id, $term_ids)){
2709
+ $term_ids[] = $outofstock_term->term_taxonomy_id;
2710
+ }
2711
+ $this->associate_terms( $missingPost['post_id'], $term_ids, 'product_visibility', $logger );
2712
+
2713
  $missingPostRecord = new PMXI_Post_Record();
2714
  $missingPostRecord->getBy('id', $missingPost['id']);
2715
  if ( ! $missingPostRecord->isEmpty())
2735
  return $this;
2736
  }
2737
 
2738
+ private function getRecordTitle($articleData){
 
2739
  switch ($this->options['custom_type']){
2740
  case 'import_users':
2741
  $title = $articleData['user_login'];
2742
  break;
2743
  default:
2744
+ $title = $articleData['post_title'];
2745
  break;
2746
  }
2747
  return $title;
2748
  }
2749
 
2750
+ public function downloadFile($url, $image_filepath, $is_cron = false, $logger, $type = 'images'){
2751
+
2752
+ $downloaded = false;
2753
+
2754
+ $image_info = false;
2755
+
2756
+ $logger and call_user_func($logger, sprintf(__('- Downloading image from `%s`', 'wp_all_import_plugin'), $url));
2757
+
2758
+ $request = get_file_curl($url, $image_filepath);
2759
+
2760
+ $get_ctx = stream_context_create(array('http' => array('timeout' => 5)));
2761
+
2762
+ if ( (is_wp_error($request) or $request === false) and ! @file_put_contents($image_filepath, @file_get_contents($url, false, $get_ctx))) {
2763
+ @unlink($image_filepath); // delete file since failed upload may result in empty file created
2764
+ } else{
2765
+
2766
+ if($type == 'images'){
2767
+ if( preg_match('%\W(svg)$%i', wp_all_import_basename($image_filepath)) or $image_info = apply_filters('pmxi_getimagesize', @getimagesize($image_filepath), $image_filepath) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
2768
+ $downloaded = true;
2769
+ $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url));
2770
+ }
2771
+ else
2772
+ {
2773
+ $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'wp_all_import_plugin'), $url));
2774
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
2775
+ }
2776
+ }
2777
+ elseif($type == 'files'){
2778
+ if( $wp_filetype = wp_check_filetype(wp_all_import_basename($image_filepath), null )) {
2779
+ $downloaded = true;
2780
+ $logger and call_user_func($logger, sprintf(__('- File `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url));
2781
+ }
2782
+ }
2783
+ }
2784
+
2785
+ return $downloaded ? $image_info : false;
2786
+ }
2787
+
2788
+ public function createAttachment($pid, $handle_image, $image_name, $post_author, $post_type, $is_cron, $logger, $type = 'images'){
2789
+
2790
+ $logger and call_user_func($logger, sprintf(__('- Creating an attachment for image `%s`', 'wp_all_import_plugin'), $handle_image['url']));
2791
+
2792
+ $attachment_title = explode(".", $image_name);
2793
+ if (is_array($attachment_title) and count($attachment_title) > 1) array_pop($attachment_title);
2794
+
2795
+ $attachment = array(
2796
+ 'post_mime_type' => $handle_image['type'],
2797
+ 'guid' => $handle_image['url'],
2798
+ 'post_title' => implode(".", $attachment_title),
2799
+ 'post_content' => '',
2800
+ 'post_author' => $post_author,
2801
+ );
2802
+ if ($type == 'images' and ($image_meta = wp_read_image_metadata($handle_image['file']))) {
2803
+ if (trim($image_meta['title']) && ! is_numeric(sanitize_title($image_meta['title'])))
2804
+ $attachment['post_title'] = $image_meta['title'];
2805
+ if (trim($image_meta['caption']))
2806
+ $attachment['post_content'] = $image_meta['caption'];
2807
+ }
2808
+
2809
+ remove_all_actions('add_attachment');
2810
+
2811
+ if ( in_array($post_type, array('taxonomies')) ){
2812
+ $attid = wp_insert_attachment($attachment, $handle_image['file'], 0);
2813
+ }
2814
+ else{
2815
+ $attid = wp_insert_attachment($attachment, $handle_image['file'], $pid);
2816
+ }
2817
+
2818
+ if (is_wp_error($attid)) {
2819
+ $logger and call_user_func($logger, __('- <b>WARNING</b>', 'wp_all_import_plugin') . ': ' . $attid->get_error_message());
2820
+ $logger and !$is_cron and PMXI_Plugin::$session->warnings++;
2821
+ } else {
2822
+ /**
2823
+ * Fires once an attachment has been added.
2824
+ */
2825
+ do_action( 'wp_all_import_add_attachment', $attid );
2826
+ wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $handle_image['file']));
2827
+ }
2828
+
2829
+ return ( $attid && ! is_wp_error($attid) ) ? $attid : false;
2830
+ }
2831
+
2832
  public function delete_source($logger = false)
2833
  {
2834
  if ($this->options['is_delete_source'])
2986
  switch ($this->options['custom_type']){
2987
  case 'import_users':
2988
  do_action('pmxi_delete_post', $ids, $this);
2989
+ // delete_user action
2990
+ foreach( $ids as $id) {
2991
+ do_action( 'delete_user', $id, $reassign = null );
2992
+ }
2993
  $sql = "delete a,b
2994
  FROM ".$this->wpdb->users." a
2995
  LEFT JOIN ".$this->wpdb->usermeta." b ON ( a.ID = b.user_id )
2996
  WHERE a.ID IN (" . implode(',', $ids) . ");";
2997
+ // deleted_user action
2998
+ foreach( $ids as $id) {
2999
+ do_action( 'deleted_user', $id, $reassign = null );
3000
+ }
3001
+
3002
  break;
3003
  case 'taxonomies':
3004
  do_action('pmxi_delete_taxonomy_term', $ids, $this);
3082
  {
3083
  $caps['unfiltered_html'] = true;
3084
  return $caps;
3085
+ }
3086
 
3087
  protected function recount_terms($pid, $post_type){
3088
 
3100
  }
3101
  }
3102
  }
3103
+
3104
+ protected function associate_terms( $pid, $assign_taxes, $tx_name, $logger, $is_cron = false, $post_status = 'publish' ) {
3105
+ $term_ids = wp_get_object_terms( $pid, $tx_name, array( 'fields' => 'ids' ) );
3106
+
3107
+ $assign_taxes = ( is_array( $assign_taxes ) ) ? array_filter( $assign_taxes ) : false;
3108
+
3109
+ if ( ! empty( $term_ids ) && ! is_wp_error( $term_ids ) ) {
3110
+ $in_tt_ids = "'" . implode( "', '", $term_ids ) . "'";
3111
+ $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count - 1 WHERE term_taxonomy_id IN ($in_tt_ids) AND count > 0" );
3112
+ $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $pid ) );
 
 
 
 
 
 
 
3113
  }
3114
 
3115
+ if ( empty( $assign_taxes ) ) return;
3116
 
3117
+ $values = array();
3118
+ $term_order = 0;
 
 
3119
 
3120
+ $term_ids = array();
3121
+ foreach ( $assign_taxes as $tt ) {
3122
+ do_action( 'wp_all_import_associate_term', $pid, $tt, $tx_name );
3123
+ $values[] = $this->wpdb->prepare( "(%d, %d, %d)", $pid, $tt, ++ $term_order );
3124
+ $term_ids[] = $tt;
3125
+ }
 
 
 
 
 
3126
 
3127
+ if ( 'draft' !== $post_status ) {
3128
+ $in_tt_ids = "'" . implode("', '", $term_ids) . "'";
3129
+ $this->wpdb->query("UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id IN ($in_tt_ids)");
3130
+ }
3131
+
3132
+ if ( $values ) {
3133
+ if ( false === $this->wpdb->query( "INSERT INTO {$this->wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)" ) ) {
3134
+ $logger and call_user_func( $logger, __( '<b>ERROR</b> Could not insert term relationship into the database', 'wp_all_import_plugin' ) . ': ' . $this->wpdb->last_error );
3135
+ }
3136
+ }
3137
 
3138
+ wp_cache_delete( $pid, $tx_name . '_relationships' );
3139
  }
3140
 
3141
  /**
3151
  if ( ! $keepPosts) {
3152
 
3153
  $missing_ids = array();
3154
+
3155
+ $sql = "SELECT post_id FROM " . PMXI_Plugin::getInstance()->getTablePrefix() . "posts WHERE import_id = %d";
3156
+ $missingPosts = $this->wpdb->get_results(
3157
+ $this->wpdb->prepare($sql, $this->id)
3158
+ );
3159
+
3160
+ if ( ! empty($missingPosts) ):
3161
 
3162
  foreach ($missingPosts as $missingPost) {
3163
 
3164
+ $missing_ids[] = $missingPost->post_id;
3165
 
3166
  }
3167
 
3225
  protected function deleteRecords( $is_delete_attachments, $is_deleted_images, $ids = array() )
3226
  {
3227
  foreach ( $ids as $k => $id ) {
3228
+
3229
+ if ( ! in_array($this->options['custom_type'], array('import_users', 'taxonomies')) ){
3230
+ // Remove attachments
3231
+ if ($is_delete_attachments == 'yes' or $is_delete_attachments == 'auto' and empty($this->options['is_keep_attachments']))
3232
+ {
3233
+ wp_delete_attachments($id, true, 'files');
3234
+ }
3235
+ else
3236
+ {
3237
+ wp_delete_attachments($id, false, 'files');
3238
+ }
3239
+ // Remove images
3240
+ if ($is_deleted_images == 'yes' or $is_deleted_images == 'auto' and empty($this->options['is_keep_imgs']))
3241
+ {
3242
+ wp_delete_attachments($id, true, 'images');
3243
+ }
3244
+ else
3245
+ {
3246
+ wp_delete_attachments($id, false, 'images');
3247
+ }
3248
+ }
3249
 
3250
+ if ( ! in_array($this->options['custom_type'], array('import_users', 'taxonomies')) ) wp_delete_object_term_relationships($id, get_object_taxonomies('' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post'));
3251
  }
3252
 
3253
+ switch ($this->options['custom_type']){
3254
+ case 'import_users':
3255
+ do_action('pmxi_delete_post', $ids, $this);
3256
+ // delete_user action
3257
+ foreach( $ids as $id) {
3258
+ do_action( 'delete_user', $id, $reassign = null );
3259
+ }
3260
+ $sql = "delete a,b
3261
+ FROM ".$this->wpdb->users." a
3262
+ LEFT JOIN ".$this->wpdb->usermeta." b ON ( a.ID = b.user_id )
3263
+ WHERE a.ID IN (".implode(',', $ids).");";
3264
+ // deleted_user action
3265
+ foreach( $ids as $id) {
3266
+ do_action( 'deleted_user', $id, $reassign = null );
3267
+ }
3268
+ break;
3269
+ case 'taxonomies':
3270
+ do_action('pmxi_delete_taxonomies', $ids);
3271
+ foreach ($ids as $term_id){
3272
+ wp_delete_term( $term_id, $this->options['taxonomy_type'] );
3273
+ }
3274
+ break;
3275
+ default:
3276
+ do_action('pmxi_delete_post', $ids, $this);
3277
+ $sql = "delete a,b,c
3278
+ FROM ".$this->wpdb->posts." a
3279
+ LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
3280
+ LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
3281
+ LEFT JOIN ".$this->wpdb->posts." d ON ( a.ID = d.post_parent )
3282
+ WHERE a.ID IN (".implode(',', $ids).");";
3283
+ break;
3284
+ }
3285
 
3286
  $this->wpdb->query(
3287
  $sql
3343
  }
3344
  return ($is_delete_import) ? parent::delete() : true;
3345
  }
3346
+
3347
+ public function canBeScheduled()
3348
+ {
3349
+ return in_array($this->type, array('url', 'ftp', 'file'));
3350
+ }
3351
 
3352
  }
plugin.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP All Import
4
  Plugin URI: http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=plugins-page&utm_campaign=free+plugin
5
  Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. A paid upgrade to WP All Import Pro is available for support and additional features.
6
- Version: 3.4.7
7
  Author: Soflyy
8
  */
9
 
@@ -25,7 +25,7 @@ define('WP_ALL_IMPORT_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
25
  */
26
  define('WP_ALL_IMPORT_PREFIX', 'pmxi_');
27
 
28
- define('PMXI_VERSION', '3.4.7');
29
 
30
  define('PMXI_EDITION', 'free');
31
 
@@ -139,6 +139,8 @@ final class PMXI_Plugin {
139
  * @var string
140
  */
141
  const HISTORY_DIRECTORY = WP_ALL_IMPORT_HISTORY_DIRECTORY;
 
 
142
 
143
  /**
144
  * Return singletone instance
@@ -278,21 +280,37 @@ final class PMXI_Plugin {
278
  $priority = 10;
279
  }
280
  add_filter($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
281
- }
282
-
283
- // register shortcodes handlers
284
- if (is_dir(self::ROOT_DIR . '/shortcodes')) foreach (PMXI_Helper::safe_glob(self::ROOT_DIR . '/shortcodes/*.php', PMXI_Helper::GLOB_RECURSE | PMXI_Helper::GLOB_PATH) as $filePath) {
285
- $tag = strtolower(str_replace('/', '_', preg_replace('%^' . preg_quote(self::ROOT_DIR . '/shortcodes/', '%') . '|\.php$%', '', $filePath)));
286
- add_shortcode($tag, array($this, 'shortcodeDispatcher'));
287
- }
288
 
289
  // register admin page pre-dispatcher
290
  add_action('admin_init', array($this, 'adminInit'));
291
  add_action('admin_init', array($this, 'fix_options'));
292
  add_action('init', array($this, 'init'));
 
 
293
 
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  public function init(){
297
  $this->load_plugin_textdomain();
298
  }
@@ -519,22 +537,7 @@ final class PMXI_Plugin {
519
  /**
520
  * pre-dispatching logic for admin page controllers
521
  */
522
- public function adminInit() {
523
-
524
- // create history folder
525
- $uploads = wp_upload_dir();
526
-
527
- $wpallimportDirs = array( WP_ALL_IMPORT_UPLOADS_BASE_DIRECTORY, self::LOGS_DIRECTORY, self::FILES_DIRECTORY, self::TEMP_DIRECTORY, self::UPLOADS_DIRECTORY, self::HISTORY_DIRECTORY);
528
-
529
- foreach ($wpallimportDirs as $destination) {
530
-
531
- $dir = $uploads['basedir'] . DIRECTORY_SEPARATOR . $destination;
532
-
533
- if ( !is_dir($dir)) wp_mkdir_p($dir);
534
-
535
- if ( ! @file_exists($dir . DIRECTORY_SEPARATOR . 'index.php') ) @touch( $dir . DIRECTORY_SEPARATOR . 'index.php' );
536
-
537
- }
538
 
539
  self::$session = new PMXI_Handler();
540
 
@@ -569,7 +572,7 @@ final class PMXI_Plugin {
569
  'is_user' => is_user_admin(),
570
  );
571
  add_filter('current_screen', array($this, 'getAdminCurrentScreen'));
572
- add_filter('admin_body_class', create_function('', 'return "' . 'wpallimport-plugin";'));
573
 
574
  $controller = new $controllerName();
575
  if ( ! $controller instanceof PMXI_Controller_Admin) {
@@ -593,9 +596,11 @@ final class PMXI_Plugin {
593
  } else { // redirect to dashboard if requested page and/or action don't exist
594
  wp_redirect(admin_url()); die();
595
  }
596
-
597
  }
 
598
 
 
 
599
  }
600
 
601
  /**
@@ -726,7 +731,15 @@ final class PMXI_Plugin {
726
  */
727
  public function activation() {
728
  // uncaught exception doesn't prevent plugin from being activated, therefore replace it with fatal error so it does
729
- set_exception_handler(create_function('$e', 'trigger_error($e->getMessage(), E_USER_ERROR);'));
 
 
 
 
 
 
 
 
730
 
731
  // create plugin options
732
  $option_name = get_class($this) . '_Options';
@@ -845,6 +858,40 @@ final class PMXI_Plugin {
845
  }
846
  }
847
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
848
  $table = $this->getTablePrefix() . 'imports';
849
 
850
  $tablefields = $wpdb->get_results("DESCRIBE {$table};");
@@ -938,7 +985,10 @@ final class PMXI_Plugin {
938
  }
939
 
940
  $wpdb->query("ALTER TABLE {$table} ADD `iteration` BIGINT(20) NOT NULL DEFAULT 0;");
941
-
 
 
 
942
  }
943
 
944
  if (!$specified and !empty($grands))
@@ -1104,6 +1154,7 @@ final class PMXI_Plugin {
1104
  'gallery_featured_image' => '',
1105
  'gallery_featured_delim' => ',',
1106
  'is_featured' => 1,
 
1107
  'set_image_meta_title' => 0,
1108
  'set_image_meta_caption' => 0,
1109
  'set_image_meta_alt' => 0,
@@ -1134,7 +1185,9 @@ final class PMXI_Plugin {
1134
  'is_tax_hierarchical_group_delim' => array(),
1135
  'tax_hierarchical_group_delim' => array(),
1136
  'nested_files' => array(),
1137
- 'xml_reader_engine' => 0
 
 
1138
  );
1139
  }
1140
 
3
  Plugin Name: WP All Import
4
  Plugin URI: http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=plugins-page&utm_campaign=free+plugin
5
  Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. A paid upgrade to WP All Import Pro is available for support and additional features.
6
+ Version: 3.4.8
7
  Author: Soflyy
8
  */
9
 
25
  */
26
  define('WP_ALL_IMPORT_PREFIX', 'pmxi_');
27
 
28
+ define('PMXI_VERSION', '3.4.8');
29
 
30
  define('PMXI_EDITION', 'free');
31
 
139
  * @var string
140
  */
141
  const HISTORY_DIRECTORY = WP_ALL_IMPORT_HISTORY_DIRECTORY;
142
+
143
+ const LANGUAGE_DOMAIN = 'wp_all_import_plugin';
144
 
145
  /**
146
  * Return singletone instance
280
  $priority = 10;
281
  }
282
  add_filter($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
283
+ }
 
 
 
 
 
 
284
 
285
  // register admin page pre-dispatcher
286
  add_action('admin_init', array($this, 'adminInit'));
287
  add_action('admin_init', array($this, 'fix_options'));
288
  add_action('init', array($this, 'init'));
289
+
290
+ add_action( 'plugins_loaded', array( $this, 'setup_allimport_dir' ) );
291
 
292
  }
293
 
294
+ /**
295
+ * Setup required directory.
296
+ */
297
+ public function setup_allimport_dir() {
298
+ // create history folder
299
+ $uploads = wp_upload_dir();
300
+
301
+ $wpallimportDirs = array( WP_ALL_IMPORT_UPLOADS_BASE_DIRECTORY, self::LOGS_DIRECTORY, self::FILES_DIRECTORY, self::TEMP_DIRECTORY, self::UPLOADS_DIRECTORY, self::HISTORY_DIRECTORY);
302
+
303
+ foreach ($wpallimportDirs as $destination) {
304
+
305
+ $dir = $uploads['basedir'] . DIRECTORY_SEPARATOR . $destination;
306
+
307
+ if ( !is_dir($dir)) wp_mkdir_p($dir);
308
+
309
+ if ( ! @file_exists($dir . DIRECTORY_SEPARATOR . 'index.php') ) @touch( $dir . DIRECTORY_SEPARATOR . 'index.php' );
310
+
311
+ }
312
+ }
313
+
314
  public function init(){
315
  $this->load_plugin_textdomain();
316
  }
537
  /**
538
  * pre-dispatching logic for admin page controllers
539
  */
540
+ public function adminInit() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
 
542
  self::$session = new PMXI_Handler();
543
 
572
  'is_user' => is_user_admin(),
573
  );
574
  add_filter('current_screen', array($this, 'getAdminCurrentScreen'));
575
+ add_filter('admin_body_class', array($this, 'getAdminBodyClass'), 10, 1);
576
 
577
  $controller = new $controllerName();
578
  if ( ! $controller instanceof PMXI_Controller_Admin) {
596
  } else { // redirect to dashboard if requested page and/or action don't exist
597
  wp_redirect(admin_url()); die();
598
  }
 
599
  }
600
+ }
601
 
602
+ public function getAdminBodyClass($class){
603
+ return $class . ' wpallimport-plugin';
604
  }
605
 
606
  /**
731
  */
732
  public function activation() {
733
  // uncaught exception doesn't prevent plugin from being activated, therefore replace it with fatal error so it does
734
+ if (version_compare(phpversion(), '7.2' , "<")){
735
+ $exception_handler = create_function('$e', 'trigger_error($e->getMessage(), E_USER_ERROR);');
736
+ }
737
+ else{
738
+ $exception_handler = function($e){
739
+ trigger_error($e->getMessage(), E_USER_ERROR);
740
+ };
741
+ }
742
+ set_exception_handler($exception_handler);
743
 
744
  // create plugin options
745
  $option_name = get_class($this) . '_Options';
858
  }
859
  }
860
 
861
+ // alter images table
862
+ $table = $this->getTablePrefix() . 'images';
863
+ $tablefields = $wpdb->get_results("DESCRIBE {$table};");
864
+ $fields_to_alter = array(
865
+ 'image_url',
866
+ 'image_filename'
867
+ );
868
+
869
+ // Check if field exists
870
+ foreach ($tablefields as $tablefield) {
871
+ if (in_array($tablefield->Field, $fields_to_alter)){
872
+ $fields_to_alter = array_diff($fields_to_alter, array($tablefield->Field));
873
+ }
874
+ }
875
+
876
+ if ( ! empty($fields_to_alter) ){
877
+
878
+ if (empty($grands)) return false;
879
+
880
+ foreach ($fields_to_alter as $field) {
881
+ switch ($field) {
882
+ case 'image_url':
883
+ $wpdb->query("ALTER TABLE {$table} ADD `image_url` VARCHAR(600) NOT NULL DEFAULT '';");
884
+ break;
885
+ case 'image_filename':
886
+ $wpdb->query("ALTER TABLE {$table} ADD `image_filename` VARCHAR(600) NOT NULL DEFAULT '';");
887
+ break;
888
+ default:
889
+ # code...
890
+ break;
891
+ }
892
+ }
893
+ }
894
+
895
  $table = $this->getTablePrefix() . 'imports';
896
 
897
  $tablefields = $wpdb->get_results("DESCRIBE {$table};");
985
  }
986
 
987
  $wpdb->query("ALTER TABLE {$table} ADD `iteration` BIGINT(20) NOT NULL DEFAULT 0;");
988
+
989
+ // Add indexing to pmxi_posts.post_id and pmxi_posts.import_id fields.
990
+ $wpdb->query("ALTER TABLE {$table} ADD INDEX `post_id`(`post_id`);");
991
+ $wpdb->query("ALTER TABLE {$table} ADD INDEX `import_id`(`import_id`)");
992
  }
993
 
994
  if (!$specified and !empty($grands))
1154
  'gallery_featured_image' => '',
1155
  'gallery_featured_delim' => ',',
1156
  'is_featured' => 1,
1157
+ 'is_featured_xpath' => '',
1158
  'set_image_meta_title' => 0,
1159
  'set_image_meta_caption' => 0,
1160
  'set_image_meta_alt' => 0,
1185
  'is_tax_hierarchical_group_delim' => array(),
1186
  'tax_hierarchical_group_delim' => array(),
1187
  'nested_files' => array(),
1188
+ 'xml_reader_engine' => 0,
1189
+ 'import_img_tags' => 0,
1190
+ 'search_existing_images_logic' => 'by_url'
1191
  );
1192
  }
1193
 
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Import any XML or CSV File to WordPress ===
2
  Contributors: soflyy, wpallimport
3
  Requires at least: 4.1
4
- Tested up to: 4.9.4
5
- Stable tag: 3.4.7
6
  Tags: wordpress csv import, wordpress xml import, xml, csv, datafeed, import, migrate, import csv to wordpress, import xml to wordpress, advanced xml import, advanced csv import, bulk csv import, bulk xml import, bulk data import, xml to custom post type, csv to custom post type, woocommerce csv import, woocommerce xml import, csv import, import csv, xml import, import xml, csv importer
7
 
8
  WP All Import is an extremely powerful importer that makes it easy to import any XML or CSV file to WordPress.
@@ -105,6 +105,13 @@ Does it work with special character encoding like Hebrew, Arabic, Chinese, etc?
105
 
106
  == Changelog ==
107
 
 
 
 
 
 
 
 
108
  = 3.4.7 =
109
  * improvement: skip to the first specified record when importing only part of a file
110
  * new filter: wp_all_import_is_render_whole_xml_tree
1
  === Import any XML or CSV File to WordPress ===
2
  Contributors: soflyy, wpallimport
3
  Requires at least: 4.1
4
+ Tested up to: 4.9.6
5
+ Stable tag: 3.4.8
6
  Tags: wordpress csv import, wordpress xml import, xml, csv, datafeed, import, migrate, import csv to wordpress, import xml to wordpress, advanced xml import, advanced csv import, bulk csv import, bulk xml import, bulk data import, xml to custom post type, csv to custom post type, woocommerce csv import, woocommerce xml import, csv import, import csv, xml import, import xml, csv importer
7
 
8
  WP All Import is an extremely powerful importer that makes it easy to import any XML or CSV file to WordPress.
105
 
106
  == Changelog ==
107
 
108
+ = 3.4.8 =
109
+ * improvement: various import speed optimizations
110
+ * bug fix: remove deprecated function calls for PHP 7.2 compatibility
111
+ * bug fix: delete db tables when mu blog deleted
112
+ * bug fix: remove BOM from import templates
113
+ * bug fix: saving CSV delimiter when changing import file
114
+
115
  = 3.4.7 =
116
  * improvement: skip to the first specified record when importing only part of a file
117
  * new filter: wp_all_import_is_render_whole_xml_tree
schema.php CHANGED
@@ -80,7 +80,9 @@ CREATE TABLE {$table_prefix}posts (
80
  product_key TEXT,
81
  iteration BIGINT(20) NOT NULL DEFAULT 0,
82
  specified BOOL NOT NULL DEFAULT 0,
83
- PRIMARY KEY (id)
 
 
84
  ) $charset_collate;
85
  CREATE TABLE {$table_prefix}files (
86
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -90,6 +92,13 @@ CREATE TABLE {$table_prefix}files (
90
  registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
91
  PRIMARY KEY (id)
92
  ) $charset_collate;
 
 
 
 
 
 
 
93
  CREATE TABLE {$table_prefix}history (
94
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
95
  import_id BIGINT(20) UNSIGNED NOT NULL,
80
  product_key TEXT,
81
  iteration BIGINT(20) NOT NULL DEFAULT 0,
82
  specified BOOL NOT NULL DEFAULT 0,
83
+ PRIMARY KEY (id),
84
+ KEY import_id (import_id),
85
+ KEY post_id (post_id)
86
  ) $charset_collate;
87
  CREATE TABLE {$table_prefix}files (
88
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
92
  registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
93
  PRIMARY KEY (id)
94
  ) $charset_collate;
95
+ CREATE TABLE {$table_prefix}images (
96
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
97
+ attachment_id BIGINT(20) UNSIGNED NOT NULL,
98
+ image_url VARCHAR(600) NOT NULL DEFAULT '',
99
+ image_filename VARCHAR(600) NOT NULL DEFAULT '',
100
+ PRIMARY KEY (id)
101
+ ) $charset_collate;
102
  CREATE TABLE {$table_prefix}history (
103
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
104
  import_id BIGINT(20) UNSIGNED NOT NULL,
static/css/admin.css CHANGED
@@ -26,6 +26,7 @@
26
  margin-left: 5px;
27
  position: relative;
28
  top: 4px;
 
29
  }
30
  .wpallimport-plugin input.datepicker {
31
  width: 8em;
@@ -1454,7 +1455,7 @@ p.upgrade_link {
1454
  .wpallimport-plugin #custom_type_selector .dd-option .dashicon-cpt:before,
1455
  .wpallimport-plugin #custom_type_selector .dd-selected .dashicon-cpt:before{
1456
  font-family: "dashicons";
1457
- content: "\f333";
1458
  color: #555;
1459
  }
1460
  .wpallimport-plugin #custom_type_selector .dd-option .dashicon-import_users:before,
@@ -3073,7 +3074,12 @@ p.upgrade_link {
3073
  width: 220px;
3074
  }
3075
  .wpallimport-plugin .pmxi-admin-imports .column-info{
3076
- width: 110px;
 
 
 
 
 
3077
  }
3078
  /*--------------------------------------------------------------------------
3079
  *
26
  margin-left: 5px;
27
  position: relative;
28
  top: 4px;
29
+ background-size: cover;
30
  }
31
  .wpallimport-plugin input.datepicker {
32
  width: 8em;
1455
  .wpallimport-plugin #custom_type_selector .dd-option .dashicon-cpt:before,
1456
  .wpallimport-plugin #custom_type_selector .dd-selected .dashicon-cpt:before{
1457
  font-family: "dashicons";
1458
+ content: "\f111";
1459
  color: #555;
1460
  }
1461
  .wpallimport-plugin #custom_type_selector .dd-option .dashicon-import_users:before,
3074
  width: 220px;
3075
  }
3076
  .wpallimport-plugin .pmxi-admin-imports .column-info{
3077
+ width: 150px;
3078
+ }
3079
+ .wpallimport-plugin .scheduling-disabled {
3080
+ color: #555;
3081
+ text-decoration: none;
3082
+ cursor: default;
3083
  }
3084
  /*--------------------------------------------------------------------------
3085
  *
static/img/help.png CHANGED
Binary file
static/js/admin.js CHANGED
@@ -958,25 +958,35 @@
958
  }
959
 
960
  $form.find('input[name$=download_images]:checked').each(function(){
961
- if ($(this).val() == 'gallery')
962
- {
963
  $(this).parents('table:first').find('.search_through_the_media_library').slideUp();
964
  }
965
- else
966
- {
967
  $(this).parents('table:first').find('.search_through_the_media_library').slideDown();
968
  }
 
 
 
 
 
 
 
969
  });
970
 
971
  $form.find('input[name$=download_images]').click(function(){
972
- if ($(this).is(':checked') && $(this).val() == 'gallery')
973
- {
974
  $(this).parents('table:first').find('.search_through_the_media_library').slideUp();
975
  }
976
- else
977
- {
978
  $(this).parents('table:first').find('.search_through_the_media_library').slideDown();
979
  }
 
 
 
 
 
 
 
980
  });
981
 
982
  $form.find('.wpallimport-dismiss-cf-welcome').click(function(){
@@ -1854,9 +1864,9 @@
1854
 
1855
  });
1856
 
1857
- $('.wpallimport-collapsed').find('.wpallimport-collapsed-header').click(function(){
1858
  var $parent = $(this).parents('.wpallimport-collapsed:first');
1859
- if ($parent.hasClass('closed')){
1860
  $parent.removeClass('closed');
1861
  $parent.find('.wpallimport-collapsed-content:first').slideDown(400, function(){
1862
  if ($('#wp_all_import_code').length) editor.setCursor(1);
@@ -1866,7 +1876,7 @@
1866
  $parent.addClass('closed');
1867
  $parent.find('.wpallimport-collapsed-content:first').slideUp();
1868
  }
1869
- });
1870
 
1871
  $('#is_delete_posts').change(function(){
1872
  if ($(this).is(':checked')){
958
  }
959
 
960
  $form.find('input[name$=download_images]:checked').each(function(){
961
+ if ($(this).val() == 'gallery') {
 
962
  $(this).parents('table:first').find('.search_through_the_media_library').slideUp();
963
  }
964
+ else {
 
965
  $(this).parents('table:first').find('.search_through_the_media_library').slideDown();
966
  }
967
+ // download images hosted elsewhere
968
+ if ($(this).val() == 'yes'){
969
+ $('.search_through_the_media_library_logic').show();
970
+ }
971
+ else{
972
+ $('.search_through_the_media_library_logic').hide();
973
+ }
974
  });
975
 
976
  $form.find('input[name$=download_images]').click(function(){
977
+ if ($(this).is(':checked') && $(this).val() == 'gallery') {
 
978
  $(this).parents('table:first').find('.search_through_the_media_library').slideUp();
979
  }
980
+ else {
 
981
  $(this).parents('table:first').find('.search_through_the_media_library').slideDown();
982
  }
983
+ // download images hosted elsewhere
984
+ if ($(this).val() == 'yes'){
985
+ $('.search_through_the_media_library_logic').slideDown();
986
+ }
987
+ else{
988
+ $('.search_through_the_media_library_logic').slideUp();
989
+ }
990
  });
991
 
992
  $form.find('.wpallimport-dismiss-cf-welcome').click(function(){
1864
 
1865
  });
1866
 
1867
+ $('.wpallimport-collapsed').find('.wpallimport-collapsed-header').not('.disabled').click(function(){
1868
  var $parent = $(this).parents('.wpallimport-collapsed:first');
1869
+ if ($parent.hasClass('closed')){
1870
  $parent.removeClass('closed');
1871
  $parent.find('.wpallimport-collapsed-content:first').slideDown(400, function(){
1872
  if ($('#wp_all_import_code').length) editor.setCursor(1);
1876
  $parent.addClass('closed');
1877
  $parent.find('.wpallimport-collapsed-content:first').slideUp();
1878
  }
1879
+ });
1880
 
1881
  $('#is_delete_posts').change(function(){
1882
  if ($(this).is(':checked')){
static/js/jquery/chosen.jquery.js ADDED
@@ -0,0 +1,1269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.4.2
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011-2015 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ (function() {
14
+ var $, AbstractChosen, Chosen, SelectParser, _ref,
15
+ __hasProp = {}.hasOwnProperty,
16
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17
+
18
+ SelectParser = (function() {
19
+ function SelectParser() {
20
+ this.options_index = 0;
21
+ this.parsed = [];
22
+ }
23
+
24
+ SelectParser.prototype.add_node = function(child) {
25
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
+ return this.add_group(child);
27
+ } else {
28
+ return this.add_option(child);
29
+ }
30
+ };
31
+
32
+ SelectParser.prototype.add_group = function(group) {
33
+ var group_position, option, _i, _len, _ref, _results;
34
+ group_position = this.parsed.length;
35
+ this.parsed.push({
36
+ array_index: group_position,
37
+ group: true,
38
+ label: this.escapeExpression(group.label),
39
+ title: group.title ? group.title : void 0,
40
+ children: 0,
41
+ disabled: group.disabled,
42
+ classes: group.className
43
+ });
44
+ _ref = group.childNodes;
45
+ _results = [];
46
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
47
+ option = _ref[_i];
48
+ _results.push(this.add_option(option, group_position, group.disabled));
49
+ }
50
+ return _results;
51
+ };
52
+
53
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
54
+ if (option.nodeName.toUpperCase() === "OPTION") {
55
+ if (option.text !== "") {
56
+ if (group_position != null) {
57
+ this.parsed[group_position].children += 1;
58
+ }
59
+ this.parsed.push({
60
+ array_index: this.parsed.length,
61
+ options_index: this.options_index,
62
+ value: option.value,
63
+ text: option.text,
64
+ html: option.innerHTML,
65
+ title: option.title ? option.title : void 0,
66
+ selected: option.selected,
67
+ disabled: group_disabled === true ? group_disabled : option.disabled,
68
+ group_array_index: group_position,
69
+ group_label: group_position != null ? this.parsed[group_position].label : null,
70
+ classes: option.className,
71
+ style: option.style.cssText,
72
+ keywords: ($(option).data().keywords!==undefined
73
+ ? $(option).data().keywords.split(',')
74
+ : false)
75
+ });
76
+ } else {
77
+ this.parsed.push({
78
+ array_index: this.parsed.length,
79
+ options_index: this.options_index,
80
+ empty: true
81
+ });
82
+ }
83
+ return this.options_index += 1;
84
+ }
85
+ };
86
+
87
+ SelectParser.prototype.escapeExpression = function(text) {
88
+ var map, unsafe_chars;
89
+ if ((text == null) || text === false) {
90
+ return "";
91
+ }
92
+ if (!/[\&\<\>\"\'\`]/.test(text)) {
93
+ return text;
94
+ }
95
+ map = {
96
+ "<": "&lt;",
97
+ ">": "&gt;",
98
+ '"': "&quot;",
99
+ "'": "&#x27;",
100
+ "`": "&#x60;"
101
+ };
102
+ unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
103
+ return text.replace(unsafe_chars, function(chr) {
104
+ return map[chr] || "&amp;";
105
+ });
106
+ };
107
+
108
+ return SelectParser;
109
+
110
+ })();
111
+
112
+ SelectParser.select_to_array = function(select) {
113
+ var child, parser, _i, _len, _ref;
114
+ parser = new SelectParser();
115
+ _ref = select.childNodes;
116
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
117
+ child = _ref[_i];
118
+ parser.add_node(child);
119
+ }
120
+ return parser.parsed;
121
+ };
122
+
123
+ AbstractChosen = (function() {
124
+ function AbstractChosen(form_field, options) {
125
+ this.form_field = form_field;
126
+ this.options = options != null ? options : {};
127
+ if (!AbstractChosen.browser_is_supported()) {
128
+ return;
129
+ }
130
+ this.is_multiple = this.form_field.multiple;
131
+ this.set_default_text();
132
+ this.set_default_values();
133
+ this.setup();
134
+ this.set_up_html();
135
+ this.register_observers();
136
+ this.on_ready();
137
+ }
138
+
139
+ AbstractChosen.prototype.set_default_values = function() {
140
+ var _this = this;
141
+ this.click_test_action = function(evt) {
142
+ return _this.test_active_click(evt);
143
+ };
144
+ this.activate_action = function(evt) {
145
+ return _this.activate_field(evt);
146
+ };
147
+ this.active_field = false;
148
+ this.mouse_on_container = false;
149
+ this.results_showing = false;
150
+ this.result_highlighted = null;
151
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
152
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
153
+ this.disable_search = this.options.disable_search || false;
154
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
155
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
156
+ this.search_contains = this.options.search_contains || false;
157
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
158
+ this.max_selected_options = this.options.max_selected_options || Infinity;
159
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
160
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
161
+ this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
162
+ return this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
163
+ };
164
+
165
+ AbstractChosen.prototype.set_default_text = function() {
166
+ if (this.form_field.getAttribute("data-placeholder")) {
167
+ this.default_text = this.form_field.getAttribute("data-placeholder");
168
+ } else if (this.is_multiple) {
169
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
170
+ } else {
171
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
172
+ }
173
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
174
+ };
175
+
176
+ AbstractChosen.prototype.choice_label = function(item) {
177
+ if (this.include_group_label_in_selected && (item.group_label != null)) {
178
+ return "<b class='group-name'>" + item.group_label + "</b>" + item.html;
179
+ } else {
180
+ return item.html;
181
+ }
182
+ };
183
+
184
+ AbstractChosen.prototype.mouse_enter = function() {
185
+ return this.mouse_on_container = true;
186
+ };
187
+
188
+ AbstractChosen.prototype.mouse_leave = function() {
189
+ return this.mouse_on_container = false;
190
+ };
191
+
192
+ AbstractChosen.prototype.input_focus = function(evt) {
193
+ var _this = this;
194
+ if (this.is_multiple) {
195
+ if (!this.active_field) {
196
+ return setTimeout((function() {
197
+ return _this.container_mousedown();
198
+ }), 50);
199
+ }
200
+ } else {
201
+ if (!this.active_field) {
202
+ return this.activate_field();
203
+ }
204
+ }
205
+ };
206
+
207
+ AbstractChosen.prototype.input_blur = function(evt) {
208
+ var _this = this;
209
+ if (!this.mouse_on_container) {
210
+ this.active_field = false;
211
+ return setTimeout((function() {
212
+ return _this.blur_test();
213
+ }), 100);
214
+ }
215
+ };
216
+
217
+ AbstractChosen.prototype.results_option_build = function(options) {
218
+ var content, data, _i, _len, _ref;
219
+ content = '';
220
+ _ref = this.results_data;
221
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
222
+ data = _ref[_i];
223
+ if (data.group) {
224
+ content += this.result_add_group(data);
225
+ } else {
226
+ content += this.result_add_option(data);
227
+ }
228
+ if (options != null ? options.first : void 0) {
229
+ if (data.selected && this.is_multiple) {
230
+ this.choice_build(data);
231
+ } else if (data.selected && !this.is_multiple) {
232
+ this.single_set_selected_text(this.choice_label(data));
233
+ }
234
+ }
235
+ }
236
+ return content;
237
+ };
238
+
239
+ AbstractChosen.prototype.result_add_option = function(option) {
240
+ var classes, option_el;
241
+ if (!option.search_match) {
242
+ return '';
243
+ }
244
+ if (!this.include_option_in_results(option)) {
245
+ return '';
246
+ }
247
+ classes = [];
248
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
249
+ classes.push("active-result");
250
+ }
251
+ if (option.disabled && !(option.selected && this.is_multiple)) {
252
+ classes.push("disabled-result");
253
+ }
254
+ if (option.selected) {
255
+ classes.push("result-selected");
256
+ }
257
+ if (option.group_array_index != null) {
258
+ classes.push("group-option");
259
+ }
260
+ if (option.classes !== "") {
261
+ classes.push(option.classes);
262
+ }
263
+ option_el = document.createElement("li");
264
+ option_el.className = classes.join(" ");
265
+ option_el.style.cssText = option.style;
266
+ option_el.setAttribute("data-option-array-index", option.array_index);
267
+ option_el.innerHTML = option.search_text;
268
+ if (option.title) {
269
+ option_el.title = option.title;
270
+ }
271
+ return this.outerHTML(option_el);
272
+ };
273
+
274
+ AbstractChosen.prototype.result_add_group = function(group) {
275
+ var classes, group_el;
276
+ if (!(group.search_match || group.group_match)) {
277
+ return '';
278
+ }
279
+ if (!(group.active_options > 0)) {
280
+ return '';
281
+ }
282
+ classes = [];
283
+ classes.push("group-result");
284
+ if (group.classes) {
285
+ classes.push(group.classes);
286
+ }
287
+ group_el = document.createElement("li");
288
+ group_el.className = classes.join(" ");
289
+ group_el.innerHTML = group.search_text;
290
+ if (group.title) {
291
+ group_el.title = group.title;
292
+ }
293
+ return this.outerHTML(group_el);
294
+ };
295
+
296
+ AbstractChosen.prototype.results_update_field = function() {
297
+ this.set_default_text();
298
+ if (!this.is_multiple) {
299
+ this.results_reset_cleanup();
300
+ }
301
+ this.result_clear_highlight();
302
+ this.results_build();
303
+ if (this.results_showing) {
304
+ return this.winnow_results();
305
+ }
306
+ };
307
+
308
+ AbstractChosen.prototype.reset_single_select_options = function() {
309
+ var result, _i, _len, _ref, _results;
310
+ _ref = this.results_data;
311
+ _results = [];
312
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
313
+ result = _ref[_i];
314
+ if (result.selected) {
315
+ _results.push(result.selected = false);
316
+ } else {
317
+ _results.push(void 0);
318
+ }
319
+ }
320
+ return _results;
321
+ };
322
+
323
+ AbstractChosen.prototype.results_toggle = function() {
324
+ if (this.results_showing) {
325
+ return this.results_hide();
326
+ } else {
327
+ return this.results_show();
328
+ }
329
+ };
330
+
331
+ AbstractChosen.prototype.results_search = function(evt) {
332
+ if (this.results_showing) {
333
+ return this.winnow_results();
334
+ } else {
335
+ return this.results_show();
336
+ }
337
+ };
338
+
339
+ AbstractChosen.prototype.winnow_results = function() {
340
+ var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, keywordMatch, _i, _len, _ref;
341
+ this.no_results_clear();
342
+ results = 0;
343
+ searchText = this.get_search_text();
344
+ escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
345
+ zregex = new RegExp(escapedSearchText, 'i');
346
+ regex = this.get_search_regex(escapedSearchText);
347
+ _ref = this.results_data;
348
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
349
+ option = _ref[_i];
350
+ option.search_match = false;
351
+ results_group = null;
352
+ if (this.include_option_in_results(option)) {
353
+ if (option.group) {
354
+ option.group_match = false;
355
+ option.active_options = 0;
356
+ }
357
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
358
+ results_group = this.results_data[option.group_array_index];
359
+ if (results_group.active_options === 0 && results_group.search_match) {
360
+ results += 1;
361
+ }
362
+ results_group.active_options += 1;
363
+ }
364
+ option.search_text = option.group ? option.label : option.html;
365
+ if (!(option.group && !this.group_search)) {
366
+ option.search_match = this.search_string_match(option.search_text, regex);
367
+ keywordMatch=(option.keywords && option.keywords.indexOf(searchText) > -1);
368
+ if(keywordMatch)
369
+ option.search_match=true;
370
+ if (option.search_match && !option.group) {
371
+ results += 1;
372
+ }
373
+ if (option.search_match) {
374
+ if (searchText.length) {
375
+ startpos = option.search_text.search(zregex);
376
+ text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
377
+ option.search_text = keywordMatch ? text : (text.substr(0, startpos) + '<em>' + text.substr(startpos));
378
+ }
379
+ if (results_group != null) {
380
+ results_group.group_match = true;
381
+ }
382
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
383
+ option.search_match = true;
384
+ }
385
+ }
386
+ }
387
+ }
388
+ this.result_clear_highlight();
389
+ if (results < 1 && searchText.length) {
390
+ this.update_results_content("");
391
+ return this.no_results(searchText);
392
+ } else {
393
+ this.update_results_content(this.results_option_build());
394
+ return this.winnow_results_set_highlight();
395
+ }
396
+ };
397
+
398
+ AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
399
+ var regex_anchor;
400
+ regex_anchor = this.search_contains ? "" : "^";
401
+ return new RegExp(regex_anchor + escaped_search_string, 'i');
402
+ };
403
+
404
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
405
+ var part, parts, _i, _len;
406
+ if (regex.test(search_string)) {
407
+ return true;
408
+ } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
409
+ parts = search_string.replace(/\[|\]/g, "").split(" ");
410
+ if (parts.length) {
411
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
412
+ part = parts[_i];
413
+ if (regex.test(part)) {
414
+ return true;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ };
420
+
421
+ AbstractChosen.prototype.choices_count = function() {
422
+ var option, _i, _len, _ref;
423
+ if (this.selected_option_count != null) {
424
+ return this.selected_option_count;
425
+ }
426
+ this.selected_option_count = 0;
427
+ _ref = this.form_field.options;
428
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
429
+ option = _ref[_i];
430
+ if (option.selected) {
431
+ this.selected_option_count += 1;
432
+ }
433
+ }
434
+ return this.selected_option_count;
435
+ };
436
+
437
+ AbstractChosen.prototype.choices_click = function(evt) {
438
+ evt.preventDefault();
439
+ if (!(this.results_showing || this.is_disabled)) {
440
+ return this.results_show();
441
+ }
442
+ };
443
+
444
+ AbstractChosen.prototype.keyup_checker = function(evt) {
445
+ var stroke, _ref;
446
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
447
+ this.search_field_scale();
448
+ switch (stroke) {
449
+ case 8:
450
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
451
+ return this.keydown_backstroke();
452
+ } else if (!this.pending_backstroke) {
453
+ this.result_clear_highlight();
454
+ return this.results_search();
455
+ }
456
+ break;
457
+ case 13:
458
+ evt.preventDefault();
459
+ if (this.results_showing) {
460
+ if (!this.is_multiple || this.result_highlight) {
461
+ return this.result_select(evt);
462
+ }
463
+ $(this.form_field).append('<option>' + $(evt.target).val() + '</option>');
464
+ $(this.form_field).trigger('chosen:updated');
465
+ this.result_highlight = this.search_results.find('li.active-result').last();
466
+ return this.result_select(evt);
467
+ }
468
+ break;
469
+ case 27:
470
+ if (this.results_showing) {
471
+ this.results_hide();
472
+ }
473
+ return true;
474
+ case 9:
475
+ case 38:
476
+ case 40:
477
+ case 16:
478
+ case 91:
479
+ case 17:
480
+ break;
481
+ default:
482
+ return this.results_search();
483
+ }
484
+ };
485
+
486
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
487
+ var _this = this;
488
+ return setTimeout((function() {
489
+ return _this.results_search();
490
+ }), 50);
491
+ };
492
+
493
+ AbstractChosen.prototype.container_width = function() {
494
+ if (this.options.width != null) {
495
+ return this.options.width;
496
+ } else {
497
+ return "" + this.form_field.offsetWidth + "px";
498
+ }
499
+ };
500
+
501
+ AbstractChosen.prototype.include_option_in_results = function(option) {
502
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
503
+ return false;
504
+ }
505
+ if (!this.display_disabled_options && option.disabled) {
506
+ return false;
507
+ }
508
+ if (option.empty) {
509
+ return false;
510
+ }
511
+ return true;
512
+ };
513
+
514
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
515
+ this.touch_started = true;
516
+ return this.search_results_mouseover(evt);
517
+ };
518
+
519
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
520
+ this.touch_started = false;
521
+ return this.search_results_mouseout(evt);
522
+ };
523
+
524
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
525
+ if (this.touch_started) {
526
+ return this.search_results_mouseup(evt);
527
+ }
528
+ };
529
+
530
+ AbstractChosen.prototype.outerHTML = function(element) {
531
+ var tmp;
532
+ if (element.outerHTML) {
533
+ return element.outerHTML;
534
+ }
535
+ tmp = document.createElement("div");
536
+ tmp.appendChild(element);
537
+ return tmp.innerHTML;
538
+ };
539
+
540
+ AbstractChosen.browser_is_supported = function() {
541
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
542
+ return document.documentMode >= 8;
543
+ }
544
+ if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
545
+ return false;
546
+ }
547
+ if (/Android/i.test(window.navigator.userAgent)) {
548
+ if (/Mobile/i.test(window.navigator.userAgent)) {
549
+ return false;
550
+ }
551
+ }
552
+ return true;
553
+ };
554
+
555
+ AbstractChosen.default_multiple_text = "Select Some Options";
556
+
557
+ AbstractChosen.default_single_text = "Select an Option";
558
+
559
+ AbstractChosen.default_no_result_text = "No results match";
560
+
561
+ return AbstractChosen;
562
+
563
+ })();
564
+
565
+ $ = jQuery;
566
+
567
+ $.fn.extend({
568
+ chosen: function(options) {
569
+ if (!AbstractChosen.browser_is_supported()) {
570
+ return this;
571
+ }
572
+ return this.each(function(input_field) {
573
+ var $this, chosen;
574
+ $this = $(this);
575
+ chosen = $this.data('chosen');
576
+ if (options === 'destroy' && chosen instanceof Chosen) {
577
+ chosen.destroy();
578
+ } else if (!(chosen instanceof Chosen)) {
579
+ $this.data('chosen', new Chosen(this, options));
580
+ }
581
+ });
582
+ }
583
+ });
584
+
585
+ Chosen = (function(_super) {
586
+ __extends(Chosen, _super);
587
+
588
+ function Chosen() {
589
+ _ref = Chosen.__super__.constructor.apply(this, arguments);
590
+ return _ref;
591
+ }
592
+
593
+ Chosen.prototype.setup = function() {
594
+ this.form_field_jq = $(this.form_field);
595
+ this.current_selectedIndex = this.form_field.selectedIndex;
596
+ return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
597
+ };
598
+
599
+ Chosen.prototype.set_up_html = function() {
600
+ var container_classes, container_props;
601
+ container_classes = ["chosen-container"];
602
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
603
+ if (this.inherit_select_classes && this.form_field.className) {
604
+ container_classes.push(this.form_field.className);
605
+ }
606
+ if (this.is_rtl) {
607
+ container_classes.push("chosen-rtl");
608
+ }
609
+ container_props = {
610
+ 'class': container_classes.join(' '),
611
+ 'style': "width: " + (this.container_width()) + ";",
612
+ 'title': this.form_field.title
613
+ };
614
+ if (this.form_field.id.length) {
615
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
616
+ }
617
+ this.container = $("<div />", container_props);
618
+ if (this.is_multiple) {
619
+ this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
620
+ } else {
621
+ this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
622
+ }
623
+ this.form_field_jq.hide().after(this.container);
624
+ this.dropdown = this.container.find('div.chosen-drop').first();
625
+ this.search_field = this.container.find('input').first();
626
+ this.search_results = this.container.find('ul.chosen-results').first();
627
+ this.search_field_scale();
628
+ this.search_no_results = this.container.find('li.no-results').first();
629
+ if (this.is_multiple) {
630
+ this.search_choices = this.container.find('ul.chosen-choices').first();
631
+ this.search_container = this.container.find('li.search-field').first();
632
+ } else {
633
+ this.search_container = this.container.find('div.chosen-search').first();
634
+ this.selected_item = this.container.find('.chosen-single').first();
635
+ }
636
+ this.results_build();
637
+ this.set_tab_index();
638
+ return this.set_label_behavior();
639
+ };
640
+
641
+ Chosen.prototype.on_ready = function() {
642
+ return this.form_field_jq.trigger("chosen:ready", {
643
+ chosen: this
644
+ });
645
+ };
646
+
647
+ Chosen.prototype.register_observers = function() {
648
+ var _this = this;
649
+ this.container.bind('touchstart.chosen', function(evt) {
650
+ _this.container_mousedown(evt);
651
+ return evt.preventDefault();
652
+ });
653
+ this.container.bind('touchend.chosen', function(evt) {
654
+ _this.container_mouseup(evt);
655
+ return evt.preventDefault();
656
+ });
657
+ this.container.bind('mousedown.chosen', function(evt) {
658
+ _this.container_mousedown(evt);
659
+ });
660
+ this.container.bind('mouseup.chosen', function(evt) {
661
+ _this.container_mouseup(evt);
662
+ });
663
+ this.container.bind('mouseenter.chosen', function(evt) {
664
+ _this.mouse_enter(evt);
665
+ });
666
+ this.container.bind('mouseleave.chosen', function(evt) {
667
+ _this.mouse_leave(evt);
668
+ });
669
+ this.search_results.bind('mouseup.chosen', function(evt) {
670
+ _this.search_results_mouseup(evt);
671
+ });
672
+ this.search_results.bind('mouseover.chosen', function(evt) {
673
+ _this.search_results_mouseover(evt);
674
+ });
675
+ this.search_results.bind('mouseout.chosen', function(evt) {
676
+ _this.search_results_mouseout(evt);
677
+ });
678
+ this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
679
+ _this.search_results_mousewheel(evt);
680
+ });
681
+ this.search_results.bind('touchstart.chosen', function(evt) {
682
+ _this.search_results_touchstart(evt);
683
+ });
684
+ this.search_results.bind('touchmove.chosen', function(evt) {
685
+ _this.search_results_touchmove(evt);
686
+ });
687
+ this.search_results.bind('touchend.chosen', function(evt) {
688
+ _this.search_results_touchend(evt);
689
+ });
690
+ this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
691
+ _this.results_update_field(evt);
692
+ });
693
+ this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
694
+ _this.activate_field(evt);
695
+ });
696
+ this.form_field_jq.bind("chosen:open.chosen", function(evt) {
697
+ _this.container_mousedown(evt);
698
+ });
699
+ this.form_field_jq.bind("chosen:close.chosen", function(evt) {
700
+ _this.input_blur(evt);
701
+ });
702
+ this.search_field.bind('blur.chosen', function(evt) {
703
+ _this.input_blur(evt);
704
+ });
705
+ this.search_field.bind('keyup.chosen', function(evt) {
706
+ _this.keyup_checker(evt);
707
+ });
708
+ this.search_field.bind('keydown.chosen', function(evt) {
709
+ _this.keydown_checker(evt);
710
+ });
711
+ this.search_field.bind('focus.chosen', function(evt) {
712
+ _this.input_focus(evt);
713
+ });
714
+ this.search_field.bind('cut.chosen', function(evt) {
715
+ _this.clipboard_event_checker(evt);
716
+ });
717
+ this.search_field.bind('paste.chosen', function(evt) {
718
+ _this.clipboard_event_checker(evt);
719
+ });
720
+ if (this.is_multiple) {
721
+ return this.search_choices.bind('click.chosen', function(evt) {
722
+ _this.choices_click(evt);
723
+ });
724
+ } else {
725
+ return this.container.bind('click.chosen', function(evt) {
726
+ evt.preventDefault();
727
+ });
728
+ }
729
+ };
730
+
731
+ Chosen.prototype.destroy = function() {
732
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
733
+ if (this.search_field[0].tabIndex) {
734
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
735
+ }
736
+ this.container.remove();
737
+ this.form_field_jq.removeData('chosen');
738
+ return this.form_field_jq.show();
739
+ };
740
+
741
+ Chosen.prototype.search_field_disabled = function() {
742
+ this.is_disabled = this.form_field_jq[0].disabled;
743
+ if (this.is_disabled) {
744
+ this.container.addClass('chosen-disabled');
745
+ this.search_field[0].disabled = true;
746
+ if (!this.is_multiple) {
747
+ this.selected_item.unbind("focus.chosen", this.activate_action);
748
+ }
749
+ return this.close_field();
750
+ } else {
751
+ this.container.removeClass('chosen-disabled');
752
+ this.search_field[0].disabled = false;
753
+ if (!this.is_multiple) {
754
+ return this.selected_item.bind("focus.chosen", this.activate_action);
755
+ }
756
+ }
757
+ };
758
+
759
+ Chosen.prototype.container_mousedown = function(evt) {
760
+ if (!this.is_disabled) {
761
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
762
+ evt.preventDefault();
763
+ }
764
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
765
+ if (!this.active_field) {
766
+ if (this.is_multiple) {
767
+ this.search_field.val("");
768
+ }
769
+ $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
770
+ this.results_show();
771
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
772
+ evt.preventDefault();
773
+ this.results_toggle();
774
+ }
775
+ return this.activate_field();
776
+ }
777
+ }
778
+ };
779
+
780
+ Chosen.prototype.container_mouseup = function(evt) {
781
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
782
+ return this.results_reset(evt);
783
+ }
784
+ };
785
+
786
+ Chosen.prototype.search_results_mousewheel = function(evt) {
787
+ var delta;
788
+ if (evt.originalEvent) {
789
+ delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
790
+ }
791
+ if (delta != null) {
792
+ evt.preventDefault();
793
+ if (evt.type === 'DOMMouseScroll') {
794
+ delta = delta * 40;
795
+ }
796
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
797
+ }
798
+ };
799
+
800
+ Chosen.prototype.blur_test = function(evt) {
801
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
802
+ return this.close_field();
803
+ }
804
+ };
805
+
806
+ Chosen.prototype.close_field = function() {
807
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
808
+ this.active_field = false;
809
+ this.results_hide();
810
+ this.container.removeClass("chosen-container-active");
811
+ this.clear_backstroke();
812
+ this.show_search_field_default();
813
+ return this.search_field_scale();
814
+ };
815
+
816
+ Chosen.prototype.activate_field = function() {
817
+ this.container.addClass("chosen-container-active");
818
+ this.active_field = true;
819
+ this.search_field.val(this.search_field.val());
820
+ return this.search_field.focus();
821
+ };
822
+
823
+ Chosen.prototype.test_active_click = function(evt) {
824
+ var active_container;
825
+ active_container = $(evt.target).closest('.chosen-container');
826
+ if (active_container.length && this.container[0] === active_container[0]) {
827
+ return this.active_field = true;
828
+ } else {
829
+ return this.close_field();
830
+ }
831
+ };
832
+
833
+ Chosen.prototype.results_build = function() {
834
+ this.parsing = true;
835
+ this.selected_option_count = null;
836
+ this.results_data = SelectParser.select_to_array(this.form_field);
837
+ if (this.is_multiple) {
838
+ this.search_choices.find("li.search-choice").remove();
839
+ } else if (!this.is_multiple) {
840
+ this.single_set_selected_text();
841
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
842
+ this.search_field[0].readOnly = true;
843
+ this.container.addClass("chosen-container-single-nosearch");
844
+ } else {
845
+ this.search_field[0].readOnly = false;
846
+ this.container.removeClass("chosen-container-single-nosearch");
847
+ }
848
+ }
849
+ this.update_results_content(this.results_option_build({
850
+ first: true
851
+ }));
852
+ this.search_field_disabled();
853
+ this.show_search_field_default();
854
+ this.search_field_scale();
855
+ return this.parsing = false;
856
+ };
857
+
858
+ Chosen.prototype.result_do_highlight = function(el) {
859
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
860
+ if (el.length) {
861
+ this.result_clear_highlight();
862
+ this.result_highlight = el;
863
+ this.result_highlight.addClass("highlighted");
864
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
865
+ visible_top = this.search_results.scrollTop();
866
+ visible_bottom = maxHeight + visible_top;
867
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
868
+ high_bottom = high_top + this.result_highlight.outerHeight();
869
+ if (high_bottom >= visible_bottom) {
870
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
871
+ } else if (high_top < visible_top) {
872
+ return this.search_results.scrollTop(high_top);
873
+ }
874
+ }
875
+ };
876
+
877
+ Chosen.prototype.result_clear_highlight = function() {
878
+ if (this.result_highlight) {
879
+ this.result_highlight.removeClass("highlighted");
880
+ }
881
+ return this.result_highlight = null;
882
+ };
883
+
884
+ Chosen.prototype.results_show = function() {
885
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
886
+ this.form_field_jq.trigger("chosen:maxselected", {
887
+ chosen: this
888
+ });
889
+ return false;
890
+ }
891
+ this.container.addClass("chosen-with-drop");
892
+ this.results_showing = true;
893
+ this.search_field.focus();
894
+ this.search_field.val(this.search_field.val());
895
+ this.winnow_results();
896
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
897
+ chosen: this
898
+ });
899
+ };
900
+
901
+ Chosen.prototype.update_results_content = function(content) {
902
+ return this.search_results.html(content);
903
+ };
904
+
905
+ Chosen.prototype.results_hide = function() {
906
+ if (this.results_showing) {
907
+ this.result_clear_highlight();
908
+ this.container.removeClass("chosen-with-drop");
909
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
910
+ chosen: this
911
+ });
912
+ }
913
+ return this.results_showing = false;
914
+ };
915
+
916
+ Chosen.prototype.set_tab_index = function(el) {
917
+ var ti;
918
+ if (this.form_field.tabIndex) {
919
+ ti = this.form_field.tabIndex;
920
+ this.form_field.tabIndex = -1;
921
+ return this.search_field[0].tabIndex = ti;
922
+ }
923
+ };
924
+
925
+ Chosen.prototype.set_label_behavior = function() {
926
+ var _this = this;
927
+ this.form_field_label = this.form_field_jq.parents("label");
928
+ if (!this.form_field_label.length && this.form_field.id.length) {
929
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
930
+ }
931
+ if (this.form_field_label.length > 0) {
932
+ return this.form_field_label.bind('click.chosen', function(evt) {
933
+ if (_this.is_multiple) {
934
+ return _this.container_mousedown(evt);
935
+ } else {
936
+ return _this.activate_field();
937
+ }
938
+ });
939
+ }
940
+ };
941
+
942
+ Chosen.prototype.show_search_field_default = function() {
943
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
944
+ this.search_field.val(this.default_text);
945
+ return this.search_field.addClass("default");
946
+ } else {
947
+ this.search_field.val("");
948
+ return this.search_field.removeClass("default");
949
+ }
950
+ };
951
+
952
+ Chosen.prototype.search_results_mouseup = function(evt) {
953
+ var target;
954
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
955
+ if (target.length) {
956
+ this.result_highlight = target;
957
+ this.result_select(evt);
958
+ return this.search_field.focus();
959
+ }
960
+ };
961
+
962
+ Chosen.prototype.search_results_mouseover = function(evt) {
963
+ var target;
964
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
965
+ if (target) {
966
+ return this.result_do_highlight(target);
967
+ }
968
+ };
969
+
970
+ Chosen.prototype.search_results_mouseout = function(evt) {
971
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
972
+ return this.result_clear_highlight();
973
+ }
974
+ };
975
+
976
+ Chosen.prototype.choice_build = function(item) {
977
+ var choice, close_link,
978
+ _this = this;
979
+ choice = $('<li />', {
980
+ "class": "search-choice"
981
+ }).html("<span>" + (this.choice_label(item)) + "</span>");
982
+ if (item.disabled) {
983
+ choice.addClass('search-choice-disabled');
984
+ } else {
985
+ close_link = $('<a />', {
986
+ "class": 'search-choice-close',
987
+ 'data-option-array-index': item.array_index
988
+ });
989
+ close_link.bind('click.chosen', function(evt) {
990
+ return _this.choice_destroy_link_click(evt);
991
+ });
992
+ choice.append(close_link);
993
+ }
994
+ return this.search_container.before(choice);
995
+ };
996
+
997
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
998
+ evt.preventDefault();
999
+ evt.stopPropagation();
1000
+ if (!this.is_disabled) {
1001
+ return this.choice_destroy($(evt.target));
1002
+ }
1003
+ };
1004
+
1005
+ Chosen.prototype.choice_destroy = function(link) {
1006
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
1007
+ this.show_search_field_default();
1008
+ if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
1009
+ this.results_hide();
1010
+ }
1011
+ link.parents('li').first().remove();
1012
+ return this.search_field_scale();
1013
+ }
1014
+ };
1015
+
1016
+ Chosen.prototype.results_reset = function() {
1017
+ this.reset_single_select_options();
1018
+ this.form_field.options[0].selected = true;
1019
+ this.single_set_selected_text();
1020
+ this.show_search_field_default();
1021
+ this.results_reset_cleanup();
1022
+ this.form_field_jq.trigger("change");
1023
+ if (this.active_field) {
1024
+ return this.results_hide();
1025
+ }
1026
+ };
1027
+
1028
+ Chosen.prototype.results_reset_cleanup = function() {
1029
+ this.current_selectedIndex = this.form_field.selectedIndex;
1030
+ return this.selected_item.find("abbr").remove();
1031
+ };
1032
+
1033
+ Chosen.prototype.result_select = function(evt) {
1034
+ var high, item;
1035
+ if (this.result_highlight) {
1036
+ high = this.result_highlight;
1037
+ this.result_clear_highlight();
1038
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
1039
+ this.form_field_jq.trigger("chosen:maxselected", {
1040
+ chosen: this
1041
+ });
1042
+ return false;
1043
+ }
1044
+ if (this.is_multiple) {
1045
+ high.removeClass("active-result");
1046
+ } else {
1047
+ this.reset_single_select_options();
1048
+ }
1049
+ high.addClass("result-selected");
1050
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
1051
+ item.selected = true;
1052
+ this.form_field.options[item.options_index].selected = true;
1053
+ this.selected_option_count = null;
1054
+ if (this.is_multiple) {
1055
+ this.choice_build(item);
1056
+ } else {
1057
+ this.single_set_selected_text(this.choice_label(item));
1058
+ }
1059
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1060
+ this.results_hide();
1061
+ }
1062
+ this.search_field.val("");
1063
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1064
+ this.form_field_jq.trigger("change", {
1065
+ 'selected': this.form_field.options[item.options_index].value
1066
+ });
1067
+ }
1068
+ this.current_selectedIndex = this.form_field.selectedIndex;
1069
+ evt.preventDefault();
1070
+ return this.search_field_scale();
1071
+ }
1072
+ };
1073
+
1074
+ Chosen.prototype.single_set_selected_text = function(text) {
1075
+ if (text == null) {
1076
+ text = this.default_text;
1077
+ }
1078
+ if (text === this.default_text) {
1079
+ this.selected_item.addClass("chosen-default");
1080
+ } else {
1081
+ this.single_deselect_control_build();
1082
+ this.selected_item.removeClass("chosen-default");
1083
+ }
1084
+ return this.selected_item.find("span").html(text);
1085
+ };
1086
+
1087
+ Chosen.prototype.result_deselect = function(pos) {
1088
+ var result_data;
1089
+ result_data = this.results_data[pos];
1090
+ if (!this.form_field.options[result_data.options_index].disabled) {
1091
+ result_data.selected = false;
1092
+ this.form_field.options[result_data.options_index].selected = false;
1093
+ this.selected_option_count = null;
1094
+ this.result_clear_highlight();
1095
+ if (this.results_showing) {
1096
+ this.winnow_results();
1097
+ }
1098
+ this.form_field_jq.trigger("change", {
1099
+ deselected: this.form_field.options[result_data.options_index].value
1100
+ });
1101
+ this.search_field_scale();
1102
+ return true;
1103
+ } else {
1104
+ return false;
1105
+ }
1106
+ };
1107
+
1108
+ Chosen.prototype.single_deselect_control_build = function() {
1109
+ if (!this.allow_single_deselect) {
1110
+ return;
1111
+ }
1112
+ if (!this.selected_item.find("abbr").length) {
1113
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1114
+ }
1115
+ return this.selected_item.addClass("chosen-single-with-deselect");
1116
+ };
1117
+
1118
+ Chosen.prototype.get_search_text = function() {
1119
+ return $('<div/>').text($.trim(this.search_field.val())).html();
1120
+ };
1121
+
1122
+ Chosen.prototype.winnow_results_set_highlight = function() {
1123
+ var do_high, selected_results;
1124
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1125
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1126
+ if (do_high != null) {
1127
+ return this.result_do_highlight(do_high);
1128
+ }
1129
+ };
1130
+
1131
+ Chosen.prototype.no_results = function(terms) {
1132
+ var no_results_html;
1133
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1134
+ no_results_html.find("span").first().html(terms);
1135
+ this.search_results.append(no_results_html);
1136
+ return this.form_field_jq.trigger("chosen:no_results", {
1137
+ chosen: this
1138
+ });
1139
+ };
1140
+
1141
+ Chosen.prototype.no_results_clear = function() {
1142
+ return this.search_results.find(".no-results").remove();
1143
+ };
1144
+
1145
+ Chosen.prototype.keydown_arrow = function() {
1146
+ var next_sib;
1147
+ if (this.results_showing && this.result_highlight) {
1148
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
1149
+ if (next_sib) {
1150
+ return this.result_do_highlight(next_sib);
1151
+ }
1152
+ } else {
1153
+ return this.results_show();
1154
+ }
1155
+ };
1156
+
1157
+ Chosen.prototype.keyup_arrow = function() {
1158
+ var prev_sibs;
1159
+ if (!this.results_showing && !this.is_multiple) {
1160
+ return this.results_show();
1161
+ } else if (this.result_highlight) {
1162
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
1163
+ if (prev_sibs.length) {
1164
+ return this.result_do_highlight(prev_sibs.first());
1165
+ } else {
1166
+ if (this.choices_count() > 0) {
1167
+ this.results_hide();
1168
+ }
1169
+ return this.result_clear_highlight();
1170
+ }
1171
+ }
1172
+ };
1173
+
1174
+ Chosen.prototype.keydown_backstroke = function() {
1175
+ var next_available_destroy;
1176
+ if (this.pending_backstroke) {
1177
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1178
+ return this.clear_backstroke();
1179
+ } else {
1180
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1181
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1182
+ this.pending_backstroke = next_available_destroy;
1183
+ if (this.single_backstroke_delete) {
1184
+ return this.keydown_backstroke();
1185
+ } else {
1186
+ return this.pending_backstroke.addClass("search-choice-focus");
1187
+ }
1188
+ }
1189
+ }
1190
+ };
1191
+
1192
+ Chosen.prototype.clear_backstroke = function() {
1193
+ if (this.pending_backstroke) {
1194
+ this.pending_backstroke.removeClass("search-choice-focus");
1195
+ }
1196
+ return this.pending_backstroke = null;
1197
+ };
1198
+
1199
+ Chosen.prototype.keydown_checker = function(evt) {
1200
+ var stroke, _ref1;
1201
+ stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1202
+ this.search_field_scale();
1203
+ if (stroke !== 8 && this.pending_backstroke) {
1204
+ this.clear_backstroke();
1205
+ }
1206
+ switch (stroke) {
1207
+ case 8:
1208
+ this.backstroke_length = this.search_field.val().length;
1209
+ break;
1210
+ case 9:
1211
+ if (this.results_showing && !this.is_multiple) {
1212
+ this.result_select(evt);
1213
+ }
1214
+ this.mouse_on_container = false;
1215
+ break;
1216
+ case 13:
1217
+ if (this.results_showing) {
1218
+ evt.preventDefault();
1219
+ }
1220
+ break;
1221
+ case 32:
1222
+ if (this.disable_search) {
1223
+ evt.preventDefault();
1224
+ }
1225
+ break;
1226
+ case 38:
1227
+ evt.preventDefault();
1228
+ this.keyup_arrow();
1229
+ break;
1230
+ case 40:
1231
+ evt.preventDefault();
1232
+ this.keydown_arrow();
1233
+ break;
1234
+ }
1235
+ };
1236
+
1237
+ Chosen.prototype.search_field_scale = function() {
1238
+ var div, f_width, h, style, style_block, styles, w, _i, _len;
1239
+ if (this.is_multiple) {
1240
+ h = 0;
1241
+ w = 0;
1242
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1243
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1244
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
1245
+ style = styles[_i];
1246
+ style_block += style + ":" + this.search_field.css(style) + ";";
1247
+ }
1248
+ div = $('<div />', {
1249
+ 'style': style_block
1250
+ });
1251
+ div.text(this.search_field.val());
1252
+ $('body').append(div);
1253
+ w = div.width() + 25;
1254
+ div.remove();
1255
+ f_width = this.container.outerWidth();
1256
+ if (w > f_width - 10) {
1257
+ w = f_width - 10;
1258
+ }
1259
+ return this.search_field.css({
1260
+ 'width': w + 'px'
1261
+ });
1262
+ }
1263
+ };
1264
+
1265
+ return Chosen;
1266
+
1267
+ })(AbstractChosen);
1268
+
1269
+ }).call(this);
static/js/jquery/chosen.jquery.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ /* Chosen v1.4.0 | (c) 2011-2015 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
2
+ (function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),title:a.title?a.title:void 0,children:0,disabled:a.disabled,classes:a.className}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,title:a.title?a.title:void 0,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,group_label:null!=b?this.parsed[b].label:null,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers(),this.on_ready())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0,this.include_group_label_in_selected=this.options.include_group_label_in_selected||!1},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.choice_label=function(a){return this.include_group_label_in_selected&&null!=a.group_label?"<b class='group-name'>"+a.group_label+"</b>"+a.html:a.html},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.html));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b,c;return a.search_match||a.group_match?a.active_options>0?(b=[],b.push("group-result"),a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.innerHTML=a.search_text,a.title&&(c.title=a.title),this.outerHTML(c)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l;for(this.no_results_clear(),d=0,f=this.get_search_text(),a=f.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),i=new RegExp(a,"i"),c=this.get_search_regex(a),l=this.results_data,j=0,k=l.length;k>j;j++)b=l[j],b.search_match=!1,e=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(e=this.results_data[b.group_array_index],0===e.active_options&&e.search_match&&(d+=1),e.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(d+=1),b.search_match?(f.length&&(g=b.search_text.search(i),h=b.search_text.substr(0,g+f.length)+"</em>"+b.search_text.substr(g+f.length),b.search_text=h.substr(0,g)+"<em>"+h.substr(g)),null!=e&&(e.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>d&&f.length?(this.update_results_content(""),this.no_results(f)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.get_search_regex=function(a){var b;return b=this.search_contains?"":"^",new RegExp(b+a,"i")},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d instanceof Chosen?d.destroy():d instanceof Chosen||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior()},Chosen.prototype.on_ready=function(){return this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("touchstart.chosen",function(b){a.container_mousedown(b)}),this.container.bind("touchend.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=a.originalEvent.deltaY||-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+this.choice_label(b)+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(this.choice_label(c)),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,a.preventDefault(),this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").html(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:this.results_showing&&a.preventDefault();break;case 32:this.disable_search&&a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}).call(this);
static/js/jquery/css/chosen/chosen-sprite.png ADDED
Binary file
static/js/jquery/css/chosen/chosen-sprite@2x.png ADDED
Binary file
static/js/jquery/css/chosen/chosen.css ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.4.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011-2015 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ /* @group Base */
14
+ .chosen-container {
15
+ position: relative;
16
+ display: inline-block;
17
+ vertical-align: middle;
18
+ font-size: 13px;
19
+ zoom: 1;
20
+ *display: inline;
21
+ -webkit-user-select: none;
22
+ -moz-user-select: none;
23
+ user-select: none;
24
+ }
25
+ .chosen-container * {
26
+ -webkit-box-sizing: border-box;
27
+ -moz-box-sizing: border-box;
28
+ box-sizing: border-box;
29
+ }
30
+ .chosen-container .chosen-drop {
31
+ position: absolute;
32
+ top: 100%;
33
+ left: -9999px;
34
+ z-index: 1010;
35
+ width: 100%;
36
+ border: 1px solid #aaa;
37
+ border-top: 0;
38
+ background: #fff;
39
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
40
+ }
41
+ .chosen-container.chosen-with-drop .chosen-drop {
42
+ left: 0;
43
+ }
44
+ .chosen-container a {
45
+ cursor: pointer;
46
+ }
47
+ .chosen-container .search-choice .group-name, .chosen-container .chosen-single .group-name {
48
+ margin-right: 4px;
49
+ overflow: hidden;
50
+ white-space: nowrap;
51
+ text-overflow: ellipsis;
52
+ font-weight: normal;
53
+ color: #999999;
54
+ }
55
+ .chosen-container .search-choice .group-name:after, .chosen-container .chosen-single .group-name:after {
56
+ content: ":";
57
+ padding-left: 2px;
58
+ vertical-align: top;
59
+ }
60
+
61
+ /* @end */
62
+ /* @group Single Chosen */
63
+ .chosen-container-single .chosen-single {
64
+ position: relative;
65
+ display: block;
66
+ overflow: hidden;
67
+ padding: 0 0 0 8px;
68
+ height: 25px;
69
+ border: 1px solid #aaa;
70
+ border-radius: 5px;
71
+ background-color: #fff;
72
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
73
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
74
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
75
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
76
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
77
+ background-clip: padding-box;
78
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
79
+ color: #444;
80
+ text-decoration: none;
81
+ white-space: nowrap;
82
+ line-height: 24px;
83
+ }
84
+ .chosen-container-single .chosen-default {
85
+ color: #999;
86
+ }
87
+ .chosen-container-single .chosen-single span {
88
+ display: block;
89
+ overflow: hidden;
90
+ margin-right: 26px;
91
+ text-overflow: ellipsis;
92
+ white-space: nowrap;
93
+ }
94
+ .chosen-container-single .chosen-single-with-deselect span {
95
+ margin-right: 38px;
96
+ }
97
+ .chosen-container-single .chosen-single abbr {
98
+ position: absolute;
99
+ top: 6px;
100
+ right: 26px;
101
+ display: block;
102
+ width: 12px;
103
+ height: 12px;
104
+ background: url('chosen-sprite.png') -42px 1px no-repeat;
105
+ font-size: 1px;
106
+ }
107
+ .chosen-container-single .chosen-single abbr:hover {
108
+ background-position: -42px -10px;
109
+ }
110
+ .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
111
+ background-position: -42px -10px;
112
+ }
113
+ .chosen-container-single .chosen-single div {
114
+ position: absolute;
115
+ top: 0;
116
+ right: 0;
117
+ display: block;
118
+ width: 18px;
119
+ height: 100%;
120
+ }
121
+ .chosen-container-single .chosen-single div b {
122
+ display: block;
123
+ width: 100%;
124
+ height: 100%;
125
+ background: url('chosen-sprite.png') no-repeat 0px 2px;
126
+ }
127
+ .chosen-container-single .chosen-search {
128
+ position: relative;
129
+ z-index: 1010;
130
+ margin: 0;
131
+ padding: 3px 4px;
132
+ white-space: nowrap;
133
+ }
134
+ .chosen-container-single .chosen-search input[type="text"] {
135
+ margin: 1px 0;
136
+ padding: 4px 20px 4px 5px;
137
+ width: 100%;
138
+ height: auto;
139
+ outline: 0;
140
+ border: 1px solid #aaa;
141
+ background: white url('chosen-sprite.png') no-repeat 100% -20px;
142
+ background: url('chosen-sprite.png') no-repeat 100% -20px;
143
+ font-size: 1em;
144
+ font-family: sans-serif;
145
+ line-height: normal;
146
+ border-radius: 0;
147
+ }
148
+ .chosen-container-single .chosen-drop {
149
+ margin-top: -1px;
150
+ border-radius: 0 0 4px 4px;
151
+ background-clip: padding-box;
152
+ }
153
+ .chosen-container-single.chosen-container-single-nosearch .chosen-search {
154
+ position: absolute;
155
+ left: -9999px;
156
+ }
157
+
158
+ /* @end */
159
+ /* @group Results */
160
+ .chosen-container .chosen-results {
161
+ color: #444;
162
+ position: relative;
163
+ overflow-x: hidden;
164
+ overflow-y: auto;
165
+ margin: 0 4px 4px 0;
166
+ padding: 0 0 0 4px;
167
+ max-height: 240px;
168
+ -webkit-overflow-scrolling: touch;
169
+ }
170
+ .chosen-container .chosen-results li {
171
+ display: none;
172
+ margin: 0;
173
+ padding: 5px 6px;
174
+ list-style: none;
175
+ line-height: 15px;
176
+ word-wrap: break-word;
177
+ -webkit-touch-callout: none;
178
+ }
179
+ .chosen-container .chosen-results li.active-result {
180
+ display: list-item;
181
+ cursor: pointer;
182
+ }
183
+ .chosen-container .chosen-results li.disabled-result {
184
+ display: list-item;
185
+ color: #ccc;
186
+ cursor: default;
187
+ }
188
+ .chosen-container .chosen-results li.highlighted {
189
+ background-color: #3875d7;
190
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
191
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
192
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
193
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
194
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
195
+ color: #fff;
196
+ }
197
+ .chosen-container .chosen-results li.no-results {
198
+ color: #777;
199
+ display: list-item;
200
+ background: #f4f4f4;
201
+ }
202
+ .chosen-container .chosen-results li.group-result {
203
+ display: list-item;
204
+ font-weight: bold;
205
+ cursor: default;
206
+ }
207
+ .chosen-container .chosen-results li.group-option {
208
+ padding-left: 15px;
209
+ }
210
+ .chosen-container .chosen-results li em {
211
+ font-style: normal;
212
+ text-decoration: underline;
213
+ }
214
+
215
+ /* @end */
216
+ /* @group Multi Chosen */
217
+ .chosen-container-multi .chosen-choices {
218
+ position: relative;
219
+ overflow: hidden;
220
+ margin: 0;
221
+ padding: 0 5px;
222
+ width: 100%;
223
+ height: auto !important;
224
+ height: 1%;
225
+ border: 1px solid #aaa;
226
+ background-color: #fff;
227
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
228
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
229
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
230
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
231
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
232
+ cursor: text;
233
+ }
234
+ .chosen-container-multi .chosen-choices li {
235
+ float: left;
236
+ list-style: none;
237
+ }
238
+ .chosen-container-multi .chosen-choices li.search-field {
239
+ margin: 0;
240
+ padding: 0;
241
+ white-space: nowrap;
242
+ }
243
+ .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
244
+ margin: 1px 0;
245
+ padding: 0;
246
+ height: 25px;
247
+ outline: 0;
248
+ border: 0 !important;
249
+ background: transparent !important;
250
+ box-shadow: none;
251
+ color: #999;
252
+ font-size: 100%;
253
+ font-family: sans-serif;
254
+ line-height: normal;
255
+ border-radius: 0;
256
+ }
257
+ .chosen-container-multi .chosen-choices li.search-choice {
258
+ position: relative;
259
+ margin: 3px 5px 3px 0;
260
+ padding: 3px 20px 3px 5px;
261
+ border: 1px solid #aaa;
262
+ max-width: 100%;
263
+ border-radius: 3px;
264
+ background-color: #eeeeee;
265
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
266
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
267
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
268
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
269
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
270
+ background-size: 100% 19px;
271
+ background-repeat: repeat-x;
272
+ background-clip: padding-box;
273
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
274
+ color: #333;
275
+ line-height: 13px;
276
+ cursor: default;
277
+ }
278
+ .chosen-container-multi .chosen-choices li.search-choice span {
279
+ word-wrap: break-word;
280
+ }
281
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
282
+ position: absolute;
283
+ top: 4px;
284
+ right: 3px;
285
+ display: block;
286
+ width: 12px;
287
+ height: 12px;
288
+ background: url('chosen-sprite.png') -42px 1px no-repeat;
289
+ font-size: 1px;
290
+ }
291
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
292
+ background-position: -42px -10px;
293
+ }
294
+ .chosen-container-multi .chosen-choices li.search-choice-disabled {
295
+ padding-right: 5px;
296
+ border: 1px solid #ccc;
297
+ background-color: #e4e4e4;
298
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
299
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
300
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
301
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
302
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
303
+ color: #666;
304
+ }
305
+ .chosen-container-multi .chosen-choices li.search-choice-focus {
306
+ background: #d4d4d4;
307
+ }
308
+ .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
309
+ background-position: -42px -10px;
310
+ }
311
+ .chosen-container-multi .chosen-results {
312
+ margin: 0;
313
+ padding: 0;
314
+ }
315
+ .chosen-container-multi .chosen-drop .result-selected {
316
+ display: list-item;
317
+ color: #ccc;
318
+ cursor: default;
319
+ }
320
+
321
+ /* @end */
322
+ /* @group Active */
323
+ .chosen-container-active .chosen-single {
324
+ border: 1px solid #5897fb;
325
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
326
+ }
327
+ .chosen-container-active.chosen-with-drop .chosen-single {
328
+ border: 1px solid #aaa;
329
+ -moz-border-radius-bottomright: 0;
330
+ border-bottom-right-radius: 0;
331
+ -moz-border-radius-bottomleft: 0;
332
+ border-bottom-left-radius: 0;
333
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
334
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
335
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
336
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
337
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
338
+ box-shadow: 0 1px 0 #fff inset;
339
+ }
340
+ .chosen-container-active.chosen-with-drop .chosen-single div {
341
+ border-left: none;
342
+ background: transparent;
343
+ }
344
+ .chosen-container-active.chosen-with-drop .chosen-single div b {
345
+ background-position: -18px 2px;
346
+ }
347
+ .chosen-container-active .chosen-choices {
348
+ border: 1px solid #5897fb;
349
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
350
+ }
351
+ .chosen-container-active .chosen-choices li.search-field input[type="text"] {
352
+ color: #222 !important;
353
+ }
354
+
355
+ /* @end */
356
+ /* @group Disabled Support */
357
+ .chosen-disabled {
358
+ opacity: 0.5 !important;
359
+ cursor: default;
360
+ }
361
+ .chosen-disabled .chosen-single {
362
+ cursor: default;
363
+ }
364
+ .chosen-disabled .chosen-choices .search-choice .search-choice-close {
365
+ cursor: default;
366
+ }
367
+
368
+ /* @end */
369
+ /* @group Right to Left */
370
+ .chosen-rtl {
371
+ text-align: right;
372
+ }
373
+ .chosen-rtl .chosen-single {
374
+ overflow: visible;
375
+ padding: 0 8px 0 0;
376
+ }
377
+ .chosen-rtl .chosen-single span {
378
+ margin-right: 0;
379
+ margin-left: 26px;
380
+ direction: rtl;
381
+ }
382
+ .chosen-rtl .chosen-single-with-deselect span {
383
+ margin-left: 38px;
384
+ }
385
+ .chosen-rtl .chosen-single div {
386
+ right: auto;
387
+ left: 3px;
388
+ }
389
+ .chosen-rtl .chosen-single abbr {
390
+ right: auto;
391
+ left: 26px;
392
+ }
393
+ .chosen-rtl .chosen-choices li {
394
+ float: right;
395
+ }
396
+ .chosen-rtl .chosen-choices li.search-field input[type="text"] {
397
+ direction: rtl;
398
+ }
399
+ .chosen-rtl .chosen-choices li.search-choice {
400
+ margin: 3px 5px 3px 0;
401
+ padding: 3px 5px 3px 19px;
402
+ }
403
+ .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
404
+ right: auto;
405
+ left: 4px;
406
+ }
407
+ .chosen-rtl.chosen-container-single-nosearch .chosen-search,
408
+ .chosen-rtl .chosen-drop {
409
+ left: 9999px;
410
+ }
411
+ .chosen-rtl.chosen-container-single .chosen-results {
412
+ margin: 0 0 4px 4px;
413
+ padding: 0 4px 0 0;
414
+ }
415
+ .chosen-rtl .chosen-results li.group-option {
416
+ padding-right: 15px;
417
+ padding-left: 0;
418
+ }
419
+ .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
420
+ border-right: none;
421
+ }
422
+ .chosen-rtl .chosen-search input[type="text"] {
423
+ padding: 4px 5px 4px 20px;
424
+ background: white url('chosen-sprite.png') no-repeat -30px -20px;
425
+ background: url('chosen-sprite.png') no-repeat -30px -20px;
426
+ direction: rtl;
427
+ }
428
+ .chosen-rtl.chosen-container-single .chosen-single div b {
429
+ background-position: 6px 2px;
430
+ }
431
+ .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
432
+ background-position: -12px 2px;
433
+ }
434
+
435
+ /* @end */
436
+ /* @group Retina compatibility */
437
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) {
438
+ .chosen-rtl .chosen-search input[type="text"],
439
+ .chosen-container-single .chosen-single abbr,
440
+ .chosen-container-single .chosen-single div b,
441
+ .chosen-container-single .chosen-search input[type="text"],
442
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
443
+ .chosen-container .chosen-results-scroll-down span,
444
+ .chosen-container .chosen-results-scroll-up span {
445
+ background-image: url('chosen-sprite@2x.png') !important;
446
+ background-size: 52px 37px !important;
447
+ background-repeat: no-repeat !important;
448
+ }
449
+ }
450
+ /* @end */
views/admin/import/index.php CHANGED
@@ -147,10 +147,24 @@
147
  </div>
148
 
149
  <?php
150
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  $custom_types = get_post_types(array('_builtin' => true), 'objects') + get_post_types(array('_builtin' => false, 'show_ui' => true), 'objects');
152
  foreach ($custom_types as $key => $ct) {
153
- if (in_array($key, array('attachment', 'revision', 'nav_menu_item', 'shop_webhook', 'import_users'))) unset($custom_types[$key]);
154
  }
155
  $custom_types = apply_filters( 'pmxi_custom_types', $custom_types );
156
 
@@ -187,7 +201,7 @@
187
 
188
  $hidden_post_types = get_post_types(array('_builtin' => false, 'show_ui' => false), 'objects');
189
  foreach ($hidden_post_types as $key => $ct) {
190
- if (in_array($key, array('attachment', 'revision', 'nav_menu_item'))) unset($hidden_post_types[$key]);
191
  }
192
  $hidden_post_types = apply_filters( 'pmxi_custom_types', $hidden_post_types );
193
 
147
  </div>
148
 
149
  <?php
150
+ $hiddenPosts = array(
151
+ 'attachment',
152
+ 'revision',
153
+ 'nav_menu_item',
154
+ 'shop_webhook',
155
+ 'import_users',
156
+ 'wp-types-group',
157
+ 'wp-types-user-group',
158
+ 'wp-types-term-group',
159
+ 'acf-field',
160
+ 'acf-field-group',
161
+ 'custom_css',
162
+ 'customize_changeset',
163
+ 'oembed_cache'
164
+ );
165
  $custom_types = get_post_types(array('_builtin' => true), 'objects') + get_post_types(array('_builtin' => false, 'show_ui' => true), 'objects');
166
  foreach ($custom_types as $key => $ct) {
167
+ if (in_array($key, $hiddenPosts)) unset($custom_types[$key]);
168
  }
169
  $custom_types = apply_filters( 'pmxi_custom_types', $custom_types );
170
 
201
 
202
  $hidden_post_types = get_post_types(array('_builtin' => false, 'show_ui' => false), 'objects');
203
  foreach ($hidden_post_types as $key => $ct) {
204
+ if (in_array($key, $hiddenPosts)) unset($hidden_post_types[$key]);
205
  }
206
  $hidden_post_types = apply_filters( 'pmxi_custom_types', $hidden_post_types );
207
 
views/admin/import/options.php CHANGED
@@ -80,6 +80,12 @@
80
 
81
  if ( in_array('reimport', $visible_sections)) include( 'options/_reimport_template.php' );
82
  do_action('pmxi_options_tab', $isWizard, $post);
 
 
 
 
 
 
83
  if ( in_array('settings', $visible_sections)) include( 'options/_settings_template.php' );
84
 
85
  include( 'options/_buttons_template.php' );
80
 
81
  if ( in_array('reimport', $visible_sections)) include( 'options/_reimport_template.php' );
82
  do_action('pmxi_options_tab', $isWizard, $post);
83
+
84
+ if(!isset($import)) {
85
+ $import = $update_previous;
86
+ }
87
+ include( 'options/scheduling/_scheduling_ui.php' );
88
+
89
  if ( in_array('settings', $visible_sections)) include( 'options/_settings_template.php' );
90
 
91
  include( 'options/_buttons_template.php' );
views/admin/import/options/_settings_template.php CHANGED
@@ -46,10 +46,24 @@
46
  <input type="hidden" name="custom_type" value="<?php echo $post['custom_type'];?>">
47
 
48
  <?php
49
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  $custom_types = get_post_types(array('_builtin' => true), 'objects') + get_post_types(array('_builtin' => false, 'show_ui' => true), 'objects');
51
  foreach ($custom_types as $key => $ct) {
52
- if (in_array($key, array('attachment', 'revision', 'nav_menu_item', 'shop_webhook', 'import_users'))) unset($custom_types[$key]);
53
  }
54
  $custom_types = apply_filters( 'pmxi_custom_types', $custom_types );
55
 
@@ -81,7 +95,7 @@
81
 
82
  $hidden_post_types = get_post_types(array('_builtin' => false, 'show_ui' => false), 'objects');
83
  foreach ($hidden_post_types as $key => $ct) {
84
- if (in_array($key, array('attachment', 'revision', 'nav_menu_item'))) unset($hidden_post_types[$key]);
85
  }
86
  $hidden_post_types = apply_filters( 'pmxi_custom_types', $hidden_post_types );
87
 
46
  <input type="hidden" name="custom_type" value="<?php echo $post['custom_type'];?>">
47
 
48
  <?php
49
+ $hiddenPosts = array(
50
+ 'attachment',
51
+ 'revision',
52
+ 'nav_menu_item',
53
+ 'shop_webhook',
54
+ 'import_users',
55
+ 'wp-types-group',
56
+ 'wp-types-user-group',
57
+ 'wp-types-term-group',
58
+ 'acf-field',
59
+ 'acf-field-group',
60
+ 'custom_css',
61
+ 'customize_changeset',
62
+ 'oembed_cache'
63
+ );
64
  $custom_types = get_post_types(array('_builtin' => true), 'objects') + get_post_types(array('_builtin' => false, 'show_ui' => true), 'objects');
65
  foreach ($custom_types as $key => $ct) {
66
+ if (in_array($key, $hiddenPosts)) unset($custom_types[$key]);
67
  }
68
  $custom_types = apply_filters( 'pmxi_custom_types', $custom_types );
69
 
95
 
96
  $hidden_post_types = get_post_types(array('_builtin' => false, 'show_ui' => false), 'objects');
97
  foreach ($hidden_post_types as $key => $ct) {
98
+ if (in_array($key, $hiddenPosts)) unset($hidden_post_types[$key]);
99
  }
100
  $hidden_post_types = apply_filters( 'pmxi_custom_types', $hidden_post_types );
101
 
views/admin/import/options/scheduling/_scheduling_ui.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wpallimport-collapsed closed wpallimport-section scheduling">
2
+ <div class="wpallimport-content-section">
3
+ <div class="wpallimport-collapsed-header disabled"
4
+ title="<?php _e("To run this import on a schedule you must use the 'Download from URL' or 'Use existing file' options in Step 1.", PMXI_Plugin::LANGUAGE_DOMAIN);?>">
5
+ <h3 id="scheduling-title"><?php _e('Scheduling Options','wp_all_import_plugin');?>
6
+ <a href="#help" class="wpallimport-help" style="position: relative; top: -2px; margin-left: 0; width: 20px; height: 20px;" title="<?php _e("To run this import on a schedule you must use the 'Download from URL' or 'Use existing file' option on the Import Settings page.", PMXI_Plugin::LANGUAGE_DOMAIN);?>">?</a>
7
+ </h3>
8
+ </div>
9
+ <div class="wpallimport-collapsed-content" style="padding: 0;">
10
+ <div class="wpallimport-collapsed-content-inner">
11
+
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
views/admin/import/process.php CHANGED
@@ -273,18 +273,24 @@
273
  count_failures++;
274
  $('.count_failures').val(count_failures);
275
 
 
 
 
 
 
 
 
 
 
276
  if (count_failures > 4 || records_per_request < 2){
277
  $('#process_notice').hide();
278
- //$('#wpallimport-try-again').hide();
279
- //$('.wp_all_import_restart_import').hide();
280
  $('.wpallimport-modal-message').html($('#wpallimport-error-terminated').html()).show();
281
-
282
- if (data != null && typeof data != 'undefined'){
283
- $('#status').html('Error ' + '<span class="pmxi_error_msg">' + data.responseText + '</span>');
284
- }
285
- else{
286
- $('#status').html('Error');
287
  }
 
 
288
  clearInterval(update);
289
  window.onbeforeunload = false;
290
 
273
  count_failures++;
274
  $('.count_failures').val(count_failures);
275
 
276
+ if (data != null && typeof data != 'undefined' && typeof data.log != 'undefined'){
277
+ $('#loglist').append(data.log);
278
+ write_log();
279
+ }
280
+
281
+ if (data != null && typeof data != 'undefined' && parseInt(data.records_per_request)){
282
+ records_per_request = data.records_per_request;
283
+ }
284
+
285
  if (count_failures > 4 || records_per_request < 2){
286
  $('#process_notice').hide();
 
 
287
  $('.wpallimport-modal-message').html($('#wpallimport-error-terminated').html()).show();
288
+ var errorMessage = "Import failed, please check logs";
289
+ if (data != null && typeof data != 'undefined' && typeof data.responseText != 'undefined'){
290
+ errorMessage = data.responseText;
 
 
 
291
  }
292
+ $('#status').html('Error ' + '<span class="pmxi_error_msg">' + errorMessage + '</span>');
293
+
294
  clearInterval(update);
295
  window.onbeforeunload = false;
296
 
views/admin/import/template/_featured_template.php CHANGED
@@ -52,9 +52,21 @@
52
  <div class="search_through_the_media_library">
53
  <div class="input" style="margin:3px;">
54
  <input type="hidden" name="<?php echo $section_slug; ?>search_existing_images" value="0" />
55
- <input type="checkbox" id="<?php echo $section_slug; ?>search_existing_images" name="<?php echo $section_slug; ?>search_existing_images" value="1" <?php echo $post[$section_slug . 'search_existing_images'] ? 'checked="checked"' : '' ?> class="fix_checkbox"/>
56
  <label for="<?php echo $section_slug; ?>search_existing_images"><?php _e('Search through the Media Library for existing images before importing new images','wp_all_import_plugin');?> </label>
57
- <a href="#help" class="wpallimport-help" title="<?php _e('If an image with the same file name is found in the Media Library then that image will be attached to this record instead of importing a new image. Disable this setting if your import has different images with the same file name.', 'wp_all_import_plugin') ?>" style="position: relative; top: -2px;">?</a>
 
 
 
 
 
 
 
 
 
 
 
 
58
  </div>
59
  <div class="input" style="margin: 3px;">
60
  <input type="hidden" name="<?php echo $section_slug; ?>do_not_remove_images" value="0" />
@@ -62,6 +74,14 @@
62
  <label for="<?php echo $section_slug; ?>do_not_remove_images"><?php _e('Keep images currently in Media Library', 'wp_all_import_plugin') ?></label>
63
  <a href="#help" class="wpallimport-help" title="<?php _e('If disabled, images attached to imported posts will be deleted and then all images will be imported.', 'wp_all_import_plugin') ?>" style="position:relative; top: -2px;">?</a>
64
  </div>
 
 
 
 
 
 
 
 
65
  </div>
66
  <?php if ($section_type == 'images'): ?>
67
  <div class="input">
52
  <div class="search_through_the_media_library">
53
  <div class="input" style="margin:3px;">
54
  <input type="hidden" name="<?php echo $section_slug; ?>search_existing_images" value="0" />
55
+ <input type="checkbox" id="<?php echo $section_slug; ?>search_existing_images" name="<?php echo $section_slug; ?>search_existing_images" value="1" <?php echo $post[$section_slug . 'search_existing_images'] ? 'checked="checked"' : '' ?> class="switcher fix_checkbox"/>
56
  <label for="<?php echo $section_slug; ?>search_existing_images"><?php _e('Search through the Media Library for existing images before importing new images','wp_all_import_plugin');?> </label>
57
+ <a href="#help" class="wpallimport-help" title="<?php _e('If an image with the same file name or remote URL is found in the Media Library then that image will be attached to this record instead of importing a new image. Disable this setting if you always want to download a new image.', 'wp_all_import_plugin') ?>" style="position: relative; top: -2px;">?</a>
58
+ <div class="switcher-target-<?php echo $section_slug; ?>search_existing_images" style="padding-left:23px;">
59
+ <div class="search_through_the_media_library_logic">
60
+ <div class="input">
61
+ <input type="radio" id="<?php echo $section_slug; ?>search_existing_images_logic_url" name="<?php echo $section_slug; ?>search_existing_images_logic" value="by_url" <?php echo ( "by_url" == $post['search_existing_images_logic'] ) ? 'checked="checked"': '' ?>/>
62
+ <label for="<?php echo $section_slug; ?>search_existing_images_logic_url"><?php _e('Match image by URL', 'wp_all_import_plugin') ?></label>
63
+ </div>
64
+ <div class="input">
65
+ <input type="radio" id="<?php echo $section_slug; ?>search_existing_images_logic_filename" name="<?php echo $section_slug; ?>search_existing_images_logic" value="by_filename" <?php echo ( "by_filename" == $post['search_existing_images_logic'] ) ? 'checked="checked"': '' ?>/>
66
+ <label for="<?php echo $section_slug; ?>search_existing_images_logic_filename"><?php _e('Match image by filename', 'wp_all_import_plugin') ?></label>
67
+ </div>
68
+ </div>
69
+ </div>
70
  </div>
71
  <div class="input" style="margin: 3px;">
72
  <input type="hidden" name="<?php echo $section_slug; ?>do_not_remove_images" value="0" />
74
  <label for="<?php echo $section_slug; ?>do_not_remove_images"><?php _e('Keep images currently in Media Library', 'wp_all_import_plugin') ?></label>
75
  <a href="#help" class="wpallimport-help" title="<?php _e('If disabled, images attached to imported posts will be deleted and then all images will be imported.', 'wp_all_import_plugin') ?>" style="position:relative; top: -2px;">?</a>
76
  </div>
77
+ <?php if ($section_type == 'images'): ?>
78
+ <div class="input" style="margin: 3px;">
79
+ <input type="hidden" name="<?php echo $section_slug; ?>import_img_tags" value="0" />
80
+ <input type="checkbox" id="<?php echo $section_slug; ?>import_img_tags" name="<?php echo $section_slug; ?>import_img_tags" value="1" <?php echo ($post[$section_slug . 'import_img_tags']) ? 'checked="checked"': '' ?> />
81
+ <label for="<?php echo $section_slug; ?>import_img_tags"><?php _e('Scan through post content and import images wrapped in &lt;img&gt; tags', 'wp_all_import_plugin') ?></label>
82
+ <a href="#help" class="wpallimport-help" title="<?php _e('Only images hosted on other sites will be imported. Images will be imported to WordPress and the <img> tag updated with the new image URL.', 'wp_all_import_plugin') ?>" style="position:relative; top: -2px;">?</a>
83
+ </div>
84
+ <?php endif; ?>
85
  </div>
86
  <?php if ($section_type == 'images'): ?>
87
  <div class="input">
views/admin/import/template/_other_template.php CHANGED
@@ -155,8 +155,8 @@
155
  foreach ($post_formats[0] as $post_format) {
156
  ?>
157
  <div class="input">
158
- <input type="radio" id="post_format_<?php echo $post_format . "_" . $entry; ?>" name="post_format" value="<?php echo $post_format; ?>" <?php echo $post_format == $post['post_format'] ? 'checked="checked"' : '' ?> />
159
- <label for="post_format_<?php echo $post_format . "_" . $entry; ?>"><?php _e( ucfirst($post_format), 'wp_all_import_plugin') ?></label>
160
  </div>
161
  <?php
162
  }
155
  foreach ($post_formats[0] as $post_format) {
156
  ?>
157
  <div class="input">
158
+ <input type="radio" id="post_format_<?php echo $post_format; ?>" name="post_format" value="<?php echo $post_format; ?>" <?php echo $post_format == $post['post_format'] ? 'checked="checked"' : '' ?> />
159
+ <label for="post_format_<?php echo $post_format; ?>"><?php _e( ucfirst($post_format), 'wp_all_import_plugin') ?></label>
160
  </div>
161
  <?php
162
  }
views/admin/import/template/_taxonomies_template.php CHANGED
@@ -206,7 +206,7 @@ if ( ! empty($post_taxonomies)):
206
  </li>
207
 
208
  </ol>
209
- <input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name; ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
210
  <?php do_action('pmxi_category_options_view', ((!empty($post['post_taxonomies'][$ctx->name])) ? $post['post_taxonomies'][$ctx->name] : false), $ctx->name, $post_type, $ctx->labels->name); ?>
211
  <div class="input" style="margin-left:17px;">
212
  <label><?php _e('Separated by', 'wp_all_import_plugin'); ?></label>
206
  </li>
207
 
208
  </ol>
209
+ <input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name; ?>]" value="<?php echo empty($post['post_taxonomies'][$ctx->name]) ? '' : esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
210
  <?php do_action('pmxi_category_options_view', ((!empty($post['post_taxonomies'][$ctx->name])) ? $post['post_taxonomies'][$ctx->name] : false), $ctx->name, $post_type, $ctx->labels->name); ?>
211
  <div class="input" style="margin-left:17px;">
212
  <label><?php _e('Separated by', 'wp_all_import_plugin'); ?></label>
views/admin/manage/index.php CHANGED
@@ -302,12 +302,11 @@ $columns = apply_filters('pmxi_manage_imports_columns', $columns);
302
  break;
303
  case 'info':
304
  ?>
305
- <td>
306
-
307
- <a href="<?php echo add_query_arg(array('id' => $item['id'], 'action' => 'scheduling'), $this->baseUrl)?>"><?php _e('Cron Scheduling', 'wp_all_import_plugin'); ?></a> <br>
308
-
309
  <a href="<?php echo add_query_arg(array('page' => 'pmxi-admin-history', 'id' => $item['id']), remove_query_arg('pagenum', $this->baseUrl))?>"><?php _e('History Logs', 'wp_all_import_plugin'); ?></a>
310
-
311
  </td>
312
  <?php
313
  break;
302
  break;
303
  case 'info':
304
  ?>
305
+ <td>
306
+ <a href="#" class="scheduling-disabled"><?php _e('Scheduling Options', 'wp_all_import_plugin'); ?></a>
307
+ <a href="#help" class="wpallimport-help" style="position: relative; top: -2px; margin-left: 0;" title="<?php _e("To run this import on a schedule you must use the 'Download from URL' or 'Use existing file' option on the Import Settings page.", PMXI_Plugin::LANGUAGE_DOMAIN);?>">?</a>
308
+ <br/>
309
  <a href="<?php echo add_query_arg(array('page' => 'pmxi-admin-history', 'id' => $item['id']), remove_query_arg('pagenum', $this->baseUrl))?>"><?php _e('History Logs', 'wp_all_import_plugin'); ?></a>
 
310
  </td>
311
  <?php
312
  break;