Import any XML or CSV File to WordPress - Version 3.0.4

Version Description

  • Fixed import categories;
  • Updated UI/UX;
  • Added import/export templates feature;
  • Added enhanced session functionality;
  • Added option to set post status with XPath;
  • Added feeds encoding feature;
Download this release

Release Info

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

Code changes from version 3.0.3 to 3.0.4

Files changed (72) hide show
  1. actions/admin_init.php +5 -0
  2. actions/admin_notices.php +1 -1
  3. actions/delete_post.php +5 -5
  4. actions/wp.php +1 -1
  5. actions/wp_loaded.php +1 -3
  6. actions/wp_session_garbage_collection.php +44 -15
  7. classes/arrayaccess.php +6 -4
  8. classes/chunk.php +93 -84
  9. classes/config.php +90 -90
  10. classes/helper.php +139 -139
  11. classes/input.php +71 -71
  12. classes/session.php +76 -22
  13. config/options.php +4 -3
  14. controllers/admin/help.php +11 -11
  15. controllers/admin/home.php +11 -11
  16. controllers/admin/import.php +362 -346
  17. controllers/admin/manage.php +14 -28
  18. controllers/admin/settings.php +68 -8
  19. controllers/controller.php +101 -101
  20. controllers/controller/admin.php +1 -1
  21. helpers/backward.php +39 -39
  22. helpers/get_file_curl.php +40 -23
  23. helpers/get_taxonomies_by_object_type.php +24 -24
  24. helpers/is_exists_term.php +26 -0
  25. helpers/pmxi_functions.php +27 -3
  26. helpers/str_getcsv.php +17 -16
  27. helpers/wp_delete_attachments.php +25 -9
  28. helpers/wp_redirect_or_javascript.php +16 -16
  29. libraries/XmlImportCsvParse.php +30 -28
  30. libraries/XmlImportParser.php +1 -1
  31. libraries/XmlImportTemplateCodeGenerator.php +2 -2
  32. libraries/XmlImportTemplateParser.php +43 -3
  33. libraries/pclzip.lib.php +5697 -5697
  34. models/file/list.php +31 -31
  35. models/file/record.php +83 -83
  36. models/import/list.php +7 -7
  37. models/import/record.php +448 -191
  38. models/model/list.php +148 -148
  39. models/model/record.php +5 -5
  40. models/post/list.php +9 -9
  41. models/post/record.php +14 -14
  42. models/template/list.php +7 -7
  43. models/template/record.php +12 -12
  44. plugin.php +48 -106
  45. readme.txt +101 -96
  46. schema.php +83 -82
  47. static/css/admin-ie.css +13 -13
  48. static/css/admin.css +183 -30
  49. static/js/admin.js +143 -43
  50. views/admin/home/index.php +16 -16
  51. views/admin/import/element_after.php +24 -5
  52. views/admin/import/error.php +2 -2
  53. views/admin/import/index.php +2 -2
  54. views/admin/import/options.php +125 -121
  55. views/admin/import/options/_author_template.php +15 -3
  56. views/admin/import/options/_buttons_template.php +3 -49
  57. views/admin/import/options/_categories_template.php +10 -9
  58. views/admin/import/options/_custom_fields_template.php +1 -1
  59. views/admin/import/options/_featured_template.php +63 -48
  60. views/admin/import/options/_main_options_template.php +51 -11
  61. views/admin/import/options/_reimport_template.php +18 -12
  62. views/admin/import/options/_settings_template.php +60 -0
  63. views/admin/import/options/_taxonomies_template.php +18 -15
  64. views/admin/import/preview.php +11 -11
  65. views/admin/import/tag.php +42 -19
  66. views/admin/import/template.php +55 -42
  67. views/admin/manage/bulk.php +17 -17
  68. views/admin/manage/delete.php +13 -13
  69. views/admin/manage/index.php +5 -8
  70. views/admin/manage/update.php +22 -22
  71. views/admin/settings/index.php +34 -20
  72. views/controller/error.php +2 -2
actions/admin_init.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxi_admin_init(){
4
+ wp_enqueue_script('pmxi-script', PMXI_ROOT_URL . '/static/js/pmxi.js', array('jquery'), PMXI_VERSION);
5
+ }
actions/admin_notices.php CHANGED
@@ -14,7 +14,7 @@ function pmxi_admin_notices() {
14
  ) ?>
15
  </p></div>
16
  <?php
17
- }
18
 
19
  // notify user
20
  if (!PMXI_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], 'pmxi-admin') !== false) {
14
  ) ?>
15
  </p></div>
16
  <?php
17
+ }
18
 
19
  // notify user
20
  if (!PMXI_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], 'pmxi-admin') !== false) {
actions/delete_post.php CHANGED
@@ -1,6 +1,6 @@
1
- <?php
2
-
3
- function pmxi_delete_post($post_id) {
4
- $post = new PMXI_Post_Record();
5
- $post->get_by_post_id($post_id)->isEmpty() or $post->delete();
6
  }
1
+ <?php
2
+
3
+ function pmxi_delete_post($post_id) {
4
+ $post = new PMXI_Post_Record();
5
+ $post->get_by_post_id($post_id)->isEmpty() or $post->delete();
6
  }
actions/wp.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- function pmxi_wp() {
4
  if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) {
5
  wp_schedule_event( time(), 'twicedaily', 'wp_session_garbage_collection' );
6
  }
1
  <?php
2
 
3
+ function pmxi_wp() {
4
  if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) {
5
  wp_schedule_event( time(), 'twicedaily', 'wp_session_garbage_collection' );
6
  }
actions/wp_loaded.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- function pmxi_wp_loaded() {
4
-
5
- wp_enqueue_script('pmxi-script', PMXI_ROOT_URL . '/static/js/pmxi.js', array('jquery'));
6
 
7
  }
1
  <?php
2
 
3
+ function pmxi_wp_loaded() {
 
 
4
 
5
  }
actions/wp_session_garbage_collection.php CHANGED
@@ -1,33 +1,62 @@
1
  <?php
2
 
3
  function pmxi_wp_session_garbage_collection() {
4
- global $wpdb;
5
 
6
  if ( defined( 'WP_SETUP_CONFIG' ) ) {
7
  return;
8
  }
9
 
 
 
10
  if ( ! defined( 'WP_INSTALLING' ) ) {
11
- $expiration_keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_pmxi_session_expires_%'" );
 
 
 
 
12
 
13
- $now = time();
14
- $expired_sessions = array();
 
 
 
15
 
16
- foreach( $expiration_keys as $expiration ) {
17
- // If the session has expired
18
- if ( $now > intval( $expiration->option_value ) ) {
19
- // Get the session ID by parsing the option_name
20
- $session_id = substr( $expiration->option_name, 20 );
21
 
22
- $expired_sessions[] = $expiration->option_name;
23
- $expired_sessions[] = "_pmxi_session_$session_id";
 
 
24
  }
25
  }
 
 
 
 
 
 
 
 
 
26
 
27
- // Delete all expired sessions in a single query
28
- if ( ! empty( $expired_sessions ) ) {
29
- $option_names = implode( "','", $expired_sessions );
30
- $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('$option_names')" );
 
 
 
 
 
 
 
 
 
 
31
  }
32
  }
33
 
1
  <?php
2
 
3
  function pmxi_wp_session_garbage_collection() {
4
+ global $wpdb;
5
 
6
  if ( defined( 'WP_SETUP_CONFIG' ) ) {
7
  return;
8
  }
9
 
10
+ $session_mode = PMXI_Plugin::getInstance()->getOption('session_mode');
11
+
12
  if ( ! defined( 'WP_INSTALLING' ) ) {
13
+ if ($session_mode == 'database'){
14
+ $expiration_keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_pmxi_session_expires_%'" );
15
+
16
+ $now = time();
17
+ $expired_sessions = array();
18
 
19
+ foreach( $expiration_keys as $expiration ) {
20
+ // If the session has expired
21
+ if ( $now > intval( $expiration->option_value ) ) {
22
+ // Get the session ID by parsing the option_name
23
+ $session_id = str_replace("_pmxi_session_expires_", "", $expiration->option_name);
24
 
25
+ $expired_sessions[] = $expiration->option_name;
26
+ $expired_sessions[] = "_pmxi_session_$session_id";
27
+ }
28
+ }
 
29
 
30
+ // Delete all expired sessions in a single query
31
+ if ( ! empty( $expired_sessions ) ) {
32
+ $option_names = implode( "','", $expired_sessions );
33
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('$option_names')" );
34
  }
35
  }
36
+ elseif ($session_mode == 'files'){
37
+ $session_files = scandir( PMXI_ROOT_DIR . '/sessions');
38
+
39
+ if (!empty($session_files)){
40
+ $now = time();
41
+ $expired_sessions = array();
42
+ foreach ($session_files as $key => $file) {
43
+ if ( strpos($file, "_pmxi_session_expires_") !== false){
44
+ $expiration_value = @file_get_contents( PMXI_ROOT_DIR . "/sessions/" . $file );
45
 
46
+ if ($now > intval($expiration_value)){
47
+ $session_id = str_replace("_pmxi_session_expires_", "", $file);
48
+ $expired_sessions[] = $file;
49
+ $expired_sessions[] = "_pmxi_session_$session_id";
50
+ }
51
+ }
52
+ }
53
+ // Delete all expired sessions in a single query
54
+ if ( ! empty( $expired_sessions ) ) {
55
+ foreach ($expired_sessions as $key => $file) {
56
+ @unlink( PMXI_ROOT_DIR . "/sessions/" . $file );
57
+ }
58
+ }
59
+ }
60
  }
61
  }
62
 
classes/arrayaccess.php CHANGED
@@ -22,7 +22,7 @@ class PMXI_ArrayAccess implements ArrayAccess {
22
  *
23
  * @var array
24
  */
25
- protected $container = array();
26
 
27
  /**
28
  * Flag whether or not the internal collection has been changed.
@@ -60,9 +60,11 @@ class PMXI_ArrayAccess implements ArrayAccess {
60
  */
61
  public function toArray() {
62
  $data = $this->container;
63
- foreach ( $data as $key => $value ) {
64
- if ( $value instanceof self ) {
65
- $data[ $key ] = $value->toArray();
 
 
66
  }
67
  }
68
  return $data;
22
  *
23
  * @var array
24
  */
25
+ public $container = array();
26
 
27
  /**
28
  * Flag whether or not the internal collection has been changed.
60
  */
61
  public function toArray() {
62
  $data = $this->container;
63
+ if (!empty($data)){
64
+ foreach ( $data as $key => $value ) {
65
+ if ( $value instanceof self ) {
66
+ $data[ $key ] = $value->toArray();
67
+ }
68
  }
69
  }
70
  return $data;
classes/chunk.php CHANGED
@@ -37,7 +37,8 @@ class PMXI_Chunk {
37
  'path' => './', // string The path to check for $file in
38
  'element' => '', // string The XML element to return
39
  'chunkSize' => 1024, // integer The amount of bytes to retrieve in each chunk
40
- 'type' => 'upload'
 
41
  );
42
 
43
  /**
@@ -63,8 +64,10 @@ class PMXI_Chunk {
63
 
64
  public $encoding = "";
65
 
66
- public $return_with_encoding = true;
67
-
 
 
68
  /**
69
  * handle
70
  *
@@ -117,12 +120,16 @@ class PMXI_Chunk {
117
  $this->options['chunkSize'] = 1024;
118
  }
119
 
120
- $this->options['chunkSize'] *= PMXI_Plugin::getInstance()->getOption('chunk_size');
 
 
121
 
122
  $this->pointer = $pointer;
123
 
124
  // set the filename
125
  $this->file = $file;
 
 
126
 
127
  // open the file
128
  $this->handle = @fopen($this->file, 'rb');
@@ -160,7 +167,7 @@ class PMXI_Chunk {
160
 
161
  } else {
162
  $element = '';
163
- }
164
 
165
  // initialize the buffer
166
  $buffer = false;
@@ -174,27 +181,30 @@ class PMXI_Chunk {
174
  while ($this->reading and (count($founded_tags) < 500)) {
175
  $c = @fread($this->handle, $this->options['chunkSize']);
176
 
177
- $c = $this->removeColonsFromRSS($c);
 
 
 
 
 
178
 
179
  if ($this->is_validate) {
180
  if (stripos($c, "xmlns") !== false){
181
  $this->is_validate = false;
182
  }
183
- }
184
-
185
- if ( preg_match_all("/<\\w+\\s*[^<|^\n]*\\s*\/?>/i", $c, $matches, PREG_PATTERN_ORDER) ){
186
  foreach ($matches[0] as $tag) {
187
- if (strpos($tag, "<br") === false) {
188
  $tag = explode(" ", trim(str_replace(array('<','>','/'), '', $tag)));
189
  array_push($founded_tags, $tag[0]);
190
  }
191
- }
192
  }
193
- $this->reading = (!@feof($this->handle));
194
  }
195
-
196
- // we must be looking for a specific element
197
- }
198
 
199
  if (empty($this->encoding)) {
200
  fseek($this->handle, 0);
@@ -202,14 +212,14 @@ class PMXI_Chunk {
202
  // read in the whole doc, cos we don't know what's wanted
203
  while ($this->reading) {
204
  $c = @fread($this->handle, $this->options['chunkSize']);
205
- $enc = preg_match("/<\?xml.*\?>/i", $c, $enc_matches);
206
  if ($enc)
207
- $this->encoding = $enc_matches[0];
208
  $this->reading = false;
209
  }
210
  }
211
 
212
- if (empty($this->encoding)) $this->encoding = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
213
 
214
  if (empty($element) and !empty($founded_tags)) {
215
 
@@ -217,30 +227,42 @@ class PMXI_Chunk {
217
 
218
  if (!empty($element_counts)){
219
 
220
- //$this->cloud = array_slice($element_counts, 0, 2);
221
-
222
  foreach ($element_counts as $tag => $count) {
223
- if (strpos($tag, ":") === false){
224
- if ($count > 1 and empty($this->options['element'])) {
225
- $this->options['element'] = $element = $tag;
226
- }
227
- else{
228
- $this->cloud[$tag] = $count;
229
- }
230
- }
231
  }
 
 
 
 
232
  }
233
 
234
  }
235
-
 
 
236
  // return it all if element doesn't founded
237
- if (empty($element)){
238
- if (!empty($element_counts)){
239
- $this->options['element'] = $element = array_shift(array_keys($element_counts));
240
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  else return false;
242
- }
243
-
244
  // we must be looking for a specific element
245
 
246
  // initialize the buffer
@@ -265,84 +287,65 @@ class PMXI_Chunk {
265
  fseek($this->handle, $this->pointer);
266
 
267
  // start reading
268
- while ($this->reading && !@feof($this->handle)) {
269
 
270
  // store the chunk in a temporary variable
271
  $tmp = @fread($this->handle, $this->options['chunkSize']);
272
 
273
- $tmp = $this->removeColonsFromRSS($tmp);
274
 
 
 
275
  // update the global buffer
276
  $this->readBuffer .= $tmp;
277
 
278
- if ($checkOpen === false){
279
-
280
- $checkOpen = preg_match_all("/".$open."[ |>]{1}/i", $tmp, $checkOpenmatches, PREG_OFFSET_CAPTURE);
281
-
282
- if (!empty($checkOpenmatches[0])){
283
-
284
- $checkOpen = $checkOpenmatches[0][0][1];
285
-
286
- }
287
- else $checkOpen = false;
288
 
289
- // check for the open string
290
- /*$checkOpen = stripos($tmp, $open." ");
291
- if ($checkOpen === false) stripos($tmp, $open.">"); */
292
 
 
 
293
  // if it wasn't in the new buffer
294
  if ($checkOpen === false && !($store)) {
295
- // check the full buffer (in case it was only half in this buffer)
296
-
297
- $checkOpen = preg_match_all("/".$open."[ |>]{1}/i", $this->readBuffer, $checkOpenmatches, PREG_OFFSET_CAPTURE);
298
-
299
- if (!empty($checkOpenmatches[0])){
300
-
301
- $checkOpen = $checkOpenmatches[0][0][1];
302
 
303
- }
304
- else $checkOpen = false;
305
-
306
- /*$checkOpen = strpos($this->readBuffer, $open." ");
307
- if ($checkOpen === false) $checkOpen = strpos($this->readBuffer, $open.">");*/
308
 
309
  // if it was in there
310
- if ($checkOpen !== false) {
311
- // set it to the remainder
312
- $checkOpen = $checkOpen % $this->options['chunkSize'];
313
- }
314
  }
315
  }
316
 
317
  // check for the close string
318
- $checkClose = preg_match_all("/<\/".$element.">/i", $tmp, $closematches, PREG_OFFSET_CAPTURE);
319
- $withoutcloseelement = (preg_match("%<".$element."(^<)*\/>%", $tmp, $matches)) ? strpos($tmp, $matches[0]) : false;
320
-
321
  if ($withoutcloseelement and $checkClose and $closematches[0][0][1] > $withoutcloseelement) $checkClose = false;
322
 
323
  if (!$checkClose){
324
- $checkClose = (preg_match("%<".$element."(^<)*\/>%", $tmp, $matches)) ? strpos($tmp, $matches[0]) : false;
325
-
326
- if ($checkClose !== false)
327
- $withoutcloseelement = true;
328
- else{
329
- $checkClose = (preg_match_all("%<".$element."(^<)*\/>%", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][count($matches[0]) - 1]) : false;
330
  if ($checkClose !== false) {
331
  $withoutcloseelement = true;
332
  $matches[0] = $matches[0][count($matches[0]) - 1];
333
  }
334
  }
335
- }
336
  else{
337
 
338
  $close_finded = false;
339
  $length = $closematches[0][0][1] - $checkOpen;
340
 
341
- $checkDuplicateOpen = preg_match_all("/".$open."[ |>]{1}/i", substr($this->readBuffer, $checkOpen, $length), $matches, PREG_OFFSET_CAPTURE);
342
-
343
  while (!$close_finded){
344
  if ($checkDuplicateOpen > 1 and !empty($closematches[0][$checkDuplicateOpen - 1])){
345
- $secondcheckDuplicateOpen = preg_match_all("/".$open."[ |>]{1}/i", substr($this->readBuffer, $checkOpen, $closematches[0][$checkDuplicateOpen - 1][1] - $checkOpen), $matches, PREG_OFFSET_CAPTURE);
346
  if ($secondcheckDuplicateOpen == $checkDuplicateOpen){
347
  $checkClose = $closematches[0][$checkDuplicateOpen - 1][1];
348
  $close_finded = true;
@@ -365,8 +368,8 @@ class PMXI_Chunk {
365
  }
366
 
367
  if ($checkClose !== false) {
368
- // add the length of the close string itself
369
- if ( ! $withoutcloseelement)
370
  $checkClose += strlen($close);
371
  else
372
  $checkClose += strlen($matches[0]); // "/>" symbols
@@ -425,20 +428,26 @@ class PMXI_Chunk {
425
  }
426
 
427
  function removeColonsFromRSS($feed) {
 
 
 
 
 
428
  // pull out colons from start tags
429
  // (<\w+):(\w+>)
430
- $pattern = '/(<\w+):(\w+[ |>]{1})/i';
431
  $replacement = '$1_$2';
432
  $feed = preg_replace($pattern, $replacement, $feed);
433
  // pull out colons from end tags
434
  // (<\/\w+):(\w+>)
435
- $pattern = '/(<\/\w+):(\w+>)/i';
436
  $replacement = '$1_$2';
437
  $feed = preg_replace($pattern, $replacement, $feed);
438
  // pull out colons from attributes
439
- $pattern = '/(\s+\w+):(\w+[=]{1})/i';
440
  $replacement = '$1_$2';
441
  $feed = preg_replace($pattern, $replacement, $feed);
 
442
  return $feed;
443
  }
444
  }
37
  'path' => './', // string The path to check for $file in
38
  'element' => '', // string The XML element to return
39
  'chunkSize' => 1024, // integer The amount of bytes to retrieve in each chunk
40
+ 'type' => 'upload',
41
+ 'is_remove_colons' => false
42
  );
43
 
44
  /**
64
 
65
  public $encoding = "";
66
 
67
+ public $case_sensitive = 1;
68
+
69
+ public $return_with_encoding = true;
70
+
71
  /**
72
  * handle
73
  *
120
  $this->options['chunkSize'] = 1024;
121
  }
122
 
123
+ $chunk_size = PMXI_Plugin::getInstance()->getOption('chunk_size');
124
+
125
+ $this->options['chunkSize'] *= $chunk_size;
126
 
127
  $this->pointer = $pointer;
128
 
129
  // set the filename
130
  $this->file = $file;
131
+
132
+ $this->case_sensitive = PMXI_Plugin::getInstance()->getOption('case_sensitive');
133
 
134
  // open the file
135
  $this->handle = @fopen($this->file, 'rb');
167
 
168
  } else {
169
  $element = '';
170
+ }
171
 
172
  // initialize the buffer
173
  $buffer = false;
181
  while ($this->reading and (count($founded_tags) < 500)) {
182
  $c = @fread($this->handle, $this->options['chunkSize']);
183
 
184
+ if ( $this->options['is_remove_colons'] === false ) {
185
+ $this->options['is_remove_colons'] = strpos($c, ":");
186
+ }
187
+
188
+ if ($this->options['is_remove_colons'] !== false)
189
+ $c = $this->removeColonsFromRSS($c);
190
 
191
  if ($this->is_validate) {
192
  if (stripos($c, "xmlns") !== false){
193
  $this->is_validate = false;
194
  }
195
+ }
196
+ if ( @preg_match_all("/<\\w+\\s*[^<|^\n|^>]*\\s*\/?>/" . ($this->case_sensitive ? "i" : ""), $c, $matches, PREG_PATTERN_ORDER) ){
 
197
  foreach ($matches[0] as $tag) {
198
+ if ( strpos($tag, "<br") === false and strpos($tag, "?xml") === false and strpos($tag, "!--") === false and strpos($tag, "<p>") === false and strpos($tag, "<li>") === false and strpos($tag, "<ul>") === false and strpos($tag, "<a ") === false) {
199
  $tag = explode(" ", trim(str_replace(array('<','>','/'), '', $tag)));
200
  array_push($founded_tags, $tag[0]);
201
  }
202
+ }
203
  }
204
+ $this->reading = (!@feof($this->handle));
205
  }
206
+ // we must be looking for a specific element
207
+ }
 
208
 
209
  if (empty($this->encoding)) {
210
  fseek($this->handle, 0);
212
  // read in the whole doc, cos we don't know what's wanted
213
  while ($this->reading) {
214
  $c = @fread($this->handle, $this->options['chunkSize']);
215
+ $enc = @preg_match("/<\?xml[^<]*\?>/" . ($this->case_sensitive ? "i" : ""), $c, $enc_matches);
216
  if ($enc)
217
+ $this->encoding = $enc_matches[0];
218
  $this->reading = false;
219
  }
220
  }
221
 
222
+ if (empty($this->encoding) or strpos($this->encoding, 'encoding') === false) $this->encoding = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
223
 
224
  if (empty($element) and !empty($founded_tags)) {
225
 
227
 
228
  if (!empty($element_counts)){
229
 
 
 
230
  foreach ($element_counts as $tag => $count) {
231
+ if (strpos($tag, ":") === false)
232
+ $this->cloud[$tag] = $count;
 
 
 
 
 
 
233
  }
234
+
235
+ $element_counts = array_flip($element_counts);
236
+ krsort($element_counts);
237
+
238
  }
239
 
240
  }
241
+
242
+ $main_elements = array('node', 'product', 'job', 'deal', 'entry', 'item', 'property', 'listing', 'hotel', 'record', 'article');
243
+
244
  // return it all if element doesn't founded
245
+ if (empty($element)){
246
+ if (!empty($this->cloud)){
247
+ foreach ($this->cloud as $element_name => $value) {
248
+ if ( in_array(strtolower($element_name), $main_elements) ){
249
+ $this->options['element'] = $element = $element_name;
250
+ break;
251
+ }
252
+ }
253
+ if (empty($element)){
254
+ if (count($element_counts) > 1) array_shift($element_counts);
255
+ foreach ($element_counts as $el) {
256
+ if ( ! preg_match("%[\'\/~`\!@#\$\^&\*\(\)\-\+=\{\}\[\]\|;:\"\<\>,\.\?\\\]%", $el) ) {
257
+ $this->options['element'] = $element = $el;
258
+ break;
259
+ }
260
+ }
261
+ }
262
+ }
263
  else return false;
264
+ }
265
+
266
  // we must be looking for a specific element
267
 
268
  // initialize the buffer
287
  fseek($this->handle, $this->pointer);
288
 
289
  // start reading
290
+ while ($this->reading && !@feof($this->handle)) {
291
 
292
  // store the chunk in a temporary variable
293
  $tmp = @fread($this->handle, $this->options['chunkSize']);
294
 
295
+ if ( $this->options['is_remove_colons'] === false ) $this->options['is_remove_colons'] = strpos($tmp, ":");
296
 
297
+ if ($this->options['is_remove_colons'] !== false) $tmp = $this->removeColonsFromRSS($tmp);
298
+
299
  // update the global buffer
300
  $this->readBuffer .= $tmp;
301
 
302
+ if ($checkOpen === false) {
 
 
 
 
 
 
 
 
 
303
 
304
+ $checkOpen = @preg_match_all( "/". $open ."[\s|>]{1}/" . ($this->case_sensitive ? "i" : ""), $tmp, $checkOpenmatches, PREG_OFFSET_CAPTURE);
 
 
305
 
306
+ $checkOpen = (!empty($checkOpenmatches[0])) ? $checkOpenmatches[0][0][1] : false;
307
+
308
  // if it wasn't in the new buffer
309
  if ($checkOpen === false && !($store)) {
 
 
 
 
 
 
 
310
 
311
+ // check the full buffer (in case it was only half in this buffer)
312
+ $checkOpen = @preg_match_all("/".$open."[\s|>]{1}/" . ($this->case_sensitive ? "i" : ""), $this->readBuffer, $checkOpenmatches, PREG_OFFSET_CAPTURE);
313
+
314
+ $checkOpen = (!empty($checkOpenmatches[0])) ? $checkOpenmatches[0][0][1] : false;
 
315
 
316
  // if it was in there
317
+ if ($checkOpen !== false) $checkOpen = $checkOpen % $this->options['chunkSize'];
318
+
 
 
319
  }
320
  }
321
 
322
  // check for the close string
323
+ $checkClose = @preg_match_all("/<\/".$element.">/" . ($this->case_sensitive ? "i" : ""), $tmp, $closematches, PREG_OFFSET_CAPTURE);
324
+ $withoutcloseelement = (@preg_match("/(<".$element."\s{1}[^<]*\/>|<".$element."\/>)/" . ($this->case_sensitive ? "i" : ""), $tmp, $matches)) ? strpos($tmp, $matches[0]) : false;
325
+
326
  if ($withoutcloseelement and $checkClose and $closematches[0][0][1] > $withoutcloseelement) $checkClose = false;
327
 
328
  if (!$checkClose){
329
+ $checkClose = $withoutcloseelement;
330
+
331
+ if ($checkClose === false){
332
+ $checkClose = (@preg_match_all("/(<".$element."\s{1}[^<]*\/>|<".$element."\/>)/" . ($this->case_sensitive ? "i" : ""), $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][count($matches[0]) - 1]) : false;
 
 
333
  if ($checkClose !== false) {
334
  $withoutcloseelement = true;
335
  $matches[0] = $matches[0][count($matches[0]) - 1];
336
  }
337
  }
338
+ }
339
  else{
340
 
341
  $close_finded = false;
342
  $length = $closematches[0][0][1] - $checkOpen;
343
 
344
+ $checkDuplicateOpen = @preg_match_all("/".$open."[\s|>]{1}/" . ($this->case_sensitive ? "i" : ""), substr($this->readBuffer, $checkOpen, $length), $matches, PREG_OFFSET_CAPTURE);
345
+
346
  while (!$close_finded){
347
  if ($checkDuplicateOpen > 1 and !empty($closematches[0][$checkDuplicateOpen - 1])){
348
+ $secondcheckDuplicateOpen = @preg_match_all("/".$open."[\s|>]{1}/" . ($this->case_sensitive ? "i" : ""), substr($this->readBuffer, $checkOpen, $closematches[0][$checkDuplicateOpen - 1][1] - $checkOpen), $matches, PREG_OFFSET_CAPTURE);
349
  if ($secondcheckDuplicateOpen == $checkDuplicateOpen){
350
  $checkClose = $closematches[0][$checkDuplicateOpen - 1][1];
351
  $close_finded = true;
368
  }
369
 
370
  if ($checkClose !== false) {
371
+ // add the length of the close string itself
372
+ if ( ! $withoutcloseelement or ( !empty($closematches[0][0][1]) and $closematches[0][0][1] < $withoutcloseelement))
373
  $checkClose += strlen($close);
374
  else
375
  $checkClose += strlen($matches[0]); // "/>" symbols
428
  }
429
 
430
  function removeColonsFromRSS($feed) {
431
+
432
+ /*$pattern = '/(<[^<:>]*):/' . ($this->case_sensitive ? 'i' : '');
433
+ $replacement = '$1_';
434
+ $feed = preg_replace($pattern, $replacement, $feed); */
435
+
436
  // pull out colons from start tags
437
  // (<\w+):(\w+>)
438
+ $pattern = '/(<\w+):(\w+[ |>]{1})/' . ($this->case_sensitive ? 'i' : '');
439
  $replacement = '$1_$2';
440
  $feed = preg_replace($pattern, $replacement, $feed);
441
  // pull out colons from end tags
442
  // (<\/\w+):(\w+>)
443
+ $pattern = '/(<\/\w+):(\w+>)/' . ($this->case_sensitive ? 'i' : '');
444
  $replacement = '$1_$2';
445
  $feed = preg_replace($pattern, $replacement, $feed);
446
  // pull out colons from attributes
447
+ $pattern = '/(\s+\w+):(\w+[=]{1})/' . ($this->case_sensitive ? 'i' : '');
448
  $replacement = '$1_$2';
449
  $feed = preg_replace($pattern, $replacement, $feed);
450
+
451
  return $feed;
452
  }
453
  }
classes/config.php CHANGED
@@ -1,91 +1,91 @@
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
- /**
9
- * Config variables stored
10
- * @var array
11
- */
12
- protected $config = array();
13
- /**
14
- * List of loaded files in order to avoid loading same file several times
15
- * @var array
16
- */
17
- protected $loaded = array();
18
-
19
- /**
20
- * Static method to create config instance from file on disc
21
- * @param string $filePath
22
- * @param string[optional] $section
23
- * @return PMXI_Config
24
- */
25
- public static function createFromFile($filePath, $section = NULL) {
26
- $config = new self();
27
- return $config->loadFromFile($filePath, $section);
28
- }
29
-
30
- /**
31
- * Load config file
32
- * @param string $filePath
33
- * @param string[optional] $section
34
- * @return PMXI_Config
35
- */
36
- public function loadFromFile($filePath, $section = NULL) {
37
- if ( ! is_null($section)) {
38
- $this->config[$section] = self::createFromFile($filePath);
39
- } else {
40
- $filePath = realpath($filePath);
41
- if ($filePath and ! in_array($filePath, $this->loaded)) {
42
- require $filePath;
43
-
44
- $sandbox = create_function('', "require '$filePath'; if(array_keys(get_defined_vars()) != array('config')) return array(); return \$config;");
45
- $config = $sandbox();
46
- $this->loaded[] = $filePath;
47
- $this->config = array_merge($this->config, $config);
48
- }
49
- }
50
- return $this;
51
- }
52
- /**
53
- * Return value of setting with specified name
54
- * @param string $field Setting name
55
- * @param string[optional] $section Section name to look setting in
56
- * @return mixed
57
- */
58
- public function get($field, $section = NULL) {
59
- return ! is_null($section) ? $this->config[$section]->get($field) : $this->config[$field];
60
- }
61
-
62
- /**
63
- * Magic method for checking whether some config option are set
64
- * @param string $field
65
- * @return bool
66
- */
67
- public function __isset($field) {
68
- return isset($this->config[$field]);
69
- }
70
- /**
71
- * Magic method to implement object-like access to config parameters
72
- * @param string $field
73
- * @return mixed
74
- */
75
- public function __get($field) {
76
- return $this->config[$field];
77
- }
78
-
79
- /**
80
- * Return all config options as array
81
- * @return array
82
- */
83
- public function toArray($section = NULL) {
84
- return ! is_null($section) ? $this->config[$section]->toArray() : $this->config;
85
- }
86
-
87
- public function getIterator() {
88
- return new ArrayIterator($this->config);
89
- }
90
-
91
  }
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
+ /**
9
+ * Config variables stored
10
+ * @var array
11
+ */
12
+ protected $config = array();
13
+ /**
14
+ * List of loaded files in order to avoid loading same file several times
15
+ * @var array
16
+ */
17
+ protected $loaded = array();
18
+
19
+ /**
20
+ * Static method to create config instance from file on disc
21
+ * @param string $filePath
22
+ * @param string[optional] $section
23
+ * @return PMXI_Config
24
+ */
25
+ public static function createFromFile($filePath, $section = NULL) {
26
+ $config = new self();
27
+ return $config->loadFromFile($filePath, $section);
28
+ }
29
+
30
+ /**
31
+ * Load config file
32
+ * @param string $filePath
33
+ * @param string[optional] $section
34
+ * @return PMXI_Config
35
+ */
36
+ public function loadFromFile($filePath, $section = NULL) {
37
+ if ( ! is_null($section)) {
38
+ $this->config[$section] = self::createFromFile($filePath);
39
+ } else {
40
+ $filePath = realpath($filePath);
41
+ if ($filePath and ! in_array($filePath, $this->loaded)) {
42
+ require $filePath;
43
+
44
+ $sandbox = create_function('', "require '$filePath'; if(array_keys(get_defined_vars()) != array('config')) return array(); return \$config;");
45
+ $config = $sandbox();
46
+ $this->loaded[] = $filePath;
47
+ $this->config = array_merge($this->config, $config);
48
+ }
49
+ }
50
+ return $this;
51
+ }
52
+ /**
53
+ * Return value of setting with specified name
54
+ * @param string $field Setting name
55
+ * @param string[optional] $section Section name to look setting in
56
+ * @return mixed
57
+ */
58
+ public function get($field, $section = NULL) {
59
+ return ! is_null($section) ? $this->config[$section]->get($field) : $this->config[$field];
60
+ }
61
+
62
+ /**
63
+ * Magic method for checking whether some config option are set
64
+ * @param string $field
65
+ * @return bool
66
+ */
67
+ public function __isset($field) {
68
+ return isset($this->config[$field]);
69
+ }
70
+ /**
71
+ * Magic method to implement object-like access to config parameters
72
+ * @param string $field
73
+ * @return mixed
74
+ */
75
+ public function __get($field) {
76
+ return $this->config[$field];
77
+ }
78
+
79
+ /**
80
+ * Return all config options as array
81
+ * @return array
82
+ */
83
+ public function toArray($section = NULL) {
84
+ return ! is_null($section) ? $this->config[$section]->toArray() : $this->config;
85
+ }
86
+
87
+ public function getIterator() {
88
+ return new ArrayIterator($this->config);
89
+ }
90
+
91
  }
classes/helper.php CHANGED
@@ -1,139 +1,139 @@
1
- <?php
2
- /**
3
- * Helper class which defnes a namespace for some commonly used functions
4
- *
5
- * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
- */
7
- class PMXI_Helper {
8
- const GLOB_MARK = 1;
9
- const GLOB_NOSORT = 2;
10
- const GLOB_ONLYDIR = 4;
11
-
12
- const GLOB_NODIR = 256;
13
- const GLOB_PATH = 512;
14
- const GLOB_NODOTS = 1024;
15
- const GLOB_RECURSE = 2048;
16
-
17
- /**
18
- * A safe empowered glob().
19
- *
20
- * Function glob() is prohibited on some server (probably in safe mode)
21
- * (Message "Warning: glob() has been disabled for security reasons in
22
- * (script) on line (line)") for security reasons as stated on:
23
- * http://seclists.org/fulldisclosure/2005/Sep/0001.html
24
- *
25
- * safe_glob() intends to replace glob() using readdir() & fnmatch() instead.
26
- * Supported flags: self::GLOB_MARK, self::GLOB_NOSORT, self::GLOB_ONLYDIR
27
- * Additional flags: self::GLOB_NODIR, self::GLOB_PATH, self::GLOB_NODOTS, self::GLOB_RECURSE
28
- * (not original glob() flags)
29
- * @author BigueNique AT yahoo DOT ca
30
- * @updates
31
- * - 080324 Added support for additional flags: self::GLOB_NODIR, self::GLOB_PATH,
32
- * self::GLOB_NODOTS, self::GLOB_RECURSE
33
- * - 100607 Recurse is_dir check fixed by Pavel Kulbakin <p.kulbakin@gmail.com>
34
- */
35
- public static function safe_glob($pattern, $flags=0) {
36
- $split = explode('/', str_replace('\\', '/', $pattern));
37
- $mask = array_pop($split);
38
- $path = implode('/', $split);
39
-
40
- if (($dir = @opendir($path)) !== false or ($dir = @opendir($path . '/')) !== false) {
41
- $glob = array();
42
- while(($file = readdir($dir)) !== false) {
43
- // Recurse subdirectories (self::GLOB_RECURSE)
44
- if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
45
- $glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
46
- }
47
- // Match file mask
48
- if (self::fnmatch($mask, $file)) {
49
- if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
50
- && (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
51
- && (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
52
- ) {
53
- $glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
54
- }
55
- }
56
- }
57
- closedir($dir);
58
- if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
59
- return $glob;
60
- } else {
61
- return false;
62
- }
63
- }
64
-
65
- /**
66
- * Prepends $string to each element of $array
67
- * If $deep is true, will indeed also apply to sub-arrays
68
- * @author BigueNique AT yahoo DOT ca
69
- * @since 080324
70
- */
71
- public static function array_prepend($array, $string, $deep=false) {
72
- if(empty($array)||empty($string)) {
73
- return $array;
74
- }
75
- foreach ($array as $key => $element) {
76
- if (is_array($element)) {
77
- if ($deep) {
78
- $array[$key] = self::array_prepend($element,$string,$deep);
79
- } else {
80
- trigger_error(__METHOD__ . ': array element', E_USER_WARNING);
81
- }
82
- } else {
83
- $array[$key] = $string.$element;
84
- }
85
- }
86
- return $array;
87
-
88
- }
89
-
90
- const FNM_PATHNAME = 1;
91
- const FNM_NOESCAPE = 2;
92
- const FNM_PERIOD = 4;
93
- const FNM_CASEFOLD = 16;
94
-
95
- /**
96
- * non-POSIX complient remplacement for the fnmatch
97
- */
98
- public static function fnmatch($pattern, $string, $flags = 0) {
99
-
100
- $modifiers = null;
101
- $transforms = array(
102
- '\*' => '.*',
103
- '\?' => '.',
104
- '\[\!' => '[^',
105
- '\[' => '[',
106
- '\]' => ']',
107
- '\.' => '\.',
108
- '\\' => '\\\\',
109
- '\-' => '-',
110
- );
111
-
112
- // Forward slash in string must be in pattern:
113
- if ($flags & FNM_PATHNAME) {
114
- $transforms['\*'] = '[^/]*';
115
- }
116
-
117
- // Back slash should not be escaped:
118
- if ($flags & FNM_NOESCAPE) {
119
- unset($transforms['\\']);
120
- }
121
-
122
- // Perform case insensitive match:
123
- if ($flags & FNM_CASEFOLD) {
124
- $modifiers .= 'i';
125
- }
126
-
127
- // Period at start must be the same as pattern:
128
- if ($flags & FNM_PERIOD) {
129
- if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false;
130
- }
131
-
132
- $pattern = '#^'
133
- .strtr(preg_quote($pattern, '#'), $transforms)
134
- .'$#'
135
- .$modifiers;
136
-
137
- return (boolean)preg_match($pattern, $string);
138
- }
139
- }
1
+ <?php
2
+ /**
3
+ * Helper class which defnes a namespace for some commonly used functions
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXI_Helper {
8
+ const GLOB_MARK = 1;
9
+ const GLOB_NOSORT = 2;
10
+ const GLOB_ONLYDIR = 4;
11
+
12
+ const GLOB_NODIR = 256;
13
+ const GLOB_PATH = 512;
14
+ const GLOB_NODOTS = 1024;
15
+ const GLOB_RECURSE = 2048;
16
+
17
+ /**
18
+ * A safe empowered glob().
19
+ *
20
+ * Function glob() is prohibited on some server (probably in safe mode)
21
+ * (Message "Warning: glob() has been disabled for security reasons in
22
+ * (script) on line (line)") for security reasons as stated on:
23
+ * http://seclists.org/fulldisclosure/2005/Sep/0001.html
24
+ *
25
+ * safe_glob() intends to replace glob() using readdir() & fnmatch() instead.
26
+ * Supported flags: self::GLOB_MARK, self::GLOB_NOSORT, self::GLOB_ONLYDIR
27
+ * Additional flags: self::GLOB_NODIR, self::GLOB_PATH, self::GLOB_NODOTS, self::GLOB_RECURSE
28
+ * (not original glob() flags)
29
+ * @author BigueNique AT yahoo DOT ca
30
+ * @updates
31
+ * - 080324 Added support for additional flags: self::GLOB_NODIR, self::GLOB_PATH,
32
+ * self::GLOB_NODOTS, self::GLOB_RECURSE
33
+ * - 100607 Recurse is_dir check fixed by Pavel Kulbakin <p.kulbakin@gmail.com>
34
+ */
35
+ public static function safe_glob($pattern, $flags=0) {
36
+ $split = explode('/', str_replace('\\', '/', $pattern));
37
+ $mask = array_pop($split);
38
+ $path = implode('/', $split);
39
+
40
+ if (($dir = @opendir($path . '/')) !== false or ($dir = @opendir($path)) !== false) {
41
+ $glob = array();
42
+ while(($file = readdir($dir)) !== false) {
43
+ // Recurse subdirectories (self::GLOB_RECURSE)
44
+ if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
45
+ $glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
46
+ }
47
+ // Match file mask
48
+ if (self::fnmatch($mask, $file, FNM_CASEFOLD)) {
49
+ if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
50
+ && (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
51
+ && (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
52
+ ) {
53
+ $glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
54
+ }
55
+ }
56
+ }
57
+ closedir($dir);
58
+ if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
59
+ return $glob;
60
+ } else {
61
+ return false;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Prepends $string to each element of $array
67
+ * If $deep is true, will indeed also apply to sub-arrays
68
+ * @author BigueNique AT yahoo DOT ca
69
+ * @since 080324
70
+ */
71
+ public static function array_prepend($array, $string, $deep=false) {
72
+ if(empty($array)||empty($string)) {
73
+ return $array;
74
+ }
75
+ foreach ($array as $key => $element) {
76
+ if (is_array($element)) {
77
+ if ($deep) {
78
+ $array[$key] = self::array_prepend($element,$string,$deep);
79
+ } else {
80
+ trigger_error(__METHOD__ . ': array element', E_USER_WARNING);
81
+ }
82
+ } else {
83
+ $array[$key] = $string.$element;
84
+ }
85
+ }
86
+ return $array;
87
+
88
+ }
89
+
90
+ const FNM_PATHNAME = 1;
91
+ const FNM_NOESCAPE = 2;
92
+ const FNM_PERIOD = 4;
93
+ const FNM_CASEFOLD = 16;
94
+
95
+ /**
96
+ * non-POSIX complient remplacement for the fnmatch
97
+ */
98
+ public static function fnmatch($pattern, $string, $flags = 0) {
99
+
100
+ $modifiers = null;
101
+ $transforms = array(
102
+ '\*' => '.*',
103
+ '\?' => '.',
104
+ '\[\!' => '[^',
105
+ '\[' => '[',
106
+ '\]' => ']',
107
+ '\.' => '\.',
108
+ '\\' => '\\\\',
109
+ '\-' => '-',
110
+ );
111
+
112
+ // Forward slash in string must be in pattern:
113
+ if ($flags & FNM_PATHNAME) {
114
+ $transforms['\*'] = '[^/]*';
115
+ }
116
+
117
+ // Back slash should not be escaped:
118
+ if ($flags & FNM_NOESCAPE) {
119
+ unset($transforms['\\']);
120
+ }
121
+
122
+ // Perform case insensitive match:
123
+ if ($flags & FNM_CASEFOLD) {
124
+ $modifiers .= 'i';
125
+ }
126
+
127
+ // Period at start must be the same as pattern:
128
+ if ($flags & FNM_PERIOD) {
129
+ if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false;
130
+ }
131
+
132
+ $pattern = '#^'
133
+ .strtr(preg_quote($pattern, '#'), $transforms)
134
+ .'$#'
135
+ .$modifiers;
136
+
137
+ return (boolean)preg_match($pattern, $string);
138
+ }
139
+ }
classes/input.php CHANGED
@@ -1,72 +1,72 @@
1
- <?php
2
- class PMXI_Input {
3
- protected $filters = array('stripslashes');
4
-
5
- public function read($inputArray, $paramName, $default = NULL) {
6
- if (is_array($paramName) and ! is_null($default)) {
7
- throw new Exception('Either array of parameter names with default values as the only argument or param name and default value as seperate arguments are expected.');
8
- }
9
- if (is_array($paramName)) {
10
- foreach ($paramName as $param => $def) {
11
- if (isset($inputArray[$param])) {
12
- $paramName[$param] = $this->applyFilters($inputArray[$param]);
13
- }
14
- }
15
- return $paramName;
16
- } else {
17
- return isset($inputArray[$paramName]) ? $this->applyFilters($inputArray[$paramName]) : $default;
18
- }
19
- }
20
-
21
- public function get($paramName, $default = NULL) {
22
- return $this->read($_GET, $paramName, $default);
23
- }
24
-
25
- public function post($paramName, $default = NULL) {
26
- return $this->read($_POST, $paramName, $default);
27
- }
28
-
29
- public function cookie($paramName, $default = NULL) {
30
- return $this->read($_COOKIE, $paramName, $default);
31
- }
32
-
33
- public function request($paramName, $default = NULL) {
34
- return $this->read($_GET + $_POST + $_COOKIE, $paramName, $default);
35
- }
36
-
37
- public function getpost($paramName, $default = NULL) {
38
- return $this->read($_GET + $_POST, $paramName, $default);
39
- }
40
-
41
- public function server($paramName, $default = NULL) {
42
- return $this->read($_SERVER, $paramName, $default);
43
- }
44
-
45
- public function addFilter($callback) {
46
- if ( ! is_callable($callback)) {
47
- throw new Exception(get_class($this) . '::' . __METHOD__ . ' parameter must be a proper callback function reference.');
48
- }
49
- if ( ! in_array($callback, $this->filters)) {
50
- $this->filters[] = $callback;
51
- }
52
- return $this;
53
- }
54
-
55
- public function removeFilter($callback) {
56
- $this->filters = array_diff($this->filters, array($callback));
57
- return $this;
58
- }
59
-
60
- protected function applyFilters($val) {
61
- if (is_array($val)) {
62
- foreach ($val as $k => $v) {
63
- $val[$k] = $this->applyFilters($v);
64
- }
65
- } else {
66
- foreach ($this->filters as $filter) {
67
- $val = call_user_func($filter, $val);
68
- }
69
- }
70
- return $val;
71
- }
72
  }
1
+ <?php
2
+ class PMXI_Input {
3
+ protected $filters = array('stripslashes');
4
+
5
+ public function read($inputArray, $paramName, $default = NULL) {
6
+ if (is_array($paramName) and ! is_null($default)) {
7
+ throw new Exception('Either array of parameter names with default values as the only argument or param name and default value as seperate arguments are expected.');
8
+ }
9
+ if (is_array($paramName)) {
10
+ foreach ($paramName as $param => $def) {
11
+ if (isset($inputArray[$param])) {
12
+ $paramName[$param] = $this->applyFilters($inputArray[$param]);
13
+ }
14
+ }
15
+ return $paramName;
16
+ } else {
17
+ return isset($inputArray[$paramName]) ? $this->applyFilters($inputArray[$paramName]) : $default;
18
+ }
19
+ }
20
+
21
+ public function get($paramName, $default = NULL) {
22
+ return $this->read($_GET, $paramName, $default);
23
+ }
24
+
25
+ public function post($paramName, $default = NULL) {
26
+ return $this->read($_POST, $paramName, $default);
27
+ }
28
+
29
+ public function cookie($paramName, $default = NULL) {
30
+ return $this->read($_COOKIE, $paramName, $default);
31
+ }
32
+
33
+ public function request($paramName, $default = NULL) {
34
+ return $this->read($_GET + $_POST + $_COOKIE, $paramName, $default);
35
+ }
36
+
37
+ public function getpost($paramName, $default = NULL) {
38
+ return $this->read($_GET + $_POST, $paramName, $default);
39
+ }
40
+
41
+ public function server($paramName, $default = NULL) {
42
+ return $this->read($_SERVER, $paramName, $default);
43
+ }
44
+
45
+ public function addFilter($callback) {
46
+ if ( ! is_callable($callback)) {
47
+ throw new Exception(get_class($this) . '::' . __METHOD__ . ' parameter must be a proper callback function reference.');
48
+ }
49
+ if ( ! in_array($callback, $this->filters)) {
50
+ $this->filters[] = $callback;
51
+ }
52
+ return $this;
53
+ }
54
+
55
+ public function removeFilter($callback) {
56
+ $this->filters = array_diff($this->filters, array($callback));
57
+ return $this;
58
+ }
59
+
60
+ protected function applyFilters($val) {
61
+ if (is_array($val)) {
62
+ foreach ($val as $k => $v) {
63
+ $val[$k] = $this->applyFilters($v);
64
+ }
65
+ } else {
66
+ foreach ($this->filters as $filter) {
67
+ $val = call_user_func($filter, $val);
68
+ }
69
+ }
70
+ return $val;
71
+ }
72
  }
classes/session.php CHANGED
@@ -47,6 +47,7 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
47
 
48
  public $data = array();
49
 
 
50
  /**
51
  * Retrieve the current session instance.
52
  *
@@ -71,28 +72,54 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
71
  * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
72
  */
73
  protected function __construct() {
74
- if ( isset( $_COOKIE[PMXI_SESSION_COOKIE] ) ) {
75
- $cookie = stripslashes( $_COOKIE[PMXI_SESSION_COOKIE] );
76
- $cookie_crumbs = explode( '||', $cookie );
77
-
78
- $this->session_id = $cookie_crumbs[0];
79
- $this->expires = $cookie_crumbs[1];
80
- $this->exp_variant = $cookie_crumbs[2];
81
-
82
- // Update the session expiration if we're past the variant time
83
- if ( time() > $this->exp_variant ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  $this->set_expiration();
85
- update_option( "_pmxi_session_expires_{$this->session_id}", $this->expires );
86
  }
87
- } else {
88
- $this->session_id = $this->generate_id();
89
- $this->set_expiration();
90
- }
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  $this->read_data();
93
 
94
  $this->set_cookie();
95
-
96
  }
97
 
98
  /**
@@ -122,7 +149,7 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
122
  * Set the session cookie
123
  */
124
  protected function set_cookie() {
125
- setcookie( PMXI_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN );
126
  }
127
 
128
  /**
@@ -145,9 +172,18 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
145
  * @return array
146
  */
147
  protected function read_data() {
148
- $this->container = get_option( "_pmxi_session_{$this->session_id}", array() );
 
 
 
 
 
 
 
 
 
149
 
150
- $this->data = $this->toArray();
151
 
152
  return $this->container;
153
  }
@@ -162,7 +198,7 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
162
  $this->data = $this->toArray();
163
 
164
  // Only write the collection to the DB if it's changed.
165
- //if ( $this->dirty ) {
166
  if ( false === get_option( $option_key ) ) {
167
  add_option( "_pmxi_session_{$this->session_id}", $this->container, '', 'no' );
168
  add_option( "_pmxi_session_expires_{$this->session_id}", $this->expires, '', 'no' );
@@ -170,7 +206,19 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
170
  delete_option("_pmxi_session_{$this->session_id}");
171
  add_option( "_pmxi_session_{$this->session_id}", $this->container, '', 'no' );
172
  }
173
- //}
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  }
176
 
@@ -208,7 +256,12 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
208
  */
209
  public function regenerate_id( $delete_old = false ) {
210
  if ( $delete_old ) {
211
- delete_option( "_pmxi_session_{$this->session_id}" );
 
 
 
 
 
212
  }
213
 
214
  $this->session_id = $this->generate_id();
@@ -239,6 +292,7 @@ final class PMXI_Session extends PMXI_ArrayAccess implements Iterator, Countable
239
  */
240
  public function reset() {
241
  $this->container = array();
 
242
  }
243
 
244
  /*****************************************************************/
47
 
48
  public $data = array();
49
 
50
+ public $session_mode = '';
51
  /**
52
  * Retrieve the current session instance.
53
  *
72
  * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
73
  */
74
  protected function __construct() {
75
+
76
+ $this->session_mode = PMXI_Plugin::getInstance()->getOption('session_mode');
77
+
78
+ if ($this->session_mode != 'default'){
79
+
80
+ if ( isset( $_COOKIE[PMXI_SESSION_COOKIE] ) ) {
81
+
82
+ $cookie = stripslashes( $_COOKIE[PMXI_SESSION_COOKIE] );
83
+ $cookie_crumbs = explode( '||', $cookie );
84
+
85
+ $this->session_id = (!empty($cookie_crumbs[0])) ? $cookie_crumbs[0] : $this->generate_id();
86
+ $this->expires = $cookie_crumbs[1];
87
+ $this->exp_variant = $cookie_crumbs[2];
88
+
89
+ // Update the session expiration if we're past the variant time
90
+ if ( time() > $this->exp_variant ) {
91
+ $this->set_expiration();
92
+ if ($this->session_mode == 'database'){
93
+ update_option( "_pmxi_session_expires_{$this->session_id}", $this->expires );
94
+ }
95
+ elseif ($this->session_mode == 'files'){
96
+ @file_put_contents(PMXI_ROOT_DIR . "/sessions/_pmxi_session_expires_{$this->session_id}.txt", $this->expires);
97
+ }
98
+ }
99
+
100
+ } else {
101
+ $this->session_id = $this->generate_id();
102
  $this->set_expiration();
 
103
  }
104
+ }
105
+ else{
106
+ try{
107
+ $path = @session_save_path();
108
+ if ( ! @is_dir($path) or ! @is_writable($path)){
109
+ @ini_set("session.save_handler", "files");
110
+ @session_save_path(sys_get_temp_dir());
111
+ }
112
+ } catch (XmlImportException $e) {
113
+
114
+ }
115
+
116
+ // enable sessions
117
+ if ( ! session_id()) @session_start();
118
+ }
119
 
120
  $this->read_data();
121
 
122
  $this->set_cookie();
 
123
  }
124
 
125
  /**
149
  * Set the session cookie
150
  */
151
  protected function set_cookie() {
152
+ @setcookie( PMXI_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN );
153
  }
154
 
155
  /**
172
  * @return array
173
  */
174
  protected function read_data() {
175
+ if ($this->session_mode == 'database'){
176
+ $this->container = get_option( "_pmxi_session_{$this->session_id}", array() );
177
+ }
178
+ elseif ($this->session_mode == 'files'){
179
+ $container = @file_get_contents(PMXI_ROOT_DIR . "/sessions/_pmxi_session_{$this->session_id}.txt");
180
+ $this->container = unserialize( (!empty($container)) ? $container : '' );
181
+ }
182
+ else{
183
+ $this['pmxi_import'] = ( ! empty($_SESSION['pmxi_import']) ) ? $_SESSION['pmxi_import'] : array();
184
+ }
185
 
186
+ $this->data = $this->toArray();
187
 
188
  return $this->container;
189
  }
198
  $this->data = $this->toArray();
199
 
200
  // Only write the collection to the DB if it's changed.
201
+ if ($this->session_mode == "database"){
202
  if ( false === get_option( $option_key ) ) {
203
  add_option( "_pmxi_session_{$this->session_id}", $this->container, '', 'no' );
204
  add_option( "_pmxi_session_expires_{$this->session_id}", $this->expires, '', 'no' );
206
  delete_option("_pmxi_session_{$this->session_id}");
207
  add_option( "_pmxi_session_{$this->session_id}", $this->container, '', 'no' );
208
  }
209
+ }
210
+ elseif ($this->session_mode == 'files'){
211
+ if ( @file_exists( PMXI_ROOT_DIR . "/sessions/" . $option_key . ".txt") ){
212
+ @file_put_contents( PMXI_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
213
+ }
214
+ else{
215
+ @file_put_contents( PMXI_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
216
+ @file_put_contents( PMXI_ROOT_DIR . "/sessions/_pmxi_session_expires_{$this->session_id}.txt", $this->expires );
217
+ }
218
+ }
219
+ else{
220
+ $session = $this->toArray(); $_SESSION['pmxi_import'] = $session['pmxi_import'];
221
+ }
222
 
223
  }
224
 
256
  */
257
  public function regenerate_id( $delete_old = false ) {
258
  if ( $delete_old ) {
259
+ if ($this->session_mode == "database"){
260
+ delete_option( "_pmxi_session_{$this->session_id}" );
261
+ }
262
+ elseif ($this->session_mode == 'files'){
263
+ @unlink( PMXI_ROOT_DIR . "/sessions/_pmxi_session_{$this->session_id}.txt");
264
+ }
265
  }
266
 
267
  $this->session_id = $this->generate_id();
292
  */
293
  public function reset() {
294
  $this->container = array();
295
+ if ($this->session_mode == "default") unset($_SESSION['pmxi_import']);
296
  }
297
 
298
  /*****************************************************************/
config/options.php CHANGED
@@ -3,8 +3,7 @@
3
  * List of plugin optins, contains only default values, actual values are stored in database
4
  * and can be changed by corresponding wordpress function calls
5
  */
6
- $config = array(
7
- "info_api_url" => "http://www.wpallimport.com/adminpanel/update/info.php",
8
  "history_file_count" => 10000,
9
  "history_file_age" => 365,
10
  "highlight_limit" => 10000,
@@ -20,5 +19,7 @@ $config = array(
20
  "cron_job_key" => url_title(rand_char(12)),
21
  "chunk_size" => 64,
22
  "pingbacks" => 1,
23
- "legacy_special_character_handling" => 0
 
 
24
  );
3
  * List of plugin optins, contains only default values, actual values are stored in database
4
  * and can be changed by corresponding wordpress function calls
5
  */
6
+ $config = array(
 
7
  "history_file_count" => 10000,
8
  "history_file_age" => 365,
9
  "highlight_limit" => 10000,
19
  "cron_job_key" => url_title(rand_char(12)),
20
  "chunk_size" => 64,
21
  "pingbacks" => 1,
22
+ "legacy_special_character_handling" => 1,
23
+ "case_sensitive" => 1,
24
+ "session_mode" => 'default'
25
  );
controllers/admin/help.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- /**
3
- * Admin Help page
4
- *
5
- * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
- */
7
- class PMXI_Admin_Help extends PMXI_Controller_Admin {
8
-
9
- public function index() {
10
- $this->render();
11
- }
12
  }
1
+ <?php
2
+ /**
3
+ * Admin Help page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXI_Admin_Help extends PMXI_Controller_Admin {
8
+
9
+ public function index() {
10
+ $this->render();
11
+ }
12
  }
controllers/admin/home.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- /**
3
- * Admin Home page
4
- *
5
- * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
- */
7
- class PMXI_Admin_Home extends PMXI_Controller_Admin {
8
-
9
- public function index() {
10
- $this->render();
11
- }
12
  }
1
+ <?php
2
+ /**
3
+ * Admin Home page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXI_Admin_Home extends PMXI_Controller_Admin {
8
+
9
+ public function index() {
10
+ $this->render();
11
+ }
12
  }
controllers/admin/import.php CHANGED
@@ -50,44 +50,53 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
50
  if ('index' == $action) return true;
51
 
52
  // step #2: element selection
53
- $this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
54
  $this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
55
  $old = libxml_use_internal_errors(true);
56
 
 
 
 
 
 
57
  $xml = $this->get_xml();
58
 
59
- if (empty($xml) and 'process' == $action){
60
  ! empty(PMXI_Plugin::$session->data['pmxi_import']['update_previous']) and $update_previous->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous']);
61
  return true;
62
- }
63
-
64
  if (empty(PMXI_Plugin::$session->data['pmxi_import'])
65
- or ! $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml))// FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
66
  //or empty(PMXI_Plugin::$session['pmxi_import']['source'])
67
  or ! empty(PMXI_Plugin::$session->data['pmxi_import']['update_previous']) and $update_previous->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous'])->isEmpty()
68
- ) {
69
  if (!PMXI_Plugin::is_ajax()){
70
  $this->errors->add('form-validation', __('Can not create DOM object for provided feed.', 'pmxi_plugin'));
71
  wp_redirect_or_javascript($this->baseUrl); die();
72
  }
73
  }
74
- libxml_use_internal_errors($old);
 
75
  if ('element' == $action) return true;
76
  if ('evaluate' == $action) return true;
77
  if ('evaluate_variations' == $action) return true;
78
 
79
  // step #3: template
80
  $xpath = new DOMXPath($dom);
81
- $elements = $xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath']);
82
 
83
- if (empty(PMXI_Plugin::$session->data['pmxi_import']['xpath']) or ! ($this->data['elements'] = $elements = $xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) or ! $elements->length) {
 
 
84
  $this->errors->add('form-validation', __('No matching elements found.', 'pmxi_plugin'));
85
  wp_redirect_or_javascript(add_query_arg('action', 'element', $this->baseUrl)); die();
86
  }
 
87
  if ('template' == $action or 'preview' == $action or 'tag' == $action) return true;
88
 
89
  // step #4: options
90
- if (empty(PMXI_Plugin::$session->data['pmxi_import']['template']) or empty(PMXI_Plugin::$session->data['pmxi_import']['template']['title']) or empty(PMXI_Plugin::$session->data['pmxi_import']['template']['title'])) {
91
  wp_redirect_or_javascript(add_query_arg('action', 'template', $this->baseUrl)); die();
92
  }
93
  if ('options' == $action) return true;
@@ -110,6 +119,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
110
 
111
  $this->data['post'] = $post = $this->input->post(array(
112
  'type' => 'upload',
 
113
  'url' => 'http://',
114
  'ftp' => array('url' => 'ftp://'),
115
  'file' => '',
@@ -123,7 +133,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
123
  ));
124
 
125
  if ($this->input->post('is_submitted_continue')) {
126
- if ( ! empty(PMXI_Plugin::$session->data['pmxi_import']['xml'])) {
127
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
128
  }
129
  } elseif ('upload' == $this->input->post('type')) {
@@ -137,7 +147,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
137
  } elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim(basename($post['filepath'])))) {
138
  $this->errors->add('form-validation', __('Uploaded file must be XML, CSV or ZIP, GZIP', 'pmxi_plugin'));
139
  } elseif (preg_match('%\W(zip)$%i', trim(basename($post['filepath'])))) {
140
-
141
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
142
 
143
  $archive = new PclZip($post['filepath']);
@@ -186,7 +196,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
186
  'path' => $post['filepath'],
187
  );
188
 
189
- if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
190
 
191
  if($uploads['error']){
192
  $this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
@@ -203,7 +213,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
203
  }
204
  }
205
 
206
- } elseif ( preg_match('%\W(csv)$%i', trim($post['filepath']))) { // If CSV file uploaded
207
 
208
  // Detect if file is very large
209
  $post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
@@ -250,7 +260,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
250
  $post['root_element'] = 'node';
251
  }
252
  }
253
- } else { // If XML file uploaded
254
 
255
  // Detect if file is very large
256
  $post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
@@ -262,7 +272,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
262
  'path' => $filePath,
263
  );
264
  }
265
- }
266
  elseif ($this->input->post('is_submitted')){
267
 
268
  $this->errors->add('form-validation', __('Upgrade to the paid edition of WP All Import to use this feature.', 'pmxi_plugin'));
@@ -273,63 +283,53 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
273
  }
274
 
275
  if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
276
-
277
- check_admin_referer('choose-file', '_wpnonce_choose-file');
278
-
279
  $elements_cloud = array();
280
-
281
  $is_validate = true;
282
-
283
  if (empty($xml)){
284
 
285
  $wp_uploads = wp_upload_dir();
286
 
287
  if (!empty($post['large_file'])){
288
 
289
- set_time_limit(0);
290
-
291
- $chunks = 0;
292
-
293
  $chunk_path = '';
294
-
295
  $local_paths = !empty($local_paths) ? $local_paths : array($filePath);
296
 
297
- foreach ($local_paths as $key => $path) {
298
 
299
- $file = new PMXI_Chunk($path, array('element' => $post['root_element'], 'path' => $wp_uploads['path']));
300
-
301
- while ($chunk_xml = $file->read()) {
302
-
303
- if (!empty($chunk_xml))
304
- {
305
- PMXI_Import_Record::preprocessXml($chunk_xml);
306
- if ( !empty($chunk_xml) ){ // save first chunk to the file
307
- $chunk_path = $wp_uploads['path'] .'/'. wp_unique_filename($wp_uploads['path'], "chunk_".basename($path));
308
- file_put_contents($chunk_path, $file->encoding . "\n" . $chunk_xml);
309
- chmod($chunk_path, 0755);
310
- $is_validate = $file->is_validate;
311
- $chunks++;
312
- break;
313
- }
314
- }
315
- }
316
- if ( ! $key ){
317
-
318
- if ( ! empty($file->options['element'])) {
319
-
320
- $post['root_element'] = $file->options['element'];
321
-
322
- $xpath = "/".$post['root_element'];
323
-
324
- $elements_cloud = $file->cloud;
325
-
326
- if (empty($chunks)) { $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin')); }
327
-
328
- $filePath && $xml = @file_get_contents($chunk_path);
329
  }
330
- else $this->errors->add('form-validation', __('Unable to find root element for this feed. Please open the feed in your browser or a text editor and ensure it is a valid feed.', 'pmxi_plugin'));
331
  }
332
- }
 
333
 
334
  } else {
335
 
@@ -343,7 +343,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
343
  if (empty($xml)) $xml = @file_get_contents($wp_uploads['path'] .'/'. basename($filePath));
344
  }
345
  }
346
- }
347
 
348
  if ((!$is_validate or PMXI_Import_Record::validateXml($xml, $this->errors)) and (empty($post['large_file']) or (!empty($post['large_file']) and !empty($chunks)))) {
349
  // xml is valid
@@ -355,15 +355,25 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
355
  $source['large_import'] = 'No';
356
  $source['root_element'] = '';
357
  }
358
-
359
  $source['first_import'] = date("Y-m-d H:i:s");
 
 
360
 
361
- PMXI_Plugin::$session['pmxi_import'] = array(
362
- //'xml' => $xml,
 
 
 
 
363
  'filePath' => $filePath,
364
  'xpath' => (!empty($xpath)) ? $xpath : '',
 
365
  'source' => $source,
366
  'large_file' => (!empty($post['large_file'])) ? true : false,
 
 
 
367
  'chunk_number' => 1,
368
  'log' => '',
369
  'current_post_ids' => '',
@@ -377,28 +387,29 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
377
  'errors' => 0,
378
  'start_time' => 0,
379
  'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
 
380
  'action' => 'import',
381
  'elements_cloud' => (!empty($elements_cloud)) ? $elements_cloud : array()
382
  );
383
-
384
  unset($xml);
385
  $update_previous = new PMXI_Import_Record();
386
  if ($post['is_update_previous'] and ! $update_previous->getById($post['update_previous'])->isEmpty()) {
387
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = $update_previous->id;
388
  PMXI_Plugin::$session['pmxi_import']['xpath'] = $update_previous->xpath;
389
  PMXI_Plugin::$session['pmxi_import']['template'] = $update_previous->template;
390
- PMXI_Plugin::$session['pmxi_import']['options'] = $update_previous->options;
391
  } else {
392
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = '';
393
  }
394
-
395
- pmxi_session_commit();
396
 
397
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
398
 
399
- }
400
- else {
401
  $this->errors->add('form-validation', __('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@soflyy.com">support@soflyy.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'pmxi_plugin'));
 
402
  }
403
  }
404
 
@@ -415,6 +426,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
415
  $post = $this->input->post(array('xpath' => ''));
416
  $this->data['post'] =& $post;
417
  $this->data['elements_cloud'] = PMXI_Plugin::$session->data['pmxi_import']['elements_cloud'];
 
418
 
419
  $wp_uploads = wp_upload_dir();
420
 
@@ -440,56 +452,9 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
440
  }
441
 
442
  if ( ! $this->errors->get_error_codes()) {
443
-
444
- PMXI_Plugin::$session['pmxi_import']['xpath'] = $post['xpath'];
445
- // counting element selected by xPath
446
- if (PMXI_Plugin::$session->data['pmxi_import']['large_file']){
447
-
448
- PMXI_Plugin::$session->data['pmxi_import']['count'] = 0;
449
-
450
- $this->data['node_list_count'] = 0;
451
-
452
- // loop through the file until all lines are read
453
- $first_loop = true;
454
-
455
- foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
456
-
457
- $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path'], 'type' => $this->input->post('type')));
458
-
459
- while ($xml = $file->read()) {
460
-
461
- if (!empty($xml))
462
- {
463
- $xml = $file->encoding . "\n" . $xml;
464
- PMXI_Import_Record::preprocessXml($xml);
465
-
466
- $dom = new DOMDocument('1.0', 'UTF-8');
467
- $old = libxml_use_internal_errors(true);
468
- $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
469
- libxml_use_internal_errors($old);
470
- $xpath = new DOMXPath($dom);
471
- if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
472
- PMXI_Plugin::$session['pmxi_import']['count']++;
473
- $this->data['node_list_count']++;
474
- if ($first_loop){
475
- //PMXI_Plugin::$session['pmxi_import']['xml'] = $xml;
476
- $first_loop = false;
477
- }
478
- }
479
- unset($dom, $xpath, $elements);
480
-
481
- }
482
- }
483
- }
484
-
485
- if ( ! $this->data['node_list_count']) {
486
- $this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
487
- }
488
-
489
- pmxi_session_commit();
490
-
491
- }
492
  wp_redirect(add_query_arg('action', 'template', $this->baseUrl)); die();
 
493
  }
494
 
495
  } else {
@@ -529,24 +494,47 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
529
  }
530
 
531
  $xpath = new DOMXPath($this->data['dom']);
532
- $post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element']));
533
  $wp_uploads = wp_upload_dir();
534
 
535
  if ('' == $post['xpath']) {
536
  $this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
537
- } else {
538
  // counting selected elements
539
- if (PMXI_Plugin::$session->data['pmxi_import']['large_file']){ // in large mode
540
 
541
- PMXI_Plugin::$session['pmxi_import']['xpath'] = $post['xpath'];
 
 
 
542
 
543
- if ($post['show_element'] == 1) {
544
- PMXI_Plugin::$session['pmxi_import']['count'] = $this->data['node_list_count'] = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
  }
546
- else{
 
 
 
 
 
 
 
547
  $this->data['node_list_count'] = PMXI_Plugin::$session->data['pmxi_import']['count'];
548
- }
549
-
550
 
551
  $xpath_elements = explode('[', $post['xpath']);
552
  $xpath_parts = explode('/', $xpath_elements[0]);
@@ -555,48 +543,49 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
555
 
556
  pmxi_session_commit();
557
 
558
- $loop = 1;
559
-
560
- foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
561
 
562
- $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
 
563
  // loop through the file until all lines are read
564
- while ($xml = $file->read()) {
565
-
566
  if (!empty($xml))
567
  {
568
- $xml = $file->encoding . "\n" . $xml;
569
  PMXI_Import_Record::preprocessXml($xml);
570
-
571
- $dom = new DOMDocument('1.0', 'UTF-8');
572
  $old = libxml_use_internal_errors(true);
573
- $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
574
  libxml_use_internal_errors($old);
575
  $xpath = new DOMXPath($dom);
576
- if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
577
-
578
- if ($post['show_element'] == 1){
579
- $this->data['node_list_count']++;
580
- PMXI_Plugin::$session['pmxi_import']['count'] = $this->data['node_list_count'];
581
  }
582
-
583
- if ($loop == $post['show_element'] ){
584
- //PMXI_Plugin::$session['pmxi_import']['xml'] = $xml;
585
  $this->data['dom'] = $dom;
586
- if ($post['show_element'] > 1)
587
- break;
588
  }
589
- else unset($dom, $xpath, $elements);
590
- $loop++;
591
- }
592
- }
593
- }
594
 
595
- unset($file);
 
 
 
 
 
 
 
596
  }
597
  if ( ! $this->data['node_list_count']) {
598
  $this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
599
- }
600
  }
601
  else{ // in default mode
602
  $this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
@@ -615,26 +604,26 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
615
  }
616
  }
617
  }
 
 
 
 
618
  if ( ! $this->errors->get_error_codes()) {
619
-
620
  //$this->shrink_xml_element($this->data['dom']->documentElement);
621
  $xpath = new DOMXPath($this->data['dom']);
622
  $this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
623
  $paths = array(); $this->data['paths'] =& $paths;
624
  if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
625
  foreach ($elements as $el) {
626
- if ( ! $el instanceof DOMElement) continue;
627
-
628
  $p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
629
  }
630
- }
631
-
632
- pmxi_session_commit();
633
-
634
- $this->render();
635
  } else {
636
  $this->error();
637
- }
 
638
  }
639
 
640
  /**
@@ -644,7 +633,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
644
  {
645
  if ( ! PMXI_Plugin::getInstance()->getAdminCurrentScreen()->is_ajax) { // call is only valid when send with ajax
646
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
647
- }
648
 
649
  $xpath = new DOMXPath($this->data['dom']);
650
  $post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'tagno' => 0));
@@ -675,8 +664,8 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
675
  }
676
  if ( ! $this->errors->get_error_codes()) {
677
 
678
- $xpath = new DOMXPath($this->data['dom']);
679
- $this->data['variation_elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
680
  $paths = array(); $this->data['paths'] =& $paths;
681
  if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
682
  foreach ($elements as $el) {
@@ -707,6 +696,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
707
  'is_leave_html' => 0,
708
  'fix_characters' => 0
709
  );
 
710
  if ($this->isWizard) {
711
  $this->data['post'] = $post = $this->input->post(
712
  (isset(PMXI_Plugin::$session->data['pmxi_import']['template']) ? PMXI_Plugin::$session->data['pmxi_import']['template'] : array())
@@ -741,26 +731,28 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
741
  $this->_validate_template($post['title'], 'Post title');
742
  }
743
 
744
- if (empty($post['content'])) {
745
- $this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
746
- } else {
747
  $this->_validate_template($post['content'], 'Post content');
748
  }
749
 
750
- if ( ! $this->errors->get_error_codes()) {
751
  if ( ! empty($post['name'])) { // save template in database
752
  $template->getByName($post['name'])->set($post)->save();
753
  PMXI_Plugin::$session['pmxi_import']['saved_template'] = $template->id;
754
  }
755
  if ($this->isWizard) {
756
  PMXI_Plugin::$session['pmxi_import']['template'] = $post;
757
-
758
- pmxi_session_commit();
759
-
760
  wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
761
  } else {
762
- $this->data['import']->set('template', $post)->save();
763
- pmxi_session_commit();
 
 
 
 
764
  wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Template updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
765
  }
766
 
@@ -800,11 +792,12 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
800
  {
801
 
802
  $wp_uploads = wp_upload_dir();
803
-
804
  if (empty($this->data['elements']->length))
805
  {
806
  $update_previous = new PMXI_Import_Record();
807
- if ($update_previous->getById($this->input->get('id'))) {
 
808
  PMXI_Plugin::$session['pmxi_import'] = array(
809
  'update_previous' => $update_previous->id,
810
  'xpath' => $update_previous->xpath,
@@ -818,15 +811,16 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
818
  $history_file = new PMXI_File_Record();
819
  $history_file->getBy('id', $history[0]['id']);
820
 
821
- if ($update_previous->large_import == 'Yes'){
822
  PMXI_Plugin::$session['pmxi_import']['filePath'] = $history_file->path;
823
  if (!@file_exists($history_file->path)) PMXI_Plugin::$session['pmxi_import']['filePath'] = $wp_uploads['basedir'] . '/wpallimport_history/' . $history_file->id;
824
  PMXI_Plugin::$session['pmxi_import']['source']['root_element'] = $update_previous->root_element;
825
  PMXI_Plugin::$session['pmxi_import']['large_file'] = true;
826
- PMXI_Plugin::$session['pmxi_import']['count'] = $update_previous->count;
 
827
  pmxi_session_commit();
828
  }
829
- else{
830
  $xml = @file_get_contents($history_file->path);
831
  $this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
832
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml));
@@ -834,39 +828,43 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
834
 
835
  $this->data['elements'] = $elements = $xpath->query($update_previous->xpath);
836
  if ( !$elements->length ) $this->data['elements'] = $elements = $xpath->query('.');
837
- }
838
  }
839
 
840
  } else {
841
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = '';
842
- }
843
  }
844
 
845
- $this->data['tagno'] = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file'] ) ? $this->data['elements']->length : PMXI_Plugin::$session->data['pmxi_import']['count']);
846
 
847
  if (PMXI_Plugin::$session->data['pmxi_import']['large_file'] and $this->data['tagno']){
848
 
849
  PMXI_Plugin::$session['pmxi_import']['local_paths'] = $local_paths = (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) ? PMXI_Plugin::$session->data['pmxi_import']['local_paths'] : array(PMXI_Plugin::$session->data['pmxi_import']['filePath']);
850
-
 
 
851
  foreach ($local_paths as $key => $path) {
852
- if (file_exists($path)){
853
 
854
- $file = new PMXI_Chunk($path, array('element' => (!empty($update_previous)) ? $update_previous->root_element : PMXI_Plugin::$session->data['pmxi_import']['source']['root_element']));
855
  // loop through the file until all lines are read
856
- while ($xml = $file->read()) {
 
857
  if (!empty($xml))
858
- {
859
- $xml = $file->encoding . "\n" . $xml;
860
  PMXI_Import_Record::preprocessXml($xml);
861
 
862
- $dom = new DOMDocument('1.0', 'UTF-8');
863
  $old = libxml_use_internal_errors(true);
864
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
865
  libxml_use_internal_errors($old);
866
  $xpath = new DOMXPath($dom);
867
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
868
- if ($loop == $this->data['tagno']){
869
- //PMXI_Plugin::$session['pmxi_import']['xml'] = $xml;
 
870
  break;
871
  } else unset($dom, $xpath, $elements);
872
  $loop++;
@@ -891,70 +889,81 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
891
  'content' => '',
892
  'is_keep_linebreaks' => 0,
893
  'is_leave_html' => 0,
894
- 'fix_characters' => 0
 
895
  ));
896
- $wp_uploads = wp_upload_dir();
897
 
898
  $legacy_handling = PMXI_Plugin::getInstance()->getOption('legacy_special_character_handling');
 
899
 
900
- $tagno = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $this->data['elements']->length : PMXI_Plugin::$session->data['pmxi_import']['count']);
901
-
902
  $xml = '';
903
 
904
  if (PMXI_Plugin::$session->data['pmxi_import']['large_file']){
905
  $loop = 1;
906
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
907
- $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
 
 
 
 
 
 
908
  // loop through the file until all lines are read
909
  while ($xml = $file->read()) {
910
  if (!empty($xml))
911
  {
912
- $xml = $file->encoding . "\n" . $xml;
913
- PMXI_Import_Record::preprocessXml($xml);
914
-
915
- $dom = new DOMDocument('1.0', 'UTF-8');
916
  $old = libxml_use_internal_errors(true);
917
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
918
  libxml_use_internal_errors($old);
919
- $xpath = new DOMXPath($dom);
920
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
921
- if ( $loop == $tagno ) {
922
- //PMXI_Plugin::$session['pmxi_import']['xml'] = $xml;
923
- break;
924
- }
925
  unset($dom, $xpath, $elements);
926
  $loop++;
927
  }
928
  }
929
  }
930
- unset($file);
931
  }
932
  $tagno = 1;
933
- }
934
  $xpath = "(" . PMXI_Plugin::$session->data['pmxi_import']['xpath'] . ")[$tagno]";
 
 
 
 
935
  // validate
936
  try {
937
- if (empty($post['title'])) {
 
 
938
  $this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
939
  } else {
940
- list($this->data['title']) = XmlImportParser::factory($xml, $xpath, $post['title'], $file)->parse(); unlink($file);
941
  if ( ! isset($this->data['title']) or '' == strval(trim(strip_tags($this->data['title'], '<img><input><textarea><iframe><object><embed>')))) {
942
  $this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post title is empty', 'pmxi_plugin'));
943
  }
944
- else $this->data['title'] = ($post['fix_characters']) ? utf8_encode( ( ! $legacy_handling) ? html_entity_decode($this->data['title']) : htmlspecialchars_decode($this->data['title'])) : (($post['is_leave_html']) ? (( ! $legacy_handling) ? html_entity_decode($this->data['title']) : htmlspecialchars_decode($this->data['title'])) : $this->data['title']);
945
  }
946
  } catch (XmlImportException $e) {
947
  $this->errors->add('form-validation', sprintf(__('Error parsing title: %s', 'pmxi_plugin'), $e->getMessage()));
948
  }
949
- try {
950
- if (empty($post['content'])) {
 
 
951
  $this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
952
  } else {
953
- list($this->data['content']) = XmlImportParser::factory($post['is_keep_linebreaks'] ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml), $xpath, $post['content'], $file)->parse(); unlink($file);
954
  if ( ! isset($this->data['content']) or '' == strval(trim(strip_tags($this->data['content'], '<img><input><textarea><iframe><object><embed>')))) {
955
  $this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post content is empty', 'pmxi_plugin'));
956
  }
957
- else $this->data['content'] = ($post['fix_characters']) ? utf8_encode(( ! $legacy_handling) ? html_entity_decode($this->data['content']) : htmlspecialchars_decode($this->data['content'])) : (($post['is_leave_html']) ? (( ! $legacy_handling) ? html_entity_decode($this->data['content']) : htmlspecialchars_decode($this->data['content'])) : $this->data['content']);
958
  }
959
  } catch (XmlImportException $e) {
960
  $this->errors->add('form-validation', sprintf(__('Error parsing content: %s', 'pmxi_plugin'), $e->getMessage()));
@@ -976,29 +985,31 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
976
  $this->data['source_type'] = PMXI_Plugin::$session->data['pmxi_import']['source']['type'];
977
  $default['unique_key'] = PMXI_Plugin::$session->data['pmxi_import']['template']['title'];
978
 
 
 
979
  // auto searching ID element
980
  if (!empty($this->data['dom'])){
981
  $this->find_unique_key($this->data['dom']->documentElement);
982
  if (!empty($this->_unique_key)){
983
- $id_finded = false;
 
 
984
  foreach ($this->_unique_key as $key) {
985
  if (stripos($key, 'id') !== false) {
986
- $default['unique_key'] .= ' - {'.$key.'[1]}';
987
- $id_finded = true;
988
  break;
989
  }
990
- }
991
- if (!$id_finded){
992
- foreach ($this->_unique_key as $key) {
993
- if (stripos($key, 'url') !== false) {
994
- $default['unique_key'] .= ' - {'.$key.'[1]}';
995
- $id_finded = true;
996
  break;
997
- }
998
- }
999
- }
1000
  }
1001
- }
1002
 
1003
  if ( class_exists('PMWI_Plugin') )
1004
  $post = $this->input->post(
@@ -1034,11 +1045,10 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1034
  'is_scheduled' => ! empty($this->data['import']->scheduled),
1035
  'scheduled_period' => ! empty($this->data['import']->scheduled) ? $this->data['import']->scheduled : '0 0 * * *', // daily by default
1036
  ));
1037
- }
1038
 
1039
  $this->data['post'] =& $post;
1040
- $this->data['scheduled'] =& $scheduled;
1041
- $this->data['is_loaded_template'] = PMXI_Plugin::$session['pmxi_import']['is_loaded_template'];
1042
 
1043
  // Get All meta keys in the system
1044
  $this->data['meta_keys'] = $keys = new PMXI_Model_List();
@@ -1066,7 +1076,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1066
  ));
1067
 
1068
  } elseif ($this->input->post('is_submitted')) {
1069
- check_admin_referer('options', '_wpnonce_options');
1070
 
1071
  if ( $post['type'] == "post" and $post['custom_type'] == "product" and class_exists('PMWI_Plugin')){
1072
  // remove entires where both custom_name and custom_value are empty
@@ -1125,8 +1135,8 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1125
  $this->errors->add('form-validation', __('Expression for `Post Unique Key` must be set, use the same expression as specified for post title if you are not sure what to put there', 'pmxi_plugin'));
1126
  } else {
1127
  $this->_validate_template($post['unique_key'], __('Post Unique Key', 'pmxi_plugin'));
1128
- }
1129
- if ( $post['is_duplicates'] and 'custom field' == $post['duplicate_indicator']){
1130
  if ('' == $post['custom_duplicate_name'])
1131
  $this->errors->add('form-validation', __('Custom field name must be specified.', 'pmxi_plugin'));
1132
  if ('' == $post['custom_duplicate_value'])
@@ -1194,7 +1204,9 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1194
  wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Options updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
1195
  }
1196
  }
1197
- }
 
 
1198
 
1199
  if ( $post['type'] == "product" and class_exists('PMWI_Plugin'))
1200
  {
@@ -1202,7 +1214,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1202
  }
1203
 
1204
  pmxi_session_commit();
1205
-
1206
  $this->render();
1207
  }
1208
 
@@ -1212,161 +1224,157 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
1212
  public function process($save_history = true)
1213
  {
1214
  $wp_uploads = wp_upload_dir();
1215
-
1216
- @set_time_limit(0);
1217
-
1218
  $import = $this->data['update_previous'];
1219
- $import->set(
1220
- (empty(PMXI_Plugin::$session->data['pmxi_import']['source']) ? array() : PMXI_Plugin::$session->data['pmxi_import']['source'])
1221
- + array(
1222
- 'xpath' => PMXI_Plugin::$session->data['pmxi_import']['xpath'],
1223
- 'template' => PMXI_Plugin::$session->data['pmxi_import']['template'],
1224
- 'options' => PMXI_Plugin::$session->data['pmxi_import']['options'],
1225
- 'scheduled' => PMXI_Plugin::$session->data['pmxi_import']['scheduled'],
1226
- 'count' => PMXI_Plugin::$session->data['pmxi_import']['count'],
1227
- 'friendly_name' => PMXI_Plugin::$session->data['pmxi_import']['options']['friendly_name'],
1228
- 'feed_type' => PMXI_Plugin::$session->data['pmxi_import']['feed_type']
1229
- )
1230
- );
1231
 
1232
- if ( ! PMXI_Plugin::is_ajax()) {
1233
- // Save import history
1234
- if ( PMXI_Plugin::$session->data['pmxi_import']['chunk_number'] === 1 ){
1235
- // store import info in database
1236
- $import->set(array(
1237
- 'imported' => 0,
1238
- 'created' => 0,
1239
- 'updated' => 0,
1240
- 'skipped' => 0,
1241
- 'feed_type' => ''
1242
- ))->save();
1243
-
1244
- do_action( 'pmxi_before_xml_import', $import->id );
1245
 
1246
- if (PMXI_Plugin::$session->data['pmxi_import']['large_file']) PMXI_Plugin::$session['pmxi_import']['update_previous'] = $import->id;
 
1247
 
1248
- // unlick previous files
1249
- $history = new PMXI_File_List();
1250
- $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $import->id), 'id DESC');
1251
- if ($history->count()){
1252
- foreach ($history as $file){
1253
- if (@file_exists($file['path']) and $file['path'] != PMXI_Plugin::$session->data['pmxi_import']['filePath']) @unlink($file['path']);
1254
- $history_file = new PMXI_File_Record();
1255
- $history_file->getBy('id', $file['id']);
1256
- if ( ! $history_file->isEmpty()) $history_file->delete();
1257
- }
1258
- }
 
1259
 
1260
- if ($save_history){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1261
  $history_file = new PMXI_File_Record();
1262
- $history_file->set(array(
1263
- 'name' => $import->name,
1264
- 'import_id' => $import->id,
1265
- 'path' => PMXI_Plugin::$session->data['pmxi_import']['filePath'],
1266
- 'contents' => $this->get_xml(), //PMXI_Plugin::$session->data['pmxi_import']['xml'],
1267
- 'registered_on' => date('Y-m-d H:i:s'),
1268
- ))->save();
1269
- }
1270
 
1271
- }
 
 
 
 
 
 
 
 
 
1272
 
1273
  $this->render();
1274
- wp_ob_end_flush_all(); flush();
1275
-
1276
- }
1277
-
1278
- $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(pmxi_strip_tags_content($m))) { PMXI_Plugin::$session[\'pmxi_import\'][\'log\'] .= "<p>".strip_tags(pmxi_strip_tags_content($m))."</p>"; flush(); }');
1279
 
1280
- PMXI_Plugin::$session['pmxi_import']['start_time'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['start_time'])) ? time() : PMXI_Plugin::$session->data['pmxi_import']['start_time'];
1281
-
1282
- in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, __('Reading files for import...', 'pmxi_plugin'));
1283
- in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, sprintf(_n('%s file found', '%s files found', count(PMXI_Plugin::$session->data['pmxi_import']['local_paths']), 'pmxi_plugin'), count(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])));
1284
- in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and !empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths']) and call_user_func($logger, sprintf(__('Importing %s (%s of %s)', 'pmxi_plugin'), PMXI_Plugin::$session->data['pmxi_import']['local_paths'][0], 1, count(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])));
 
 
1285
 
1286
  if (PMXI_Plugin::is_ajax()) {
1287
 
1288
- PMXI_Plugin::$session['pmxi_import']['current_post_ids'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['current_post_ids'])) ? array() : PMXI_Plugin::$session->data['pmxi_import']['current_post_ids'];
1289
-
1290
- PMXI_Plugin::$session['pmxi_import']['pointer'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['pointer'])) ? 0 : PMXI_Plugin::$session->data['pmxi_import']['pointer'];
1291
-
1292
  pmxi_session_commit();
1293
 
1294
  $loop = 0;
1295
 
1296
  if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])){
 
1297
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
1298
 
1299
  $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), PMXI_Plugin::$session->data['pmxi_import']['pointer']);
1300
 
1301
  // loop through the file until all lines are read
1302
- while ($xml = $file->read()) {
1303
-
1304
  if (!empty($xml))
1305
  {
1306
- $xml = $file->encoding . "\n" . $xml;
1307
  PMXI_Import_Record::preprocessXml($xml);
1308
 
1309
- $dom = new DOMDocument('1.0', 'UTF-8');
1310
  $old = libxml_use_internal_errors(true);
1311
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
1312
  libxml_use_internal_errors($old);
1313
  $xpath = new DOMXPath($dom);
1314
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
1315
- PMXI_Plugin::$session['pmxi_import']['pointer'] = $file->pointer;
1316
- //PMXI_Plugin::$session['pmxi_import']['xml'] = $xml;
1317
-
1318
- if ( ! $loop ) ob_start();
1319
- $import->process($xml, $logger, PMXI_Plugin::$session->data['pmxi_import']['chunk_number']);
 
 
 
 
 
 
 
 
1320
  if ( $loop == PMXI_Plugin::$session->data['pmxi_import']['options']['records_per_request'] - 1 ) exit(ob_get_clean());
1321
  $loop++;
1322
  }
1323
  }
1324
 
1325
- if (($import->created + $import->updated + $import->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'] == PMXI_Plugin::$session->data['pmxi_import']['count']) and !in_array($import->type, array('ftp'))){
1326
  PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
1327
  array_shift(PMXI_Plugin::$session->data['pmxi_import']['local_paths']);
1328
  PMXI_Plugin::$session['pmxi_import']['local_paths'] = PMXI_Plugin::$session->data['pmxi_import']['local_paths'];
1329
  pmxi_session_commit();
1330
  exit(ob_get_clean());
1331
  }
1332
- }
1333
-
1334
- if (in_array($import->type, array('ftp'))) {
1335
- PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
1336
- array_shift(PMXI_Plugin::$session->data['pmxi_import']['local_paths']);
1337
- PMXI_Plugin::$session['pmxi_import']['local_paths'] = PMXI_Plugin::$session->data['pmxi_import']['local_paths'];
1338
- if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) {
1339
- $logger and call_user_func($logger, sprintf(__('Importing %s', 'pmxi_plugin'), PMXI_Plugin::$session->data['pmxi_import']['local_paths'][0]));
1340
- }
1341
- pmxi_session_commit();
1342
- exit(ob_get_clean());
1343
- }
1344
  }
1345
  }
1346
  }
1347
 
1348
- if (! PMXI_Plugin::$session->data['pmxi_import']['large_file'] or PMXI_Plugin::is_ajax()){
1349
 
1350
  // Save import process log
1351
  $log_file = $wp_uploads['basedir'] . '/wpallimport_logs/' . $import->id . '.html';
1352
  if (file_exists($log_file)) unlink($log_file);
1353
- @file_put_contents($log_file, PMXI_Plugin::$session->data['pmxi_import']['log']);
1354
-
1355
- if (!empty(PMXI_Plugin::$session->data['pmxi_import'])) do_action( 'pmxi_after_xml_import', $import->id );
1356
 
 
 
 
 
 
 
 
 
1357
  // clear import session
1358
- //unset(PMXI_Plugin::$session['pmxi_import']); // clear session data (prevent from reimporting the same data on page refresh)
1359
-
1360
- pmxi_session_unset();
1361
 
1362
  // [indicate in header process is complete]
1363
- $msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
1364
-
1365
- delete_option('category_children');
1366
 
1367
  ob_start();
1368
 
1369
  echo '<a id="download_pmxi_log" class="update" href="'.esc_url(add_query_arg(array('id' => $import->id, 'action' => 'log', 'page' => 'pmxi-admin-manage'), $this->baseUrl)).'">'.__('Download log','pmxi_plugin').'</a>';
 
1370
  echo <<<COMPLETE
1371
  <script type="text/javascript">
1372
  //<![CDATA[
@@ -1377,19 +1385,17 @@ echo <<<COMPLETE
1377
  $('#right_progress').html(percents + '%');
1378
  $('#progressbar div').css({'width': ((parseInt(percents) > 100) ? 100 : percents) + '%'});
1379
  }
1380
- $('#status').html('$msg');
1381
  window.onbeforeunload = false;
1382
  })(jQuery);
1383
  //]]>
1384
  </script>
1385
  COMPLETE;
1386
  // [/indicate in header process is complete]
 
 
1387
 
1388
- echo ob_get_clean();
1389
-
1390
- die;
1391
-
1392
- }
1393
  }
1394
 
1395
  protected $_sibling_limit = 20;
@@ -1639,18 +1645,28 @@ COMPLETE;
1639
 
1640
  protected function get_xml(){
1641
  $xml = '';
1642
- $wp_uploads = wp_upload_dir();
 
 
 
 
 
1643
  if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) {
1644
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
1645
- if ( @file_exists($path) ){
1646
- $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), (!empty(PMXI_Plugin::$session->data['pmxi_import']['pointer'])) ? PMXI_Plugin::$session->data['pmxi_import']['pointer'] : 0);
1647
- while ($xml = $file->read()) {
 
 
 
 
1648
  if (!empty($xml))
1649
  {
1650
- $xml = $file->encoding . "\n" . $xml;
1651
- PMXI_Import_Record::preprocessXml($xml);
 
1652
  if ( '' != PMXI_Plugin::$session->data['pmxi_import']['xpath']){
1653
- $dom = new DOMDocument('1.0', 'UTF-8');
1654
  $old = libxml_use_internal_errors(true);
1655
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
1656
  libxml_use_internal_errors($old);
@@ -1662,7 +1678,7 @@ COMPLETE;
1662
  }
1663
  }
1664
  }
1665
- }
1666
  return $xml;
1667
  }
1668
  }
50
  if ('index' == $action) return true;
51
 
52
  // step #2: element selection
53
+ $this->data['dom'] = $dom = new DOMDocument('1.0', PMXI_Plugin::$session->data['pmxi_import']['encoding']);
54
  $this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
55
  $old = libxml_use_internal_errors(true);
56
 
57
+ if ( ! in_array($action, array('evaluate_variations', 'process')) ){
58
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
59
+ pmxi_session_commit();
60
+ }
61
+
62
  $xml = $this->get_xml();
63
 
64
+ if (empty($xml) and in_array($action, array('process')) ){
65
  ! empty(PMXI_Plugin::$session->data['pmxi_import']['update_previous']) and $update_previous->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous']);
66
  return true;
67
+ }
68
+
69
  if (empty(PMXI_Plugin::$session->data['pmxi_import'])
70
+ or ! @$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml))// FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
71
  //or empty(PMXI_Plugin::$session['pmxi_import']['source'])
72
  or ! empty(PMXI_Plugin::$session->data['pmxi_import']['update_previous']) and $update_previous->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous'])->isEmpty()
73
+ ) {
74
  if (!PMXI_Plugin::is_ajax()){
75
  $this->errors->add('form-validation', __('Can not create DOM object for provided feed.', 'pmxi_plugin'));
76
  wp_redirect_or_javascript($this->baseUrl); die();
77
  }
78
  }
79
+
80
+ libxml_use_internal_errors($old);
81
  if ('element' == $action) return true;
82
  if ('evaluate' == $action) return true;
83
  if ('evaluate_variations' == $action) return true;
84
 
85
  // step #3: template
86
  $xpath = new DOMXPath($dom);
87
+ $this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath']);
88
 
89
+ if ('preview' == $action or 'tag' == $action) return true;
90
+
91
+ if (empty(PMXI_Plugin::$session->data['pmxi_import']['xpath']) or empty($elements) or ! $elements->length) {
92
  $this->errors->add('form-validation', __('No matching elements found.', 'pmxi_plugin'));
93
  wp_redirect_or_javascript(add_query_arg('action', 'element', $this->baseUrl)); die();
94
  }
95
+
96
  if ('template' == $action or 'preview' == $action or 'tag' == $action) return true;
97
 
98
  // step #4: options
99
+ if (empty(PMXI_Plugin::$session->data['pmxi_import']['template']) or empty(PMXI_Plugin::$session->data['pmxi_import']['template']['title']) or empty(PMXI_Plugin::$session->data['pmxi_import']['template']['content'])) {
100
  wp_redirect_or_javascript(add_query_arg('action', 'template', $this->baseUrl)); die();
101
  }
102
  if ('options' == $action) return true;
119
 
120
  $this->data['post'] = $post = $this->input->post(array(
121
  'type' => 'upload',
122
+ 'feed_type' => '',
123
  'url' => 'http://',
124
  'ftp' => array('url' => 'ftp://'),
125
  'file' => '',
133
  ));
134
 
135
  if ($this->input->post('is_submitted_continue')) {
136
+ if ( ! empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) {
137
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
138
  }
139
  } elseif ('upload' == $this->input->post('type')) {
147
  } elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim(basename($post['filepath'])))) {
148
  $this->errors->add('form-validation', __('Uploaded file must be XML, CSV or ZIP, GZIP', 'pmxi_plugin'));
149
  } elseif (preg_match('%\W(zip)$%i', trim(basename($post['filepath'])))) {
150
+
151
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
152
 
153
  $archive = new PclZip($post['filepath']);
196
  'path' => $post['filepath'],
197
  );
198
 
199
+ if (preg_match('%\W(csv|txt|dat|psv)$%i', trim($filePath))){ // If CSV file found in archieve
200
 
201
  if($uploads['error']){
202
  $this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
213
  }
214
  }
215
 
216
+ } elseif ( preg_match('%\W(csv|txt|dat|psv)$%i', trim($post['filepath']))) { // If CSV file uploaded
217
 
218
  // Detect if file is very large
219
  $post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
260
  $post['root_element'] = 'node';
261
  }
262
  }
263
+ } else { // If XML file uploaded
264
 
265
  // Detect if file is very large
266
  $post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
272
  'path' => $filePath,
273
  );
274
  }
275
+ }
276
  elseif ($this->input->post('is_submitted')){
277
 
278
  $this->errors->add('form-validation', __('Upgrade to the paid edition of WP All Import to use this feature.', 'pmxi_plugin'));
283
  }
284
 
285
  if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
286
+
287
+ check_admin_referer('choose-file', '_wpnonce_choose-file');
 
288
  $elements_cloud = array();
 
289
  $is_validate = true;
290
+
291
  if (empty($xml)){
292
 
293
  $wp_uploads = wp_upload_dir();
294
 
295
  if (!empty($post['large_file'])){
296
 
297
+ @set_time_limit(0);
298
+ $chunks = 0;
 
 
299
  $chunk_path = '';
 
300
  $local_paths = !empty($local_paths) ? $local_paths : array($filePath);
301
 
302
+ foreach ($local_paths as $key => $path) {
303
 
304
+ if ( @file_exists($path) ){
305
+
306
+ $file = new PMXI_Chunk($path, array('element' => $post['root_element'], 'path' => $wp_uploads['path']));
307
+
308
+ while ($xml = $file->read()) {
309
+ if (!empty($xml))
310
+ {
311
+ PMXI_Import_Record::preprocessXml($xml);
312
+ if ( !empty($xml) ){
313
+ $xml = $file->encoding . "\n" . $xml;
314
+ $is_validate = $file->is_validate;
315
+ $chunks++;
316
+ break;
317
+ }
318
+ }
319
+ }
320
+
321
+ if ( ! $key ){
322
+ if ( ! empty($file->options['element'])) {
323
+ $post['root_element'] = $file->options['element'];
324
+ $xpath = "/".$post['root_element'];
325
+ $elements_cloud = $file->cloud;
326
+ if (empty($chunks)) { $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin')); }
327
+ }
328
+ else $this->errors->add('form-validation', __('Unable to find root element for this feed. Please open the feed in your browser or a text editor and ensure it is a valid feed.', 'pmxi_plugin'));
 
 
 
 
 
329
  }
 
330
  }
331
+ else $this->errors->add('form-validation', __('Unable to download feed resource.', 'pmxi_plugin'));
332
+ }
333
 
334
  } else {
335
 
343
  if (empty($xml)) $xml = @file_get_contents($wp_uploads['path'] .'/'. basename($filePath));
344
  }
345
  }
346
+ }
347
 
348
  if ((!$is_validate or PMXI_Import_Record::validateXml($xml, $this->errors)) and (empty($post['large_file']) or (!empty($post['large_file']) and !empty($chunks)))) {
349
  // xml is valid
355
  $source['large_import'] = 'No';
356
  $source['root_element'] = '';
357
  }
358
+
359
  $source['first_import'] = date("Y-m-d H:i:s");
360
+
361
+ pmxi_session_unset();
362
 
363
+ $encoding = 'UTF-8';
364
+ preg_match('~encoding=["|\']{1}([-a-z0-9_]+)["|\']{1}~i', $file->encoding, $encoding);
365
+
366
+ if ( "" == $post['feed_type'] and "" != PMXI_Plugin::$is_csv) $post['feed_type'] = 'csv';
367
+
368
+ PMXI_Plugin::$session['pmxi_import'] = array(
369
  'filePath' => $filePath,
370
  'xpath' => (!empty($xpath)) ? $xpath : '',
371
+ 'feed_type' => $post['feed_type'],
372
  'source' => $source,
373
  'large_file' => (!empty($post['large_file'])) ? true : false,
374
+ 'encoding' => (is_array($encoding)) ? $encoding[1] : $encoding,
375
+ 'is_csv' => PMXI_Plugin::$is_csv,
376
+ 'csv_path' => PMXI_Plugin::$csv_path,
377
  'chunk_number' => 1,
378
  'log' => '',
379
  'current_post_ids' => '',
387
  'errors' => 0,
388
  'start_time' => 0,
389
  'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
390
+ 'csv_paths' => (!empty($csv_paths)) ? $csv_paths : array(PMXI_Plugin::$csv_path), // ftp import local copies of remote CSV files
391
  'action' => 'import',
392
  'elements_cloud' => (!empty($elements_cloud)) ? $elements_cloud : array()
393
  );
394
+
395
  unset($xml);
396
  $update_previous = new PMXI_Import_Record();
397
  if ($post['is_update_previous'] and ! $update_previous->getById($post['update_previous'])->isEmpty()) {
398
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = $update_previous->id;
399
  PMXI_Plugin::$session['pmxi_import']['xpath'] = $update_previous->xpath;
400
  PMXI_Plugin::$session['pmxi_import']['template'] = $update_previous->template;
401
+ PMXI_Plugin::$session['pmxi_import']['options'] = $update_previous->options;
402
  } else {
403
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = '';
404
  }
405
+
406
+ pmxi_session_commit();
407
 
408
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
409
 
410
+ } else {
 
411
  $this->errors->add('form-validation', __('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@soflyy.com">support@soflyy.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'pmxi_plugin'));
412
+ if ( "" != PMXI_Plugin::$is_csv) $this->errors->add('form-validation', __('Probably your CSV feed contains HTML code. In this case, you can enable the <strong>"My CSV feed contains HTML code"</strong> option on the settings screen.', 'pmxi_plugin'));
413
  }
414
  }
415
 
426
  $post = $this->input->post(array('xpath' => ''));
427
  $this->data['post'] =& $post;
428
  $this->data['elements_cloud'] = PMXI_Plugin::$session->data['pmxi_import']['elements_cloud'];
429
+ $this->data['is_csv'] = PMXI_Plugin::$session->data['pmxi_import']['is_csv'];
430
 
431
  $wp_uploads = wp_upload_dir();
432
 
452
  }
453
 
454
  if ( ! $this->errors->get_error_codes()) {
455
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  wp_redirect(add_query_arg('action', 'template', $this->baseUrl)); die();
457
+
458
  }
459
 
460
  } else {
494
  }
495
 
496
  $xpath = new DOMXPath($this->data['dom']);
497
+ $post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'delimiter' => '', 'pointer' => 0, 'chunk' => 0));
498
  $wp_uploads = wp_upload_dir();
499
 
500
  if ('' == $post['xpath']) {
501
  $this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
502
+ } else {
503
  // counting selected elements
504
+ if (PMXI_Plugin::$session->data['pmxi_import']['large_file']){ // in large mode
505
 
506
+ if ('' != $post['delimiter'] and $post['delimiter'] != PMXI_Plugin::$session->data['pmxi_import']['is_csv']) {
507
+ include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
508
+
509
+ PMXI_Plugin::$session['pmxi_import']['is_csv'] = $post['delimiter'];
510
 
511
+ if (PMXI_Plugin::$session->data['pmxi_import']['source']['type'] != 'ftp'){
512
+ $csv = new PMXI_CsvParser(PMXI_Plugin::$session->data['pmxi_import']['csv_path'], true, '', $post['delimiter']); // create chunks
513
+ $filePath = $csv->xml_path;
514
+ PMXI_Plugin::$session['pmxi_import']['filePath'] = $filePath;
515
+ PMXI_Plugin::$session['pmxi_import']['local_paths'] = array($filePath);
516
+ }
517
+ else{
518
+ $local_paths = array();
519
+ foreach (PMXI_Plugin::$session->data['pmxi_import']['csv_paths'] as $key => $path) {
520
+ $csv = new PMXI_CsvParser($path, true, '', $post['delimiter']); // create chunks
521
+ $filePath = $csv->xml_path;
522
+ if (!$key) PMXI_Plugin::$session['pmxi_import']['filePath'] = $filePath;
523
+ $local_paths[] = $filePath;
524
+ }
525
+ PMXI_Plugin::$session['pmxi_import']['local_paths'] = $local_paths;
526
+ }
527
  }
528
+
529
+ // counting selected elements
530
+ PMXI_Plugin::$session['pmxi_import']['xpath'] = $post['xpath'];
531
+
532
+ if ($post['show_element'] == 1 and ! $post['pointer']) {
533
+ PMXI_Plugin::$session['pmxi_import']['count'] = $this->data['node_list_count'] = 0;
534
+ }else{
535
+ if($post['show_element'] > 1 and ! $post['chunk'] ) $post['pointer'] = 0;
536
  $this->data['node_list_count'] = PMXI_Plugin::$session->data['pmxi_import']['count'];
537
+ }
 
538
 
539
  $xpath_elements = explode('[', $post['xpath']);
540
  $xpath_parts = explode('/', $xpath_elements[0]);
543
 
544
  pmxi_session_commit();
545
 
546
+ $loop = $post['chunk'] * 100 + 1;
 
 
547
 
548
+ foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
549
+ $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), $post['pointer']);
550
  // loop through the file until all lines are read
551
+ while ($xml = $file->read()) {
 
552
  if (!empty($xml))
553
  {
554
+ $xml = "<?xml version=\"1.0\" encoding=\"". PMXI_Plugin::$session->data['pmxi_import']['encoding'] ."\"?>" . "\n" . $xml;
555
  PMXI_Import_Record::preprocessXml($xml);
556
+
557
+ $dom = new DOMDocument('1.0', PMXI_Plugin::$session->data['pmxi_import']['encoding']);
558
  $old = libxml_use_internal_errors(true);
559
+ $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
560
  libxml_use_internal_errors($old);
561
  $xpath = new DOMXPath($dom);
562
+
563
+ if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
564
+ if ( $post['show_element'] == 1 ){
565
+ $this->data['node_list_count'] += $elements->length;
566
+ PMXI_Plugin::$session['pmxi_import']['count'] = $this->data['node_list_count'];
567
  }
568
+
569
+ if ( $loop == $post['show_element'] ){
 
570
  $this->data['dom'] = $dom;
571
+ if ($post['show_element'] > 1)
572
+ break;
573
  }
574
+ unset($dom, $xpath, $elements);
575
+ }
 
 
 
576
 
577
+ if ($loop % 100 == 0){
578
+ exit( json_encode( array('result' => false, 'pointer' => $file->pointer, 'chunk' => ++$post['chunk'] ) ));
579
+ }
580
+
581
+ if ($this->data['elements']->length) $loop++;
582
+ }
583
+ }
584
+ unset($file);
585
  }
586
  if ( ! $this->data['node_list_count']) {
587
  $this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
588
+ }
589
  }
590
  else{ // in default mode
591
  $this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
604
  }
605
  }
606
  }
607
+
608
+ pmxi_session_commit();
609
+
610
+ ob_start();
611
  if ( ! $this->errors->get_error_codes()) {
 
612
  //$this->shrink_xml_element($this->data['dom']->documentElement);
613
  $xpath = new DOMXPath($this->data['dom']);
614
  $this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
615
  $paths = array(); $this->data['paths'] =& $paths;
616
  if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
617
  foreach ($elements as $el) {
618
+ if ( ! $el instanceof DOMElement) continue;
 
619
  $p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
620
  }
621
+ }
622
+ $this->render();
 
 
 
623
  } else {
624
  $this->error();
625
+ }
626
+ exit( json_encode( array('result' => true, 'html' => ob_get_clean() ) ));
627
  }
628
 
629
  /**
633
  {
634
  if ( ! PMXI_Plugin::getInstance()->getAdminCurrentScreen()->is_ajax) { // call is only valid when send with ajax
635
  wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
636
+ }
637
 
638
  $xpath = new DOMXPath($this->data['dom']);
639
  $post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'tagno' => 0));
664
  }
665
  if ( ! $this->errors->get_error_codes()) {
666
 
667
+ //$xpath = new DOMXPath($this->data['dom']);
668
+ //$this->data['variation_elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
669
  $paths = array(); $this->data['paths'] =& $paths;
670
  if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
671
  foreach ($elements as $el) {
696
  'is_leave_html' => 0,
697
  'fix_characters' => 0
698
  );
699
+
700
  if ($this->isWizard) {
701
  $this->data['post'] = $post = $this->input->post(
702
  (isset(PMXI_Plugin::$session->data['pmxi_import']['template']) ? PMXI_Plugin::$session->data['pmxi_import']['template'] : array())
731
  $this->_validate_template($post['title'], 'Post title');
732
  }
733
 
734
+ if ( ! empty($post['content'])) {
735
+ /*$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
736
+ } else {*/
737
  $this->_validate_template($post['content'], 'Post content');
738
  }
739
 
740
+ if ( ! $this->errors->get_error_codes()) {
741
  if ( ! empty($post['name'])) { // save template in database
742
  $template->getByName($post['name'])->set($post)->save();
743
  PMXI_Plugin::$session['pmxi_import']['saved_template'] = $template->id;
744
  }
745
  if ($this->isWizard) {
746
  PMXI_Plugin::$session['pmxi_import']['template'] = $post;
747
+ pmxi_session_commit();
 
 
748
  wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
749
  } else {
750
+ $this->data['import']->set('template', $post)->save();
751
+ if ( ! empty($_POST['import_encoding'])){
752
+ $options = $this->data['import']->options;
753
+ $options['encoding'] = $_POST['import_encoding'];
754
+ $this->data['import']->set('options', $options)->save();
755
+ }
756
  wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Template updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
757
  }
758
 
792
  {
793
 
794
  $wp_uploads = wp_upload_dir();
795
+
796
  if (empty($this->data['elements']->length))
797
  {
798
  $update_previous = new PMXI_Import_Record();
799
+ $id = $this->input->get('id');
800
+ if ($id and $update_previous->getById($id)) {
801
  PMXI_Plugin::$session['pmxi_import'] = array(
802
  'update_previous' => $update_previous->id,
803
  'xpath' => $update_previous->xpath,
811
  $history_file = new PMXI_File_Record();
812
  $history_file->getBy('id', $history[0]['id']);
813
 
814
+ if ($update_previous->large_import == 'Yes' and empty(PMXI_Plugin::$session->data['pmxi_import'])){
815
  PMXI_Plugin::$session['pmxi_import']['filePath'] = $history_file->path;
816
  if (!@file_exists($history_file->path)) PMXI_Plugin::$session['pmxi_import']['filePath'] = $wp_uploads['basedir'] . '/wpallimport_history/' . $history_file->id;
817
  PMXI_Plugin::$session['pmxi_import']['source']['root_element'] = $update_previous->root_element;
818
  PMXI_Plugin::$session['pmxi_import']['large_file'] = true;
819
+ PMXI_Plugin::$session['pmxi_import']['count'] = $update_previous->count;
820
+ PMXI_Plugin::$session['pmxi_import']['encoding'] = (!empty($update_previous->options['encoding'])) ? $update_previous->options['encoding'] : 'UTF-8';
821
  pmxi_session_commit();
822
  }
823
+ /*else{
824
  $xml = @file_get_contents($history_file->path);
825
  $this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
826
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml));
828
 
829
  $this->data['elements'] = $elements = $xpath->query($update_previous->xpath);
830
  if ( !$elements->length ) $this->data['elements'] = $elements = $xpath->query('.');
831
+ }*/
832
  }
833
 
834
  } else {
835
  PMXI_Plugin::$session['pmxi_import']['update_previous'] = '';
836
+ }
837
  }
838
 
839
+ $this->data['tagno'] = max(intval($this->input->getpost('tagno', 1)), 1);
840
 
841
  if (PMXI_Plugin::$session->data['pmxi_import']['large_file'] and $this->data['tagno']){
842
 
843
  PMXI_Plugin::$session['pmxi_import']['local_paths'] = $local_paths = (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) ? PMXI_Plugin::$session->data['pmxi_import']['local_paths'] : array(PMXI_Plugin::$session->data['pmxi_import']['filePath']);
844
+
845
+ $loop = 1;
846
+
847
  foreach ($local_paths as $key => $path) {
848
+ if (@file_exists($path)){
849
 
850
+ $file = new PMXI_Chunk($path, array('element' => (!empty($update_previous->root_element)) ? $update_previous->root_element : ((!empty($this->data['update_previous']->root_element)) ? $this->data['update_previous']->root_element : PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'])));
851
  // loop through the file until all lines are read
852
+ while ($xml = $file->read()) {
853
+
854
  if (!empty($xml))
855
+ {
856
+ $xml = "<?xml version=\"1.0\" encoding=\"". PMXI_Plugin::$session->data['pmxi_import']['encoding'] ."\"?>" . "\n" . $xml;
857
  PMXI_Import_Record::preprocessXml($xml);
858
 
859
+ $dom = new DOMDocument('1.0', PMXI_Plugin::$session->data['pmxi_import']['encoding']);
860
  $old = libxml_use_internal_errors(true);
861
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
862
  libxml_use_internal_errors($old);
863
  $xpath = new DOMXPath($dom);
864
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
865
+ if ($loop == $this->data['tagno']){
866
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = $file->pointer;
867
+ pmxi_session_commit();
868
  break;
869
  } else unset($dom, $xpath, $elements);
870
  $loop++;
889
  'content' => '',
890
  'is_keep_linebreaks' => 0,
891
  'is_leave_html' => 0,
892
+ 'fix_characters' => 0,
893
+ 'import_encoding' => 'UFT-8'
894
  ));
895
+ $wp_uploads = wp_upload_dir();
896
 
897
  $legacy_handling = PMXI_Plugin::getInstance()->getOption('legacy_special_character_handling');
898
+ $tagno = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $this->data['elements']->length : PMXI_Plugin::$session->data['pmxi_import']['count']);
899
 
 
 
900
  $xml = '';
901
 
902
  if (PMXI_Plugin::$session->data['pmxi_import']['large_file']){
903
  $loop = 1;
904
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
905
+
906
+ if (PMXI_Plugin::$session->data['pmxi_import']['encoding'] != $post['import_encoding'] and ! empty(PMXI_Plugin::$session->data['pmxi_import']['csv_paths'][$key])){
907
+ include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
908
+ $csv = new PMXI_CsvParser(PMXI_Plugin::$session->data['pmxi_import']['csv_paths'][$key], true, '', PMXI_Plugin::$is_csv, $post['import_encoding'], $path); // conver CSV to XML with selected encoding
909
+ }
910
+
911
+ $file = new PMXI_Chunk($path, array('element' => (!empty($this->data['update_previous']->root_element)) ? $this->data['update_previous']->root_element : PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
912
  // loop through the file until all lines are read
913
  while ($xml = $file->read()) {
914
  if (!empty($xml))
915
  {
916
+ $xml = "<?xml version=\"1.0\" encoding=\"". $post['import_encoding'] ."\"?>" . "\n" . $xml;
917
+ PMXI_Import_Record::preprocessXml($xml);
918
+ $dom = new DOMDocument('1.0', $post['import_encoding']);
 
919
  $old = libxml_use_internal_errors(true);
920
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
921
  libxml_use_internal_errors($old);
922
+ $xpath = new DOMXPath($dom);
923
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
924
+ if ( $loop == $tagno )
925
+ break;
 
 
926
  unset($dom, $xpath, $elements);
927
  $loop++;
928
  }
929
  }
930
  }
931
+ unset($file);
932
  }
933
  $tagno = 1;
934
+ }
935
  $xpath = "(" . PMXI_Plugin::$session->data['pmxi_import']['xpath'] . ")[$tagno]";
936
+ //if ( "" != $xml){
937
+ PMXI_Plugin::$session['pmxi_import']['encoding'] = $post['import_encoding'];
938
+ pmxi_session_commit();
939
+ //}
940
  // validate
941
  try {
942
+ if (empty($xml)){
943
+ $this->errors->add('form-validation', __('Error parsing title: String could not be parsed as XML', 'pmxi_plugin'));
944
+ } elseif (empty($post['title'])) {
945
  $this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
946
  } else {
947
+ list($this->data['title']) = XmlImportParser::factory($xml, $xpath, $post['title'], $file)->parse(); unlink($file);
948
  if ( ! isset($this->data['title']) or '' == strval(trim(strip_tags($this->data['title'], '<img><input><textarea><iframe><object><embed>')))) {
949
  $this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post title is empty', 'pmxi_plugin'));
950
  }
951
+ else $this->data['title'] = ($post['is_leave_html']) ? html_entity_decode($this->data['title']) : $this->data['title'];
952
  }
953
  } catch (XmlImportException $e) {
954
  $this->errors->add('form-validation', sprintf(__('Error parsing title: %s', 'pmxi_plugin'), $e->getMessage()));
955
  }
956
+ try {
957
+ if (empty($xml)){
958
+ $this->errors->add('form-validation', __('Error parsing content: String could not be parsed as XML', 'pmxi_plugin'));
959
+ } elseif (empty($post['content'])) {
960
  $this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
961
  } else {
962
+ list($this->data['content']) = XmlImportParser::factory($post['is_keep_linebreaks'] ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml), $xpath, $post['content'], $file)->parse(); unlink($file);
963
  if ( ! isset($this->data['content']) or '' == strval(trim(strip_tags($this->data['content'], '<img><input><textarea><iframe><object><embed>')))) {
964
  $this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post content is empty', 'pmxi_plugin'));
965
  }
966
+ else $this->data['content'] = ($post['is_leave_html']) ? html_entity_decode($this->data['content']) : $this->data['content'];
967
  }
968
  } catch (XmlImportException $e) {
969
  $this->errors->add('form-validation', sprintf(__('Error parsing content: %s', 'pmxi_plugin'), $e->getMessage()));
985
  $this->data['source_type'] = PMXI_Plugin::$session->data['pmxi_import']['source']['type'];
986
  $default['unique_key'] = PMXI_Plugin::$session->data['pmxi_import']['template']['title'];
987
 
988
+ $keys_black_list = array('programurl');
989
+
990
  // auto searching ID element
991
  if (!empty($this->data['dom'])){
992
  $this->find_unique_key($this->data['dom']->documentElement);
993
  if (!empty($this->_unique_key)){
994
+ foreach ($keys_black_list as $key => $value) {
995
+ $default['unique_key'] = str_replace('{' . $value . '[1]}', "", $default['unique_key']);
996
+ }
997
  foreach ($this->_unique_key as $key) {
998
  if (stripos($key, 'id') !== false) {
999
+ $default['unique_key'] .= ' - {'.$key.'[1]}';
 
1000
  break;
1001
  }
1002
+ }
1003
+ foreach ($this->_unique_key as $key) {
1004
+ if (stripos($key, 'url') !== false or stripos($key, 'sku') !== false or stripos($key, 'ref') !== false) {
1005
+ if ( ! in_array($key, $keys_black_list) ){
1006
+ $default['unique_key'] .= ' - {'.$key.'[1]}';
 
1007
  break;
1008
+ }
1009
+ }
1010
+ }
1011
  }
1012
+ }
1013
 
1014
  if ( class_exists('PMWI_Plugin') )
1015
  $post = $this->input->post(
1045
  'is_scheduled' => ! empty($this->data['import']->scheduled),
1046
  'scheduled_period' => ! empty($this->data['import']->scheduled) ? $this->data['import']->scheduled : '0 0 * * *', // daily by default
1047
  ));
1048
+ }
1049
 
1050
  $this->data['post'] =& $post;
1051
+ $this->data['scheduled'] =& $scheduled;
 
1052
 
1053
  // Get All meta keys in the system
1054
  $this->data['meta_keys'] = $keys = new PMXI_Model_List();
1076
  ));
1077
 
1078
  } elseif ($this->input->post('is_submitted')) {
1079
+ check_admin_referer('options', '_wpnonce_options');
1080
 
1081
  if ( $post['type'] == "post" and $post['custom_type'] == "product" and class_exists('PMWI_Plugin')){
1082
  // remove entires where both custom_name and custom_value are empty
1135
  $this->errors->add('form-validation', __('Expression for `Post Unique Key` must be set, use the same expression as specified for post title if you are not sure what to put there', 'pmxi_plugin'));
1136
  } else {
1137
  $this->_validate_template($post['unique_key'], __('Post Unique Key', 'pmxi_plugin'));
1138
+ }
1139
+ if ( 'manual' == $post['duplicate_matching'] and 'custom field' == $post['duplicate_indicator']){
1140
  if ('' == $post['custom_duplicate_name'])
1141
  $this->errors->add('form-validation', __('Custom field name must be specified.', 'pmxi_plugin'));
1142
  if ('' == $post['custom_duplicate_value'])
1204
  wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Options updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
1205
  }
1206
  }
1207
+ }
1208
+
1209
+ ! empty($post['custom_name']) or $post['custom_name'] = array('') and $post['custom_value'] = array('');
1210
 
1211
  if ( $post['type'] == "product" and class_exists('PMWI_Plugin'))
1212
  {
1214
  }
1215
 
1216
  pmxi_session_commit();
1217
+
1218
  $this->render();
1219
  }
1220
 
1224
  public function process($save_history = true)
1225
  {
1226
  $wp_uploads = wp_upload_dir();
1227
+ @set_time_limit(0);
 
 
1228
  $import = $this->data['update_previous'];
1229
+ $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(pmxi_strip_tags_content($m))) { PMXI_Plugin::$session[\'pmxi_import\'][\'log\'] .= "<p>".strip_tags(pmxi_strip_tags_content($m))."</p>"; flush(); }');
 
 
 
 
 
 
 
 
 
 
 
1230
 
1231
+ if ( ! PMXI_Plugin::is_ajax()) {
1232
+ // Save import history
 
 
 
 
 
 
 
 
 
 
 
1233
 
1234
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
1235
+ pmxi_session_commit();
1236
 
1237
+ $import->set(
1238
+ (empty(PMXI_Plugin::$session->data['pmxi_import']['source']) ? array() : PMXI_Plugin::$session->data['pmxi_import']['source'])
1239
+ + array(
1240
+ 'xpath' => PMXI_Plugin::$session->data['pmxi_import']['xpath'],
1241
+ 'template' => PMXI_Plugin::$session->data['pmxi_import']['template'],
1242
+ 'options' => PMXI_Plugin::$session->data['pmxi_import']['options'],
1243
+ 'scheduled' => PMXI_Plugin::$session->data['pmxi_import']['scheduled'],
1244
+ 'count' => PMXI_Plugin::$session->data['pmxi_import']['count'],
1245
+ 'friendly_name' => PMXI_Plugin::$session->data['pmxi_import']['options']['friendly_name'],
1246
+ 'feed_type' => PMXI_Plugin::$session->data['pmxi_import']['feed_type']
1247
+ )
1248
+ );
1249
 
1250
+ // store import info in database
1251
+ $import->set(array(
1252
+ 'imported' => 0,
1253
+ 'created' => 0,
1254
+ 'updated' => 0,
1255
+ 'skipped' => 0
1256
+ ))->save();
1257
+
1258
+ do_action( 'pmxi_before_xml_import', $import->id );
1259
+
1260
+ PMXI_Plugin::$session['pmxi_import']['update_previous'] = $import->id;
1261
+
1262
+ // unlick previous files
1263
+ $history = new PMXI_File_List();
1264
+ $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $import->id), 'id DESC');
1265
+ if ($history->count()){
1266
+ foreach ($history as $file){
1267
+ if (@file_exists($file['path']) and $file['path'] != PMXI_Plugin::$session->data['pmxi_import']['filePath']) @unlink($file['path']);
1268
  $history_file = new PMXI_File_Record();
1269
+ $history_file->getBy('id', $file['id']);
1270
+ if ( ! $history_file->isEmpty()) $history_file->delete();
1271
+ }
1272
+ }
 
 
 
 
1273
 
1274
+ if ($save_history){
1275
+ $history_file = new PMXI_File_Record();
1276
+ $history_file->set(array(
1277
+ 'name' => $import->name,
1278
+ 'import_id' => $import->id,
1279
+ 'path' => PMXI_Plugin::$session->data['pmxi_import']['filePath'],
1280
+ 'contents' => $this->get_xml(),
1281
+ 'registered_on' => date('Y-m-d H:i:s'),
1282
+ ))->save();
1283
+ }
1284
 
1285
  $this->render();
1286
+ wp_ob_end_flush_all(); flush();
 
 
 
 
1287
 
1288
+ }
1289
+ elseif (empty($import->id)){
1290
+ $import = new PMXI_Import_Record();
1291
+ $import->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous']);
1292
+ }
1293
+
1294
+ PMXI_Plugin::$session['pmxi_import']['start_time'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['start_time'])) ? time() : PMXI_Plugin::$session->data['pmxi_import']['start_time'];
1295
 
1296
  if (PMXI_Plugin::is_ajax()) {
1297
 
1298
+ PMXI_Plugin::$session['pmxi_import']['current_post_ids'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['current_post_ids'])) ? array() : PMXI_Plugin::$session->data['pmxi_import']['current_post_ids'];
1299
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = (empty(PMXI_Plugin::$session->data['pmxi_import']['pointer'])) ? 0 : PMXI_Plugin::$session->data['pmxi_import']['pointer'];
 
 
1300
  pmxi_session_commit();
1301
 
1302
  $loop = 0;
1303
 
1304
  if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])){
1305
+
1306
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
1307
 
1308
  $file = new PMXI_Chunk($path, array('element' => PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), PMXI_Plugin::$session->data['pmxi_import']['pointer']);
1309
 
1310
  // loop through the file until all lines are read
1311
+ while ($xml = $file->read()) {
 
1312
  if (!empty($xml))
1313
  {
1314
+ $xml = "<?xml version=\"1.0\" encoding=\"". PMXI_Plugin::$session->data['pmxi_import']['encoding'] ."\"?>" . "\n" . $xml;
1315
  PMXI_Import_Record::preprocessXml($xml);
1316
 
1317
+ $dom = new DOMDocument('1.0', PMXI_Plugin::$session->data['pmxi_import']['encoding']);
1318
  $old = libxml_use_internal_errors(true);
1319
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
1320
  libxml_use_internal_errors($old);
1321
  $xpath = new DOMXPath($dom);
1322
  if (($this->data['elements'] = $elements = @$xpath->query(PMXI_Plugin::$session->data['pmxi_import']['xpath'])) and $elements->length){
1323
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = $file->pointer;
1324
+ if ( ! $loop ) ob_start();
1325
+ do_action('pmxi_before_post_import', $import->id);
1326
+ $import->process($xml, $logger, PMXI_Plugin::$session->data['pmxi_import']['chunk_number']);
1327
+ do_action('pmxi_after_post_import', $import->id);
1328
+ if (($import->created + $import->updated + $import->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'] == $import->count) and !in_array($import->type, array('ftp'))){
1329
+ PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
1330
+ array_shift(PMXI_Plugin::$session->data['pmxi_import']['local_paths']);
1331
+ PMXI_Plugin::$session['pmxi_import']['local_paths'] = PMXI_Plugin::$session->data['pmxi_import']['local_paths'];
1332
+ unset($dom, $xpath);
1333
+ pmxi_session_commit();
1334
+ exit(ob_get_clean());
1335
+ }
1336
  if ( $loop == PMXI_Plugin::$session->data['pmxi_import']['options']['records_per_request'] - 1 ) exit(ob_get_clean());
1337
  $loop++;
1338
  }
1339
  }
1340
 
1341
+ if (($import->created + $import->updated + $import->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'] == $import->count) and !in_array($import->type, array('ftp'))){
1342
  PMXI_Plugin::$session['pmxi_import']['pointer'] = 0;
1343
  array_shift(PMXI_Plugin::$session->data['pmxi_import']['local_paths']);
1344
  PMXI_Plugin::$session['pmxi_import']['local_paths'] = PMXI_Plugin::$session->data['pmxi_import']['local_paths'];
1345
  pmxi_session_commit();
1346
  exit(ob_get_clean());
1347
  }
1348
+ }
 
 
 
 
 
 
 
 
 
 
 
1349
  }
1350
  }
1351
  }
1352
 
1353
+ if ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file'] or PMXI_Plugin::is_ajax()){
1354
 
1355
  // Save import process log
1356
  $log_file = $wp_uploads['basedir'] . '/wpallimport_logs/' . $import->id . '.html';
1357
  if (file_exists($log_file)) unlink($log_file);
1358
+ @file_put_contents($log_file, PMXI_Plugin::$session->data['pmxi_import']['log']);
 
 
1359
 
1360
+ if (!empty(PMXI_Plugin::$session->data['pmxi_import'])) do_action( 'pmxi_after_xml_import', $import->id );
1361
+
1362
+ wp_cache_flush();
1363
+ foreach ( get_taxonomies() as $tax ) {
1364
+ delete_option( "{$tax}_children" );
1365
+ _get_term_hierarchy( $tax );
1366
+ }
1367
+
1368
  // clear import session
1369
+ pmxi_session_unset(); // clear session data (prevent from reimporting the same data on page refresh)
 
 
1370
 
1371
  // [indicate in header process is complete]
1372
+ $msg = addcslashes(__('Complete', 'pmxi_plugin'), "\n\r");
 
 
1373
 
1374
  ob_start();
1375
 
1376
  echo '<a id="download_pmxi_log" class="update" href="'.esc_url(add_query_arg(array('id' => $import->id, 'action' => 'log', 'page' => 'pmxi-admin-manage'), $this->baseUrl)).'">'.__('Download log','pmxi_plugin').'</a>';
1377
+
1378
  echo <<<COMPLETE
1379
  <script type="text/javascript">
1380
  //<![CDATA[
1385
  $('#right_progress').html(percents + '%');
1386
  $('#progressbar div').css({'width': ((parseInt(percents) > 100) ? 100 : percents) + '%'});
1387
  }
1388
+ $('#status').attr('rel',1).html('$msg');
1389
  window.onbeforeunload = false;
1390
  })(jQuery);
1391
  //]]>
1392
  </script>
1393
  COMPLETE;
1394
  // [/indicate in header process is complete]
1395
+
1396
+ exit(ob_get_clean());
1397
 
1398
+ }
 
 
 
 
1399
  }
1400
 
1401
  protected $_sibling_limit = 20;
1645
 
1646
  protected function get_xml(){
1647
  $xml = '';
1648
+ $wp_uploads = wp_upload_dir();
1649
+ $update_previous = new PMXI_Import_Record();
1650
+
1651
+ if ( !empty(PMXI_Plugin::$session->data['pmxi_import']['update_previous']))
1652
+ $update_previous->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous']);
1653
+
1654
  if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) {
1655
  foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) {
1656
+
1657
+ if ( @file_exists($path) ){
1658
+
1659
+ $root_element = ( ! $update_previous->isEmpty() ) ? $update_previous->root_element : PMXI_Plugin::$session->data['pmxi_import']['source']['root_element'];
1660
+
1661
+ $file = new PMXI_Chunk($path, array('element' => $root_element, 'path' => $wp_uploads['path']), (!empty(PMXI_Plugin::$session->data['pmxi_import']['pointer'])) ? PMXI_Plugin::$session->data['pmxi_import']['pointer'] : 0);
1662
+ while ($xml = $file->read()) {
1663
  if (!empty($xml))
1664
  {
1665
+ $xml = "<?xml version=\"1.0\" encoding=\"". PMXI_Plugin::$session->data['pmxi_import']['encoding'] ."\"?>" . "\n" . $xml;
1666
+ PMXI_Import_Record::preprocessXml($xml);
1667
+
1668
  if ( '' != PMXI_Plugin::$session->data['pmxi_import']['xpath']){
1669
+ $dom = new DOMDocument('1.0', PMXI_Plugin::$session->data['pmxi_import']['encoding']);
1670
  $old = libxml_use_internal_errors(true);
1671
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
1672
  libxml_use_internal_errors($old);
1678
  }
1679
  }
1680
  }
1681
+ }
1682
  return $xml;
1683
  }
1684
  }
controllers/admin/manage.php CHANGED
@@ -24,7 +24,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
24
  'order_by' => 'registered_on',
25
  'order' => 'DESC',
26
  'pagenum' => 1,
27
- 'perPage' => 10,
28
  ));
29
  $get['pagenum'] = absint($get['pagenum']);
30
  extract($get);
@@ -93,8 +93,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
93
  if ( ! $id or $item->getById($id)->isEmpty()) {
94
  wp_redirect($this->baseUrl); die();
95
  }
96
-
97
- //unset(PMXI_Plugin::$session['pmxi_import']);
98
  pmxi_session_unset();
99
 
100
  if ($this->input->post('is_confirmed')) {
@@ -159,7 +158,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
159
  }
160
  else{
161
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
162
- $csv = new PMXI_CsvParser($filePath, true); // create chunks
163
  $filePath = $csv->xml_path;
164
  }
165
  }
@@ -174,7 +173,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
174
  $filePath = PMXI_Plugin::csv_to_xml($item->path);
175
  } else{
176
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
177
- $csv = new PMXI_CsvParser($item->path, true);
178
  $filePath = $csv->xml_path;
179
  }
180
  } elseif(preg_match('%\W(gz)$%i', trim($item->path))){ // If gz file uploaded
@@ -187,7 +186,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
187
  }
188
  else{
189
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
190
- $csv = new PMXI_CsvParser($filePath, true); // create chunks
191
  $filePath = $csv->xml_path;
192
  }
193
  }
@@ -203,7 +202,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
203
 
204
  if ($item->large_import == 'Yes'){
205
 
206
- set_time_limit(0);
207
 
208
  $chunks = 0;
209
 
@@ -226,17 +225,12 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
226
  $xml = $file->encoding . "\n" . $xml;
227
  PMXI_Import_Record::preprocessXml($xml);
228
 
229
- $dom = new DOMDocument('1.0', 'UTF-8');
230
  $old = libxml_use_internal_errors(true);
231
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
232
  libxml_use_internal_errors($old);
233
  $xpath = new DOMXPath($dom);
234
- if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
235
- $chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
236
- file_put_contents($chunk_path, $xml);
237
- chmod($chunk_path, 0755);
238
- $chunk_founded = true;
239
- }
240
  unset($dom, $xpath, $elements);
241
  }
242
  $chunks++;
@@ -250,19 +244,12 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
250
  $xml = $file->encoding . "\n" . $xml;
251
  PMXI_Import_Record::preprocessXml($xml);
252
 
253
- $dom = new DOMDocument('1.0', 'UTF-8');
254
  $old = libxml_use_internal_errors(true);
255
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
256
  libxml_use_internal_errors($old);
257
  $xpath = new DOMXPath($dom);
258
- if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
259
- if ( !$chunks) {
260
- $chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
261
- file_put_contents($chunk_path, $xml);
262
- chmod($chunk_path, 0755);
263
- }
264
- $chunks++;
265
- }
266
  unset($dom, $xpath, $elements);
267
  }
268
  }
@@ -273,9 +260,7 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
273
  }
274
 
275
  if (empty($chunks))
276
- $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin'));
277
- else
278
- $xml = @file_get_contents($chunk_path);
279
 
280
  } else {
281
 
@@ -292,8 +277,6 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
292
  }
293
  }
294
 
295
- //if (!empty(PMXI_Plugin::$session['pmxi_import']['xml'])) $xml = PMXI_Plugin::$session['pmxi_import']['xml'];
296
-
297
  if ($item->large_import == 'Yes' or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
298
 
299
  if ( ! PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->data['pmxi_import']['chunk_number'])){
@@ -328,6 +311,9 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
328
  'xpath' => $item->xpath,
329
  'template' => $item->template,
330
  'options' => $item->options,
 
 
 
331
  'scheduled' => $item->scheduled,
332
  'current_post_ids' => '',
333
  'large_file' => ($item->large_import == 'Yes') ? true : false,
24
  'order_by' => 'registered_on',
25
  'order' => 'DESC',
26
  'pagenum' => 1,
27
+ 'perPage' => 25,
28
  ));
29
  $get['pagenum'] = absint($get['pagenum']);
30
  extract($get);
93
  if ( ! $id or $item->getById($id)->isEmpty()) {
94
  wp_redirect($this->baseUrl); die();
95
  }
96
+
 
97
  pmxi_session_unset();
98
 
99
  if ($this->input->post('is_confirmed')) {
158
  }
159
  else{
160
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
161
+ $csv = new PMXI_CsvParser($filePath, true, '', ( ! empty($item->options['delimiter']) ) ? $item->options['delimiter'] : '', ( ! empty($item->options['encoding']) ) ? $item->options['encoding'] : ''); // create chunks
162
  $filePath = $csv->xml_path;
163
  }
164
  }
173
  $filePath = PMXI_Plugin::csv_to_xml($item->path);
174
  } else{
175
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
176
+ $csv = new PMXI_CsvParser($item->path, true, '', ( ! empty($item->options['delimiter']) ) ? $item->options['delimiter'] : '', ( ! empty($item->options['encoding']) ) ? $item->options['encoding'] : '');
177
  $filePath = $csv->xml_path;
178
  }
179
  } elseif(preg_match('%\W(gz)$%i', trim($item->path))){ // If gz file uploaded
186
  }
187
  else{
188
  include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
189
+ $csv = new PMXI_CsvParser($filePath, true, '', ( ! empty($item->options['delimiter']) ) ? $item->options['delimiter'] : '', ( ! empty($item->options['encoding']) ) ? $item->options['encoding'] : ''); // create chunks
190
  $filePath = $csv->xml_path;
191
  }
192
  }
202
 
203
  if ($item->large_import == 'Yes'){
204
 
205
+ @set_time_limit(0);
206
 
207
  $chunks = 0;
208
 
225
  $xml = $file->encoding . "\n" . $xml;
226
  PMXI_Import_Record::preprocessXml($xml);
227
 
228
+ $dom = new DOMDocument('1.0', ( ! empty($item->options['encoding']) ) ? $item->options['encoding'] : 'UTF-8');
229
  $old = libxml_use_internal_errors(true);
230
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
231
  libxml_use_internal_errors($old);
232
  $xpath = new DOMXPath($dom);
233
+ if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) $chunk_founded = true;
 
 
 
 
 
234
  unset($dom, $xpath, $elements);
235
  }
236
  $chunks++;
244
  $xml = $file->encoding . "\n" . $xml;
245
  PMXI_Import_Record::preprocessXml($xml);
246
 
247
+ $dom = new DOMDocument('1.0', ( ! empty($item->options['encoding']) ) ? $item->options['encoding'] : 'UTF-8');
248
  $old = libxml_use_internal_errors(true);
249
  $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
250
  libxml_use_internal_errors($old);
251
  $xpath = new DOMXPath($dom);
252
+ if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) $chunks++;
 
 
 
 
 
 
 
253
  unset($dom, $xpath, $elements);
254
  }
255
  }
260
  }
261
 
262
  if (empty($chunks))
263
+ $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin'));
 
 
264
 
265
  } else {
266
 
277
  }
278
  }
279
 
 
 
280
  if ($item->large_import == 'Yes' or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
281
 
282
  if ( ! PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->data['pmxi_import']['chunk_number'])){
311
  'xpath' => $item->xpath,
312
  'template' => $item->template,
313
  'options' => $item->options,
314
+ 'encoding' => (!empty($item->options['encoding'])) ? $item->options['encoding'] : 'UTF-8',
315
+ 'is_csv' => (!empty($item->options['delimiter'])) ? $item->options['delimiter'] : PMXI_Plugin::$is_csv,
316
+ 'csv_path' => PMXI_Plugin::$csv_path,
317
  'scheduled' => $item->scheduled,
318
  'current_post_ids' => '',
319
  'large_file' => ($item->large_import == 'Yes') ? true : false,
controllers/admin/settings.php CHANGED
@@ -31,16 +31,76 @@ class PMXI_Admin_Settings extends PMXI_Controller_Admin {
31
  }
32
 
33
  if ($this->input->post('is_templates_submitted')) { // delete templates form
34
- $templates_ids = $this->input->post('templates', array());
35
- if (empty($templates_ids)) {
36
- $this->errors->add('form-validation', __('Templates must be selected', 'pmxi_plugin'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
- if ( ! $this->errors->get_error_codes()) { // no validation errors detected
39
- $template = new PMXI_Template_Record();
40
- foreach ($templates_ids as $template_id) {
41
- $template->clear()->set('id', $template_id)->delete();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
- wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(_n('%d template deleted', '%d templates deleted', count($templates_ids), 'pmxi_plugin'), count($templates_ids))), $this->baseUrl)); die();
44
  }
45
  }
46
 
31
  }
32
 
33
  if ($this->input->post('is_templates_submitted')) { // delete templates form
34
+
35
+ if ($this->input->post('import_templates')){
36
+
37
+ if (!empty($_FILES)){
38
+ $file_name = $_FILES['template_file']['name'];
39
+ $file_size = $_FILES['template_file']['size'];
40
+ $tmp_name = $_FILES['template_file']['tmp_name'];
41
+
42
+ if(isset($file_name))
43
+ {
44
+
45
+ $filename = stripslashes($file_name);
46
+ $extension = strtolower(pmxi_getExtension($filename));
47
+
48
+ if (($extension != "txt"))
49
+ {
50
+ $this->errors->add('form-validation', __('Unknown File extension. Only txt files are permitted', 'pmxi_plugin'));
51
+ }
52
+ else {
53
+ $import_data = @file_get_contents($tmp_name);
54
+ if (!empty($import_data)){
55
+ $templates_data = json_decode($import_data, true);
56
+
57
+ if (!empty($templates_data)){
58
+ $template = new PMXI_Template_Record();
59
+ foreach ($templates_data as $template_data) {
60
+ unset($template_data['id']);
61
+ $template->clear()->set($template_data)->insert();
62
+ }
63
+ wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(_n('%d template imported', '%d templates imported', count($templates_data), 'pmxi_plugin'), count($templates_data))), $this->baseUrl)); die();
64
+ }
65
+ else $this->errors->add('form-validation', __('Wrong imported data format', 'pmxi_plugin'));
66
+ }
67
+ else $this->errors->add('form-validation', __('File is empty or doesn\'t exests', 'pmxi_plugin'));
68
+ }
69
+ }
70
+ else $this->errors->add('form-validation', __('Undefined entry!', 'pmxi_plugin'));
71
+ }
72
+ else $this->errors->add('form-validation', __('Please select file.', 'pmxi_plugin'));
73
+
74
  }
75
+ else{
76
+ $templates_ids = $this->input->post('templates', array());
77
+ if (empty($templates_ids)) {
78
+ $this->errors->add('form-validation', __('Templates must be selected', 'pmxi_plugin'));
79
+ }
80
+
81
+ if ( ! $this->errors->get_error_codes()) { // no validation errors detected
82
+ if ($this->input->post('delete_templates')){
83
+ $template = new PMXI_Template_Record();
84
+ foreach ($templates_ids as $template_id) {
85
+ $template->clear()->set('id', $template_id)->delete();
86
+ }
87
+ wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(_n('%d template deleted', '%d templates deleted', count($templates_ids), 'pmxi_plugin'), count($templates_ids))), $this->baseUrl)); die();
88
+ }
89
+ if ($this->input->post('export_templates')){
90
+ $export_data = array();
91
+ $template = new PMXI_Template_Record();
92
+ foreach ($templates_ids as $template_id) {
93
+ $export_data[] = $template->clear()->getBy('id', $template_id)->toArray(TRUE);
94
+ }
95
+
96
+ $uploads = wp_upload_dir();
97
+ $export_file_name = "templates_".uniqid().".txt";
98
+ file_put_contents($uploads['path'] . DIRECTORY_SEPARATOR . $export_file_name, json_encode($export_data));
99
+
100
+ PMXI_download::csv($uploads['path'] . DIRECTORY_SEPARATOR . $export_file_name);
101
+
102
+ }
103
  }
 
104
  }
105
  }
106
 
controllers/controller.php CHANGED
@@ -1,102 +1,102 @@
1
- <?php
2
- /**
3
- * Common logic for all shortcodes plugin implements
4
- *
5
- * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
- */
7
- abstract class PMXI_Controller {
8
- /**
9
- * Input class instance to retrieve parameters submitted during page request
10
- * @var PMXI_Input
11
- */
12
- protected $input;
13
- /**
14
- * Error messages
15
- * @var WP_Error
16
- */
17
- protected $errors;
18
- /**
19
- * Associative array of data which will be automatically available as variables when template is rendered
20
- * @var array
21
- */
22
- public $data = array();
23
- /**
24
- * Constructor
25
- */
26
- public function __construct() {
27
- $this->input = new PMXI_Input();
28
- $this->input->addFilter('trim');
29
-
30
- $this->errors = new WP_Error();
31
-
32
- $this->init();
33
- }
34
-
35
- /**
36
- * Method to put controller initialization logic to
37
- */
38
- protected function init() {}
39
-
40
- /**
41
- * Checks wether protocol is HTTPS and redirects user to secure connection if not
42
- */
43
- protected function force_ssl() {
44
- if (force_ssl_admin() && ! is_ssl()) {
45
- if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
46
- wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); die();
47
- } else {
48
- wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); die();
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * Method returning resolved template content
55
- *
56
- * @param string[optional] $viewPath Template path to render
57
- */
58
- protected function render($viewPath = null) {
59
- // assume template file name depending on calling function
60
- if (is_null($viewPath)) {
61
- $trace = debug_backtrace();
62
- $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXI_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
63
- }
64
- // append file extension if not specified
65
- if ( ! preg_match('%\.php$%', $viewPath)) {
66
- $viewPath .= '.php';
67
- }
68
- $filePath = PMXI_Plugin::ROOT_DIR . '/views/' . $viewPath;
69
- if (is_file($filePath)) {
70
- extract($this->data);
71
- include $filePath;
72
- } else {
73
- throw new Exception("Requested template file $filePath is not found.");
74
- }
75
- }
76
-
77
- /**
78
- * Display list of errors
79
- *
80
- * @param string|array|WP_Error[optional] $msgs
81
- */
82
- protected function error($msgs = NULL) {
83
- if (is_null($msgs)) {
84
- $msgs = $this->errors;
85
- }
86
- if (is_wp_error($msgs)) {
87
- $msgs = $msgs->get_error_messages();
88
- }
89
- if ( ! is_array($msgs)) {
90
- $msgs = array($msgs);
91
- }
92
- $this->data['errors'] = $msgs;
93
-
94
- $viewPathRel = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXI_Plugin::PREFIX, '%') . '%', '', strtolower(get_class($this)))) . '/error.php';
95
- if (is_file(PMXI_Plugin::ROOT_DIR . '/views/' . $viewPathRel)) { // if calling controller class has specific error view
96
- $this->render($viewPathRel);
97
- } else { // render default error view
98
- $this->render('controller/error.php');
99
- }
100
- }
101
-
102
  }
1
+ <?php
2
+ /**
3
+ * Common logic for all shortcodes plugin implements
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXI_Controller {
8
+ /**
9
+ * Input class instance to retrieve parameters submitted during page request
10
+ * @var PMXI_Input
11
+ */
12
+ protected $input;
13
+ /**
14
+ * Error messages
15
+ * @var WP_Error
16
+ */
17
+ protected $errors;
18
+ /**
19
+ * Associative array of data which will be automatically available as variables when template is rendered
20
+ * @var array
21
+ */
22
+ public $data = array();
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct() {
27
+ $this->input = new PMXI_Input();
28
+ $this->input->addFilter('trim');
29
+
30
+ $this->errors = new WP_Error();
31
+
32
+ $this->init();
33
+ }
34
+
35
+ /**
36
+ * Method to put controller initialization logic to
37
+ */
38
+ protected function init() {}
39
+
40
+ /**
41
+ * Checks wether protocol is HTTPS and redirects user to secure connection if not
42
+ */
43
+ protected function force_ssl() {
44
+ if (force_ssl_admin() && ! is_ssl()) {
45
+ if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
46
+ wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); die();
47
+ } else {
48
+ wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); die();
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Method returning resolved template content
55
+ *
56
+ * @param string[optional] $viewPath Template path to render
57
+ */
58
+ protected function render($viewPath = null) {
59
+ // assume template file name depending on calling function
60
+ if (is_null($viewPath)) {
61
+ $trace = debug_backtrace();
62
+ $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXI_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
63
+ }
64
+ // append file extension if not specified
65
+ if ( ! preg_match('%\.php$%', $viewPath)) {
66
+ $viewPath .= '.php';
67
+ }
68
+ $filePath = PMXI_Plugin::ROOT_DIR . '/views/' . $viewPath;
69
+ if (is_file($filePath)) {
70
+ extract($this->data);
71
+ include $filePath;
72
+ } else {
73
+ throw new Exception("Requested template file $filePath is not found.");
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Display list of errors
79
+ *
80
+ * @param string|array|WP_Error[optional] $msgs
81
+ */
82
+ protected function error($msgs = NULL) {
83
+ if (is_null($msgs)) {
84
+ $msgs = $this->errors;
85
+ }
86
+ if (is_wp_error($msgs)) {
87
+ $msgs = $msgs->get_error_messages();
88
+ }
89
+ if ( ! is_array($msgs)) {
90
+ $msgs = array($msgs);
91
+ }
92
+ $this->data['errors'] = $msgs;
93
+
94
+ $viewPathRel = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXI_Plugin::PREFIX, '%') . '%', '', strtolower(get_class($this)))) . '/error.php';
95
+ if (is_file(PMXI_Plugin::ROOT_DIR . '/views/' . $viewPathRel)) { // if calling controller class has specific error view
96
+ $this->render($viewPathRel);
97
+ } else { // render default error view
98
+ $this->render('controller/error.php');
99
+ }
100
+ }
101
+
102
  }
controllers/controller/admin.php CHANGED
@@ -65,7 +65,7 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
65
  wp_enqueue_script('jquery-browserplus-min', 'http://bp.yahooapis.com/2.4.21/browserplus-min.js', array('jquery'));
66
  wp_enqueue_script('full-plupload', PMXI_ROOT_URL . '/static/js/plupload/plupload.full.js', array('jquery-browserplus-min'));
67
  wp_enqueue_script('jquery-plupload', PMXI_ROOT_URL . '/static/js/plupload/wplupload.js', array('full-plupload', 'jquery'));
68
-
69
  wp_enqueue_script('pmxi-admin-script', PMXI_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
70
 
71
  }
65
  wp_enqueue_script('jquery-browserplus-min', 'http://bp.yahooapis.com/2.4.21/browserplus-min.js', array('jquery'));
66
  wp_enqueue_script('full-plupload', PMXI_ROOT_URL . '/static/js/plupload/plupload.full.js', array('jquery-browserplus-min'));
67
  wp_enqueue_script('jquery-plupload', PMXI_ROOT_URL . '/static/js/plupload/wplupload.js', array('full-plupload', 'jquery'));
68
+
69
  wp_enqueue_script('pmxi-admin-script', PMXI_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
70
 
71
  }
helpers/backward.php CHANGED
@@ -1,40 +1,40 @@
1
- <?php
2
- /**
3
- * Contains function which were introduced in late wordpress versions
4
- */
5
-
6
- if ( ! function_exists('is_network_admin')):
7
- /**
8
- * Whether the current request is for a network admin screen /wp-admin/network/
9
- *
10
- * Does not inform on whether the user is a network admin! Use capability checks to
11
- * tell if the user should be accessing a section or not.
12
- *
13
- * @since 3.1.0
14
- *
15
- * @return bool True if inside WordPress network administration pages.
16
- */
17
- function is_network_admin() {
18
- if ( defined( 'WP_NETWORK_ADMIN' ) )
19
- return WP_NETWORK_ADMIN;
20
- return false;
21
- }
22
- endif;
23
-
24
- if ( ! function_exists('is_user_admin')):
25
- /**
26
- * Whether the current request is for a user admin screen /wp-admin/user/
27
- *
28
- * Does not inform on whether the user is an admin! Use capability checks to
29
- * tell if the user should be accessing a section or not.
30
- *
31
- * @since 3.1.0
32
- *
33
- * @return bool True if inside WordPress user administration pages.
34
- */
35
- function is_user_admin() {
36
- if ( defined( 'WP_USER_ADMIN' ) )
37
- return WP_USER_ADMIN;
38
- return false;
39
- }
40
  endif;
1
+ <?php
2
+ /**
3
+ * Contains function which were introduced in late wordpress versions
4
+ */
5
+
6
+ if ( ! function_exists('is_network_admin')):
7
+ /**
8
+ * Whether the current request is for a network admin screen /wp-admin/network/
9
+ *
10
+ * Does not inform on whether the user is a network admin! Use capability checks to
11
+ * tell if the user should be accessing a section or not.
12
+ *
13
+ * @since 3.1.0
14
+ *
15
+ * @return bool True if inside WordPress network administration pages.
16
+ */
17
+ function is_network_admin() {
18
+ if ( defined( 'WP_NETWORK_ADMIN' ) )
19
+ return WP_NETWORK_ADMIN;
20
+ return false;
21
+ }
22
+ endif;
23
+
24
+ if ( ! function_exists('is_user_admin')):
25
+ /**
26
+ * Whether the current request is for a user admin screen /wp-admin/user/
27
+ *
28
+ * Does not inform on whether the user is an admin! Use capability checks to
29
+ * tell if the user should be accessing a section or not.
30
+ *
31
+ * @since 3.1.0
32
+ *
33
+ * @return bool True if inside WordPress user administration pages.
34
+ */
35
+ function is_user_admin() {
36
+ if ( defined( 'WP_USER_ADMIN' ) )
37
+ return WP_USER_ADMIN;
38
+ return false;
39
+ }
40
  endif;
helpers/get_file_curl.php CHANGED
@@ -1,27 +1,45 @@
1
  <?php
2
- if ( ! function_exists('get_file_curl')):
3
 
4
- function get_file_curl($url, $fullpath, $to_variable = false) {
 
 
5
 
6
  $rawdata = wp_remote_retrieve_body( wp_remote_get($url) );
7
 
8
- if (empty($rawdata)){
9
- $ch = curl_init($url);
10
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
11
- $rawdata = curl_exec_follow($ch);
12
-
13
- $result = curl_getinfo($ch, CURLINFO_HTTP_CODE);
14
 
15
- curl_close ($ch);
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- if (!@file_put_contents($fullpath, $rawdata)){
18
- $fp = fopen($fullpath,'w');
19
- fwrite($fp, $rawdata);
20
- fclose($fp);
21
- }
22
 
23
- return ($result == 200) ? (($to_variable) ? $rawdata : true) : false;
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  if (!@file_put_contents($fullpath, $rawdata)){
27
  $fp = fopen($fullpath,'w');
@@ -29,12 +47,13 @@ if ( ! function_exists('get_file_curl')):
29
  fclose($fp);
30
  }
31
 
32
- return ($to_variable) ? $rawdata : true;
33
  }
34
 
35
- endif;
 
 
36
 
37
- if (!function_exists('curl_exec_follow')):
38
  function curl_exec_follow($ch, &$maxredirect = null) {
39
 
40
  $mr = $maxredirect === null ? 5 : intval($maxredirect);
@@ -87,10 +106,8 @@ if (!function_exists('curl_exec_follow')):
87
 
88
  if (!$mr)
89
  {
90
- if ($maxredirect === null)
91
- trigger_error('Too many redirects.', E_USER_WARNING);
92
- else
93
- $maxredirect = 0;
94
 
95
  return false;
96
  }
1
  <?php
 
2
 
3
+ if ( ! function_exists('get_file_curl') ):
4
+
5
+ function get_file_curl($url, $fullpath, $to_variable = false) {
6
 
7
  $rawdata = wp_remote_retrieve_body( wp_remote_get($url) );
8
 
9
+ if (empty($rawdata))
10
+
11
+ return pmxi_curl_download($url, $fullpath, $to_variable);
 
 
 
12
 
13
+ if ( ! @file_put_contents($fullpath, $rawdata) ){
14
+ $fp = fopen($fullpath,'w');
15
+ fwrite($fp, $rawdata);
16
+ fclose($fp);
17
+ }
18
+
19
+ if( ! ($image_info = @getimagesize($fullpath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG)))
20
+
21
+ return pmxi_curl_download($url, $fullpath, $to_variable);
22
+
23
+ return ($to_variable) ? $rawdata : true;
24
+ }
25
 
26
+ endif;
 
 
 
 
27
 
28
+ if ( ! function_exists('pmxi_curl_download') ) {
29
+
30
+ function pmxi_curl_download($url, $fullpath, $to_variable){
31
+
32
+ if ( ! function_exists('curl_version') ) return false;
33
+
34
+ $ch = curl_init($url);
35
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
36
+ $rawdata = curl_exec_follow($ch);
37
+
38
+ $result = curl_getinfo($ch, CURLINFO_HTTP_CODE);
39
+
40
+ curl_close ($ch);
41
+
42
+ if ( empty($rawdata) ) return false;
43
 
44
  if (!@file_put_contents($fullpath, $rawdata)){
45
  $fp = fopen($fullpath,'w');
47
  fclose($fp);
48
  }
49
 
50
+ return ($result == 200) ? (($to_variable) ? $rawdata : true) : false;
51
  }
52
 
53
+ }
54
+
55
+ if ( ! function_exists('curl_exec_follow') ):
56
 
 
57
  function curl_exec_follow($ch, &$maxredirect = null) {
58
 
59
  $mr = $maxredirect === null ? 5 : intval($maxredirect);
106
 
107
  if (!$mr)
108
  {
109
+ if ($maxredirect !== null)
110
+ $maxredirect = 0;
 
 
111
 
112
  return false;
113
  }
helpers/get_taxonomies_by_object_type.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
- if ( ! function_exists('get_taxonomies_by_object_type')):
3
- /**
4
- * get_taxnomies doesn't filter propery by object_type, so these function can be used when filtering by object type requied
5
- * @param string|array $object_type
6
- * @param string[optional] $output
7
- */
8
- function get_taxonomies_by_object_type($object_type, $output = 'names') {
9
- global $wp_taxonomies;
10
-
11
- is_array($object_type) or $object_type = array($object_type);
12
- $field = ('names' == $output) ? 'name' : false;
13
- $filtered = array();
14
- foreach ($wp_taxonomies as $key => $obj) {
15
- if (array_intersect($object_type, $obj->object_type)) {
16
- $filtered[$key] = $obj;
17
- }
18
- }
19
- if ($field) {
20
- $filtered = wp_list_pluck($filtered, $field);
21
- }
22
- return $filtered;
23
- }
24
-
25
  endif;
1
+ <?php
2
+ if ( ! function_exists('get_taxonomies_by_object_type')):
3
+ /**
4
+ * get_taxnomies doesn't filter propery by object_type, so these function can be used when filtering by object type requied
5
+ * @param string|array $object_type
6
+ * @param string[optional] $output
7
+ */
8
+ function get_taxonomies_by_object_type($object_type, $output = 'names') {
9
+ global $wp_taxonomies;
10
+
11
+ is_array($object_type) or $object_type = array($object_type);
12
+ $field = ('names' == $output) ? 'name' : false;
13
+ $filtered = array();
14
+ foreach ($wp_taxonomies as $key => $obj) {
15
+ if (array_intersect($object_type, $obj->object_type)) {
16
+ $filtered[$key] = $obj;
17
+ }
18
+ }
19
+ if ($field) {
20
+ $filtered = wp_list_pluck($filtered, $field);
21
+ }
22
+ return $filtered;
23
+ }
24
+
25
  endif;
helpers/is_exists_term.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!function_exists('is_exists_term')){
3
+ function is_exists_term($tx_name, $name, $parent_id = ''){
4
+
5
+ $term = false;
6
+
7
+ delete_option("{$tx_name}_children");
8
+
9
+ $siblings = get_terms($tx_name, array('fields' => 'all', 'get' => 'all', 'parent' => (int)$parent_id) );
10
+
11
+ $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
12
+ $args = wp_parse_args(array('name' => $name, 'taxonomy' => $tx_name), $defaults);
13
+ $args = sanitize_term($args, $tx_name, 'db');
14
+
15
+ if (!empty($siblings)) foreach ($siblings as $t) {
16
+
17
+ if ($t->name == wp_unslash($args['name'])){
18
+ $term = array('term_id' => $t->term_id);
19
+ break;
20
+ }
21
+ }
22
+
23
+ return $term;
24
+ }
25
+ }
26
+ ?>
helpers/pmxi_functions.php CHANGED
@@ -217,7 +217,7 @@
217
  if (!$type) $type = (preg_match('%\W(xml)$%i', basename($filePath))) ? 'xml' : false;
218
 
219
  $uploads = wp_upload_dir();
220
- $tmpname = wp_unique_filename($uploads['path'], basename($filePath));
221
  $localPath = $uploads['path'] .'/'. $tmpname;
222
 
223
  $file = @fopen($filePath, "rb");
@@ -260,7 +260,7 @@
260
 
261
  $type = 'csv';
262
  $uploads = wp_upload_dir();
263
- $tmpname = wp_unique_filename($uploads['path'], basename($filename));
264
  $fp = @fopen($uploads['path'] .'/'. $tmpname, 'w');
265
 
266
  $file = @gzopen($filename, 'rb', $use_include_path);
@@ -376,11 +376,35 @@
376
 
377
  if ( empty($change_array) or count($orig_array) != count($change_array)) return "";
378
 
379
- return str_replace($orig_array, $change_array, $value);
380
 
381
  }
382
  }
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
 
385
  /* Session */
386
 
217
  if (!$type) $type = (preg_match('%\W(xml)$%i', basename($filePath))) ? 'xml' : false;
218
 
219
  $uploads = wp_upload_dir();
220
+ $tmpname = wp_unique_filename($uploads['path'], ($type and strlen(basename($filePath)) < 30) ? basename($filePath) : time());
221
  $localPath = $uploads['path'] .'/'. $tmpname;
222
 
223
  $file = @fopen($filePath, "rb");
260
 
261
  $type = 'csv';
262
  $uploads = wp_upload_dir();
263
+ $tmpname = wp_unique_filename($uploads['path'], (strlen(basename($filename)) < 30) ? basename($filename) : time());
264
  $fp = @fopen($uploads['path'] .'/'. $tmpname, 'w');
265
 
266
  $file = @gzopen($filename, 'rb', $use_include_path);
376
 
377
  if ( empty($change_array) or count($orig_array) != count($change_array)) return "";
378
 
379
+ return str_replace(array_map('trim', $orig_array), array_map('trim', $change_array), $value);
380
 
381
  }
382
  }
383
 
384
+ if ( ! function_exists('pmxi_convert_encoding')){
385
+
386
+ function pmxi_convert_encoding ( $source, $target_encoding = 'ASCII' )
387
+ {
388
+
389
+ // detect the character encoding of the incoming file
390
+ $encoding = mb_detect_encoding( $source, "auto" );
391
+
392
+ // escape all of the question marks so we can remove artifacts from
393
+ // the unicode conversion process
394
+ $target = str_replace( "?", "[question_mark]", $source );
395
+
396
+ // convert the string to the target encoding
397
+ $target = mb_convert_encoding( $target, $target_encoding, $encoding);
398
+
399
+ // remove any question marks that have been introduced because of illegal characters
400
+ $target = str_replace( "?", "", $target );
401
+
402
+ // replace the token string "[question_mark]" with the symbol "?"
403
+ $target = str_replace( "[question_mark]", "?", $target );
404
+
405
+ return html_entity_decode($target, ENT_COMPAT, 'UTF-8');
406
+ }
407
+ }
408
 
409
  /* Session */
410
 
helpers/str_getcsv.php CHANGED
@@ -1,17 +1,18 @@
1
- <?php
2
- if ( ! function_exists('str_getcsv')):
3
- /**
4
- * str_getcsv function for PHP less than 5.3
5
- * @see http://php.net/manual/en/function.str-getcsv.php
6
- * NOTE: function doesn't support escape paramter (in correspondance to fgetcsv not supporting it prior 5.3)
7
- */
8
- function str_getcsv($input, $delimiter=',', $enclosure='"') {
9
- $temp = fopen("php://memory", "rw");
10
- fwrite($temp, $input);
11
- fseek($temp, 0);
12
- $r = fgetcsv($temp, strlen($input), $delimiter, $enclosure);
13
- fclose($temp);
14
- return $r;
15
- }
16
-
 
17
  endif;
1
+ <?php
2
+ if ( ! function_exists('str_getcsv')):
3
+ /**
4
+ * str_getcsv function for PHP less than 5.3
5
+ * @see http://php.net/manual/en/function.str-getcsv.php
6
+ * NOTE: function doesn't support escape paramter (in correspondance to fgetcsv not supporting it prior 5.3)
7
+ */
8
+ function str_getcsv($input, $delimiter=',', $enclosure='"') {
9
+ if ("" == $delimiter) $delimiter = ',';
10
+ $temp = fopen("php://memory", "rw");
11
+ fwrite($temp, $input);
12
+ fseek($temp, 0);
13
+ $r = fgetcsv($temp, strlen($input), $delimiter, $enclosure);
14
+ fclose($temp);
15
+ return $r;
16
+ }
17
+
18
  endif;
helpers/wp_delete_attachments.php CHANGED
@@ -1,10 +1,26 @@
1
- <?php
2
- /**
3
- * Delete attachments linked to a specified post
4
- * @param int $parent_id Parent id of post to delete attachments for
5
- */
6
- function wp_delete_attachments($parent_id) {
7
- foreach (get_posts(array('post_parent' => $parent_id, 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null)) as $attach) {
8
- wp_delete_attachment($attach->ID, true);
9
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
1
+ <?php
2
+ /**
3
+ * Delete attachments linked to a specified post
4
+ * @param int $parent_id Parent id of post to delete attachments for
5
+ */
6
+ function wp_delete_attachments($parent_id, $unlink = true) {
7
+ foreach (get_posts(array('post_parent' => $parent_id, 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null)) as $attach) {
8
+ if ($unlink){
9
+ wp_delete_attachment($attach->ID, true);
10
+ }
11
+ else{
12
+ global $wpdb;
13
+ $sql = "delete a,b,c
14
+ FROM ".$wpdb->posts." a
15
+ LEFT JOIN ".$wpdb->term_relationships." b ON ( a.ID = b.object_id )
16
+ LEFT JOIN ".$wpdb->postmeta." c ON ( a.ID = c.post_id )
17
+ LEFT JOIN ".$wpdb->posts." d ON ( a.ID = d.post_parent )
18
+ WHERE a.ID = ".$attach->ID.";";
19
+
20
+ $wpdb->query(
21
+ $wpdb->prepare($sql, '')
22
+ );
23
+ }
24
+
25
+ }
26
  }
helpers/wp_redirect_or_javascript.php CHANGED
@@ -1,17 +1,17 @@
1
- <?php
2
- if ( ! function_exists('wp_redirect_or_javascript')):
3
- /**
4
- * For AJAX request outputs javascript specified, otherwise acts like wp_redirect
5
- * @param string $location
6
- * @param string[optional] $javascript
7
- * @param int[optional] $status
8
- */
9
- function wp_redirect_or_javascript($location, $javascript = NULL, $status = 302) {
10
- if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
11
- is_null($javascript) and $javascript = 'location.href="' . addslashes($location) . '";';
12
- echo '<script type="text/javascript">' . $javascript . '</script>';
13
- } else {
14
- return wp_redirect($location, $status);
15
- }
16
- }
17
  endif;
1
+ <?php
2
+ if ( ! function_exists('wp_redirect_or_javascript')):
3
+ /**
4
+ * For AJAX request outputs javascript specified, otherwise acts like wp_redirect
5
+ * @param string $location
6
+ * @param string[optional] $javascript
7
+ * @param int[optional] $status
8
+ */
9
+ function wp_redirect_or_javascript($location, $javascript = NULL, $status = 302) {
10
+ if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
11
+ is_null($javascript) and $javascript = 'location.href="' . addslashes($location) . '";';
12
+ echo '<script type="text/javascript">' . $javascript . '</script>';
13
+ } else {
14
+ return wp_redirect($location, $status);
15
+ }
16
+ }
17
  endif;
libraries/XmlImportCsvParse.php CHANGED
@@ -77,13 +77,19 @@ class PMXI_CsvParser
77
 
78
  $xpath = '',
79
 
 
 
80
  $large_import = false,
81
 
82
  $htmlentities = false,
83
 
84
  $xml_path = '',
85
 
86
- $iteration = 0;
 
 
 
 
87
 
88
  protected
89
 
@@ -120,14 +126,21 @@ class PMXI_CsvParser
120
  * @see load()
121
  * @return void
122
  */
123
- public function __construct($filename = null, $large_import = false, $xpath = '')
124
  {
125
-
 
126
  $this->large_import = $large_import;
127
  $this->xpath = (!empty($xpath) ? $xpath : ((!empty($_POST['xpath'])) ? $_POST['xpath'] : '/node'));
 
 
 
 
 
 
128
 
129
- ini_set( "display_errors", 0);
130
- ini_set('auto_detect_line_endings', true);
131
 
132
  $file_params = self::analyse_file($filename, 1);
133
 
@@ -941,18 +954,20 @@ class PMXI_CsvParser
941
  }
942
 
943
  $c = 0;
944
- $d = $this->settings['delimiter'];
945
  $e = $this->settings['escape'];
946
- $l = $this->settings['length'];
 
 
947
 
948
  $res = fopen($this->_filename, 'rb');
949
 
950
  $wp_uploads = wp_upload_dir();
951
  if ($this->large_import){
952
  $tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($this->_filename)));
953
- $this->xml_path = $wp_uploads['path'] .'/'. $tmpname;
954
  $fp = fopen($this->xml_path, 'w');
955
- fwrite($fp, "<?xml version=\"1.0\" encoding=\"utf-8\"?><data>");
956
  }
957
  $create_new_headers = false;
958
 
@@ -983,7 +998,10 @@ class PMXI_CsvParser
983
  $chunk = array();
984
 
985
  foreach ($this->headers as $key => $header) {
986
- $chunk[$header] = $this->fixEncoding( ($legacy_special_character_handling) ? htmlspecialchars($keys[$key]) : htmlentities($keys[$key]));
 
 
 
987
  }
988
 
989
  if (!empty($chunk))
@@ -1000,23 +1018,7 @@ class PMXI_CsvParser
1000
  fwrite($fp, '</data>');
1001
  fclose($fp);
1002
  fclose($res);
1003
- $this->removeEmpty();
1004
-
1005
- /*$errors = array();
1006
- $xml = file_get_contents($this->xml_path);
1007
-
1008
- PMXI_Import_Record::preprocessXml($xml);
1009
-
1010
- if (PMXI_Import_Record::validateXml($xml, $errors)){
1011
- return true;
1012
- }
1013
- else{
1014
- $this->htmlentities = true;
1015
- $this->rows = array();
1016
- $this->iteration++;
1017
- if ($this->iteration > 1) return true;
1018
- return $this->parse();
1019
- } */
1020
 
1021
  return true;
1022
  }
@@ -1141,7 +1143,7 @@ class PMXI_CsvParser
1141
  'comma' => ',',
1142
  'semicolon' => ';',
1143
  'pipe' => '|',
1144
- 'tabulation' => "\t"
1145
  );
1146
 
1147
  // specify allowed line endings
77
 
78
  $xpath = '',
79
 
80
+ $delimiter = '',
81
+
82
  $large_import = false,
83
 
84
  $htmlentities = false,
85
 
86
  $xml_path = '',
87
 
88
+ $iteration = 0,
89
+
90
+ $csv_encoding = 'UTF-8',
91
+
92
+ $auto_encoding = true;
93
 
94
  protected
95
 
126
  * @see load()
127
  * @return void
128
  */
129
+ public function __construct($filename = null, $large_import = false, $xpath = '', $delimiter = '', $encoding = '', $xml_path = '')
130
  {
131
+ PMXI_Plugin::$csv_path = $filename;
132
+
133
  $this->large_import = $large_import;
134
  $this->xpath = (!empty($xpath) ? $xpath : ((!empty($_POST['xpath'])) ? $_POST['xpath'] : '/node'));
135
+ $this->delimiter = $delimiter;
136
+ if ('' != $encoding){
137
+ $this->csv_encoding = $encoding;
138
+ $this->auto_encoding = false;
139
+ }
140
+ if ('' != $xml_path) $this->xml_path = $xml_path;
141
 
142
+ @ini_set( "display_errors", 0);
143
+ @ini_set('auto_detect_line_endings', true);
144
 
145
  $file_params = self::analyse_file($filename, 1);
146
 
954
  }
955
 
956
  $c = 0;
957
+ $d = ( "" != $this->delimiter ) ? $this->delimiter : $this->settings['delimiter'];
958
  $e = $this->settings['escape'];
959
+ $l = $this->settings['length'];
960
+
961
+ PMXI_Plugin::$is_csv = $d;
962
 
963
  $res = fopen($this->_filename, 'rb');
964
 
965
  $wp_uploads = wp_upload_dir();
966
  if ($this->large_import){
967
  $tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($this->_filename)));
968
+ if ('' == $this->xml_path) $this->xml_path = $wp_uploads['path'] .'/'. $tmpname;
969
  $fp = fopen($this->xml_path, 'w');
970
+ fwrite($fp, "<?xml version=\"1.0\" encoding=\"".$this->csv_encoding."\"?><data>");
971
  }
972
  $create_new_headers = false;
973
 
998
  $chunk = array();
999
 
1000
  foreach ($this->headers as $key => $header) {
1001
+ if ($this->auto_encoding)
1002
+ $chunk[$header] = $this->fixEncoding( ($legacy_special_character_handling) ? htmlspecialchars($keys[$key], ENT_COMPAT, $this->csv_encoding) : $keys[$key] );
1003
+ else
1004
+ $chunk[$header] = ($legacy_special_character_handling) ? htmlspecialchars($keys[$key], ENT_COMPAT, $this->csv_encoding) : $keys[$key];
1005
  }
1006
 
1007
  if (!empty($chunk))
1018
  fwrite($fp, '</data>');
1019
  fclose($fp);
1020
  fclose($res);
1021
+ $this->removeEmpty();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1022
 
1023
  return true;
1024
  }
1143
  'comma' => ',',
1144
  'semicolon' => ';',
1145
  'pipe' => '|',
1146
+ 'tabulation' => "\t"
1147
  );
1148
 
1149
  // specify allowed line endings
libraries/XmlImportParser.php CHANGED
@@ -110,7 +110,7 @@ class XmlImportParser {
110
  $tree = $t_parser->parse();
111
  $codegenerator = new XmlImportTemplateCodeGenerator($tree);
112
  $file = $codegenerator->generate();
113
-
114
  return new self($xml, $rootNodeXPath, $file);
115
  }
116
  }
110
  $tree = $t_parser->parse();
111
  $codegenerator = new XmlImportTemplateCodeGenerator($tree);
112
  $file = $codegenerator->generate();
113
+
114
  return new self($xml, $rootNodeXPath, $file);
115
  }
116
  }
libraries/XmlImportTemplateCodeGenerator.php CHANGED
@@ -103,9 +103,9 @@ class XmlImportTemplateCodeGenerator
103
  {
104
  $filename = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
105
  }
106
- if ( ! $filename or ! is_writable($filename) ){
107
  $uploads = wp_upload_dir();
108
- $filename = $uploads['path'] . '/' . wp_unique_filename($uploads['path']);
109
  }
110
 
111
  file_put_contents($filename, $result);
103
  {
104
  $filename = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
105
  }
106
+ if ( ! $filename or ! @is_writable($filename) ){
107
  $uploads = wp_upload_dir();
108
+ $filename = $uploads['path'] . '/' . wp_unique_filename($uploads['path'], 'tmpfile');
109
  }
110
 
111
  file_put_contents($filename, $result);
libraries/XmlImportTemplateParser.php CHANGED
@@ -17,6 +17,7 @@ require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
17
  require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
18
  require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
19
  require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
 
20
 
21
  /**
22
  * Parses a list of nodes into AST (Abstract Syntax Tree)
@@ -185,8 +186,11 @@ class XmlImportTemplateParser
185
  {
186
  if ($this->index + 1 == count($this->tokens))
187
  throw new XmlImportException("Reached end of template but expression was expected");
188
-
189
- if($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
 
 
 
190
  {
191
  return $this->parseMath();
192
  }
@@ -214,7 +218,43 @@ class XmlImportTemplateParser
214
  }
215
  else
216
  throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
217
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
  /**
220
  * Parses function
17
  require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
18
  require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
19
  require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
20
+ require_once dirname(__FILE__) . '/ast/XmlImportAstFunction.php';
21
 
22
  /**
23
  * Parses a list of nodes into AST (Abstract Syntax Tree)
186
  {
187
  if ($this->index + 1 == count($this->tokens))
188
  throw new XmlImportException("Reached end of template but expression was expected");
189
+ if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_FUNCTION)
190
+ {
191
+ return $this->parseFunction();
192
+ }
193
+ elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
194
  {
195
  return $this->parseMath();
196
  }
218
  }
219
  else
220
  throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
221
+ }
222
+
223
+ /**
224
+ * Parses function
225
+ *
226
+ * @return XmlImportAstFunction
227
+ */
228
+ private function parseFunction()
229
+ {
230
+ $function = new XmlImportAstFunction($this->tokens[++$this->index]->getValue());
231
+ if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
232
+ throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
233
+ $this->index++;
234
+ if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
235
+ {
236
+ $this->index++;
237
+ return $function;
238
+ }
239
+ else
240
+ {
241
+ while ($this->index < count($this->tokens) - 2)
242
+ {
243
+ $function->addArgument($this->parseExpression());
244
+ if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
245
+ {
246
+ $this->index++;
247
+ return $function;
248
+ break;
249
+ }
250
+ elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
251
+ $this->index++;
252
+ else
253
+ throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
254
+ }
255
+ throw new XmlImportException("Unexpected end of {$function->getName()} function argument list");
256
+ }
257
+ }
258
 
259
  /**
260
  * Parses function
libraries/pclzip.lib.php CHANGED
@@ -1,5697 +1,5697 @@
1
- <?php
2
- // --------------------------------------------------------------------------------
3
- // PhpConcept Library - Zip Module 2.8.2
4
- // --------------------------------------------------------------------------------
5
- // License GNU/LGPL - Vincent Blavet - August 2009
6
- // http://www.phpconcept.net
7
- // --------------------------------------------------------------------------------
8
- //
9
- // Presentation :
10
- // PclZip is a PHP library that manage ZIP archives.
11
- // So far tests show that archives generated by PclZip are readable by
12
- // WinZip application and other tools.
13
- //
14
- // Description :
15
- // See readme.txt and http://www.phpconcept.net
16
- //
17
- // Warning :
18
- // This library and the associated files are non commercial, non professional
19
- // work.
20
- // It should not have unexpected results. However if any damage is caused by
21
- // this software the author can not be responsible.
22
- // The use of this software is at the risk of the user.
23
- //
24
- // --------------------------------------------------------------------------------
25
- // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
26
- // --------------------------------------------------------------------------------
27
-
28
- // ----- Constants
29
- if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
30
- define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
31
- }
32
-
33
- // ----- File list separator
34
- // In version 1.x of PclZip, the separator for file list is a space
35
- // (which is not a very smart choice, specifically for windows paths !).
36
- // A better separator should be a comma (,). This constant gives you the
37
- // abilty to change that.
38
- // However notice that changing this value, may have impact on existing
39
- // scripts, using space separated filenames.
40
- // Recommanded values for compatibility with older versions :
41
- //define( 'PCLZIP_SEPARATOR', ' ' );
42
- // Recommanded values for smart separation of filenames.
43
- if (!defined('PCLZIP_SEPARATOR')) {
44
- define( 'PCLZIP_SEPARATOR', ',' );
45
- }
46
-
47
- // ----- Error configuration
48
- // 0 : PclZip Class integrated error handling
49
- // 1 : PclError external library error handling. By enabling this
50
- // you must ensure that you have included PclError library.
51
- // [2,...] : reserved for futur use
52
- if (!defined('PCLZIP_ERROR_EXTERNAL')) {
53
- define( 'PCLZIP_ERROR_EXTERNAL', 0 );
54
- }
55
-
56
- // ----- Optional static temporary directory
57
- // By default temporary files are generated in the script current
58
- // path.
59
- // If defined :
60
- // - MUST BE terminated by a '/'.
61
- // - MUST be a valid, already created directory
62
- // Samples :
63
- // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
64
- // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
65
-
66
- $wp_uploads = wp_upload_dir();
67
-
68
- if (!defined('PCLZIP_TEMPORARY_DIR')) {
69
- define( 'PCLZIP_TEMPORARY_DIR', $wp_uploads['path'] );
70
- }
71
-
72
- // ----- Optional threshold ratio for use of temporary files
73
- // Pclzip sense the size of the file to add/extract and decide to
74
- // use or not temporary file. The algorythm is looking for
75
- // memory_limit of PHP and apply a ratio.
76
- // threshold = memory_limit * ratio.
77
- // Recommended values are under 0.5. Default 0.47.
78
- // Samples :
79
- // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
80
- if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
81
- define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
82
- }
83
-
84
- // --------------------------------------------------------------------------------
85
- // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
86
- // --------------------------------------------------------------------------------
87
-
88
- // ----- Global variables
89
- $g_pclzip_version = "2.8.2";
90
-
91
- // ----- Error codes
92
- // -1 : Unable to open file in binary write mode
93
- // -2 : Unable to open file in binary read mode
94
- // -3 : Invalid parameters
95
- // -4 : File does not exist
96
- // -5 : Filename is too long (max. 255)
97
- // -6 : Not a valid zip file
98
- // -7 : Invalid extracted file size
99
- // -8 : Unable to create directory
100
- // -9 : Invalid archive extension
101
- // -10 : Invalid archive format
102
- // -11 : Unable to delete file (unlink)
103
- // -12 : Unable to rename file (rename)
104
- // -13 : Invalid header checksum
105
- // -14 : Invalid archive size
106
- define( 'PCLZIP_ERR_USER_ABORTED', 2 );
107
- define( 'PCLZIP_ERR_NO_ERROR', 0 );
108
- define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
109
- define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
110
- define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
111
- define( 'PCLZIP_ERR_MISSING_FILE', -4 );
112
- define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
113
- define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
114
- define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
115
- define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
116
- define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
117
- define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
118
- define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
119
- define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
120
- define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
121
- define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
122
- define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
123
- define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
124
- define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
125
- define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
126
- define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
127
- define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
128
- define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
129
-
130
- // ----- Options values
131
- define( 'PCLZIP_OPT_PATH', 77001 );
132
- define( 'PCLZIP_OPT_ADD_PATH', 77002 );
133
- define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
134
- define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
135
- define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
136
- define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
137
- define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
138
- define( 'PCLZIP_OPT_BY_NAME', 77008 );
139
- define( 'PCLZIP_OPT_BY_INDEX', 77009 );
140
- define( 'PCLZIP_OPT_BY_EREG', 77010 );
141
- define( 'PCLZIP_OPT_BY_PREG', 77011 );
142
- define( 'PCLZIP_OPT_COMMENT', 77012 );
143
- define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
144
- define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
145
- define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
146
- define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
147
- define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
148
- // Having big trouble with crypt. Need to multiply 2 long int
149
- // which is not correctly supported by PHP ...
150
- //define( 'PCLZIP_OPT_CRYPT', 77018 );
151
- define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
152
- define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
153
- define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
154
- define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
155
- define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
156
- define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
157
- define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
158
-
159
- // ----- File description attributes
160
- define( 'PCLZIP_ATT_FILE_NAME', 79001 );
161
- define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
162
- define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
163
- define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
164
- define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
165
- define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
166
-
167
- // ----- Call backs values
168
- define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
169
- define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
170
- define( 'PCLZIP_CB_PRE_ADD', 78003 );
171
- define( 'PCLZIP_CB_POST_ADD', 78004 );
172
- /* For futur use
173
- define( 'PCLZIP_CB_PRE_LIST', 78005 );
174
- define( 'PCLZIP_CB_POST_LIST', 78006 );
175
- define( 'PCLZIP_CB_PRE_DELETE', 78007 );
176
- define( 'PCLZIP_CB_POST_DELETE', 78008 );
177
- */
178
-
179
- // --------------------------------------------------------------------------------
180
- // Class : PclZip
181
- // Description :
182
- // PclZip is the class that represent a Zip archive.
183
- // The public methods allow the manipulation of the archive.
184
- // Attributes :
185
- // Attributes must not be accessed directly.
186
- // Methods :
187
- // PclZip() : Object creator
188
- // create() : Creates the Zip archive
189
- // listContent() : List the content of the Zip archive
190
- // extract() : Extract the content of the archive
191
- // properties() : List the properties of the archive
192
- // --------------------------------------------------------------------------------
193
- class PclZip
194
- {
195
- // ----- Filename of the zip file
196
- var $zipname = '';
197
-
198
- // ----- File descriptor of the zip file
199
- var $zip_fd = 0;
200
-
201
- // ----- Internal error handling
202
- var $error_code = 1;
203
- var $error_string = '';
204
-
205
- // ----- Current status of the magic_quotes_runtime
206
- // This value store the php configuration for magic_quotes
207
- // The class can then disable the magic_quotes and reset it after
208
- var $magic_quotes_status;
209
-
210
- // --------------------------------------------------------------------------------
211
- // Function : PclZip()
212
- // Description :
213
- // Creates a PclZip object and set the name of the associated Zip archive
214
- // filename.
215
- // Note that no real action is taken, if the archive does not exist it is not
216
- // created. Use create() for that.
217
- // --------------------------------------------------------------------------------
218
- function PclZip($p_zipname)
219
- {
220
-
221
- // ----- Tests the zlib
222
- if (!function_exists('gzopen'))
223
- {
224
- die('Abort '.basename(__FILE__).' : Missing zlib extensions');
225
- }
226
-
227
- // ----- Set the attributes
228
- $this->zipname = $p_zipname;
229
- $this->zip_fd = 0;
230
- $this->magic_quotes_status = -1;
231
-
232
- // ----- Return
233
- return;
234
- }
235
- // --------------------------------------------------------------------------------
236
-
237
- // --------------------------------------------------------------------------------
238
- // Function :
239
- // create($p_filelist, $p_add_dir="", $p_remove_dir="")
240
- // create($p_filelist, $p_option, $p_option_value, ...)
241
- // Description :
242
- // This method supports two different synopsis. The first one is historical.
243
- // This method creates a Zip Archive. The Zip file is created in the
244
- // filesystem. The files and directories indicated in $p_filelist
245
- // are added in the archive. See the parameters description for the
246
- // supported format of $p_filelist.
247
- // When a directory is in the list, the directory and its content is added
248
- // in the archive.
249
- // In this synopsis, the function takes an optional variable list of
250
- // options. See bellow the supported options.
251
- // Parameters :
252
- // $p_filelist : An array containing file or directory names, or
253
- // a string containing one filename or one directory name, or
254
- // a string containing a list of filenames and/or directory
255
- // names separated by spaces.
256
- // $p_add_dir : A path to add before the real path of the archived file,
257
- // in order to have it memorized in the archive.
258
- // $p_remove_dir : A path to remove from the real path of the file to archive,
259
- // in order to have a shorter path memorized in the archive.
260
- // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
261
- // is removed first, before $p_add_dir is added.
262
- // Options :
263
- // PCLZIP_OPT_ADD_PATH :
264
- // PCLZIP_OPT_REMOVE_PATH :
265
- // PCLZIP_OPT_REMOVE_ALL_PATH :
266
- // PCLZIP_OPT_COMMENT :
267
- // PCLZIP_CB_PRE_ADD :
268
- // PCLZIP_CB_POST_ADD :
269
- // Return Values :
270
- // 0 on failure,
271
- // The list of the added files, with a status of the add action.
272
- // (see PclZip::listContent() for list entry format)
273
- // --------------------------------------------------------------------------------
274
- function create($p_filelist)
275
- {
276
- $v_result=1;
277
-
278
- // ----- Reset the error handler
279
- $this->privErrorReset();
280
-
281
- // ----- Set default values
282
- $v_options = array();
283
- $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
284
-
285
- // ----- Look for variable options arguments
286
- $v_size = func_num_args();
287
-
288
- // ----- Look for arguments
289
- if ($v_size > 1) {
290
- // ----- Get the arguments
291
- $v_arg_list = func_get_args();
292
-
293
- // ----- Remove from the options list the first argument
294
- array_shift($v_arg_list);
295
- $v_size--;
296
-
297
- // ----- Look for first arg
298
- if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
299
-
300
- // ----- Parse the options
301
- $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
302
- array (PCLZIP_OPT_REMOVE_PATH => 'optional',
303
- PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
304
- PCLZIP_OPT_ADD_PATH => 'optional',
305
- PCLZIP_CB_PRE_ADD => 'optional',
306
- PCLZIP_CB_POST_ADD => 'optional',
307
- PCLZIP_OPT_NO_COMPRESSION => 'optional',
308
- PCLZIP_OPT_COMMENT => 'optional',
309
- PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
310
- PCLZIP_OPT_TEMP_FILE_ON => 'optional',
311
- PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
312
- //, PCLZIP_OPT_CRYPT => 'optional'
313
- ));
314
- if ($v_result != 1) {
315
- return 0;
316
- }
317
- }
318
-
319
- // ----- Look for 2 args
320
- // Here we need to support the first historic synopsis of the
321
- // method.
322
- else {
323
-
324
- // ----- Get the first argument
325
- $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
326
-
327
- // ----- Look for the optional second argument
328
- if ($v_size == 2) {
329
- $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
330
- }
331
- else if ($v_size > 2) {
332
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
333
- "Invalid number / type of arguments");
334
- return 0;
335
- }
336
- }
337
- }
338
-
339
- // ----- Look for default option values
340
- $this->privOptionDefaultThreshold($v_options);
341
-
342
- // ----- Init
343
- $v_string_list = array();
344
- $v_att_list = array();
345
- $v_filedescr_list = array();
346
- $p_result_list = array();
347
-
348
- // ----- Look if the $p_filelist is really an array
349
- if (is_array($p_filelist)) {
350
-
351
- // ----- Look if the first element is also an array
352
- // This will mean that this is a file description entry
353
- if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
354
- $v_att_list = $p_filelist;
355
- }
356
-
357
- // ----- The list is a list of string names
358
- else {
359
- $v_string_list = $p_filelist;
360
- }
361
- }
362
-
363
- // ----- Look if the $p_filelist is a string
364
- else if (is_string($p_filelist)) {
365
- // ----- Create a list from the string
366
- $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
367
- }
368
-
369
- // ----- Invalid variable type for $p_filelist
370
- else {
371
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
372
- return 0;
373
- }
374
-
375
- // ----- Reformat the string list
376
- if (sizeof($v_string_list) != 0) {
377
- foreach ($v_string_list as $v_string) {
378
- if ($v_string != '') {
379
- $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
380
- }
381
- else {
382
- }
383
- }
384
- }
385
-
386
- // ----- For each file in the list check the attributes
387
- $v_supported_attributes
388
- = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
389
- ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
390
- ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
391
- ,PCLZIP_ATT_FILE_MTIME => 'optional'
392
- ,PCLZIP_ATT_FILE_CONTENT => 'optional'
393
- ,PCLZIP_ATT_FILE_COMMENT => 'optional'
394
- );
395
- foreach ($v_att_list as $v_entry) {
396
- $v_result = $this->privFileDescrParseAtt($v_entry,
397
- $v_filedescr_list[],
398
- $v_options,
399
- $v_supported_attributes);
400
- if ($v_result != 1) {
401
- return 0;
402
- }
403
- }
404
-
405
- // ----- Expand the filelist (expand directories)
406
- $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
407
- if ($v_result != 1) {
408
- return 0;
409
- }
410
-
411
- // ----- Call the create fct
412
- $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
413
- if ($v_result != 1) {
414
- return 0;
415
- }
416
-
417
- // ----- Return
418
- return $p_result_list;
419
- }
420
- // --------------------------------------------------------------------------------
421
-
422
- // --------------------------------------------------------------------------------
423
- // Function :
424
- // add($p_filelist, $p_add_dir="", $p_remove_dir="")
425
- // add($p_filelist, $p_option, $p_option_value, ...)
426
- // Description :
427
- // This method supports two synopsis. The first one is historical.
428
- // This methods add the list of files in an existing archive.
429
- // If a file with the same name already exists, it is added at the end of the
430
- // archive, the first one is still present.
431
- // If the archive does not exist, it is created.
432
- // Parameters :
433
- // $p_filelist : An array containing file or directory names, or
434
- // a string containing one filename or one directory name, or
435
- // a string containing a list of filenames and/or directory
436
- // names separated by spaces.
437
- // $p_add_dir : A path to add before the real path of the archived file,
438
- // in order to have it memorized in the archive.
439
- // $p_remove_dir : A path to remove from the real path of the file to archive,
440
- // in order to have a shorter path memorized in the archive.
441
- // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
442
- // is removed first, before $p_add_dir is added.
443
- // Options :
444
- // PCLZIP_OPT_ADD_PATH :
445
- // PCLZIP_OPT_REMOVE_PATH :
446
- // PCLZIP_OPT_REMOVE_ALL_PATH :
447
- // PCLZIP_OPT_COMMENT :
448
- // PCLZIP_OPT_ADD_COMMENT :
449
- // PCLZIP_OPT_PREPEND_COMMENT :
450
- // PCLZIP_CB_PRE_ADD :
451
- // PCLZIP_CB_POST_ADD :
452
- // Return Values :
453
- // 0 on failure,
454
- // The list of the added files, with a status of the add action.
455
- // (see PclZip::listContent() for list entry format)
456
- // --------------------------------------------------------------------------------
457
- function add($p_filelist)
458
- {
459
- $v_result=1;
460
-
461
- // ----- Reset the error handler
462
- $this->privErrorReset();
463
-
464
- // ----- Set default values
465
- $v_options = array();
466
- $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
467
-
468
- // ----- Look for variable options arguments
469
- $v_size = func_num_args();
470
-
471
- // ----- Look for arguments
472
- if ($v_size > 1) {
473
- // ----- Get the arguments
474
- $v_arg_list = func_get_args();
475
-
476
- // ----- Remove form the options list the first argument
477
- array_shift($v_arg_list);
478
- $v_size--;
479
-
480
- // ----- Look for first arg
481
- if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
482
-
483
- // ----- Parse the options
484
- $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
485
- array (PCLZIP_OPT_REMOVE_PATH => 'optional',
486
- PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
487
- PCLZIP_OPT_ADD_PATH => 'optional',
488
- PCLZIP_CB_PRE_ADD => 'optional',
489
- PCLZIP_CB_POST_ADD => 'optional',
490
- PCLZIP_OPT_NO_COMPRESSION => 'optional',
491
- PCLZIP_OPT_COMMENT => 'optional',
492
- PCLZIP_OPT_ADD_COMMENT => 'optional',
493
- PCLZIP_OPT_PREPEND_COMMENT => 'optional',
494
- PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
495
- PCLZIP_OPT_TEMP_FILE_ON => 'optional',
496
- PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
497
- //, PCLZIP_OPT_CRYPT => 'optional'
498
- ));
499
- if ($v_result != 1) {
500
- return 0;
501
- }
502
- }
503
-
504
- // ----- Look for 2 args
505
- // Here we need to support the first historic synopsis of the
506
- // method.
507
- else {
508
-
509
- // ----- Get the first argument
510
- $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
511
-
512
- // ----- Look for the optional second argument
513
- if ($v_size == 2) {
514
- $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
515
- }
516
- else if ($v_size > 2) {
517
- // ----- Error log
518
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
519
-
520
- // ----- Return
521
- return 0;
522
- }
523
- }
524
- }
525
-
526
- // ----- Look for default option values
527
- $this->privOptionDefaultThreshold($v_options);
528
-
529
- // ----- Init
530
- $v_string_list = array();
531
- $v_att_list = array();
532
- $v_filedescr_list = array();
533
- $p_result_list = array();
534
-
535
- // ----- Look if the $p_filelist is really an array
536
- if (is_array($p_filelist)) {
537
-
538
- // ----- Look if the first element is also an array
539
- // This will mean that this is a file description entry
540
- if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
541
- $v_att_list = $p_filelist;
542
- }
543
-
544
- // ----- The list is a list of string names
545
- else {
546
- $v_string_list = $p_filelist;
547
- }
548
- }
549
-
550
- // ----- Look if the $p_filelist is a string
551
- else if (is_string($p_filelist)) {
552
- // ----- Create a list from the string
553
- $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
554
- }
555
-
556
- // ----- Invalid variable type for $p_filelist
557
- else {
558
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
559
- return 0;
560
- }
561
-
562
- // ----- Reformat the string list
563
- if (sizeof($v_string_list) != 0) {
564
- foreach ($v_string_list as $v_string) {
565
- $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
566
- }
567
- }
568
-
569
- // ----- For each file in the list check the attributes
570
- $v_supported_attributes
571
- = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
572
- ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
573
- ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
574
- ,PCLZIP_ATT_FILE_MTIME => 'optional'
575
- ,PCLZIP_ATT_FILE_CONTENT => 'optional'
576
- ,PCLZIP_ATT_FILE_COMMENT => 'optional'
577
- );
578
- foreach ($v_att_list as $v_entry) {
579
- $v_result = $this->privFileDescrParseAtt($v_entry,
580
- $v_filedescr_list[],
581
- $v_options,
582
- $v_supported_attributes);
583
- if ($v_result != 1) {
584
- return 0;
585
- }
586
- }
587
-
588
- // ----- Expand the filelist (expand directories)
589
- $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
590
- if ($v_result != 1) {
591
- return 0;
592
- }
593
-
594
- // ----- Call the create fct
595
- $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
596
- if ($v_result != 1) {
597
- return 0;
598
- }
599
-
600
- // ----- Return
601
- return $p_result_list;
602
- }
603
- // --------------------------------------------------------------------------------
604
-
605
- // --------------------------------------------------------------------------------
606
- // Function : listContent()
607
- // Description :
608
- // This public method, gives the list of the files and directories, with their
609
- // properties.
610
- // The properties of each entries in the list are (used also in other functions) :
611
- // filename : Name of the file. For a create or add action it is the filename
612
- // given by the user. For an extract function it is the filename
613
- // of the extracted file.
614
- // stored_filename : Name of the file / directory stored in the archive.
615
- // size : Size of the stored file.
616
- // compressed_size : Size of the file's data compressed in the archive
617
- // (without the headers overhead)
618
- // mtime : Last known modification date of the file (UNIX timestamp)
619
- // comment : Comment associated with the file
620
- // folder : true | false
621
- // index : index of the file in the archive
622
- // status : status of the action (depending of the action) :
623
- // Values are :
624
- // ok : OK !
625
- // filtered : the file / dir is not extracted (filtered by user)
626
- // already_a_directory : the file can not be extracted because a
627
- // directory with the same name already exists
628
- // write_protected : the file can not be extracted because a file
629
- // with the same name already exists and is
630
- // write protected
631
- // newer_exist : the file was not extracted because a newer file exists
632
- // path_creation_fail : the file is not extracted because the folder
633
- // does not exist and can not be created
634
- // write_error : the file was not extracted because there was a
635
- // error while writing the file
636
- // read_error : the file was not extracted because there was a error
637
- // while reading the file
638
- // invalid_header : the file was not extracted because of an archive
639
- // format error (bad file header)
640
- // Note that each time a method can continue operating when there
641
- // is an action error on a file, the error is only logged in the file status.
642
- // Return Values :
643
- // 0 on an unrecoverable failure,
644
- // The list of the files in the archive.
645
- // --------------------------------------------------------------------------------
646
- function listContent()
647
- {
648
- $v_result=1;
649
-
650
- // ----- Reset the error handler
651
- $this->privErrorReset();
652
-
653
- // ----- Check archive
654
- if (!$this->privCheckFormat()) {
655
- return(0);
656
- }
657
-
658
- // ----- Call the extracting fct
659
- $p_list = array();
660
- if (($v_result = $this->privList($p_list)) != 1)
661
- {
662
- unset($p_list);
663
- return(0);
664
- }
665
-
666
- // ----- Return
667
- return $p_list;
668
- }
669
- // --------------------------------------------------------------------------------
670
-
671
- // --------------------------------------------------------------------------------
672
- // Function :
673
- // extract($p_path="./", $p_remove_path="")
674
- // extract([$p_option, $p_option_value, ...])
675
- // Description :
676
- // This method supports two synopsis. The first one is historical.
677
- // This method extract all the files / directories from the archive to the
678
- // folder indicated in $p_path.
679
- // If you want to ignore the 'root' part of path of the memorized files
680
- // you can indicate this in the optional $p_remove_path parameter.
681
- // By default, if a newer file with the same name already exists, the
682
- // file is not extracted.
683
- //
684
- // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
685
- // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
686
- // at the end of the path value of PCLZIP_OPT_PATH.
687
- // Parameters :
688
- // $p_path : Path where the files and directories are to be extracted
689
- // $p_remove_path : First part ('root' part) of the memorized path
690
- // (if any similar) to remove while extracting.
691
- // Options :
692
- // PCLZIP_OPT_PATH :
693
- // PCLZIP_OPT_ADD_PATH :
694
- // PCLZIP_OPT_REMOVE_PATH :
695
- // PCLZIP_OPT_REMOVE_ALL_PATH :
696
- // PCLZIP_CB_PRE_EXTRACT :
697
- // PCLZIP_CB_POST_EXTRACT :
698
- // Return Values :
699
- // 0 or a negative value on failure,
700
- // The list of the extracted files, with a status of the action.
701
- // (see PclZip::listContent() for list entry format)
702
- // --------------------------------------------------------------------------------
703
- function extract()
704
- {
705
- $v_result=1;
706
-
707
- // ----- Reset the error handler
708
- $this->privErrorReset();
709
-
710
- // ----- Check archive
711
- if (!$this->privCheckFormat()) {
712
- return(0);
713
- }
714
-
715
- // ----- Set default values
716
- $v_options = array();
717
- // $v_path = "./";
718
- $v_path = '';
719
- $v_remove_path = "";
720
- $v_remove_all_path = false;
721
-
722
- // ----- Look for variable options arguments
723
- $v_size = func_num_args();
724
-
725
- // ----- Default values for option
726
- $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
727
-
728
- // ----- Look for arguments
729
- if ($v_size > 0) {
730
- // ----- Get the arguments
731
- $v_arg_list = func_get_args();
732
-
733
- // ----- Look for first arg
734
- if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
735
-
736
- // ----- Parse the options
737
- $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
738
- array (PCLZIP_OPT_PATH => 'optional',
739
- PCLZIP_OPT_REMOVE_PATH => 'optional',
740
- PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
741
- PCLZIP_OPT_ADD_PATH => 'optional',
742
- PCLZIP_CB_PRE_EXTRACT => 'optional',
743
- PCLZIP_CB_POST_EXTRACT => 'optional',
744
- PCLZIP_OPT_SET_CHMOD => 'optional',
745
- PCLZIP_OPT_BY_NAME => 'optional',
746
- PCLZIP_OPT_BY_EREG => 'optional',
747
- PCLZIP_OPT_BY_PREG => 'optional',
748
- PCLZIP_OPT_BY_INDEX => 'optional',
749
- PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
750
- PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
751
- PCLZIP_OPT_REPLACE_NEWER => 'optional'
752
- ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
753
- ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
754
- PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
755
- PCLZIP_OPT_TEMP_FILE_ON => 'optional',
756
- PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
757
- ));
758
- if ($v_result != 1) {
759
- return 0;
760
- }
761
-
762
- // ----- Set the arguments
763
- if (isset($v_options[PCLZIP_OPT_PATH])) {
764
- $v_path = $v_options[PCLZIP_OPT_PATH];
765
- }
766
- if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
767
- $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
768
- }
769
- if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
770
- $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
771
- }
772
- if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
773
- // ----- Check for '/' in last path char
774
- if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
775
- $v_path .= '/';
776
- }
777
- $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
778
- }
779
- }
780
-
781
- // ----- Look for 2 args
782
- // Here we need to support the first historic synopsis of the
783
- // method.
784
- else {
785
-
786
- // ----- Get the first argument
787
- $v_path = $v_arg_list[0];
788
-
789
- // ----- Look for the optional second argument
790
- if ($v_size == 2) {
791
- $v_remove_path = $v_arg_list[1];
792
- }
793
- else if ($v_size > 2) {
794
- // ----- Error log
795
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
796
-
797
- // ----- Return
798
- return 0;
799
- }
800
- }
801
- }
802
-
803
- // ----- Look for default option values
804
- $this->privOptionDefaultThreshold($v_options);
805
-
806
- // ----- Trace
807
-
808
- // ----- Call the extracting fct
809
- $p_list = array();
810
- $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
811
- $v_remove_all_path, $v_options);
812
- if ($v_result < 1) {
813
- unset($p_list);
814
- return(0);
815
- }
816
-
817
- // ----- Return
818
- return $p_list;
819
- }
820
- // --------------------------------------------------------------------------------
821
-
822
-
823
- // --------------------------------------------------------------------------------
824
- // Function :
825
- // extractByIndex($p_index, $p_path="./", $p_remove_path="")
826
- // extractByIndex($p_index, [$p_option, $p_option_value, ...])
827
- // Description :
828
- // This method supports two synopsis. The first one is historical.
829
- // This method is doing a partial extract of the archive.
830
- // The extracted files or folders are identified by their index in the
831
- // archive (from 0 to n).
832
- // Note that if the index identify a folder, only the folder entry is
833
- // extracted, not all the files included in the archive.
834
- // Parameters :
835
- // $p_index : A single index (integer) or a string of indexes of files to
836
- // extract. The form of the string is "0,4-6,8-12" with only numbers
837
- // and '-' for range or ',' to separate ranges. No spaces or ';'
838
- // are allowed.
839
- // $p_path : Path where the files and directories are to be extracted
840
- // $p_remove_path : First part ('root' part) of the memorized path
841
- // (if any similar) to remove while extracting.
842
- // Options :
843
- // PCLZIP_OPT_PATH :
844
- // PCLZIP_OPT_ADD_PATH :
845
- // PCLZIP_OPT_REMOVE_PATH :
846
- // PCLZIP_OPT_REMOVE_ALL_PATH :
847
- // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
848
- // not as files.
849
- // The resulting content is in a new field 'content' in the file
850
- // structure.
851
- // This option must be used alone (any other options are ignored).
852
- // PCLZIP_CB_PRE_EXTRACT :
853
- // PCLZIP_CB_POST_EXTRACT :
854
- // Return Values :
855
- // 0 on failure,
856
- // The list of the extracted files, with a status of the action.
857
- // (see PclZip::listContent() for list entry format)
858
- // --------------------------------------------------------------------------------
859
- //function extractByIndex($p_index, options...)
860
- function extractByIndex($p_index)
861
- {
862
- $v_result=1;
863
-
864
- // ----- Reset the error handler
865
- $this->privErrorReset();
866
-
867
- // ----- Check archive
868
- if (!$this->privCheckFormat()) {
869
- return(0);
870
- }
871
-
872
- // ----- Set default values
873
- $v_options = array();
874
- // $v_path = "./";
875
- $v_path = '';
876
- $v_remove_path = "";
877
- $v_remove_all_path = false;
878
-
879
- // ----- Look for variable options arguments
880
- $v_size = func_num_args();
881
-
882
- // ----- Default values for option
883
- $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
884
-
885
- // ----- Look for arguments
886
- if ($v_size > 1) {
887
- // ----- Get the arguments
888
- $v_arg_list = func_get_args();
889
-
890
- // ----- Remove form the options list the first argument
891
- array_shift($v_arg_list);
892
- $v_size--;
893
-
894
- // ----- Look for first arg
895
- if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
896
-
897
- // ----- Parse the options
898
- $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
899
- array (PCLZIP_OPT_PATH => 'optional',
900
- PCLZIP_OPT_REMOVE_PATH => 'optional',
901
- PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
902
- PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
903
- PCLZIP_OPT_ADD_PATH => 'optional',
904
- PCLZIP_CB_PRE_EXTRACT => 'optional',
905
- PCLZIP_CB_POST_EXTRACT => 'optional',
906
- PCLZIP_OPT_SET_CHMOD => 'optional',
907
- PCLZIP_OPT_REPLACE_NEWER => 'optional'
908
- ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
909
- ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
910
- PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
911
- PCLZIP_OPT_TEMP_FILE_ON => 'optional',
912
- PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
913
- ));
914
- if ($v_result != 1) {
915
- return 0;
916
- }
917
-
918
- // ----- Set the arguments
919
- if (isset($v_options[PCLZIP_OPT_PATH])) {
920
- $v_path = $v_options[PCLZIP_OPT_PATH];
921
- }
922
- if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
923
- $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
924
- }
925
- if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
926
- $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
927
- }
928
- if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
929
- // ----- Check for '/' in last path char
930
- if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
931
- $v_path .= '/';
932
- }
933
- $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
934
- }
935
- if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
936
- $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
937
- }
938
- else {
939
- }
940
- }
941
-
942
- // ----- Look for 2 args
943
- // Here we need to support the first historic synopsis of the
944
- // method.
945
- else {
946
-
947
- // ----- Get the first argument
948
- $v_path = $v_arg_list[0];
949
-
950
- // ----- Look for the optional second argument
951
- if ($v_size == 2) {
952
- $v_remove_path = $v_arg_list[1];
953
- }
954
- else if ($v_size > 2) {
955
- // ----- Error log
956
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
957
-
958
- // ----- Return
959
- return 0;
960
- }
961
- }
962
- }
963
-
964
- // ----- Trace
965
-
966
- // ----- Trick
967
- // Here I want to reuse extractByRule(), so I need to parse the $p_index
968
- // with privParseOptions()
969
- $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
970
- $v_options_trick = array();
971
- $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
972
- array (PCLZIP_OPT_BY_INDEX => 'optional' ));
973
- if ($v_result != 1) {
974
- return 0;
975
- }
976
- $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
977
-
978
- // ----- Look for default option values
979
- $this->privOptionDefaultThreshold($v_options);
980
-
981
- // ----- Call the extracting fct
982
- if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
983
- return(0);
984
- }
985
-
986
- // ----- Return
987
- return $p_list;
988
- }
989
- // --------------------------------------------------------------------------------
990
-
991
- // --------------------------------------------------------------------------------
992
- // Function :
993
- // delete([$p_option, $p_option_value, ...])
994
- // Description :
995
- // This method removes files from the archive.
996
- // If no parameters are given, then all the archive is emptied.
997
- // Parameters :
998
- // None or optional arguments.
999
- // Options :
1000
- // PCLZIP_OPT_BY_INDEX :
1001
- // PCLZIP_OPT_BY_NAME :
1002
- // PCLZIP_OPT_BY_EREG :
1003
- // PCLZIP_OPT_BY_PREG :
1004
- // Return Values :
1005
- // 0 on failure,
1006
- // The list of the files which are still present in the archive.
1007
- // (see PclZip::listContent() for list entry format)
1008
- // --------------------------------------------------------------------------------
1009
- function delete()
1010
- {
1011
- $v_result=1;
1012
-
1013
- // ----- Reset the error handler
1014
- $this->privErrorReset();
1015
-
1016
- // ----- Check archive
1017
- if (!$this->privCheckFormat()) {
1018
- return(0);
1019
- }
1020
-
1021
- // ----- Set default values
1022
- $v_options = array();
1023
-
1024
- // ----- Look for variable options arguments
1025
- $v_size = func_num_args();
1026
-
1027
- // ----- Look for arguments
1028
- if ($v_size > 0) {
1029
- // ----- Get the arguments
1030
- $v_arg_list = func_get_args();
1031
-
1032
- // ----- Parse the options
1033
- $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1034
- array (PCLZIP_OPT_BY_NAME => 'optional',
1035
- PCLZIP_OPT_BY_EREG => 'optional',
1036
- PCLZIP_OPT_BY_PREG => 'optional',
1037
- PCLZIP_OPT_BY_INDEX => 'optional' ));
1038
- if ($v_result != 1) {
1039
- return 0;
1040
- }
1041
- }
1042
-
1043
- // ----- Magic quotes trick
1044
- $this->privDisableMagicQuotes();
1045
-
1046
- // ----- Call the delete fct
1047
- $v_list = array();
1048
- if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1049
- $this->privSwapBackMagicQuotes();
1050
- unset($v_list);
1051
- return(0);
1052
- }
1053
-
1054
- // ----- Magic quotes trick
1055
- $this->privSwapBackMagicQuotes();
1056
-
1057
- // ----- Return
1058
- return $v_list;
1059
- }
1060
- // --------------------------------------------------------------------------------
1061
-
1062
- // --------------------------------------------------------------------------------
1063
- // Function : deleteByIndex()
1064
- // Description :
1065
- // ***** Deprecated *****
1066
- // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1067
- // --------------------------------------------------------------------------------
1068
- function deleteByIndex($p_index)
1069
- {
1070
-
1071
- $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1072
-
1073
- // ----- Return
1074
- return $p_list;
1075
- }
1076
- // --------------------------------------------------------------------------------
1077
-
1078
- // --------------------------------------------------------------------------------
1079
- // Function : properties()
1080
- // Description :
1081
- // This method gives the properties of the archive.
1082
- // The properties are :
1083
- // nb : Number of files in the archive
1084
- // comment : Comment associated with the archive file
1085
- // status : not_exist, ok
1086
- // Parameters :
1087
- // None
1088
- // Return Values :
1089
- // 0 on failure,
1090
- // An array with the archive properties.
1091
- // --------------------------------------------------------------------------------
1092
- function properties()
1093
- {
1094
-
1095
- // ----- Reset the error handler
1096
- $this->privErrorReset();
1097
-
1098
- // ----- Magic quotes trick
1099
- $this->privDisableMagicQuotes();
1100
-
1101
- // ----- Check archive
1102
- if (!$this->privCheckFormat()) {
1103
- $this->privSwapBackMagicQuotes();
1104
- return(0);
1105
- }
1106
-
1107
- // ----- Default properties
1108
- $v_prop = array();
1109
- $v_prop['comment'] = '';
1110
- $v_prop['nb'] = 0;
1111
- $v_prop['status'] = 'not_exist';
1112
-
1113
- // ----- Look if file exists
1114
- if (@is_file($this->zipname))
1115
- {
1116
- // ----- Open the zip file
1117
- if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1118
- {
1119
- $this->privSwapBackMagicQuotes();
1120
-
1121
- // ----- Error log
1122
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1123
-
1124
- // ----- Return
1125
- return 0;
1126
- }
1127
-
1128
- // ----- Read the central directory informations
1129
- $v_central_dir = array();
1130
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1131
- {
1132
- $this->privSwapBackMagicQuotes();
1133
- return 0;
1134
- }
1135
-
1136
- // ----- Close the zip file
1137
- $this->privCloseFd();
1138
-
1139
- // ----- Set the user attributes
1140
- $v_prop['comment'] = $v_central_dir['comment'];
1141
- $v_prop['nb'] = $v_central_dir['entries'];
1142
- $v_prop['status'] = 'ok';
1143
- }
1144
-
1145
- // ----- Magic quotes trick
1146
- $this->privSwapBackMagicQuotes();
1147
-
1148
- // ----- Return
1149
- return $v_prop;
1150
- }
1151
- // --------------------------------------------------------------------------------
1152
-
1153
- // --------------------------------------------------------------------------------
1154
- // Function : duplicate()
1155
- // Description :
1156
- // This method creates an archive by copying the content of an other one. If
1157
- // the archive already exist, it is replaced by the new one without any warning.
1158
- // Parameters :
1159
- // $p_archive : The filename of a valid archive, or
1160
- // a valid PclZip object.
1161
- // Return Values :
1162
- // 1 on success.
1163
- // 0 or a negative value on error (error code).
1164
- // --------------------------------------------------------------------------------
1165
- function duplicate($p_archive)
1166
- {
1167
- $v_result = 1;
1168
-
1169
- // ----- Reset the error handler
1170
- $this->privErrorReset();
1171
-
1172
- // ----- Look if the $p_archive is a PclZip object
1173
- if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1174
- {
1175
-
1176
- // ----- Duplicate the archive
1177
- $v_result = $this->privDuplicate($p_archive->zipname);
1178
- }
1179
-
1180
- // ----- Look if the $p_archive is a string (so a filename)
1181
- else if (is_string($p_archive))
1182
- {
1183
-
1184
- // ----- Check that $p_archive is a valid zip file
1185
- // TBC : Should also check the archive format
1186
- if (!is_file($p_archive)) {
1187
- // ----- Error log
1188
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1189
- $v_result = PCLZIP_ERR_MISSING_FILE;
1190
- }
1191
- else {
1192
- // ----- Duplicate the archive
1193
- $v_result = $this->privDuplicate($p_archive);
1194
- }
1195
- }
1196
-
1197
- // ----- Invalid variable
1198
- else
1199
- {
1200
- // ----- Error log
1201
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1202
- $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1203
- }
1204
-
1205
- // ----- Return
1206
- return $v_result;
1207
- }
1208
- // --------------------------------------------------------------------------------
1209
-
1210
- // --------------------------------------------------------------------------------
1211
- // Function : merge()
1212
- // Description :
1213
- // This method merge the $p_archive_to_add archive at the end of the current
1214
- // one ($this).
1215
- // If the archive ($this) does not exist, the merge becomes a duplicate.
1216
- // If the $p_archive_to_add archive does not exist, the merge is a success.
1217
- // Parameters :
1218
- // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1219
- // or a PclZip object archive.
1220
- // Return Values :
1221
- // 1 on success,
1222
- // 0 or negative values on error (see below).
1223
- // --------------------------------------------------------------------------------
1224
- function merge($p_archive_to_add)
1225
- {
1226
- $v_result = 1;
1227
-
1228
- // ----- Reset the error handler
1229
- $this->privErrorReset();
1230
-
1231
- // ----- Check archive
1232
- if (!$this->privCheckFormat()) {
1233
- return(0);
1234
- }
1235
-
1236
- // ----- Look if the $p_archive_to_add is a PclZip object
1237
- if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1238
- {
1239
-
1240
- // ----- Merge the archive
1241
- $v_result = $this->privMerge($p_archive_to_add);
1242
- }
1243
-
1244
- // ----- Look if the $p_archive_to_add is a string (so a filename)
1245
- else if (is_string($p_archive_to_add))
1246
- {
1247
-
1248
- // ----- Create a temporary archive
1249
- $v_object_archive = new PclZip($p_archive_to_add);
1250
-
1251
- // ----- Merge the archive
1252
- $v_result = $this->privMerge($v_object_archive);
1253
- }
1254
-
1255
- // ----- Invalid variable
1256
- else
1257
- {
1258
- // ----- Error log
1259
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1260
- $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1261
- }
1262
-
1263
- // ----- Return
1264
- return $v_result;
1265
- }
1266
- // --------------------------------------------------------------------------------
1267
-
1268
-
1269
-
1270
- // --------------------------------------------------------------------------------
1271
- // Function : errorCode()
1272
- // Description :
1273
- // Parameters :
1274
- // --------------------------------------------------------------------------------
1275
- function errorCode()
1276
- {
1277
- if (PCLZIP_ERROR_EXTERNAL == 1) {
1278
- return(PclErrorCode());
1279
- }
1280
- else {
1281
- return($this->error_code);
1282
- }
1283
- }
1284
- // --------------------------------------------------------------------------------
1285
-
1286
- // --------------------------------------------------------------------------------
1287
- // Function : errorName()
1288
- // Description :
1289
- // Parameters :
1290
- // --------------------------------------------------------------------------------
1291
- function errorName($p_with_code=false)
1292
- {
1293
- $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1294
- PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1295
- PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1296
- PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1297
- PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1298
- PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1299
- PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1300
- PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1301
- PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1302
- PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1303
- PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1304
- PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1305
- PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1306
- PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1307
- PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1308
- PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1309
- PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1310
- PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1311
- PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1312
- ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1313
- ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1314
- );
1315
-
1316
- if (isset($v_name[$this->error_code])) {
1317
- $v_value = $v_name[$this->error_code];
1318
- }
1319
- else {
1320
- $v_value = 'NoName';
1321
- }
1322
-
1323
- if ($p_with_code) {
1324
- return($v_value.' ('.$this->error_code.')');
1325
- }
1326
- else {
1327
- return($v_value);
1328
- }
1329
- }
1330
- // --------------------------------------------------------------------------------
1331
-
1332
- // --------------------------------------------------------------------------------
1333
- // Function : errorInfo()
1334
- // Description :
1335
- // Parameters :
1336
- // --------------------------------------------------------------------------------
1337
- function errorInfo($p_full=false)
1338
- {
1339
- if (PCLZIP_ERROR_EXTERNAL == 1) {
1340
- return(PclErrorString());
1341
- }
1342
- else {
1343
- if ($p_full) {
1344
- return($this->errorName(true)." : ".$this->error_string);
1345
- }
1346
- else {
1347
- return($this->error_string." [code ".$this->error_code."]");
1348
- }
1349
- }
1350
- }
1351
- // --------------------------------------------------------------------------------
1352
-
1353
-
1354
- // --------------------------------------------------------------------------------
1355
- // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1356
- // ***** *****
1357
- // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1358
- // --------------------------------------------------------------------------------
1359
-
1360
-
1361
-
1362
- // --------------------------------------------------------------------------------
1363
- // Function : privCheckFormat()
1364
- // Description :
1365
- // This method check that the archive exists and is a valid zip archive.
1366
- // Several level of check exists. (futur)
1367
- // Parameters :
1368
- // $p_level : Level of check. Default 0.
1369
- // 0 : Check the first bytes (magic codes) (default value))
1370
- // 1 : 0 + Check the central directory (futur)
1371
- // 2 : 1 + Check each file header (futur)
1372
- // Return Values :
1373
- // true on success,
1374
- // false on error, the error code is set.
1375
- // --------------------------------------------------------------------------------
1376
- function privCheckFormat($p_level=0)
1377
- {
1378
- $v_result = true;
1379
-
1380
- // ----- Reset the file system cache
1381
- clearstatcache();
1382
-
1383
- // ----- Reset the error handler
1384
- $this->privErrorReset();
1385
-
1386
- // ----- Look if the file exits
1387
- if (!is_file($this->zipname)) {
1388
- // ----- Error log
1389
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1390
- return(false);
1391
- }
1392
-
1393
- // ----- Check that the file is readeable
1394
- if (!is_readable($this->zipname)) {
1395
- // ----- Error log
1396
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1397
- return(false);
1398
- }
1399
-
1400
- // ----- Check the magic code
1401
- // TBC
1402
-
1403
- // ----- Check the central header
1404
- // TBC
1405
-
1406
- // ----- Check each file header
1407
- // TBC
1408
-
1409
- // ----- Return
1410
- return $v_result;
1411
- }
1412
- // --------------------------------------------------------------------------------
1413
-
1414
- // --------------------------------------------------------------------------------
1415
- // Function : privParseOptions()
1416
- // Description :
1417
- // This internal methods reads the variable list of arguments ($p_options_list,
1418
- // $p_size) and generate an array with the options and values ($v_result_list).
1419
- // $v_requested_options contains the options that can be present and those that
1420
- // must be present.
1421
- // $v_requested_options is an array, with the option value as key, and 'optional',
1422
- // or 'mandatory' as value.
1423
- // Parameters :
1424
- // See above.
1425
- // Return Values :
1426
- // 1 on success.
1427
- // 0 on failure.
1428
- // --------------------------------------------------------------------------------
1429
- function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1430
- {
1431
- $v_result=1;
1432
-
1433
- // ----- Read the options
1434
- $i=0;
1435
- while ($i<$p_size) {
1436
-
1437
- // ----- Check if the option is supported
1438
- if (!isset($v_requested_options[$p_options_list[$i]])) {
1439
- // ----- Error log
1440
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1441
-
1442
- // ----- Return
1443
- return PclZip::errorCode();
1444
- }
1445
-
1446
- // ----- Look for next option
1447
- switch ($p_options_list[$i]) {
1448
- // ----- Look for options that request a path value
1449
- case PCLZIP_OPT_PATH :
1450
- case PCLZIP_OPT_REMOVE_PATH :
1451
- case PCLZIP_OPT_ADD_PATH :
1452
- // ----- Check the number of parameters
1453
- if (($i+1) >= $p_size) {
1454
- // ----- Error log
1455
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1456
-
1457
- // ----- Return
1458
- return PclZip::errorCode();
1459
- }
1460
-
1461
- // ----- Get the value
1462
- $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1463
- $i++;
1464
- break;
1465
-
1466
- case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1467
- // ----- Check the number of parameters
1468
- if (($i+1) >= $p_size) {
1469
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1470
- return PclZip::errorCode();
1471
- }
1472
-
1473
- // ----- Check for incompatible options
1474
- if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1475
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1476
- return PclZip::errorCode();
1477
- }
1478
-
1479
- // ----- Check the value
1480
- $v_value = $p_options_list[$i+1];
1481
- if ((!is_integer($v_value)) || ($v_value<0)) {
1482
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1483
- return PclZip::errorCode();
1484
- }
1485
-
1486
- // ----- Get the value (and convert it in bytes)
1487
- $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1488
- $i++;
1489
- break;
1490
-
1491
- case PCLZIP_OPT_TEMP_FILE_ON :
1492
- // ----- Check for incompatible options
1493
- if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1494
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1495
- return PclZip::errorCode();
1496
- }
1497
-
1498
- $v_result_list[$p_options_list[$i]] = true;
1499
- break;
1500
-
1501
- case PCLZIP_OPT_TEMP_FILE_OFF :
1502
- // ----- Check for incompatible options
1503
- if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1504
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1505
- return PclZip::errorCode();
1506
- }
1507
- // ----- Check for incompatible options
1508
- if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1509
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1510
- return PclZip::errorCode();
1511
- }
1512
-
1513
- $v_result_list[$p_options_list[$i]] = true;
1514
- break;
1515
-
1516
- case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1517
- // ----- Check the number of parameters
1518
- if (($i+1) >= $p_size) {
1519
- // ----- Error log
1520
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1521
-
1522
- // ----- Return
1523
- return PclZip::errorCode();
1524
- }
1525
-
1526
- // ----- Get the value
1527
- if ( is_string($p_options_list[$i+1])
1528
- && ($p_options_list[$i+1] != '')) {
1529
- $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1530
- $i++;
1531
- }
1532
- else {
1533
- }
1534
- break;
1535
-
1536
- // ----- Look for options that request an array of string for value
1537
- case PCLZIP_OPT_BY_NAME :
1538
- // ----- Check the number of parameters
1539
- if (($i+1) >= $p_size) {
1540
- // ----- Error log
1541
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1542
-
1543
- // ----- Return
1544
- return PclZip::errorCode();
1545
- }
1546
-
1547
- // ----- Get the value
1548
- if (is_string($p_options_list[$i+1])) {
1549
- $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1550
- }
1551
- else if (is_array($p_options_list[$i+1])) {
1552
- $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1553
- }
1554
- else {
1555
- // ----- Error log
1556
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1557
-
1558
- // ----- Return
1559
- return PclZip::errorCode();
1560
- }
1561
- $i++;
1562
- break;
1563
-
1564
- // ----- Look for options that request an EREG or PREG expression
1565
- case PCLZIP_OPT_BY_EREG :
1566
- // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1567
- // to PCLZIP_OPT_BY_PREG
1568
- $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1569
- case PCLZIP_OPT_BY_PREG :
1570
- //case PCLZIP_OPT_CRYPT :
1571
- // ----- Check the number of parameters
1572
- if (($i+1) >= $p_size) {
1573
- // ----- Error log
1574
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1575
-
1576
- // ----- Return
1577
- return PclZip::errorCode();
1578
- }
1579
-
1580
- // ----- Get the value
1581
- if (is_string($p_options_list[$i+1])) {
1582
- $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1583
- }
1584
- else {
1585
- // ----- Error log
1586
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1587
-
1588
- // ----- Return
1589
- return PclZip::errorCode();
1590
- }
1591
- $i++;
1592
- break;
1593
-
1594
- // ----- Look for options that takes a string
1595
- case PCLZIP_OPT_COMMENT :
1596
- case PCLZIP_OPT_ADD_COMMENT :
1597
- case PCLZIP_OPT_PREPEND_COMMENT :
1598
- // ----- Check the number of parameters
1599
- if (($i+1) >= $p_size) {
1600
- // ----- Error log
1601
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1602
- "Missing parameter value for option '"
1603
- .PclZipUtilOptionText($p_options_list[$i])
1604
- ."'");
1605
-
1606
- // ----- Return
1607
- return PclZip::errorCode();
1608
- }
1609
-
1610
- // ----- Get the value
1611
- if (is_string($p_options_list[$i+1])) {
1612
- $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1613
- }
1614
- else {
1615
- // ----- Error log
1616
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1617
- "Wrong parameter value for option '"
1618
- .PclZipUtilOptionText($p_options_list[$i])
1619
- ."'");
1620
-
1621
- // ----- Return
1622
- return PclZip::errorCode();
1623
- }
1624
- $i++;
1625
- break;
1626
-
1627
- // ----- Look for options that request an array of index
1628
- case PCLZIP_OPT_BY_INDEX :
1629
- // ----- Check the number of parameters
1630
- if (($i+1) >= $p_size) {
1631
- // ----- Error log
1632
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1633
-
1634
- // ----- Return
1635
- return PclZip::errorCode();
1636
- }
1637
-
1638
- // ----- Get the value
1639
- $v_work_list = array();
1640
- if (is_string($p_options_list[$i+1])) {
1641
-
1642
- // ----- Remove spaces
1643
- $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1644
-
1645
- // ----- Parse items
1646
- $v_work_list = explode(",", $p_options_list[$i+1]);
1647
- }
1648
- else if (is_integer($p_options_list[$i+1])) {
1649
- $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1650
- }
1651
- else if (is_array($p_options_list[$i+1])) {
1652
- $v_work_list = $p_options_list[$i+1];
1653
- }
1654
- else {
1655
- // ----- Error log
1656
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1657
-
1658
- // ----- Return
1659
- return PclZip::errorCode();
1660
- }
1661
-
1662
- // ----- Reduce the index list
1663
- // each index item in the list must be a couple with a start and
1664
- // an end value : [0,3], [5-5], [8-10], ...
1665
- // ----- Check the format of each item
1666
- $v_sort_flag=false;
1667
- $v_sort_value=0;
1668
- for ($j=0; $j<sizeof($v_work_list); $j++) {
1669
- // ----- Explode the item
1670
- $v_item_list = explode("-", $v_work_list[$j]);
1671
- $v_size_item_list = sizeof($v_item_list);
1672
-
1673
- // ----- TBC : Here we might check that each item is a
1674
- // real integer ...
1675
-
1676
- // ----- Look for single value
1677
- if ($v_size_item_list == 1) {
1678
- // ----- Set the option value
1679
- $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1680
- $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1681
- }
1682
- elseif ($v_size_item_list == 2) {
1683
- // ----- Set the option value
1684
- $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1685
- $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1686
- }
1687
- else {
1688
- // ----- Error log
1689
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1690
-
1691
- // ----- Return
1692
- return PclZip::errorCode();
1693
- }
1694
-
1695
-
1696
- // ----- Look for list sort
1697
- if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1698
- $v_sort_flag=true;
1699
-
1700
- // ----- TBC : An automatic sort should be writen ...
1701
- // ----- Error log
1702
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1703
-
1704
- // ----- Return
1705
- return PclZip::errorCode();
1706
- }
1707
- $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1708
- }
1709
-
1710
- // ----- Sort the items
1711
- if ($v_sort_flag) {
1712
- // TBC : To Be Completed
1713
- }
1714
-
1715
- // ----- Next option
1716
- $i++;
1717
- break;
1718
-
1719
- // ----- Look for options that request no value
1720
- case PCLZIP_OPT_REMOVE_ALL_PATH :
1721
- case PCLZIP_OPT_EXTRACT_AS_STRING :
1722
- case PCLZIP_OPT_NO_COMPRESSION :
1723
- case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1724
- case PCLZIP_OPT_REPLACE_NEWER :
1725
- case PCLZIP_OPT_STOP_ON_ERROR :
1726
- $v_result_list[$p_options_list[$i]] = true;
1727
- break;
1728
-
1729
- // ----- Look for options that request an octal value
1730
- case PCLZIP_OPT_SET_CHMOD :
1731
- // ----- Check the number of parameters
1732
- if (($i+1) >= $p_size) {
1733
- // ----- Error log
1734
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1735
-
1736
- // ----- Return
1737
- return PclZip::errorCode();
1738
- }
1739
-
1740
- // ----- Get the value
1741
- $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1742
- $i++;
1743
- break;
1744
-
1745
- // ----- Look for options that request a call-back
1746
- case PCLZIP_CB_PRE_EXTRACT :
1747
- case PCLZIP_CB_POST_EXTRACT :
1748
- case PCLZIP_CB_PRE_ADD :
1749
- case PCLZIP_CB_POST_ADD :
1750
- /* for futur use
1751
- case PCLZIP_CB_PRE_DELETE :
1752
- case PCLZIP_CB_POST_DELETE :
1753
- case PCLZIP_CB_PRE_LIST :
1754
- case PCLZIP_CB_POST_LIST :
1755
- */
1756
- // ----- Check the number of parameters
1757
- if (($i+1) >= $p_size) {
1758
- // ----- Error log
1759
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1760
-
1761
- // ----- Return
1762
- return PclZip::errorCode();
1763
- }
1764
-
1765
- // ----- Get the value
1766
- $v_function_name = $p_options_list[$i+1];
1767
-
1768
- // ----- Check that the value is a valid existing function
1769
- if (!function_exists($v_function_name)) {
1770
- // ----- Error log
1771
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1772
-
1773
- // ----- Return
1774
- return PclZip::errorCode();
1775
- }
1776
-
1777
- // ----- Set the attribute
1778
- $v_result_list[$p_options_list[$i]] = $v_function_name;
1779
- $i++;
1780
- break;
1781
-
1782
- default :
1783
- // ----- Error log
1784
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1785
- "Unknown parameter '"
1786
- .$p_options_list[$i]."'");
1787
-
1788
- // ----- Return
1789
- return PclZip::errorCode();
1790
- }
1791
-
1792
- // ----- Next options
1793
- $i++;
1794
- }
1795
-
1796
- // ----- Look for mandatory options
1797
- if ($v_requested_options !== false) {
1798
- for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1799
- // ----- Look for mandatory option
1800
- if ($v_requested_options[$key] == 'mandatory') {
1801
- // ----- Look if present
1802
- if (!isset($v_result_list[$key])) {
1803
- // ----- Error log
1804
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1805
-
1806
- // ----- Return
1807
- return PclZip::errorCode();
1808
- }
1809
- }
1810
- }
1811
- }
1812
-
1813
- // ----- Look for default values
1814
- if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1815
-
1816
- }
1817
-
1818
- // ----- Return
1819
- return $v_result;
1820
- }
1821
- // --------------------------------------------------------------------------------
1822
-
1823
- // --------------------------------------------------------------------------------
1824
- // Function : privOptionDefaultThreshold()
1825
- // Description :
1826
- // Parameters :
1827
- // Return Values :
1828
- // --------------------------------------------------------------------------------
1829
- function privOptionDefaultThreshold(&$p_options)
1830
- {
1831
- $v_result=1;
1832
-
1833
- if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1834
- || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1835
- return $v_result;
1836
- }
1837
-
1838
- // ----- Get 'memory_limit' configuration value
1839
- $v_memory_limit = ini_get('memory_limit');
1840
- $v_memory_limit = trim($v_memory_limit);
1841
- $last = strtolower(substr($v_memory_limit, -1));
1842
-
1843
- if($last == 'g')
1844
- //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1845
- $v_memory_limit = $v_memory_limit*1073741824;
1846
- if($last == 'm')
1847
- //$v_memory_limit = $v_memory_limit*1024*1024;
1848
- $v_memory_limit = $v_memory_limit*1048576;
1849
- if($last == 'k')
1850
- $v_memory_limit = $v_memory_limit*1024;
1851
-
1852
- $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1853
-
1854
-
1855
- // ----- Sanity check : No threshold if value lower than 1M
1856
- if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1857
- unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1858
- }
1859
-
1860
- // ----- Return
1861
- return $v_result;
1862
- }
1863
- // --------------------------------------------------------------------------------
1864
-
1865
- // --------------------------------------------------------------------------------
1866
- // Function : privFileDescrParseAtt()
1867
- // Description :
1868
- // Parameters :
1869
- // Return Values :
1870
- // 1 on success.
1871
- // 0 on failure.
1872
- // --------------------------------------------------------------------------------
1873
- function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1874
- {
1875
- $v_result=1;
1876
-
1877
- // ----- For each file in the list check the attributes
1878
- foreach ($p_file_list as $v_key => $v_value) {
1879
-
1880
- // ----- Check if the option is supported
1881
- if (!isset($v_requested_options[$v_key])) {
1882
- // ----- Error log
1883
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1884
-
1885
- // ----- Return
1886
- return PclZip::errorCode();
1887
- }
1888
-
1889
- // ----- Look for attribute
1890
- switch ($v_key) {
1891
- case PCLZIP_ATT_FILE_NAME :
1892
- if (!is_string($v_value)) {
1893
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1894
- return PclZip::errorCode();
1895
- }
1896
-
1897
- $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1898
-
1899
- if ($p_filedescr['filename'] == '') {
1900
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1901
- return PclZip::errorCode();
1902
- }
1903
-
1904
- break;
1905
-
1906
- case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1907
- if (!is_string($v_value)) {
1908
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1909
- return PclZip::errorCode();
1910
- }
1911
-
1912
- $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1913
-
1914
- if ($p_filedescr['new_short_name'] == '') {
1915
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1916
- return PclZip::errorCode();
1917
- }
1918
- break;
1919
-
1920
- case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1921
- if (!is_string($v_value)) {
1922
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1923
- return PclZip::errorCode();
1924
- }
1925
-
1926
- $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1927
-
1928
- if ($p_filedescr['new_full_name'] == '') {
1929
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1930
- return PclZip::errorCode();
1931
- }
1932
- break;
1933
-
1934
- // ----- Look for options that takes a string
1935
- case PCLZIP_ATT_FILE_COMMENT :
1936
- if (!is_string($v_value)) {
1937
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1938
- return PclZip::errorCode();
1939
- }
1940
-
1941
- $p_filedescr['comment'] = $v_value;
1942
- break;
1943
-
1944
- case PCLZIP_ATT_FILE_MTIME :
1945
- if (!is_integer($v_value)) {
1946
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1947
- return PclZip::errorCode();
1948
- }
1949
-
1950
- $p_filedescr['mtime'] = $v_value;
1951
- break;
1952
-
1953
- case PCLZIP_ATT_FILE_CONTENT :
1954
- $p_filedescr['content'] = $v_value;
1955
- break;
1956
-
1957
- default :
1958
- // ----- Error log
1959
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1960
- "Unknown parameter '".$v_key."'");
1961
-
1962
- // ----- Return
1963
- return PclZip::errorCode();
1964
- }
1965
-
1966
- // ----- Look for mandatory options
1967
- if ($v_requested_options !== false) {
1968
- for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1969
- // ----- Look for mandatory option
1970
- if ($v_requested_options[$key] == 'mandatory') {
1971
- // ----- Look if present
1972
- if (!isset($p_file_list[$key])) {
1973
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1974
- return PclZip::errorCode();
1975
- }
1976
- }
1977
- }
1978
- }
1979
-
1980
- // end foreach
1981
- }
1982
-
1983
- // ----- Return
1984
- return $v_result;
1985
- }
1986
- // --------------------------------------------------------------------------------
1987
-
1988
- // --------------------------------------------------------------------------------
1989
- // Function : privFileDescrExpand()
1990
- // Description :
1991
- // This method look for each item of the list to see if its a file, a folder
1992
- // or a string to be added as file. For any other type of files (link, other)
1993
- // just ignore the item.
1994
- // Then prepare the information that will be stored for that file.
1995
- // When its a folder, expand the folder with all the files that are in that
1996
- // folder (recursively).
1997
- // Parameters :
1998
- // Return Values :
1999
- // 1 on success.
2000
- // 0 on failure.
2001
- // --------------------------------------------------------------------------------
2002
- function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2003
- {
2004
- $v_result=1;
2005
-
2006
- // ----- Create a result list
2007
- $v_result_list = array();
2008
-
2009
- // ----- Look each entry
2010
- for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
2011
-
2012
- // ----- Get filedescr
2013
- $v_descr = $p_filedescr_list[$i];
2014
-
2015
- // ----- Reduce the filename
2016
- $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2017
- $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2018
-
2019
- // ----- Look for real file or folder
2020
- if (file_exists($v_descr['filename'])) {
2021
- if (@is_file($v_descr['filename'])) {
2022
- $v_descr['type'] = 'file';
2023
- }
2024
- else if (@is_dir($v_descr['filename'])) {
2025
- $v_descr['type'] = 'folder';
2026
- }
2027
- else if (@is_link($v_descr['filename'])) {
2028
- // skip
2029
- continue;
2030
- }
2031
- else {
2032
- // skip
2033
- continue;
2034
- }
2035
- }
2036
-
2037
- // ----- Look for string added as file
2038
- else if (isset($v_descr['content'])) {
2039
- $v_descr['type'] = 'virtual_file';
2040
- }
2041
-
2042
- // ----- Missing file
2043
- else {
2044
- // ----- Error log
2045
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2046
-
2047
- // ----- Return
2048
- return PclZip::errorCode();
2049
- }
2050
-
2051
- // ----- Calculate the stored filename
2052
- $this->privCalculateStoredFilename($v_descr, $p_options);
2053
-
2054
- // ----- Add the descriptor in result list
2055
- $v_result_list[sizeof($v_result_list)] = $v_descr;
2056
-
2057
- // ----- Look for folder
2058
- if ($v_descr['type'] == 'folder') {
2059
- // ----- List of items in folder
2060
- $v_dirlist_descr = array();
2061
- $v_dirlist_nb = 0;
2062
- if ($v_folder_handler = @opendir($v_descr['filename'])) {
2063
- while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2064
-
2065
- // ----- Skip '.' and '..'
2066
- if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2067
- continue;
2068
- }
2069
-
2070
- // ----- Compose the full filename
2071
- $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2072
-
2073
- // ----- Look for different stored filename
2074
- // Because the name of the folder was changed, the name of the
2075
- // files/sub-folders also change
2076
- if (($v_descr['stored_filename'] != $v_descr['filename'])
2077
- && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2078
- if ($v_descr['stored_filename'] != '') {
2079
- $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2080
- }
2081
- else {
2082
- $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2083
- }
2084
- }
2085
-
2086
- $v_dirlist_nb++;
2087
- }
2088
-
2089
- @closedir($v_folder_handler);
2090
- }
2091
- else {
2092
- // TBC : unable to open folder in read mode
2093
- }
2094
-
2095
- // ----- Expand each element of the list
2096
- if ($v_dirlist_nb != 0) {
2097
- // ----- Expand
2098
- if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2099
- return $v_result;
2100
- }
2101
-
2102
- // ----- Concat the resulting list
2103
- $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2104
- }
2105
- else {
2106
- }
2107
-
2108
- // ----- Free local array
2109
- unset($v_dirlist_descr);
2110
- }
2111
- }
2112
-
2113
- // ----- Get the result list
2114
- $p_filedescr_list = $v_result_list;
2115
-
2116
- // ----- Return
2117
- return $v_result;
2118
- }
2119
- // --------------------------------------------------------------------------------
2120
-
2121
- // --------------------------------------------------------------------------------
2122
- // Function : privCreate()
2123
- // Description :
2124
- // Parameters :
2125
- // Return Values :
2126
- // --------------------------------------------------------------------------------
2127
- function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2128
- {
2129
- $v_result=1;
2130
- $v_list_detail = array();
2131
-
2132
- // ----- Magic quotes trick
2133
- $this->privDisableMagicQuotes();
2134
-
2135
- // ----- Open the file in write mode
2136
- if (($v_result = $this->privOpenFd('wb')) != 1)
2137
- {
2138
- // ----- Return
2139
- return $v_result;
2140
- }
2141
-
2142
- // ----- Add the list of files
2143
- $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2144
-
2145
- // ----- Close
2146
- $this->privCloseFd();
2147
-
2148
- // ----- Magic quotes trick
2149
- $this->privSwapBackMagicQuotes();
2150
-
2151
- // ----- Return
2152
- return $v_result;
2153
- }
2154
- // --------------------------------------------------------------------------------
2155
-
2156
- // --------------------------------------------------------------------------------
2157
- // Function : privAdd()
2158
- // Description :
2159
- // Parameters :
2160
- // Return Values :
2161
- // --------------------------------------------------------------------------------
2162
- function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2163
- {
2164
- $v_result=1;
2165
- $v_list_detail = array();
2166
-
2167
- // ----- Look if the archive exists or is empty
2168
- if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2169
- {
2170
-
2171
- // ----- Do a create
2172
- $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2173
-
2174
- // ----- Return
2175
- return $v_result;
2176
- }
2177
- // ----- Magic quotes trick
2178
- $this->privDisableMagicQuotes();
2179
-
2180
- // ----- Open the zip file
2181
- if (($v_result=$this->privOpenFd('rb')) != 1)
2182
- {
2183
- // ----- Magic quotes trick
2184
- $this->privSwapBackMagicQuotes();
2185
-
2186
- // ----- Return
2187
- return $v_result;
2188
- }
2189
-
2190
- // ----- Read the central directory informations
2191
- $v_central_dir = array();
2192
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2193
- {
2194
- $this->privCloseFd();
2195
- $this->privSwapBackMagicQuotes();
2196
- return $v_result;
2197
- }
2198
-
2199
- // ----- Go to beginning of File
2200
- @rewind($this->zip_fd);
2201
-
2202
- // ----- Creates a temporay file
2203
- $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2204
-
2205
- // ----- Open the temporary file in write mode
2206
- if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2207
- {
2208
- $this->privCloseFd();
2209
- $this->privSwapBackMagicQuotes();
2210
-
2211
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2212
-
2213
- // ----- Return
2214
- return PclZip::errorCode();
2215
- }
2216
-
2217
- // ----- Copy the files from the archive to the temporary file
2218
- // TBC : Here I should better append the file and go back to erase the central dir
2219
- $v_size = $v_central_dir['offset'];
2220
- while ($v_size != 0)
2221
- {
2222
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2223
- $v_buffer = fread($this->zip_fd, $v_read_size);
2224
- @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2225
- $v_size -= $v_read_size;
2226
- }
2227
-
2228
- // ----- Swap the file descriptor
2229
- // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2230
- // the following methods on the temporary fil and not the real archive
2231
- $v_swap = $this->zip_fd;
2232
- $this->zip_fd = $v_zip_temp_fd;
2233
- $v_zip_temp_fd = $v_swap;
2234
-
2235
- // ----- Add the files
2236
- $v_header_list = array();
2237
- if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2238
- {
2239
- fclose($v_zip_temp_fd);
2240
- $this->privCloseFd();
2241
- @unlink($v_zip_temp_name);
2242
- $this->privSwapBackMagicQuotes();
2243
-
2244
- // ----- Return
2245
- return $v_result;
2246
- }
2247
-
2248
- // ----- Store the offset of the central dir
2249
- $v_offset = @ftell($this->zip_fd);
2250
-
2251
- // ----- Copy the block of file headers from the old archive
2252
- $v_size = $v_central_dir['size'];
2253
- while ($v_size != 0)
2254
- {
2255
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2256
- $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2257
- @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2258
- $v_size -= $v_read_size;
2259
- }
2260
-
2261
- // ----- Create the Central Dir files header
2262
- for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2263
- {
2264
- // ----- Create the file header
2265
- if ($v_header_list[$i]['status'] == 'ok') {
2266
- if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2267
- fclose($v_zip_temp_fd);
2268
- $this->privCloseFd();
2269
- @unlink($v_zip_temp_name);
2270
- $this->privSwapBackMagicQuotes();
2271
-
2272
- // ----- Return
2273
- return $v_result;
2274
- }
2275
- $v_count++;
2276
- }
2277
-
2278
- // ----- Transform the header to a 'usable' info
2279
- $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2280
- }
2281
-
2282
- // ----- Zip file comment
2283
- $v_comment = $v_central_dir['comment'];
2284
- if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2285
- $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2286
- }
2287
- if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2288
- $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2289
- }
2290
- if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2291
- $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2292
- }
2293
-
2294
- // ----- Calculate the size of the central header
2295
- $v_size = @ftell($this->zip_fd)-$v_offset;
2296
-
2297
- // ----- Create the central dir footer
2298
- if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2299
- {
2300
- // ----- Reset the file list
2301
- unset($v_header_list);
2302
- $this->privSwapBackMagicQuotes();
2303
-
2304
- // ----- Return
2305
- return $v_result;
2306
- }
2307
-
2308
- // ----- Swap back the file descriptor
2309
- $v_swap = $this->zip_fd;
2310
- $this->zip_fd = $v_zip_temp_fd;
2311
- $v_zip_temp_fd = $v_swap;
2312
-
2313
- // ----- Close
2314
- $this->privCloseFd();
2315
-
2316
- // ----- Close the temporary file
2317
- @fclose($v_zip_temp_fd);
2318
-
2319
- // ----- Magic quotes trick
2320
- $this->privSwapBackMagicQuotes();
2321
-
2322
- // ----- Delete the zip file
2323
- // TBC : I should test the result ...
2324
- @unlink($this->zipname);
2325
-
2326
- // ----- Rename the temporary file
2327
- // TBC : I should test the result ...
2328
- //@rename($v_zip_temp_name, $this->zipname);
2329
- PclZipUtilRename($v_zip_temp_name, $this->zipname);
2330
-
2331
- // ----- Return
2332
- return $v_result;
2333
- }
2334
- // --------------------------------------------------------------------------------
2335
-
2336
- // --------------------------------------------------------------------------------
2337
- // Function : privOpenFd()
2338
- // Description :
2339
- // Parameters :
2340
- // --------------------------------------------------------------------------------
2341
- function privOpenFd($p_mode)
2342
- {
2343
- $v_result=1;
2344
-
2345
- // ----- Look if already open
2346
- if ($this->zip_fd != 0)
2347
- {
2348
- // ----- Error log
2349
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2350
-
2351
- // ----- Return
2352
- return PclZip::errorCode();
2353
- }
2354
-
2355
- // ----- Open the zip file
2356
- if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2357
- {
2358
- // ----- Error log
2359
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2360
-
2361
- // ----- Return
2362
- return PclZip::errorCode();
2363
- }
2364
-
2365
- // ----- Return
2366
- return $v_result;
2367
- }
2368
- // --------------------------------------------------------------------------------
2369
-
2370
- // --------------------------------------------------------------------------------
2371
- // Function : privCloseFd()
2372
- // Description :
2373
- // Parameters :
2374
- // --------------------------------------------------------------------------------
2375
- function privCloseFd()
2376
- {
2377
- $v_result=1;
2378
-
2379
- if ($this->zip_fd != 0)
2380
- @fclose($this->zip_fd);
2381
- $this->zip_fd = 0;
2382
-
2383
- // ----- Return
2384
- return $v_result;
2385
- }
2386
- // --------------------------------------------------------------------------------
2387
-
2388
- // --------------------------------------------------------------------------------
2389
- // Function : privAddList()
2390
- // Description :
2391
- // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2392
- // different from the real path of the file. This is usefull if you want to have PclTar
2393
- // running in any directory, and memorize relative path from an other directory.
2394
- // Parameters :
2395
- // $p_list : An array containing the file or directory names to add in the tar
2396
- // $p_result_list : list of added files with their properties (specially the status field)
2397
- // $p_add_dir : Path to add in the filename path archived
2398
- // $p_remove_dir : Path to remove in the filename path archived
2399
- // Return Values :
2400
- // --------------------------------------------------------------------------------
2401
- // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2402
- function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2403
- {
2404
- $v_result=1;
2405
-
2406
- // ----- Add the files
2407
- $v_header_list = array();
2408
- if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2409
- {
2410
- // ----- Return
2411
- return $v_result;
2412
- }
2413
-
2414
- // ----- Store the offset of the central dir
2415
- $v_offset = @ftell($this->zip_fd);
2416
-
2417
- // ----- Create the Central Dir files header
2418
- for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2419
- {
2420
- // ----- Create the file header
2421
- if ($v_header_list[$i]['status'] == 'ok') {
2422
- if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2423
- // ----- Return
2424
- return $v_result;
2425
- }
2426
- $v_count++;
2427
- }
2428
-
2429
- // ----- Transform the header to a 'usable' info
2430
- $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2431
- }
2432
-
2433
- // ----- Zip file comment
2434
- $v_comment = '';
2435
- if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2436
- $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2437
- }
2438
-
2439
- // ----- Calculate the size of the central header
2440
- $v_size = @ftell($this->zip_fd)-$v_offset;
2441
-
2442
- // ----- Create the central dir footer
2443
- if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2444
- {
2445
- // ----- Reset the file list
2446
- unset($v_header_list);
2447
-
2448
- // ----- Return
2449
- return $v_result;
2450
- }
2451
-
2452
- // ----- Return
2453
- return $v_result;
2454
- }
2455
- // --------------------------------------------------------------------------------
2456
-
2457
- // --------------------------------------------------------------------------------
2458
- // Function : privAddFileList()
2459
- // Description :
2460
- // Parameters :
2461
- // $p_filedescr_list : An array containing the file description
2462
- // or directory names to add in the zip
2463
- // $p_result_list : list of added files with their properties (specially the status field)
2464
- // Return Values :
2465
- // --------------------------------------------------------------------------------
2466
- function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2467
- {
2468
- $v_result=1;
2469
- $v_header = array();
2470
-
2471
- // ----- Recuperate the current number of elt in list
2472
- $v_nb = sizeof($p_result_list);
2473
-
2474
- // ----- Loop on the files
2475
- for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2476
- // ----- Format the filename
2477
- $p_filedescr_list[$j]['filename']
2478
- = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2479
-
2480
-
2481
- // ----- Skip empty file names
2482
- // TBC : Can this be possible ? not checked in DescrParseAtt ?
2483
- if ($p_filedescr_list[$j]['filename'] == "") {
2484
- continue;
2485
- }
2486
-
2487
- // ----- Check the filename
2488
- if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
2489
- && (!file_exists($p_filedescr_list[$j]['filename']))) {
2490
- PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2491
- return PclZip::errorCode();
2492
- }
2493
-
2494
- // ----- Look if it is a file or a dir with no all path remove option
2495
- // or a dir with all its path removed
2496
- // if ( (is_file($p_filedescr_list[$j]['filename']))
2497
- // || ( is_dir($p_filedescr_list[$j]['filename'])
2498
- if ( ($p_filedescr_list[$j]['type'] == 'file')
2499
- || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2500
- || ( ($p_filedescr_list[$j]['type'] == 'folder')
2501
- && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2502
- || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2503
- ) {
2504
-
2505
- // ----- Add the file
2506
- $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2507
- $p_options);
2508
- if ($v_result != 1) {
2509
- return $v_result;
2510
- }
2511
-
2512
- // ----- Store the file infos
2513
- $p_result_list[$v_nb++] = $v_header;
2514
- }
2515
- }
2516
-
2517
- // ----- Return
2518
- return $v_result;
2519
- }
2520
- // --------------------------------------------------------------------------------
2521
-
2522
- // --------------------------------------------------------------------------------
2523
- // Function : privAddFile()
2524
- // Description :
2525
- // Parameters :
2526
- // Return Values :
2527
- // --------------------------------------------------------------------------------
2528
- function privAddFile($p_filedescr, &$p_header, &$p_options)
2529
- {
2530
- $v_result=1;
2531
-
2532
- // ----- Working variable
2533
- $p_filename = $p_filedescr['filename'];
2534
-
2535
- // TBC : Already done in the fileAtt check ... ?
2536
- if ($p_filename == "") {
2537
- // ----- Error log
2538
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2539
-
2540
- // ----- Return
2541
- return PclZip::errorCode();
2542
- }
2543
-
2544
- // ----- Look for a stored different filename
2545
- /* TBC : Removed
2546
- if (isset($p_filedescr['stored_filename'])) {
2547
- $v_stored_filename = $p_filedescr['stored_filename'];
2548
- }
2549
- else {
2550
- $v_stored_filename = $p_filedescr['stored_filename'];
2551
- }
2552
- */
2553
-
2554
- // ----- Set the file properties
2555
- clearstatcache();
2556
- $p_header['version'] = 20;
2557
- $p_header['version_extracted'] = 10;
2558
- $p_header['flag'] = 0;
2559
- $p_header['compression'] = 0;
2560
- $p_header['crc'] = 0;
2561
- $p_header['compressed_size'] = 0;
2562
- $p_header['filename_len'] = strlen($p_filename);
2563
- $p_header['extra_len'] = 0;
2564
- $p_header['disk'] = 0;
2565
- $p_header['internal'] = 0;
2566
- $p_header['offset'] = 0;
2567
- $p_header['filename'] = $p_filename;
2568
- // TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
2569
- $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2570
- $p_header['extra'] = '';
2571
- $p_header['status'] = 'ok';
2572
- $p_header['index'] = -1;
2573
-
2574
- // ----- Look for regular file
2575
- if ($p_filedescr['type']=='file') {
2576
- $p_header['external'] = 0x00000000;
2577
- $p_header['size'] = filesize($p_filename);
2578
- }
2579
-
2580
- // ----- Look for regular folder
2581
- else if ($p_filedescr['type']=='folder') {
2582
- $p_header['external'] = 0x00000010;
2583
- $p_header['mtime'] = filemtime($p_filename);
2584
- $p_header['size'] = filesize($p_filename);
2585
- }
2586
-
2587
- // ----- Look for virtual file
2588
- else if ($p_filedescr['type'] == 'virtual_file') {
2589
- $p_header['external'] = 0x00000000;
2590
- $p_header['size'] = strlen($p_filedescr['content']);
2591
- }
2592
-
2593
-
2594
- // ----- Look for filetime
2595
- if (isset($p_filedescr['mtime'])) {
2596
- $p_header['mtime'] = $p_filedescr['mtime'];
2597
- }
2598
- else if ($p_filedescr['type'] == 'virtual_file') {
2599
- $p_header['mtime'] = time();
2600
- }
2601
- else {
2602
- $p_header['mtime'] = filemtime($p_filename);
2603
- }
2604
-
2605
- // ------ Look for file comment
2606
- if (isset($p_filedescr['comment'])) {
2607
- $p_header['comment_len'] = strlen($p_filedescr['comment']);
2608
- $p_header['comment'] = $p_filedescr['comment'];
2609
- }
2610
- else {
2611
- $p_header['comment_len'] = 0;
2612
- $p_header['comment'] = '';
2613
- }
2614
-
2615
- // ----- Look for pre-add callback
2616
- if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2617
-
2618
- // ----- Generate a local information
2619
- $v_local_header = array();
2620
- $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2621
-
2622
- // ----- Call the callback
2623
- // Here I do not use call_user_func() because I need to send a reference to the
2624
- // header.
2625
- // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2626
- $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2627
- if ($v_result == 0) {
2628
- // ----- Change the file status
2629
- $p_header['status'] = "skipped";
2630
- $v_result = 1;
2631
- }
2632
-
2633
- // ----- Update the informations
2634
- // Only some fields can be modified
2635
- if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2636
- $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2637
- }
2638
- }
2639
-
2640
- // ----- Look for empty stored filename
2641
- if ($p_header['stored_filename'] == "") {
2642
- $p_header['status'] = "filtered";
2643
- }
2644
-
2645
- // ----- Check the path length
2646
- if (strlen($p_header['stored_filename']) > 0xFF) {
2647
- $p_header['status'] = 'filename_too_long';
2648
- }
2649
-
2650
- // ----- Look if no error, or file not skipped
2651
- if ($p_header['status'] == 'ok') {
2652
-
2653
- // ----- Look for a file
2654
- if ($p_filedescr['type'] == 'file') {
2655
- // ----- Look for using temporary file to zip
2656
- if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2657
- && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2658
- || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2659
- && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2660
- $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2661
- if ($v_result < PCLZIP_ERR_NO_ERROR) {
2662
- return $v_result;
2663
- }
2664
- }
2665
-
2666
- // ----- Use "in memory" zip algo
2667
- else {
2668
-
2669
- // ----- Open the source file
2670
- if (($v_file = @fopen($p_filename, "rb")) == 0) {
2671
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2672
- return PclZip::errorCode();
2673
- }
2674
-
2675
- // ----- Read the file content
2676
- $v_content = @fread($v_file, $p_header['size']);
2677
-
2678
- // ----- Close the file
2679
- @fclose($v_file);
2680
-
2681
- // ----- Calculate the CRC
2682
- $p_header['crc'] = @crc32($v_content);
2683
-
2684
- // ----- Look for no compression
2685
- if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2686
- // ----- Set header parameters
2687
- $p_header['compressed_size'] = $p_header['size'];
2688
- $p_header['compression'] = 0;
2689
- }
2690
-
2691
- // ----- Look for normal compression
2692
- else {
2693
- // ----- Compress the content
2694
- $v_content = @gzdeflate($v_content);
2695
-
2696
- // ----- Set header parameters
2697
- $p_header['compressed_size'] = strlen($v_content);
2698
- $p_header['compression'] = 8;
2699
- }
2700
-
2701
- // ----- Call the header generation
2702
- if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2703
- @fclose($v_file);
2704
- return $v_result;
2705
- }
2706
-
2707
- // ----- Write the compressed (or not) content
2708
- @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2709
-
2710
- }
2711
-
2712
- }
2713
-
2714
- // ----- Look for a virtual file (a file from string)
2715
- else if ($p_filedescr['type'] == 'virtual_file') {
2716
-
2717
- $v_content = $p_filedescr['content'];
2718
-
2719
- // ----- Calculate the CRC
2720
- $p_header['crc'] = @crc32($v_content);
2721
-
2722
- // ----- Look for no compression
2723
- if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2724
- // ----- Set header parameters
2725
- $p_header['compressed_size'] = $p_header['size'];
2726
- $p_header['compression'] = 0;
2727
- }
2728
-
2729
- // ----- Look for normal compression
2730
- else {
2731
- // ----- Compress the content
2732
- $v_content = @gzdeflate($v_content);
2733
-
2734
- // ----- Set header parameters
2735
- $p_header['compressed_size'] = strlen($v_content);
2736
- $p_header['compression'] = 8;
2737
- }
2738
-
2739
- // ----- Call the header generation
2740
- if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2741
- @fclose($v_file);
2742
- return $v_result;
2743
- }
2744
-
2745
- // ----- Write the compressed (or not) content
2746
- @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2747
- }
2748
-
2749
- // ----- Look for a directory
2750
- else if ($p_filedescr['type'] == 'folder') {
2751
- // ----- Look for directory last '/'
2752
- if (@substr($p_header['stored_filename'], -1) != '/') {
2753
- $p_header['stored_filename'] .= '/';
2754
- }
2755
-
2756
- // ----- Set the file properties
2757
- $p_header['size'] = 0;
2758
- //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2759
- $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2760
-
2761
- // ----- Call the header generation
2762
- if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2763
- {
2764
- return $v_result;
2765
- }
2766
- }
2767
- }
2768
-
2769
- // ----- Look for post-add callback
2770
- if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2771
-
2772
- // ----- Generate a local information
2773
- $v_local_header = array();
2774
- $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2775
-
2776
- // ----- Call the callback
2777
- // Here I do not use call_user_func() because I need to send a reference to the
2778
- // header.
2779
- // eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2780
- $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2781
- if ($v_result == 0) {
2782
- // ----- Ignored
2783
- $v_result = 1;
2784
- }
2785
-
2786
- // ----- Update the informations
2787
- // Nothing can be modified
2788
- }
2789
-
2790
- // ----- Return
2791
- return $v_result;
2792
- }
2793
- // --------------------------------------------------------------------------------
2794
-
2795
- // --------------------------------------------------------------------------------
2796
- // Function : privAddFileUsingTempFile()
2797
- // Description :
2798
- // Parameters :
2799
- // Return Values :
2800
- // --------------------------------------------------------------------------------
2801
- function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
2802
- {
2803
- $v_result=PCLZIP_ERR_NO_ERROR;
2804
-
2805
- // ----- Working variable
2806
- $p_filename = $p_filedescr['filename'];
2807
-
2808
-
2809
- // ----- Open the source file
2810
- if (($v_file = @fopen($p_filename, "rb")) == 0) {
2811
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2812
- return PclZip::errorCode();
2813
- }
2814
-
2815
- // ----- Creates a compressed temporary file
2816
- $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2817
- if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2818
- fclose($v_file);
2819
- PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2820
- return PclZip::errorCode();
2821
- }
2822
-
2823
- // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2824
- $v_size = filesize($p_filename);
2825
- while ($v_size != 0) {
2826
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2827
- $v_buffer = @fread($v_file, $v_read_size);
2828
- //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2829
- @gzputs($v_file_compressed, $v_buffer, $v_read_size);
2830
- $v_size -= $v_read_size;
2831
- }
2832
-
2833
- // ----- Close the file
2834
- @fclose($v_file);
2835
- @gzclose($v_file_compressed);
2836
-
2837
- // ----- Check the minimum file size
2838
- if (filesize($v_gzip_temp_name) < 18) {
2839
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2840
- return PclZip::errorCode();
2841
- }
2842
-
2843
- // ----- Extract the compressed attributes
2844
- if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2845
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2846
- return PclZip::errorCode();
2847
- }
2848
-
2849
- // ----- Read the gzip file header
2850
- $v_binary_data = @fread($v_file_compressed, 10);
2851
- $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2852
-
2853
- // ----- Check some parameters
2854
- $v_data_header['os'] = bin2hex($v_data_header['os']);
2855
-
2856
- // ----- Read the gzip file footer
2857
- @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
2858
- $v_binary_data = @fread($v_file_compressed, 8);
2859
- $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2860
-
2861
- // ----- Set the attributes
2862
- $p_header['compression'] = ord($v_data_header['cm']);
2863
- //$p_header['mtime'] = $v_data_header['mtime'];
2864
- $p_header['crc'] = $v_data_footer['crc'];
2865
- $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2866
-
2867
- // ----- Close the file
2868
- @fclose($v_file_compressed);
2869
-
2870
- // ----- Call the header generation
2871
- if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2872
- return $v_result;
2873
- }
2874
-
2875
- // ----- Add the compressed data
2876
- if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2877
- {
2878
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2879
- return PclZip::errorCode();
2880
- }
2881
-
2882
- // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2883
- fseek($v_file_compressed, 10);
2884
- $v_size = $p_header['compressed_size'];
2885
- while ($v_size != 0)
2886
- {
2887
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2888
- $v_buffer = @fread($v_file_compressed, $v_read_size);
2889
- //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2890
- @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2891
- $v_size -= $v_read_size;
2892
- }
2893
-
2894
- // ----- Close the file
2895
- @fclose($v_file_compressed);
2896
-
2897
- // ----- Unlink the temporary file
2898
- @unlink($v_gzip_temp_name);
2899
-
2900
- // ----- Return
2901
- return $v_result;
2902
- }
2903
- // --------------------------------------------------------------------------------
2904
-
2905
- // --------------------------------------------------------------------------------
2906
- // Function : privCalculateStoredFilename()
2907
- // Description :
2908
- // Based on file descriptor properties and global options, this method
2909
- // calculate the filename that will be stored in the archive.
2910
- // Parameters :
2911
- // Return Values :
2912
- // --------------------------------------------------------------------------------
2913
- function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2914
- {
2915
- $v_result=1;
2916
-
2917
- // ----- Working variables
2918
- $p_filename = $p_filedescr['filename'];
2919
- if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2920
- $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2921
- }
2922
- else {
2923
- $p_add_dir = '';
2924
- }
2925
- if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2926
- $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2927
- }
2928
- else {
2929
- $p_remove_dir = '';
2930
- }
2931
- if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2932
- $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2933
- }
2934
- else {
2935
- $p_remove_all_dir = 0;
2936
- }
2937
-
2938
-
2939
- // ----- Look for full name change
2940
- if (isset($p_filedescr['new_full_name'])) {
2941
- // ----- Remove drive letter if any
2942
- $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2943
- }
2944
-
2945
- // ----- Look for path and/or short name change
2946
- else {
2947
-
2948
- // ----- Look for short name change
2949
- // Its when we cahnge just the filename but not the path
2950
- if (isset($p_filedescr['new_short_name'])) {
2951
- $v_path_info = pathinfo($p_filename);
2952
- $v_dir = '';
2953
- if ($v_path_info['dirname'] != '') {
2954
- $v_dir = $v_path_info['dirname'].'/';
2955
- }
2956
- $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2957
- }
2958
- else {
2959
- // ----- Calculate the stored filename
2960
- $v_stored_filename = $p_filename;
2961
- }
2962
-
2963
- // ----- Look for all path to remove
2964
- if ($p_remove_all_dir) {
2965
- $v_stored_filename = basename($p_filename);
2966
- }
2967
- // ----- Look for partial path remove
2968
- else if ($p_remove_dir != "") {
2969
- if (substr($p_remove_dir, -1) != '/')
2970
- $p_remove_dir .= "/";
2971
-
2972
- if ( (substr($p_filename, 0, 2) == "./")
2973
- || (substr($p_remove_dir, 0, 2) == "./")) {
2974
-
2975
- if ( (substr($p_filename, 0, 2) == "./")
2976
- && (substr($p_remove_dir, 0, 2) != "./")) {
2977
- $p_remove_dir = "./".$p_remove_dir;
2978
- }
2979
- if ( (substr($p_filename, 0, 2) != "./")
2980
- && (substr($p_remove_dir, 0, 2) == "./")) {
2981
- $p_remove_dir = substr($p_remove_dir, 2);
2982
- }
2983
- }
2984
-
2985
- $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2986
- $v_stored_filename);
2987
- if ($v_compare > 0) {
2988
- if ($v_compare == 2) {
2989
- $v_stored_filename = "";
2990
- }
2991
- else {
2992
- $v_stored_filename = substr($v_stored_filename,
2993
- strlen($p_remove_dir));
2994
- }
2995
- }
2996
- }
2997
-
2998
- // ----- Remove drive letter if any
2999
- $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
3000
-
3001
- // ----- Look for path to add
3002
- if ($p_add_dir != "") {
3003
- if (substr($p_add_dir, -1) == "/")
3004
- $v_stored_filename = $p_add_dir.$v_stored_filename;
3005
- else
3006
- $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3007
- }
3008
- }
3009
-
3010
- // ----- Filename (reduce the path of stored name)
3011
- $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3012
- $p_filedescr['stored_filename'] = $v_stored_filename;
3013
-
3014
- // ----- Return
3015
- return $v_result;
3016
- }
3017
- // --------------------------------------------------------------------------------
3018
-
3019
- // --------------------------------------------------------------------------------
3020
- // Function : privWriteFileHeader()
3021
- // Description :
3022
- // Parameters :
3023
- // Return Values :
3024
- // --------------------------------------------------------------------------------
3025
- function privWriteFileHeader(&$p_header)
3026
- {
3027
- $v_result=1;
3028
-
3029
- // ----- Store the offset position of the file
3030
- $p_header['offset'] = ftell($this->zip_fd);
3031
-
3032
- // ----- Transform UNIX mtime to DOS format mdate/mtime
3033
- $v_date = getdate($p_header['mtime']);
3034
- $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3035
- $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3036
-
3037
- // ----- Packed data
3038
- $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3039
- $p_header['version_extracted'], $p_header['flag'],
3040
- $p_header['compression'], $v_mtime, $v_mdate,
3041
- $p_header['crc'], $p_header['compressed_size'],
3042
- $p_header['size'],
3043
- strlen($p_header['stored_filename']),
3044
- $p_header['extra_len']);
3045
-
3046
- // ----- Write the first 148 bytes of the header in the archive
3047
- fputs($this->zip_fd, $v_binary_data, 30);
3048
-
3049
- // ----- Write the variable fields
3050
- if (strlen($p_header['stored_filename']) != 0)
3051
- {
3052
- fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3053
- }
3054
- if ($p_header['extra_len'] != 0)
3055
- {
3056
- fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3057
- }
3058
-
3059
- // ----- Return
3060
- return $v_result;
3061
- }
3062
- // --------------------------------------------------------------------------------
3063
-
3064
- // --------------------------------------------------------------------------------
3065
- // Function : privWriteCentralFileHeader()
3066
- // Description :
3067
- // Parameters :
3068
- // Return Values :
3069
- // --------------------------------------------------------------------------------
3070
- function privWriteCentralFileHeader(&$p_header)
3071
- {
3072
- $v_result=1;
3073
-
3074
- // TBC
3075
- //for(reset($p_header); $key = key($p_header); next($p_header)) {
3076
- //}
3077
-
3078
- // ----- Transform UNIX mtime to DOS format mdate/mtime
3079
- $v_date = getdate($p_header['mtime']);
3080
- $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3081
- $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3082
-
3083
-
3084
- // ----- Packed data
3085
- $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3086
- $p_header['version'], $p_header['version_extracted'],
3087
- $p_header['flag'], $p_header['compression'],
3088
- $v_mtime, $v_mdate, $p_header['crc'],
3089
- $p_header['compressed_size'], $p_header['size'],
3090
- strlen($p_header['stored_filename']),
3091
- $p_header['extra_len'], $p_header['comment_len'],
3092
- $p_header['disk'], $p_header['internal'],
3093
- $p_header['external'], $p_header['offset']);
3094
-
3095
- // ----- Write the 42 bytes of the header in the zip file
3096
- fputs($this->zip_fd, $v_binary_data, 46);
3097
-
3098
- // ----- Write the variable fields
3099
- if (strlen($p_header['stored_filename']) != 0)
3100
- {
3101
- fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3102
- }
3103
- if ($p_header['extra_len'] != 0)
3104
- {
3105
- fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3106
- }
3107
- if ($p_header['comment_len'] != 0)
3108
- {
3109
- fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3110
- }
3111
-
3112
- // ----- Return
3113
- return $v_result;
3114
- }
3115
- // --------------------------------------------------------------------------------
3116
-
3117
- // --------------------------------------------------------------------------------
3118
- // Function : privWriteCentralHeader()
3119
- // Description :
3120
- // Parameters :
3121
- // Return Values :
3122
- // --------------------------------------------------------------------------------
3123
- function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3124
- {
3125
- $v_result=1;
3126
-
3127
- // ----- Packed data
3128
- $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3129
- $p_nb_entries, $p_size,
3130
- $p_offset, strlen($p_comment));
3131
-
3132
- // ----- Write the 22 bytes of the header in the zip file
3133
- fputs($this->zip_fd, $v_binary_data, 22);
3134
-
3135
- // ----- Write the variable fields
3136
- if (strlen($p_comment) != 0)
3137
- {
3138
- fputs($this->zip_fd, $p_comment, strlen($p_comment));
3139
- }
3140
-
3141
- // ----- Return
3142
- return $v_result;
3143
- }
3144
- // --------------------------------------------------------------------------------
3145
-
3146
- // --------------------------------------------------------------------------------
3147
- // Function : privList()
3148
- // Description :
3149
- // Parameters :
3150
- // Return Values :
3151
- // --------------------------------------------------------------------------------
3152
- function privList(&$p_list)
3153
- {
3154
- $v_result=1;
3155
-
3156
- // ----- Magic quotes trick
3157
- $this->privDisableMagicQuotes();
3158
-
3159
- // ----- Open the zip file
3160
- if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3161
- {
3162
- // ----- Magic quotes trick
3163
- $this->privSwapBackMagicQuotes();
3164
-
3165
- // ----- Error log
3166
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3167
-
3168
- // ----- Return
3169
- return PclZip::errorCode();
3170
- }
3171
-
3172
- // ----- Read the central directory informations
3173
- $v_central_dir = array();
3174
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3175
- {
3176
- $this->privSwapBackMagicQuotes();
3177
- return $v_result;
3178
- }
3179
-
3180
- // ----- Go to beginning of Central Dir
3181
- @rewind($this->zip_fd);
3182
- if (@fseek($this->zip_fd, $v_central_dir['offset']))
3183
- {
3184
- $this->privSwapBackMagicQuotes();
3185
-
3186
- // ----- Error log
3187
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3188
-
3189
- // ----- Return
3190
- return PclZip::errorCode();
3191
- }
3192
-
3193
- // ----- Read each entry
3194
- for ($i=0; $i<$v_central_dir['entries']; $i++)
3195
- {
3196
- // ----- Read the file header
3197
- if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3198
- {
3199
- $this->privSwapBackMagicQuotes();
3200
- return $v_result;
3201
- }
3202
- $v_header['index'] = $i;
3203
-
3204
- // ----- Get the only interesting attributes
3205
- $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3206
- unset($v_header);
3207
- }
3208
-
3209
- // ----- Close the zip file
3210
- $this->privCloseFd();
3211
-
3212
- // ----- Magic quotes trick
3213
- $this->privSwapBackMagicQuotes();
3214
-
3215
- // ----- Return
3216
- return $v_result;
3217
- }
3218
- // --------------------------------------------------------------------------------
3219
-
3220
- // --------------------------------------------------------------------------------
3221
- // Function : privConvertHeader2FileInfo()
3222
- // Description :
3223
- // This function takes the file informations from the central directory
3224
- // entries and extract the interesting parameters that will be given back.
3225
- // The resulting file infos are set in the array $p_info
3226
- // $p_info['filename'] : Filename with full path. Given by user (add),
3227
- // extracted in the filesystem (extract).
3228
- // $p_info['stored_filename'] : Stored filename in the archive.
3229
- // $p_info['size'] = Size of the file.
3230
- // $p_info['compressed_size'] = Compressed size of the file.
3231
- // $p_info['mtime'] = Last modification date of the file.
3232
- // $p_info['comment'] = Comment associated with the file.
3233
- // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3234
- // $p_info['status'] = status of the action on the file.
3235
- // $p_info['crc'] = CRC of the file content.
3236
- // Parameters :
3237
- // Return Values :
3238
- // --------------------------------------------------------------------------------
3239
- function privConvertHeader2FileInfo($p_header, &$p_info)
3240
- {
3241
- $v_result=1;
3242
-
3243
- // ----- Get the interesting attributes
3244
- $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3245
- $p_info['filename'] = $v_temp_path;
3246
- $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3247
- $p_info['stored_filename'] = $v_temp_path;
3248
- $p_info['size'] = $p_header['size'];
3249
- $p_info['compressed_size'] = $p_header['compressed_size'];
3250
- $p_info['mtime'] = $p_header['mtime'];
3251
- $p_info['comment'] = $p_header['comment'];
3252
- $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3253
- $p_info['index'] = $p_header['index'];
3254
- $p_info['status'] = $p_header['status'];
3255
- $p_info['crc'] = $p_header['crc'];
3256
-
3257
- // ----- Return
3258
- return $v_result;
3259
- }
3260
- // --------------------------------------------------------------------------------
3261
-
3262
- // --------------------------------------------------------------------------------
3263
- // Function : privExtractByRule()
3264
- // Description :
3265
- // Extract a file or directory depending of rules (by index, by name, ...)
3266
- // Parameters :
3267
- // $p_file_list : An array where will be placed the properties of each
3268
- // extracted file
3269
- // $p_path : Path to add while writing the extracted files
3270
- // $p_remove_path : Path to remove (from the file memorized path) while writing the
3271
- // extracted files. If the path does not match the file path,
3272
- // the file is extracted with its memorized path.
3273
- // $p_remove_path does not apply to 'list' mode.
3274
- // $p_path and $p_remove_path are commulative.
3275
- // Return Values :
3276
- // 1 on success,0 or less on error (see error code list)
3277
- // --------------------------------------------------------------------------------
3278
- function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3279
- {
3280
- $v_result=1;
3281
-
3282
- // ----- Magic quotes trick
3283
- $this->privDisableMagicQuotes();
3284
-
3285
- // ----- Check the path
3286
- if ( ($p_path == "")
3287
- || ( (substr($p_path, 0, 1) != "/")
3288
- && (substr($p_path, 0, 3) != "../")
3289
- && (substr($p_path,1,2)!=":/")))
3290
- $p_path = "./".$p_path;
3291
-
3292
- // ----- Reduce the path last (and duplicated) '/'
3293
- if (($p_path != "./") && ($p_path != "/"))
3294
- {
3295
- // ----- Look for the path end '/'
3296
- while (substr($p_path, -1) == "/")
3297
- {
3298
- $p_path = substr($p_path, 0, strlen($p_path)-1);
3299
- }
3300
- }
3301
-
3302
- // ----- Look for path to remove format (should end by /)
3303
- if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3304
- {
3305
- $p_remove_path .= '/';
3306
- }
3307
- $p_remove_path_size = strlen($p_remove_path);
3308
-
3309
- // ----- Open the zip file
3310
- if (($v_result = $this->privOpenFd('rb')) != 1)
3311
- {
3312
- $this->privSwapBackMagicQuotes();
3313
- return $v_result;
3314
- }
3315
-
3316
- // ----- Read the central directory informations
3317
- $v_central_dir = array();
3318
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3319
- {
3320
- // ----- Close the zip file
3321
- $this->privCloseFd();
3322
- $this->privSwapBackMagicQuotes();
3323
-
3324
- return $v_result;
3325
- }
3326
-
3327
- // ----- Start at beginning of Central Dir
3328
- $v_pos_entry = $v_central_dir['offset'];
3329
-
3330
- // ----- Read each entry
3331
- $j_start = 0;
3332
- for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3333
- {
3334
-
3335
- // ----- Read next Central dir entry
3336
- @rewind($this->zip_fd);
3337
- if (@fseek($this->zip_fd, $v_pos_entry))
3338
- {
3339
- // ----- Close the zip file
3340
- $this->privCloseFd();
3341
- $this->privSwapBackMagicQuotes();
3342
-
3343
- // ----- Error log
3344
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3345
-
3346
- // ----- Return
3347
- return PclZip::errorCode();
3348
- }
3349
-
3350
- // ----- Read the file header
3351
- $v_header = array();
3352
- if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3353
- {
3354
- // ----- Close the zip file
3355
- $this->privCloseFd();
3356
- $this->privSwapBackMagicQuotes();
3357
-
3358
- return $v_result;
3359
- }
3360
-
3361
- // ----- Store the index
3362
- $v_header['index'] = $i;
3363
-
3364
- // ----- Store the file position
3365
- $v_pos_entry = ftell($this->zip_fd);
3366
-
3367
- // ----- Look for the specific extract rules
3368
- $v_extract = false;
3369
-
3370
- // ----- Look for extract by name rule
3371
- if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
3372
- && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3373
-
3374
- // ----- Look if the filename is in the list
3375
- for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3376
-
3377
- // ----- Look for a directory
3378
- if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3379
-
3380
- // ----- Look if the directory is in the filename path
3381
- if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3382
- && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3383
- $v_extract = true;
3384
- }
3385
- }
3386
- // ----- Look for a filename
3387
- elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3388
- $v_extract = true;
3389
- }
3390
- }
3391
- }
3392
-
3393
- // ----- Look for extract by ereg rule
3394
- // ereg() is deprecated with PHP 5.3
3395
- /*
3396
- else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
3397
- && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3398
-
3399
- if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3400
- $v_extract = true;
3401
- }
3402
- }
3403
- */
3404
-
3405
- // ----- Look for extract by preg rule
3406
- else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
3407
- && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3408
-
3409
- if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3410
- $v_extract = true;
3411
- }
3412
- }
3413
-
3414
- // ----- Look for extract by index rule
3415
- else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3416
- && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3417
-
3418
- // ----- Look if the index is in the list
3419
- for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3420
-
3421
- if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3422
- $v_extract = true;
3423
- }
3424
- if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3425
- $j_start = $j+1;
3426
- }
3427
-
3428
- if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3429
- break;
3430
- }
3431
- }
3432
- }
3433
-
3434
- // ----- Look for no rule, which means extract all the archive
3435
- else {
3436
- $v_extract = true;
3437
- }
3438
-
3439
- // ----- Check compression method
3440
- if ( ($v_extract)
3441
- && ( ($v_header['compression'] != 8)
3442
- && ($v_header['compression'] != 0))) {
3443
- $v_header['status'] = 'unsupported_compression';
3444
-
3445
- // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3446
- if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3447
- && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3448
-
3449
- $this->privSwapBackMagicQuotes();
3450
-
3451
- PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3452
- "Filename '".$v_header['stored_filename']."' is "
3453
- ."compressed by an unsupported compression "
3454
- ."method (".$v_header['compression'].") ");
3455
-
3456
- return PclZip::errorCode();
3457
- }
3458
- }
3459
-
3460
- // ----- Check encrypted files
3461
- if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3462
- $v_header['status'] = 'unsupported_encryption';
3463
-
3464
- // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3465
- if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3466
- && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3467
-
3468
- $this->privSwapBackMagicQuotes();
3469
-
3470
- PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3471
- "Unsupported encryption for "
3472
- ." filename '".$v_header['stored_filename']
3473
- ."'");
3474
-
3475
- return PclZip::errorCode();
3476
- }
3477
- }
3478
-
3479
- // ----- Look for real extraction
3480
- if (($v_extract) && ($v_header['status'] != 'ok')) {
3481
- $v_result = $this->privConvertHeader2FileInfo($v_header,
3482
- $p_file_list[$v_nb_extracted++]);
3483
- if ($v_result != 1) {
3484
- $this->privCloseFd();
3485
- $this->privSwapBackMagicQuotes();
3486
- return $v_result;
3487
- }
3488
-
3489
- $v_extract = false;
3490
- }
3491
-
3492
- // ----- Look for real extraction
3493
- if ($v_extract)
3494
- {
3495
-
3496
- // ----- Go to the file position
3497
- @rewind($this->zip_fd);
3498
- if (@fseek($this->zip_fd, $v_header['offset']))
3499
- {
3500
- // ----- Close the zip file
3501
- $this->privCloseFd();
3502
-
3503
- $this->privSwapBackMagicQuotes();
3504
-
3505
- // ----- Error log
3506
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3507
-
3508
- // ----- Return
3509
- return PclZip::errorCode();
3510
- }
3511
-
3512
- // ----- Look for extraction as string
3513
- if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3514
-
3515
- $v_string = '';
3516
-
3517
- // ----- Extracting the file
3518
- $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3519
- if ($v_result1 < 1) {
3520
- $this->privCloseFd();
3521
- $this->privSwapBackMagicQuotes();
3522
- return $v_result1;
3523
- }
3524
-
3525
- // ----- Get the only interesting attributes
3526
- if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3527
- {
3528
- // ----- Close the zip file
3529
- $this->privCloseFd();
3530
- $this->privSwapBackMagicQuotes();
3531
-
3532
- return $v_result;
3533
- }
3534
-
3535
- // ----- Set the file content
3536
- $p_file_list[$v_nb_extracted]['content'] = $v_string;
3537
-
3538
- // ----- Next extracted file
3539
- $v_nb_extracted++;
3540
-
3541
- // ----- Look for user callback abort
3542
- if ($v_result1 == 2) {
3543
- break;
3544
- }
3545
- }
3546
- // ----- Look for extraction in standard output
3547
- elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3548
- && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3549
- // ----- Extracting the file in standard output
3550
- $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3551
- if ($v_result1 < 1) {
3552
- $this->privCloseFd();
3553
- $this->privSwapBackMagicQuotes();
3554
- return $v_result1;
3555
- }
3556
-
3557
- // ----- Get the only interesting attributes
3558
- if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3559
- $this->privCloseFd();
3560
- $this->privSwapBackMagicQuotes();
3561
- return $v_result;
3562
- }
3563
-
3564
- // ----- Look for user callback abort
3565
- if ($v_result1 == 2) {
3566
- break;
3567
- }
3568
- }
3569
- // ----- Look for normal extraction
3570
- else {
3571
- // ----- Extracting the file
3572
- $v_result1 = $this->privExtractFile($v_header,
3573
- $p_path, $p_remove_path,
3574
- $p_remove_all_path,
3575
- $p_options);
3576
- if ($v_result1 < 1) {
3577
- $this->privCloseFd();
3578
- $this->privSwapBackMagicQuotes();
3579
- return $v_result1;
3580
- }
3581
-
3582
- // ----- Get the only interesting attributes
3583
- if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3584
- {
3585
- // ----- Close the zip file
3586
- $this->privCloseFd();
3587
- $this->privSwapBackMagicQuotes();
3588
-
3589
- return $v_result;
3590
- }
3591
-
3592
- // ----- Look for user callback abort
3593
- if ($v_result1 == 2) {
3594
- break;
3595
- }
3596
- }
3597
- }
3598
- }
3599
-
3600
- // ----- Close the zip file
3601
- $this->privCloseFd();
3602
- $this->privSwapBackMagicQuotes();
3603
-
3604
- // ----- Return
3605
- return $v_result;
3606
- }
3607
- // --------------------------------------------------------------------------------
3608
-
3609
- // --------------------------------------------------------------------------------
3610
- // Function : privExtractFile()
3611
- // Description :
3612
- // Parameters :
3613
- // Return Values :
3614
- //
3615
- // 1 : ... ?
3616
- // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3617
- // --------------------------------------------------------------------------------
3618
- function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3619
- {
3620
- $v_result=1;
3621
-
3622
- // ----- Read the file header
3623
- if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3624
- {
3625
- // ----- Return
3626
- return $v_result;
3627
- }
3628
-
3629
-
3630
- // ----- Check that the file header is coherent with $p_entry info
3631
- if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3632
- // TBC
3633
- }
3634
-
3635
- // ----- Look for all path to remove
3636
- if ($p_remove_all_path == true) {
3637
- // ----- Look for folder entry that not need to be extracted
3638
- if (($p_entry['external']&0x00000010)==0x00000010) {
3639
-
3640
- $p_entry['status'] = "filtered";
3641
-
3642
- return $v_result;
3643
- }
3644
-
3645
- // ----- Get the basename of the path
3646
- $p_entry['filename'] = basename($p_entry['filename']);
3647
- }
3648
-
3649
- // ----- Look for path to remove
3650
- else if ($p_remove_path != "")
3651
- {
3652
- if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3653
- {
3654
-
3655
- // ----- Change the file status
3656
- $p_entry['status'] = "filtered";
3657
-
3658
- // ----- Return
3659
- return $v_result;
3660
- }
3661
-
3662
- $p_remove_path_size = strlen($p_remove_path);
3663
- if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3664
- {
3665
-
3666
- // ----- Remove the path
3667
- $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3668
-
3669
- }
3670
- }
3671
-
3672
- // ----- Add the path
3673
- if ($p_path != '') {
3674
- $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3675
- }
3676
-
3677
- // ----- Check a base_dir_restriction
3678
- if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3679
- $v_inclusion
3680
- = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3681
- $p_entry['filename']);
3682
- if ($v_inclusion == 0) {
3683
-
3684
- PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3685
- "Filename '".$p_entry['filename']."' is "
3686
- ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3687
-
3688
- return PclZip::errorCode();
3689
- }
3690
- }
3691
-
3692
- // ----- Look for pre-extract callback
3693
- if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3694
-
3695
- // ----- Generate a local information
3696
- $v_local_header = array();
3697
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3698
-
3699
- // ----- Call the callback
3700
- // Here I do not use call_user_func() because I need to send a reference to the
3701
- // header.
3702
- // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3703
- $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3704
- if ($v_result == 0) {
3705
- // ----- Change the file status
3706
- $p_entry['status'] = "skipped";
3707
- $v_result = 1;
3708
- }
3709
-
3710
- // ----- Look for abort result
3711
- if ($v_result == 2) {
3712
- // ----- This status is internal and will be changed in 'skipped'
3713
- $p_entry['status'] = "aborted";
3714
- $v_result = PCLZIP_ERR_USER_ABORTED;
3715
- }
3716
-
3717
- // ----- Update the informations
3718
- // Only some fields can be modified
3719
- $p_entry['filename'] = $v_local_header['filename'];
3720
- }
3721
-
3722
-
3723
- // ----- Look if extraction should be done
3724
- if ($p_entry['status'] == 'ok') {
3725
-
3726
- // ----- Look for specific actions while the file exist
3727
- if (file_exists($p_entry['filename']))
3728
- {
3729
-
3730
- // ----- Look if file is a directory
3731
- if (is_dir($p_entry['filename']))
3732
- {
3733
-
3734
- // ----- Change the file status
3735
- $p_entry['status'] = "already_a_directory";
3736
-
3737
- // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3738
- // For historical reason first PclZip implementation does not stop
3739
- // when this kind of error occurs.
3740
- if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3741
- && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3742
-
3743
- PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3744
- "Filename '".$p_entry['filename']."' is "
3745
- ."already used by an existing directory");
3746
-
3747
- return PclZip::errorCode();
3748
- }
3749
- }
3750
- // ----- Look if file is write protected
3751
- else if (!is_writeable($p_entry['filename']))
3752
- {
3753
-
3754
- // ----- Change the file status
3755
- $p_entry['status'] = "write_protected";
3756
-
3757
- // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3758
- // For historical reason first PclZip implementation does not stop
3759
- // when this kind of error occurs.
3760
- if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3761
- && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3762
-
3763
- PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3764
- "Filename '".$p_entry['filename']."' exists "
3765
- ."and is write protected");
3766
-
3767
- return PclZip::errorCode();
3768
- }
3769
- }
3770
-
3771
- // ----- Look if the extracted file is older
3772
- else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3773
- {
3774
- // ----- Change the file status
3775
- if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3776
- && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3777
- }
3778
- else {
3779
- $p_entry['status'] = "newer_exist";
3780
-
3781
- // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3782
- // For historical reason first PclZip implementation does not stop
3783
- // when this kind of error occurs.
3784
- if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3785
- && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3786
-
3787
- PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3788
- "Newer version of '".$p_entry['filename']."' exists "
3789
- ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3790
-
3791
- return PclZip::errorCode();
3792
- }
3793
- }
3794
- }
3795
- else {
3796
- }
3797
- }
3798
-
3799
- // ----- Check the directory availability and create it if necessary
3800
- else {
3801
- if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3802
- $v_dir_to_check = $p_entry['filename'];
3803
- else if (!strstr($p_entry['filename'], "/"))
3804
- $v_dir_to_check = "";
3805
- else
3806
- $v_dir_to_check = dirname($p_entry['filename']);
3807
-
3808
- if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3809
-
3810
- // ----- Change the file status
3811
- $p_entry['status'] = "path_creation_fail";
3812
-
3813
- // ----- Return
3814
- //return $v_result;
3815
- $v_result = 1;
3816
- }
3817
- }
3818
- }
3819
-
3820
- // ----- Look if extraction should be done
3821
- if ($p_entry['status'] == 'ok') {
3822
-
3823
- // ----- Do the extraction (if not a folder)
3824
- if (!(($p_entry['external']&0x00000010)==0x00000010))
3825
- {
3826
- // ----- Look for not compressed file
3827
- if ($p_entry['compression'] == 0) {
3828
-
3829
- // ----- Opening destination file
3830
- if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3831
- {
3832
-
3833
- // ----- Change the file status
3834
- $p_entry['status'] = "write_error";
3835
-
3836
- // ----- Return
3837
- return $v_result;
3838
- }
3839
-
3840
-
3841
- // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3842
- $v_size = $p_entry['compressed_size'];
3843
- while ($v_size != 0)
3844
- {
3845
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3846
- $v_buffer = @fread($this->zip_fd, $v_read_size);
3847
- /* Try to speed up the code
3848
- $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3849
- @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3850
- */
3851
- @fwrite($v_dest_file, $v_buffer, $v_read_size);
3852
- $v_size -= $v_read_size;
3853
- }
3854
-
3855
- // ----- Closing the destination file
3856
- fclose($v_dest_file);
3857
-
3858
- // ----- Change the file mtime
3859
- touch($p_entry['filename'], $p_entry['mtime']);
3860
-
3861
-
3862
- }
3863
- else {
3864
- // ----- TBC
3865
- // Need to be finished
3866
- if (($p_entry['flag'] & 1) == 1) {
3867
- PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3868
- return PclZip::errorCode();
3869
- }
3870
-
3871
-
3872
- // ----- Look for using temporary file to unzip
3873
- if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3874
- && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3875
- || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3876
- && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3877
- $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3878
- if ($v_result < PCLZIP_ERR_NO_ERROR) {
3879
- return $v_result;
3880
- }
3881
- }
3882
-
3883
- // ----- Look for extract in memory
3884
- else {
3885
-
3886
-
3887
- // ----- Read the compressed file in a buffer (one shot)
3888
- $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3889
-
3890
- // ----- Decompress the file
3891
- $v_file_content = @gzinflate($v_buffer);
3892
- unset($v_buffer);
3893
- if ($v_file_content === FALSE) {
3894
-
3895
- // ----- Change the file status
3896
- // TBC
3897
- $p_entry['status'] = "error";
3898
-
3899
- return $v_result;
3900
- }
3901
-
3902
- // ----- Opening destination file
3903
- if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3904
-
3905
- // ----- Change the file status
3906
- $p_entry['status'] = "write_error";
3907
-
3908
- return $v_result;
3909
- }
3910
-
3911
- // ----- Write the uncompressed data
3912
- @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3913
- unset($v_file_content);
3914
-
3915
- // ----- Closing the destination file
3916
- @fclose($v_dest_file);
3917
-
3918
- }
3919
-
3920
- // ----- Change the file mtime
3921
- @touch($p_entry['filename'], $p_entry['mtime']);
3922
- }
3923
-
3924
- // ----- Look for chmod option
3925
- if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3926
-
3927
- // ----- Change the mode of the file
3928
- @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3929
- }
3930
-
3931
- }
3932
- }
3933
-
3934
- // ----- Change abort status
3935
- if ($p_entry['status'] == "aborted") {
3936
- $p_entry['status'] = "skipped";
3937
- }
3938
-
3939
- // ----- Look for post-extract callback
3940
- elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3941
-
3942
- // ----- Generate a local information
3943
- $v_local_header = array();
3944
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3945
-
3946
- // ----- Call the callback
3947
- // Here I do not use call_user_func() because I need to send a reference to the
3948
- // header.
3949
- // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3950
- $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3951
-
3952
- // ----- Look for abort result
3953
- if ($v_result == 2) {
3954
- $v_result = PCLZIP_ERR_USER_ABORTED;
3955
- }
3956
- }
3957
-
3958
- // ----- Return
3959
- return $v_result;
3960
- }
3961
- // --------------------------------------------------------------------------------
3962
-
3963
- // --------------------------------------------------------------------------------
3964
- // Function : privExtractFileUsingTempFile()
3965
- // Description :
3966
- // Parameters :
3967
- // Return Values :
3968
- // --------------------------------------------------------------------------------
3969
- function privExtractFileUsingTempFile(&$p_entry, &$p_options)
3970
- {
3971
- $v_result=1;
3972
-
3973
- // ----- Creates a temporary file
3974
- $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3975
- if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3976
- fclose($v_file);
3977
- PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3978
- return PclZip::errorCode();
3979
- }
3980
-
3981
-
3982
- // ----- Write gz file format header
3983
- $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
3984
- @fwrite($v_dest_file, $v_binary_data, 10);
3985
-
3986
- // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3987
- $v_size = $p_entry['compressed_size'];
3988
- while ($v_size != 0)
3989
- {
3990
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3991
- $v_buffer = @fread($this->zip_fd, $v_read_size);
3992
- //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3993
- @fwrite($v_dest_file, $v_buffer, $v_read_size);
3994
- $v_size -= $v_read_size;
3995
- }
3996
-
3997
- // ----- Write gz file format footer
3998
- $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3999
- @fwrite($v_dest_file, $v_binary_data, 8);
4000
-
4001
- // ----- Close the temporary file
4002
- @fclose($v_dest_file);
4003
-
4004
- // ----- Opening destination file
4005
- if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4006
- $p_entry['status'] = "write_error";
4007
- return $v_result;
4008
- }
4009
-
4010
- // ----- Open the temporary gz file
4011
- if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4012
- @fclose($v_dest_file);
4013
- $p_entry['status'] = "read_error";
4014
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4015
- return PclZip::errorCode();
4016
- }
4017
-
4018
-
4019
- // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4020
- $v_size = $p_entry['size'];
4021
- while ($v_size != 0) {
4022
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4023
- $v_buffer = @gzread($v_src_file, $v_read_size);
4024
- //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4025
- @fwrite($v_dest_file, $v_buffer, $v_read_size);
4026
- $v_size -= $v_read_size;
4027
- }
4028
- @fclose($v_dest_file);
4029
- @gzclose($v_src_file);
4030
-
4031
- // ----- Delete the temporary file
4032
- @unlink($v_gzip_temp_name);
4033
-
4034
- // ----- Return
4035
- return $v_result;
4036
- }
4037
- // --------------------------------------------------------------------------------
4038
-
4039
- // --------------------------------------------------------------------------------
4040
- // Function : privExtractFileInOutput()
4041
- // Description :
4042
- // Parameters :
4043
- // Return Values :
4044
- // --------------------------------------------------------------------------------
4045
- function privExtractFileInOutput(&$p_entry, &$p_options)
4046
- {
4047
- $v_result=1;
4048
-
4049
- // ----- Read the file header
4050
- if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4051
- return $v_result;
4052
- }
4053
-
4054
-
4055
- // ----- Check that the file header is coherent with $p_entry info
4056
- if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4057
- // TBC
4058
- }
4059
-
4060
- // ----- Look for pre-extract callback
4061
- if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4062
-
4063
- // ----- Generate a local information
4064
- $v_local_header = array();
4065
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4066
-
4067
- // ----- Call the callback
4068
- // Here I do not use call_user_func() because I need to send a reference to the
4069
- // header.
4070
- // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4071
- $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4072
- if ($v_result == 0) {
4073
- // ----- Change the file status
4074
- $p_entry['status'] = "skipped";
4075
- $v_result = 1;
4076
- }
4077
-
4078
- // ----- Look for abort result
4079
- if ($v_result == 2) {
4080
- // ----- This status is internal and will be changed in 'skipped'
4081
- $p_entry['status'] = "aborted";
4082
- $v_result = PCLZIP_ERR_USER_ABORTED;
4083
- }
4084
-
4085
- // ----- Update the informations
4086
- // Only some fields can be modified
4087
- $p_entry['filename'] = $v_local_header['filename'];
4088
- }
4089
-
4090
- // ----- Trace
4091
-
4092
- // ----- Look if extraction should be done
4093
- if ($p_entry['status'] == 'ok') {
4094
-
4095
- // ----- Do the extraction (if not a folder)
4096
- if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4097
- // ----- Look for not compressed file
4098
- if ($p_entry['compressed_size'] == $p_entry['size']) {
4099
-
4100
- // ----- Read the file in a buffer (one shot)
4101
- $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4102
-
4103
- // ----- Send the file to the output
4104
- echo $v_buffer;
4105
- unset($v_buffer);
4106
- }
4107
- else {
4108
-
4109
- // ----- Read the compressed file in a buffer (one shot)
4110
- $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4111
-
4112
- // ----- Decompress the file
4113
- $v_file_content = gzinflate($v_buffer);
4114
- unset($v_buffer);
4115
-
4116
- // ----- Send the file to the output
4117
- echo $v_file_content;
4118
- unset($v_file_content);
4119
- }
4120
- }
4121
- }
4122
-
4123
- // ----- Change abort status
4124
- if ($p_entry['status'] == "aborted") {
4125
- $p_entry['status'] = "skipped";
4126
- }
4127
-
4128
- // ----- Look for post-extract callback
4129
- elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4130
-
4131
- // ----- Generate a local information
4132
- $v_local_header = array();
4133
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4134
-
4135
- // ----- Call the callback
4136
- // Here I do not use call_user_func() because I need to send a reference to the
4137
- // header.
4138
- // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4139
- $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4140
-
4141
- // ----- Look for abort result
4142
- if ($v_result == 2) {
4143
- $v_result = PCLZIP_ERR_USER_ABORTED;
4144
- }
4145
- }
4146
-
4147
- return $v_result;
4148
- }
4149
- // --------------------------------------------------------------------------------
4150
-
4151
- // --------------------------------------------------------------------------------
4152
- // Function : privExtractFileAsString()
4153
- // Description :
4154
- // Parameters :
4155
- // Return Values :
4156
- // --------------------------------------------------------------------------------
4157
- function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
4158
- {
4159
- $v_result=1;
4160
-
4161
- // ----- Read the file header
4162
- $v_header = array();
4163
- if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4164
- {
4165
- // ----- Return
4166
- return $v_result;
4167
- }
4168
-
4169
-
4170
- // ----- Check that the file header is coherent with $p_entry info
4171
- if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4172
- // TBC
4173
- }
4174
-
4175
- // ----- Look for pre-extract callback
4176
- if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4177
-
4178
- // ----- Generate a local information
4179
- $v_local_header = array();
4180
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4181
-
4182
- // ----- Call the callback
4183
- // Here I do not use call_user_func() because I need to send a reference to the
4184
- // header.
4185
- // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4186
- $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4187
- if ($v_result == 0) {
4188
- // ----- Change the file status
4189
- $p_entry['status'] = "skipped";
4190
- $v_result = 1;
4191
- }
4192
-
4193
- // ----- Look for abort result
4194
- if ($v_result == 2) {
4195
- // ----- This status is internal and will be changed in 'skipped'
4196
- $p_entry['status'] = "aborted";
4197
- $v_result = PCLZIP_ERR_USER_ABORTED;
4198
- }
4199
-
4200
- // ----- Update the informations
4201
- // Only some fields can be modified
4202
- $p_entry['filename'] = $v_local_header['filename'];
4203
- }
4204
-
4205
-
4206
- // ----- Look if extraction should be done
4207
- if ($p_entry['status'] == 'ok') {
4208
-
4209
- // ----- Do the extraction (if not a folder)
4210
- if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4211
- // ----- Look for not compressed file
4212
- // if ($p_entry['compressed_size'] == $p_entry['size'])
4213
- if ($p_entry['compression'] == 0) {
4214
-
4215
- // ----- Reading the file
4216
- $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4217
- }
4218
- else {
4219
-
4220
- // ----- Reading the file
4221
- $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4222
-
4223
- // ----- Decompress the file
4224
- if (($p_string = @gzinflate($v_data)) === FALSE) {
4225
- // TBC
4226
- }
4227
- }
4228
-
4229
- // ----- Trace
4230
- }
4231
- else {
4232
- // TBC : error : can not extract a folder in a string
4233
- }
4234
-
4235
- }
4236
-
4237
- // ----- Change abort status
4238
- if ($p_entry['status'] == "aborted") {
4239
- $p_entry['status'] = "skipped";
4240
- }
4241
-
4242
- // ----- Look for post-extract callback
4243
- elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4244
-
4245
- // ----- Generate a local information
4246
- $v_local_header = array();
4247
- $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4248
-
4249
- // ----- Swap the content to header
4250
- $v_local_header['content'] = $p_string;
4251
- $p_string = '';
4252
-
4253
- // ----- Call the callback
4254
- // Here I do not use call_user_func() because I need to send a reference to the
4255
- // header.
4256
- // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4257
- $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4258
-
4259
- // ----- Swap back the content to header
4260
- $p_string = $v_local_header['content'];
4261
- unset($v_local_header['content']);
4262
-
4263
- // ----- Look for abort result
4264
- if ($v_result == 2) {
4265
- $v_result = PCLZIP_ERR_USER_ABORTED;
4266
- }
4267
- }
4268
-
4269
- // ----- Return
4270
- return $v_result;
4271
- }
4272
- // --------------------------------------------------------------------------------
4273
-
4274
- // --------------------------------------------------------------------------------
4275
- // Function : privReadFileHeader()
4276
- // Description :
4277
- // Parameters :
4278
- // Return Values :
4279
- // --------------------------------------------------------------------------------
4280
- function privReadFileHeader(&$p_header)
4281
- {
4282
- $v_result=1;
4283
-
4284
- // ----- Read the 4 bytes signature
4285
- $v_binary_data = @fread($this->zip_fd, 4);
4286
- $v_data = unpack('Vid', $v_binary_data);
4287
-
4288
- // ----- Check signature
4289
- if ($v_data['id'] != 0x04034b50)
4290
- {
4291
-
4292
- // ----- Error log
4293
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4294
-
4295
- // ----- Return
4296
- return PclZip::errorCode();
4297
- }
4298
-
4299
- // ----- Read the first 42 bytes of the header
4300
- $v_binary_data = fread($this->zip_fd, 26);
4301
-
4302
- // ----- Look for invalid block size
4303
- if (strlen($v_binary_data) != 26)
4304
- {
4305
- $p_header['filename'] = "";
4306
- $p_header['status'] = "invalid_header";
4307
-
4308
- // ----- Error log
4309
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4310
-
4311
- // ----- Return
4312
- return PclZip::errorCode();
4313
- }
4314
-
4315
- // ----- Extract the values
4316
- $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4317
-
4318
- // ----- Get filename
4319
- $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4320
-
4321
- // ----- Get extra_fields
4322
- if ($v_data['extra_len'] != 0) {
4323
- $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4324
- }
4325
- else {
4326
- $p_header['extra'] = '';
4327
- }
4328
-
4329
- // ----- Extract properties
4330
- $p_header['version_extracted'] = $v_data['version'];
4331
- $p_header['compression'] = $v_data['compression'];
4332
- $p_header['size'] = $v_data['size'];
4333
- $p_header['compressed_size'] = $v_data['compressed_size'];
4334
- $p_header['crc'] = $v_data['crc'];
4335
- $p_header['flag'] = $v_data['flag'];
4336
- $p_header['filename_len'] = $v_data['filename_len'];
4337
-
4338
- // ----- Recuperate date in UNIX format
4339
- $p_header['mdate'] = $v_data['mdate'];
4340
- $p_header['mtime'] = $v_data['mtime'];
4341
- if ($p_header['mdate'] && $p_header['mtime'])
4342
- {
4343
- // ----- Extract time
4344
- $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4345
- $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4346
- $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4347
-
4348
- // ----- Extract date
4349
- $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4350
- $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4351
- $v_day = $p_header['mdate'] & 0x001F;
4352
-
4353
- // ----- Get UNIX date format
4354
- $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4355
-
4356
- }
4357
- else
4358
- {
4359
- $p_header['mtime'] = time();
4360
- }
4361
-
4362
- // TBC
4363
- //for(reset($v_data); $key = key($v_data); next($v_data)) {
4364
- //}
4365
-
4366
- // ----- Set the stored filename
4367
- $p_header['stored_filename'] = $p_header['filename'];
4368
-
4369
- // ----- Set the status field
4370
- $p_header['status'] = "ok";
4371
-
4372
- // ----- Return
4373
- return $v_result;
4374
- }
4375
- // --------------------------------------------------------------------------------
4376
-
4377
- // --------------------------------------------------------------------------------
4378
- // Function : privReadCentralFileHeader()
4379
- // Description :
4380
- // Parameters :
4381
- // Return Values :
4382
- // --------------------------------------------------------------------------------
4383
- function privReadCentralFileHeader(&$p_header)
4384
- {
4385
- $v_result=1;
4386
-
4387
- // ----- Read the 4 bytes signature
4388
- $v_binary_data = @fread($this->zip_fd, 4);
4389
- $v_data = unpack('Vid', $v_binary_data);
4390
-
4391
- // ----- Check signature
4392
- if ($v_data['id'] != 0x02014b50)
4393
- {
4394
-
4395
- // ----- Error log
4396
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4397
-
4398
- // ----- Return
4399
- return PclZip::errorCode();
4400
- }
4401
-
4402
- // ----- Read the first 42 bytes of the header
4403
- $v_binary_data = fread($this->zip_fd, 42);
4404
-
4405
- // ----- Look for invalid block size
4406
- if (strlen($v_binary_data) != 42)
4407
- {
4408
- $p_header['filename'] = "";
4409
- $p_header['status'] = "invalid_header";
4410
-
4411
- // ----- Error log
4412
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4413
-
4414
- // ----- Return
4415
- return PclZip::errorCode();
4416
- }
4417
-
4418
- // ----- Extract the values
4419
- $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
4420
-
4421
- // ----- Get filename
4422
- if ($p_header['filename_len'] != 0)
4423
- $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4424
- else
4425
- $p_header['filename'] = '';
4426
-
4427
- // ----- Get extra
4428
- if ($p_header['extra_len'] != 0)
4429
- $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4430
- else
4431
- $p_header['extra'] = '';
4432
-
4433
- // ----- Get comment
4434
- if ($p_header['comment_len'] != 0)
4435
- $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4436
- else
4437
- $p_header['comment'] = '';
4438
-
4439
- // ----- Extract properties
4440
-
4441
- // ----- Recuperate date in UNIX format
4442
- //if ($p_header['mdate'] && $p_header['mtime'])
4443
- // TBC : bug : this was ignoring time with 0/0/0
4444
- if (1)
4445
- {
4446
- // ----- Extract time
4447
- $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4448
- $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4449
- $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4450
-
4451
- // ----- Extract date
4452
- $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4453
- $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4454
- $v_day = $p_header['mdate'] & 0x001F;
4455
-
4456
- // ----- Get UNIX date format
4457
- $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4458
-
4459
- }
4460
- else
4461
- {
4462
- $p_header['mtime'] = time();
4463
- }
4464
-
4465
- // ----- Set the stored filename
4466
- $p_header['stored_filename'] = $p_header['filename'];
4467
-
4468
- // ----- Set default status to ok
4469
- $p_header['status'] = 'ok';
4470
-
4471
- // ----- Look if it is a directory
4472
- if (substr($p_header['filename'], -1) == '/') {
4473
- //$p_header['external'] = 0x41FF0010;
4474
- $p_header['external'] = 0x00000010;
4475
- }
4476
-
4477
-
4478
- // ----- Return
4479
- return $v_result;
4480
- }
4481
- // --------------------------------------------------------------------------------
4482
-
4483
- // --------------------------------------------------------------------------------
4484
- // Function : privCheckFileHeaders()
4485
- // Description :
4486
- // Parameters :
4487
- // Return Values :
4488
- // 1 on success,
4489
- // 0 on error;
4490
- // --------------------------------------------------------------------------------
4491
- function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4492
- {
4493
- $v_result=1;
4494
-
4495
- // ----- Check the static values
4496
- // TBC
4497
- if ($p_local_header['filename'] != $p_central_header['filename']) {
4498
- }
4499
- if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4500
- }
4501
- if ($p_local_header['flag'] != $p_central_header['flag']) {
4502
- }
4503
- if ($p_local_header['compression'] != $p_central_header['compression']) {
4504
- }
4505
- if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4506
- }
4507
- if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4508
- }
4509
-
4510
- // ----- Look for flag bit 3
4511
- if (($p_local_header['flag'] & 8) == 8) {
4512
- $p_local_header['size'] = $p_central_header['size'];
4513
- $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4514
- $p_local_header['crc'] = $p_central_header['crc'];
4515
- }
4516
-
4517
- // ----- Return
4518
- return $v_result;
4519
- }
4520
- // --------------------------------------------------------------------------------
4521
-
4522
- // --------------------------------------------------------------------------------
4523
- // Function : privReadEndCentralDir()
4524
- // Description :
4525
- // Parameters :
4526
- // Return Values :
4527
- // --------------------------------------------------------------------------------
4528
- function privReadEndCentralDir(&$p_central_dir)
4529
- {
4530
- $v_result=1;
4531
-
4532
- // ----- Go to the end of the zip file
4533
- $v_size = filesize($this->zipname);
4534
- @fseek($this->zip_fd, $v_size);
4535
- if (@ftell($this->zip_fd) != $v_size)
4536
- {
4537
- // ----- Error log
4538
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4539
-
4540
- // ----- Return
4541
- return PclZip::errorCode();
4542
- }
4543
-
4544
- // ----- First try : look if this is an archive with no commentaries (most of the time)
4545
- // in this case the end of central dir is at 22 bytes of the file end
4546
- $v_found = 0;
4547
- if ($v_size > 26) {
4548
- @fseek($this->zip_fd, $v_size-22);
4549
- if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4550
- {
4551
- // ----- Error log
4552
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4553
-
4554
- // ----- Return
4555
- return PclZip::errorCode();
4556
- }
4557
-
4558
- // ----- Read for bytes
4559
- $v_binary_data = @fread($this->zip_fd, 4);
4560
- $v_data = @unpack('Vid', $v_binary_data);
4561
-
4562
- // ----- Check signature
4563
- if ($v_data['id'] == 0x06054b50) {
4564
- $v_found = 1;
4565
- }
4566
-
4567
- $v_pos = ftell($this->zip_fd);
4568
- }
4569
-
4570
- // ----- Go back to the maximum possible size of the Central Dir End Record
4571
- if (!$v_found) {
4572
- $v_maximum_size = 65557; // 0xFFFF + 22;
4573
- if ($v_maximum_size > $v_size)
4574
- $v_maximum_size = $v_size;
4575
- @fseek($this->zip_fd, $v_size-$v_maximum_size);
4576
- if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4577
- {
4578
- // ----- Error log
4579
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4580
-
4581
- // ----- Return
4582
- return PclZip::errorCode();
4583
- }
4584
-
4585
- // ----- Read byte per byte in order to find the signature
4586
- $v_pos = ftell($this->zip_fd);
4587
- $v_bytes = 0x00000000;
4588
- while ($v_pos < $v_size)
4589
- {
4590
- // ----- Read a byte
4591
- $v_byte = @fread($this->zip_fd, 1);
4592
-
4593
- // ----- Add the byte
4594
- //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4595
- // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4596
- // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4597
- $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4598
-
4599
- // ----- Compare the bytes
4600
- if ($v_bytes == 0x504b0506)
4601
- {
4602
- $v_pos++;
4603
- break;
4604
- }
4605
-
4606
- $v_pos++;
4607
- }
4608
-
4609
- // ----- Look if not found end of central dir
4610
- if ($v_pos == $v_size)
4611
- {
4612
-
4613
- // ----- Error log
4614
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4615
-
4616
- // ----- Return
4617
- return PclZip::errorCode();
4618
- }
4619
- }
4620
-
4621
- // ----- Read the first 18 bytes of the header
4622
- $v_binary_data = fread($this->zip_fd, 18);
4623
-
4624
- // ----- Look for invalid block size
4625
- if (strlen($v_binary_data) != 18)
4626
- {
4627
-
4628
- // ----- Error log
4629
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4630
-
4631
- // ----- Return
4632
- return PclZip::errorCode();
4633
- }
4634
-
4635
- // ----- Extract the values
4636
- $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4637
-
4638
- // ----- Check the global size
4639
- if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4640
-
4641
- // ----- Removed in release 2.2 see readme file
4642
- // The check of the file size is a little too strict.
4643
- // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4644
- // While decrypted, zip has training 0 bytes
4645
- if (0) {
4646
- // ----- Error log
4647
- PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4648
- 'The central dir is not at the end of the archive.'
4649
- .' Some trailing bytes exists after the archive.');
4650
-
4651
- // ----- Return
4652
- return PclZip::errorCode();
4653
- }
4654
- }
4655
-
4656
- // ----- Get comment
4657
- if ($v_data['comment_size'] != 0) {
4658
- $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4659
- }
4660
- else
4661
- $p_central_dir['comment'] = '';
4662
-
4663
- $p_central_dir['entries'] = $v_data['entries'];
4664
- $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4665
- $p_central_dir['offset'] = $v_data['offset'];
4666
- $p_central_dir['size'] = $v_data['size'];
4667
- $p_central_dir['disk'] = $v_data['disk'];
4668
- $p_central_dir['disk_start'] = $v_data['disk_start'];
4669
-
4670
- // TBC
4671
- //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4672
- //}
4673
-
4674
- // ----- Return
4675
- return $v_result;
4676
- }
4677
- // --------------------------------------------------------------------------------
4678
-
4679
- // --------------------------------------------------------------------------------
4680
- // Function : privDeleteByRule()
4681
- // Description :
4682
- // Parameters :
4683
- // Return Values :
4684
- // --------------------------------------------------------------------------------
4685
- function privDeleteByRule(&$p_result_list, &$p_options)
4686
- {
4687
- $v_result=1;
4688
- $v_list_detail = array();
4689
-
4690
- // ----- Open the zip file
4691
- if (($v_result=$this->privOpenFd('rb')) != 1)
4692
- {
4693
- // ----- Return
4694
- return $v_result;
4695
- }
4696
-
4697
- // ----- Read the central directory informations
4698
- $v_central_dir = array();
4699
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4700
- {
4701
- $this->privCloseFd();
4702
- return $v_result;
4703
- }
4704
-
4705
- // ----- Go to beginning of File
4706
- @rewind($this->zip_fd);
4707
-
4708
- // ----- Scan all the files
4709
- // ----- Start at beginning of Central Dir
4710
- $v_pos_entry = $v_central_dir['offset'];
4711
- @rewind($this->zip_fd);
4712
- if (@fseek($this->zip_fd, $v_pos_entry))
4713
- {
4714
- // ----- Close the zip file
4715
- $this->privCloseFd();
4716
-
4717
- // ----- Error log
4718
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4719
-
4720
- // ----- Return
4721
- return PclZip::errorCode();
4722
- }
4723
-
4724
- // ----- Read each entry
4725
- $v_header_list = array();
4726
- $j_start = 0;
4727
- for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4728
- {
4729
-
4730
- // ----- Read the file header
4731
- $v_header_list[$v_nb_extracted] = array();
4732
- if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4733
- {
4734
- // ----- Close the zip file
4735
- $this->privCloseFd();
4736
-
4737
- return $v_result;
4738
- }
4739
-
4740
-
4741
- // ----- Store the index
4742
- $v_header_list[$v_nb_extracted]['index'] = $i;
4743
-
4744
- // ----- Look for the specific extract rules
4745
- $v_found = false;
4746
-
4747
- // ----- Look for extract by name rule
4748
- if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
4749
- && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4750
-
4751
- // ----- Look if the filename is in the list
4752
- for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4753
-
4754
- // ----- Look for a directory
4755
- if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4756
-
4757
- // ----- Look if the directory is in the filename path
4758
- if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4759
- && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4760
- $v_found = true;
4761
- }
4762
- elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4763
- && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4764
- $v_found = true;
4765
- }
4766
- }
4767
- // ----- Look for a filename
4768
- elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4769
- $v_found = true;
4770
- }
4771
- }
4772
- }
4773
-
4774
- // ----- Look for extract by ereg rule
4775
- // ereg() is deprecated with PHP 5.3
4776
- /*
4777
- else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
4778
- && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4779
-
4780
- if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4781
- $v_found = true;
4782
- }
4783
- }
4784
- */
4785
-
4786
- // ----- Look for extract by preg rule
4787
- else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
4788
- && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4789
-
4790
- if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4791
- $v_found = true;
4792
- }
4793
- }
4794
-
4795
- // ----- Look for extract by index rule
4796
- else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4797
- && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4798
-
4799
- // ----- Look if the index is in the list
4800
- for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4801
-
4802
- if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4803
- $v_found = true;
4804
- }
4805
- if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4806
- $j_start = $j+1;
4807
- }
4808
-
4809
- if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4810
- break;
4811
- }
4812
- }
4813
- }
4814
- else {
4815
- $v_found = true;
4816
- }
4817
-
4818
- // ----- Look for deletion
4819
- if ($v_found)
4820
- {
4821
- unset($v_header_list[$v_nb_extracted]);
4822
- }
4823
- else
4824
- {
4825
- $v_nb_extracted++;
4826
- }
4827
- }
4828
-
4829
- // ----- Look if something need to be deleted
4830
- if ($v_nb_extracted > 0) {
4831
-
4832
- // ----- Creates a temporay file
4833
- $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4834
-
4835
- // ----- Creates a temporary zip archive
4836
- $v_temp_zip = new PclZip($v_zip_temp_name);
4837
-
4838
- // ----- Open the temporary zip file in write mode
4839
- if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4840
- $this->privCloseFd();
4841
-
4842
- // ----- Return
4843
- return $v_result;
4844
- }
4845
-
4846
- // ----- Look which file need to be kept
4847
- for ($i=0; $i<sizeof($v_header_list); $i++) {
4848
-
4849
- // ----- Calculate the position of the header
4850
- @rewind($this->zip_fd);
4851
- if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4852
- // ----- Close the zip file
4853
- $this->privCloseFd();
4854
- $v_temp_zip->privCloseFd();
4855
- @unlink($v_zip_temp_name);
4856
-
4857
- // ----- Error log
4858
- PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4859
-
4860
- // ----- Return
4861
- return PclZip::errorCode();
4862
- }
4863
-
4864
- // ----- Read the file header
4865
- $v_local_header = array();
4866
- if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4867
- // ----- Close the zip file
4868
- $this->privCloseFd();
4869
- $v_temp_zip->privCloseFd();
4870
- @unlink($v_zip_temp_name);
4871
-
4872
- // ----- Return
4873
- return $v_result;
4874
- }
4875
-
4876
- // ----- Check that local file header is same as central file header
4877
- if ($this->privCheckFileHeaders($v_local_header,
4878
- $v_header_list[$i]) != 1) {
4879
- // TBC
4880
- }
4881
- unset($v_local_header);
4882
-
4883
- // ----- Write the file header
4884
- if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4885
- // ----- Close the zip file
4886
- $this->privCloseFd();
4887
- $v_temp_zip->privCloseFd();
4888
- @unlink($v_zip_temp_name);
4889
-
4890
- // ----- Return
4891
- return $v_result;
4892
- }
4893
-
4894
- // ----- Read/write the data block
4895
- if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4896
- // ----- Close the zip file
4897
- $this->privCloseFd();
4898
- $v_temp_zip->privCloseFd();
4899
- @unlink($v_zip_temp_name);
4900
-
4901
- // ----- Return
4902
- return $v_result;
4903
- }
4904
- }
4905
-
4906
- // ----- Store the offset of the central dir
4907
- $v_offset = @ftell($v_temp_zip->zip_fd);
4908
-
4909
- // ----- Re-Create the Central Dir files header
4910
- for ($i=0; $i<sizeof($v_header_list); $i++) {
4911
- // ----- Create the file header
4912
- if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4913
- $v_temp_zip->privCloseFd();
4914
- $this->privCloseFd();
4915
- @unlink($v_zip_temp_name);
4916
-
4917
- // ----- Return
4918
- return $v_result;
4919
- }
4920
-
4921
- // ----- Transform the header to a 'usable' info
4922
- $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4923
- }
4924
-
4925
-
4926
- // ----- Zip file comment
4927
- $v_comment = '';
4928
- if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4929
- $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4930
- }
4931
-
4932
- // ----- Calculate the size of the central header
4933
- $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4934
-
4935
- // ----- Create the central dir footer
4936
- if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4937
- // ----- Reset the file list
4938
- unset($v_header_list);
4939
- $v_temp_zip->privCloseFd();
4940
- $this->privCloseFd();
4941
- @unlink($v_zip_temp_name);
4942
-
4943
- // ----- Return
4944
- return $v_result;
4945
- }
4946
-
4947
- // ----- Close
4948
- $v_temp_zip->privCloseFd();
4949
- $this->privCloseFd();
4950
-
4951
- // ----- Delete the zip file
4952
- // TBC : I should test the result ...
4953
- @unlink($this->zipname);
4954
-
4955
- // ----- Rename the temporary file
4956
- // TBC : I should test the result ...
4957
- //@rename($v_zip_temp_name, $this->zipname);
4958
- PclZipUtilRename($v_zip_temp_name, $this->zipname);
4959
-
4960
- // ----- Destroy the temporary archive
4961
- unset($v_temp_zip);
4962
- }
4963
-
4964
- // ----- Remove every files : reset the file
4965
- else if ($v_central_dir['entries'] != 0) {
4966
- $this->privCloseFd();
4967
-
4968
- if (($v_result = $this->privOpenFd('wb')) != 1) {
4969
- return $v_result;
4970
- }
4971
-
4972
- if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4973
- return $v_result;
4974
- }
4975
-
4976
- $this->privCloseFd();
4977
- }
4978
-
4979
- // ----- Return
4980
- return $v_result;
4981
- }
4982
- // --------------------------------------------------------------------------------
4983
-
4984
- // --------------------------------------------------------------------------------
4985
- // Function : privDirCheck()
4986
- // Description :
4987
- // Check if a directory exists, if not it creates it and all the parents directory
4988
- // which may be useful.
4989
- // Parameters :
4990
- // $p_dir : Directory path to check.
4991
- // Return Values :
4992
- // 1 : OK
4993
- // -1 : Unable to create directory
4994
- // --------------------------------------------------------------------------------
4995
- function privDirCheck($p_dir, $p_is_dir=false)
4996
- {
4997
- $v_result = 1;
4998
-
4999
-
5000
- // ----- Remove the final '/'
5001
- if (($p_is_dir) && (substr($p_dir, -1)=='/'))
5002
- {
5003
- $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5004
- }
5005
-
5006
- // ----- Check the directory availability
5007
- if ((is_dir($p_dir)) || ($p_dir == ""))
5008
- {
5009
- return 1;
5010
- }
5011
-
5012
- // ----- Extract parent directory
5013
- $p_parent_dir = dirname($p_dir);
5014
-
5015
- // ----- Just a check
5016
- if ($p_parent_dir != $p_dir)
5017
- {
5018
- // ----- Look for parent directory
5019
- if ($p_parent_dir != "")
5020
- {
5021
- if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5022
- {
5023
- return $v_result;
5024
- }
5025
- }
5026
- }
5027
-
5028
- // ----- Create the directory
5029
- if (!@mkdir($p_dir, 0777))
5030
- {
5031
- // ----- Error log
5032
- PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5033
-
5034
- // ----- Return
5035
- return PclZip::errorCode();
5036
- }
5037
-
5038
- // ----- Return
5039
- return $v_result;
5040
- }
5041
- // --------------------------------------------------------------------------------
5042
-
5043
- // --------------------------------------------------------------------------------
5044
- // Function : privMerge()
5045
- // Description :
5046
- // If $p_archive_to_add does not exist, the function exit with a success result.
5047
- // Parameters :
5048
- // Return Values :
5049
- // --------------------------------------------------------------------------------
5050
- function privMerge(&$p_archive_to_add)
5051
- {
5052
- $v_result=1;
5053
-
5054
- // ----- Look if the archive_to_add exists
5055
- if (!is_file($p_archive_to_add->zipname))
5056
- {
5057
-
5058
- // ----- Nothing to merge, so merge is a success
5059
- $v_result = 1;
5060
-
5061
- // ----- Return
5062
- return $v_result;
5063
- }
5064
-
5065
- // ----- Look if the archive exists
5066
- if (!is_file($this->zipname))
5067
- {
5068
-
5069
- // ----- Do a duplicate
5070
- $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5071
-
5072
- // ----- Return
5073
- return $v_result;
5074
- }
5075
-
5076
- // ----- Open the zip file
5077
- if (($v_result=$this->privOpenFd('rb')) != 1)
5078
- {
5079
- // ----- Return
5080
- return $v_result;
5081
- }
5082
-
5083
- // ----- Read the central directory informations
5084
- $v_central_dir = array();
5085
- if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5086
- {
5087
- $this->privCloseFd();
5088
- return $v_result;
5089
- }
5090
-
5091
- // ----- Go to beginning of File
5092
- @rewind($this->zip_fd);
5093
-
5094
- // ----- Open the archive_to_add file
5095
- if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5096
- {
5097
- $this->privCloseFd();
5098
-
5099
- // ----- Return
5100
- return $v_result;
5101
- }
5102
-
5103
- // ----- Read the central directory informations
5104
- $v_central_dir_to_add = array();
5105
- if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5106
- {
5107
- $this->privCloseFd();
5108
- $p_archive_to_add->privCloseFd();
5109
-
5110
- return $v_result;
5111
- }
5112
-
5113
- // ----- Go to beginning of File
5114
- @rewind($p_archive_to_add->zip_fd);
5115
-
5116
- // ----- Creates a temporay file
5117
- $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5118
-
5119
- // ----- Open the temporary file in write mode
5120
- if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5121
- {
5122
- $this->privCloseFd();
5123
- $p_archive_to_add->privCloseFd();
5124
-
5125
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5126
-
5127
- // ----- Return
5128
- return PclZip::errorCode();
5129
- }
5130
-
5131
- // ----- Copy the files from the archive to the temporary file
5132
- // TBC : Here I should better append the file and go back to erase the central dir
5133
- $v_size = $v_central_dir['offset'];
5134
- while ($v_size != 0)
5135
- {
5136
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5137
- $v_buffer = fread($this->zip_fd, $v_read_size);
5138
- @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5139
- $v_size -= $v_read_size;
5140
- }
5141
-
5142
- // ----- Copy the files from the archive_to_add into the temporary file
5143
- $v_size = $v_central_dir_to_add['offset'];
5144
- while ($v_size != 0)
5145
- {
5146
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5147
- $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5148
- @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5149
- $v_size -= $v_read_size;
5150
- }
5151
-
5152
- // ----- Store the offset of the central dir
5153
- $v_offset = @ftell($v_zip_temp_fd);
5154
-
5155
- // ----- Copy the block of file headers from the old archive
5156
- $v_size = $v_central_dir['size'];
5157
- while ($v_size != 0)
5158
- {
5159
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5160
- $v_buffer = @fread($this->zip_fd, $v_read_size);
5161
- @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5162
- $v_size -= $v_read_size;
5163
- }
5164
-
5165
- // ----- Copy the block of file headers from the archive_to_add
5166
- $v_size = $v_central_dir_to_add['size'];
5167
- while ($v_size != 0)
5168
- {
5169
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5170
- $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5171
- @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5172
- $v_size -= $v_read_size;
5173
- }
5174
-
5175
- // ----- Merge the file comments
5176
- $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5177
-
5178
- // ----- Calculate the size of the (new) central header
5179
- $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5180
-
5181
- // ----- Swap the file descriptor
5182
- // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5183
- // the following methods on the temporary fil and not the real archive fd
5184
- $v_swap = $this->zip_fd;
5185
- $this->zip_fd = $v_zip_temp_fd;
5186
- $v_zip_temp_fd = $v_swap;
5187
-
5188
- // ----- Create the central dir footer
5189
- if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5190
- {
5191
- $this->privCloseFd();
5192
- $p_archive_to_add->privCloseFd();
5193
- @fclose($v_zip_temp_fd);
5194
- $this->zip_fd = null;
5195
-
5196
- // ----- Reset the file list
5197
- unset($v_header_list);
5198
-
5199
- // ----- Return
5200
- return $v_result;
5201
- }
5202
-
5203
- // ----- Swap back the file descriptor
5204
- $v_swap = $this->zip_fd;
5205
- $this->zip_fd = $v_zip_temp_fd;
5206
- $v_zip_temp_fd = $v_swap;
5207
-
5208
- // ----- Close
5209
- $this->privCloseFd();
5210
- $p_archive_to_add->privCloseFd();
5211
-
5212
- // ----- Close the temporary file
5213
- @fclose($v_zip_temp_fd);
5214
-
5215
- // ----- Delete the zip file
5216
- // TBC : I should test the result ...
5217
- @unlink($this->zipname);
5218
-
5219
- // ----- Rename the temporary file
5220
- // TBC : I should test the result ...
5221
- //@rename($v_zip_temp_name, $this->zipname);
5222
- PclZipUtilRename($v_zip_temp_name, $this->zipname);
5223
-
5224
- // ----- Return
5225
- return $v_result;
5226
- }
5227
- // --------------------------------------------------------------------------------
5228
-
5229
- // --------------------------------------------------------------------------------
5230
- // Function : privDuplicate()
5231
- // Description :
5232
- // Parameters :
5233
- // Return Values :
5234
- // --------------------------------------------------------------------------------
5235
- function privDuplicate($p_archive_filename)
5236
- {
5237
- $v_result=1;
5238
-
5239
- // ----- Look if the $p_archive_filename exists
5240
- if (!is_file($p_archive_filename))
5241
- {
5242
-
5243
- // ----- Nothing to duplicate, so duplicate is a success.
5244
- $v_result = 1;
5245
-
5246
- // ----- Return
5247
- return $v_result;
5248
- }
5249
-
5250
- // ----- Open the zip file
5251
- if (($v_result=$this->privOpenFd('wb')) != 1)
5252
- {
5253
- // ----- Return
5254
- return $v_result;
5255
- }
5256
-
5257
- // ----- Open the temporary file in write mode
5258
- if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5259
- {
5260
- $this->privCloseFd();
5261
-
5262
- PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5263
-
5264
- // ----- Return
5265
- return PclZip::errorCode();
5266
- }
5267
-
5268
- // ----- Copy the files from the archive to the temporary file
5269
- // TBC : Here I should better append the file and go back to erase the central dir
5270
- $v_size = filesize($p_archive_filename);
5271
- while ($v_size != 0)
5272
- {
5273
- $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5274
- $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5275
- @fwrite($this->zip_fd, $v_buffer, $v_read_size);
5276
- $v_size -= $v_read_size;
5277
- }
5278
-
5279
- // ----- Close
5280
- $this->privCloseFd();
5281
-
5282
- // ----- Close the temporary file
5283
- @fclose($v_zip_temp_fd);
5284
-
5285
- // ----- Return
5286
- return $v_result;
5287
- }
5288
- // --------------------------------------------------------------------------------
5289
-
5290
- // --------------------------------------------------------------------------------
5291
- // Function : privErrorLog()
5292
- // Description :
5293
- // Parameters :
5294
- // --------------------------------------------------------------------------------
5295
- function privErrorLog($p_error_code=0, $p_error_string='')
5296
- {
5297
- if (PCLZIP_ERROR_EXTERNAL == 1) {
5298
- PclError($p_error_code, $p_error_string);
5299
- }
5300
- else {
5301
- $this->error_code = $p_error_code;
5302
- $this->error_string = $p_error_string;
5303
- }
5304
- }
5305
- // --------------------------------------------------------------------------------
5306
-
5307
- // --------------------------------------------------------------------------------
5308
- // Function : privErrorReset()
5309
- // Description :
5310
- // Parameters :
5311
- // --------------------------------------------------------------------------------
5312
- function privErrorReset()
5313
- {
5314
- if (PCLZIP_ERROR_EXTERNAL == 1) {
5315
- PclErrorReset();
5316
- }
5317
- else {
5318
- $this->error_code = 0;
5319
- $this->error_string = '';
5320
- }
5321
- }
5322
- // --------------------------------------------------------------------------------
5323
-
5324
- // --------------------------------------------------------------------------------
5325
- // Function : privDisableMagicQuotes()
5326
- // Description :
5327
- // Parameters :
5328
- // Return Values :
5329
- // --------------------------------------------------------------------------------
5330
- function privDisableMagicQuotes()
5331
- {
5332
- $v_result=1;
5333
-
5334
- // ----- Look if function exists
5335
- if ( (!function_exists("get_magic_quotes_runtime"))
5336
- || (!function_exists("set_magic_quotes_runtime"))) {
5337
- return $v_result;
5338
- }
5339
-
5340
- // ----- Look if already done
5341
- if ($this->magic_quotes_status != -1) {
5342
- return $v_result;
5343
- }
5344
-
5345
- // ----- Get and memorize the magic_quote value
5346
- $this->magic_quotes_status = @get_magic_quotes_runtime();
5347
-
5348
- // ----- Disable magic_quotes
5349
- if ($this->magic_quotes_status == 1) {
5350
- @set_magic_quotes_runtime(0);
5351
- }
5352
-
5353
- // ----- Return
5354
- return $v_result;
5355
- }
5356
- // --------------------------------------------------------------------------------
5357
-
5358
- // --------------------------------------------------------------------------------
5359
- // Function : privSwapBackMagicQuotes()
5360
- // Description :
5361
- // Parameters :
5362
- // Return Values :
5363
- // --------------------------------------------------------------------------------
5364
- function privSwapBackMagicQuotes()
5365
- {
5366
- $v_result=1;
5367
-
5368
- // ----- Look if function exists
5369
- if ( (!function_exists("get_magic_quotes_runtime"))
5370
- || (!function_exists("set_magic_quotes_runtime"))) {
5371
- return $v_result;
5372
- }
5373
-
5374
- // ----- Look if something to do
5375
- if ($this->magic_quotes_status != -1) {
5376
- return $v_result;
5377
- }
5378
-
5379
- // ----- Swap back magic_quotes
5380
- if ($this->magic_quotes_status == 1) {
5381
- @set_magic_quotes_runtime($this->magic_quotes_status);
5382
- }
5383
-
5384
- // ----- Return
5385
- return $v_result;
5386
- }
5387
- // --------------------------------------------------------------------------------
5388
-
5389
- }
5390
- // End of class
5391
- // --------------------------------------------------------------------------------
5392
-
5393
- // --------------------------------------------------------------------------------
5394
- // Function : PclZipUtilPathReduction()
5395
- // Description :
5396
- // Parameters :
5397
- // Return Values :
5398
- // --------------------------------------------------------------------------------
5399
- function PclZipUtilPathReduction($p_dir)
5400
- {
5401
- $v_result = "";
5402
-
5403
- // ----- Look for not empty path
5404
- if ($p_dir != "") {
5405
- // ----- Explode path by directory names
5406
- $v_list = explode("/", $p_dir);
5407
-
5408
- // ----- Study directories from last to first
5409
- $v_skip = 0;
5410
- for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5411
- // ----- Look for current path
5412
- if ($v_list[$i] == ".") {
5413
- // ----- Ignore this directory
5414
- // Should be the first $i=0, but no check is done
5415
- }
5416
- else if ($v_list[$i] == "..") {
5417
- $v_skip++;
5418
- }
5419
- else if ($v_list[$i] == "") {
5420
- // ----- First '/' i.e. root slash
5421
- if ($i == 0) {
5422
- $v_result = "/".$v_result;
5423
- if ($v_skip > 0) {
5424
- // ----- It is an invalid path, so the path is not modified
5425
- // TBC
5426
- $v_result = $p_dir;
5427
- $v_skip = 0;
5428
- }
5429
- }
5430
- // ----- Last '/' i.e. indicates a directory
5431
- else if ($i == (sizeof($v_list)-1)) {
5432
- $v_result = $v_list[$i];
5433
- }
5434
- // ----- Double '/' inside the path
5435
- else {
5436
- // ----- Ignore only the double '//' in path,
5437
- // but not the first and last '/'
5438
- }
5439
- }
5440
- else {
5441
- // ----- Look for item to skip
5442
- if ($v_skip > 0) {
5443
- $v_skip--;
5444
- }
5445
- else {
5446
- $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5447
- }
5448
- }
5449
- }
5450
-
5451
- // ----- Look for skip
5452
- if ($v_skip > 0) {
5453
- while ($v_skip > 0) {
5454
- $v_result = '../'.$v_result;
5455
- $v_skip--;
5456
- }
5457
- }
5458
- }
5459
-
5460
- // ----- Return
5461
- return $v_result;
5462
- }
5463
- // --------------------------------------------------------------------------------
5464
-
5465
- // --------------------------------------------------------------------------------
5466
- // Function : PclZipUtilPathInclusion()
5467
- // Description :
5468
- // This function indicates if the path $p_path is under the $p_dir tree. Or,
5469
- // said in an other way, if the file or sub-dir $p_path is inside the dir
5470
- // $p_dir.
5471
- // The function indicates also if the path is exactly the same as the dir.
5472
- // This function supports path with duplicated '/' like '//', but does not
5473
- // support '.' or '..' statements.
5474
- // Parameters :
5475
- // Return Values :
5476
- // 0 if $p_path is not inside directory $p_dir
5477
- // 1 if $p_path is inside directory $p_dir
5478
- // 2 if $p_path is exactly the same as $p_dir
5479
- // --------------------------------------------------------------------------------
5480
- function PclZipUtilPathInclusion($p_dir, $p_path)
5481
- {
5482
- $v_result = 1;
5483
-
5484
- // ----- Look for path beginning by ./
5485
- if ( ($p_dir == '.')
5486
- || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5487
- $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5488
- }
5489
- if ( ($p_path == '.')
5490
- || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5491
- $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5492
- }
5493
-
5494
- // ----- Explode dir and path by directory separator
5495
- $v_list_dir = explode("/", $p_dir);
5496
- $v_list_dir_size = sizeof($v_list_dir);
5497
- $v_list_path = explode("/", $p_path);
5498
- $v_list_path_size = sizeof($v_list_path);
5499
-
5500
- // ----- Study directories paths
5501
- $i = 0;
5502
- $j = 0;
5503
- while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5504
-
5505
- // ----- Look for empty dir (path reduction)
5506
- if ($v_list_dir[$i] == '') {
5507
- $i++;
5508
- continue;
5509
- }
5510
- if ($v_list_path[$j] == '') {
5511
- $j++;
5512
- continue;
5513
- }
5514
-
5515
- // ----- Compare the items
5516
- if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
5517
- $v_result = 0;
5518
- }
5519
-
5520
- // ----- Next items
5521
- $i++;
5522
- $j++;
5523
- }
5524
-
5525
- // ----- Look if everything seems to be the same
5526
- if ($v_result) {
5527
- // ----- Skip all the empty items
5528
- while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5529
- while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5530
-
5531
- if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5532
- // ----- There are exactly the same
5533
- $v_result = 2;
5534
- }
5535
- else if ($i < $v_list_dir_size) {
5536
- // ----- The path is shorter than the dir
5537
- $v_result = 0;
5538
- }
5539
- }
5540
-
5541
- // ----- Return
5542
- return $v_result;
5543
- }
5544
- // --------------------------------------------------------------------------------
5545
-
5546
- // --------------------------------------------------------------------------------
5547
- // Function : PclZipUtilCopyBlock()
5548
- // Description :
5549
- // Parameters :
5550
- // $p_mode : read/write compression mode
5551
- // 0 : src & dest normal
5552
- // 1 : src gzip, dest normal
5553
- // 2 : src normal, dest gzip
5554
- // 3 : src & dest gzip
5555
- // Return Values :
5556
- // --------------------------------------------------------------------------------
5557
- function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5558
- {
5559
- $v_result = 1;
5560
-
5561
- if ($p_mode==0)
5562
- {
5563
- while ($p_size != 0)
5564
- {
5565
- $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5566
- $v_buffer = @fread($p_src, $v_read_size);
5567
- @fwrite($p_dest, $v_buffer, $v_read_size);
5568
- $p_size -= $v_read_size;
5569
- }
5570
- }
5571
- else if ($p_mode==1)
5572
- {
5573
- while ($p_size != 0)
5574
- {
5575
- $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5576
- $v_buffer = @gzread($p_src, $v_read_size);
5577
- @fwrite($p_dest, $v_buffer, $v_read_size);
5578
- $p_size -= $v_read_size;
5579
- }
5580
- }
5581
- else if ($p_mode==2)
5582
- {
5583
- while ($p_size != 0)
5584
- {
5585
- $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5586
- $v_buffer = @fread($p_src, $v_read_size);
5587
- @gzwrite($p_dest, $v_buffer, $v_read_size);
5588
- $p_size -= $v_read_size;
5589
- }
5590
- }
5591
- else if ($p_mode==3)
5592
- {
5593
- while ($p_size != 0)
5594
- {
5595
- $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5596
- $v_buffer = @gzread($p_src, $v_read_size);
5597
- @gzwrite($p_dest, $v_buffer, $v_read_size);
5598
- $p_size -= $v_read_size;
5599
- }
5600
- }
5601
-
5602
- // ----- Return
5603
- return $v_result;
5604
- }
5605
- // --------------------------------------------------------------------------------
5606
-
5607
- // --------------------------------------------------------------------------------
5608
- // Function : PclZipUtilRename()
5609
- // Description :
5610
- // This function tries to do a simple rename() function. If it fails, it
5611
- // tries to copy the $p_src file in a new $p_dest file and then unlink the
5612
- // first one.
5613
- // Parameters :
5614
- // $p_src : Old filename
5615
- // $p_dest : New filename
5616
- // Return Values :
5617
- // 1 on success, 0 on failure.
5618
- // --------------------------------------------------------------------------------
5619
- function PclZipUtilRename($p_src, $p_dest)
5620
- {
5621
- $v_result = 1;
5622
-
5623
- // ----- Try to rename the files
5624
- if (!@rename($p_src, $p_dest)) {
5625
-
5626
- // ----- Try to copy & unlink the src
5627
- if (!@copy($p_src, $p_dest)) {
5628
- $v_result = 0;
5629
- }
5630
- else if (!@unlink($p_src)) {
5631
- $v_result = 0;
5632
- }
5633
- }
5634
-
5635
- // ----- Return
5636
- return $v_result;
5637
- }
5638
- // --------------------------------------------------------------------------------
5639
-
5640
- // --------------------------------------------------------------------------------
5641
- // Function : PclZipUtilOptionText()
5642
- // Description :
5643
- // Translate option value in text. Mainly for debug purpose.
5644
- // Parameters :
5645
- // $p_option : the option value.
5646
- // Return Values :
5647
- // The option text value.
5648
- // --------------------------------------------------------------------------------
5649
- function PclZipUtilOptionText($p_option)
5650
- {
5651
-
5652
- $v_list = get_defined_constants();
5653
- for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5654
- $v_prefix = substr($v_key, 0, 10);
5655
- if (( ($v_prefix == 'PCLZIP_OPT')
5656
- || ($v_prefix == 'PCLZIP_CB_')
5657
- || ($v_prefix == 'PCLZIP_ATT'))
5658
- && ($v_list[$v_key] == $p_option)) {
5659
- return $v_key;
5660
- }
5661
- }
5662
-
5663
- $v_result = 'Unknown';
5664
-
5665
- return $v_result;
5666
- }
5667
- // --------------------------------------------------------------------------------
5668
-
5669
- // --------------------------------------------------------------------------------
5670
- // Function : PclZipUtilTranslateWinPath()
5671
- // Description :
5672
- // Translate windows path by replacing '\' by '/' and optionally removing
5673
- // drive letter.
5674
- // Parameters :
5675
- // $p_path : path to translate.
5676
- // $p_remove_disk_letter : true | false
5677
- // Return Values :
5678
- // The path translated.
5679
- // --------------------------------------------------------------------------------
5680
- function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5681
- {
5682
- if (stristr(php_uname(), 'windows')) {
5683
- // ----- Look for potential disk letter
5684
- if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
5685
- $p_path = substr($p_path, $v_position+1);
5686
- }
5687
- // ----- Change potential windows directory separator
5688
- if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5689
- $p_path = strtr($p_path, '\\', '/');
5690
- }
5691
- }
5692
- return $p_path;
5693
- }
5694
- // --------------------------------------------------------------------------------
5695
-
5696
-
5697
- ?>
1
+ <?php
2
+ // --------------------------------------------------------------------------------
3
+ // PhpConcept Library - Zip Module 2.8.2
4
+ // --------------------------------------------------------------------------------
5
+ // License GNU/LGPL - Vincent Blavet - August 2009
6
+ // http://www.phpconcept.net
7
+ // --------------------------------------------------------------------------------
8
+ //
9
+ // Presentation :
10
+ // PclZip is a PHP library that manage ZIP archives.
11
+ // So far tests show that archives generated by PclZip are readable by
12
+ // WinZip application and other tools.
13
+ //
14
+ // Description :
15
+ // See readme.txt and http://www.phpconcept.net
16
+ //
17
+ // Warning :
18
+ // This library and the associated files are non commercial, non professional
19
+ // work.
20
+ // It should not have unexpected results. However if any damage is caused by
21
+ // this software the author can not be responsible.
22
+ // The use of this software is at the risk of the user.
23
+ //
24
+ // --------------------------------------------------------------------------------
25
+ // $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
26
+ // --------------------------------------------------------------------------------
27
+
28
+ // ----- Constants
29
+ if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
30
+ define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
31
+ }
32
+
33
+ // ----- File list separator
34
+ // In version 1.x of PclZip, the separator for file list is a space
35
+ // (which is not a very smart choice, specifically for windows paths !).
36
+ // A better separator should be a comma (,). This constant gives you the
37
+ // abilty to change that.
38
+ // However notice that changing this value, may have impact on existing
39
+ // scripts, using space separated filenames.
40
+ // Recommanded values for compatibility with older versions :
41
+ //define( 'PCLZIP_SEPARATOR', ' ' );
42
+ // Recommanded values for smart separation of filenames.
43
+ if (!defined('PCLZIP_SEPARATOR')) {
44
+ define( 'PCLZIP_SEPARATOR', ',' );
45
+ }
46
+
47
+ // ----- Error configuration
48
+ // 0 : PclZip Class integrated error handling
49
+ // 1 : PclError external library error handling. By enabling this
50
+ // you must ensure that you have included PclError library.
51
+ // [2,...] : reserved for futur use
52
+ if (!defined('PCLZIP_ERROR_EXTERNAL')) {
53
+ define( 'PCLZIP_ERROR_EXTERNAL', 0 );
54
+ }
55
+
56
+ // ----- Optional static temporary directory
57
+ // By default temporary files are generated in the script current
58
+ // path.
59
+ // If defined :
60
+ // - MUST BE terminated by a '/'.
61
+ // - MUST be a valid, already created directory
62
+ // Samples :
63
+ // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
64
+ // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
65
+
66
+ $wp_uploads = wp_upload_dir();
67
+
68
+ if (!defined('PCLZIP_TEMPORARY_DIR')) {
69
+ define( 'PCLZIP_TEMPORARY_DIR', $wp_uploads['path'] );
70
+ }
71
+
72
+ // ----- Optional threshold ratio for use of temporary files
73
+ // Pclzip sense the size of the file to add/extract and decide to
74
+ // use or not temporary file. The algorythm is looking for
75
+ // memory_limit of PHP and apply a ratio.
76
+ // threshold = memory_limit * ratio.
77
+ // Recommended values are under 0.5. Default 0.47.
78
+ // Samples :
79
+ // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
80
+ if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
81
+ define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
82
+ }
83
+
84
+ // --------------------------------------------------------------------------------
85
+ // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
86
+ // --------------------------------------------------------------------------------
87
+
88
+ // ----- Global variables
89
+ $g_pclzip_version = "2.8.2";
90
+
91
+ // ----- Error codes
92
+ // -1 : Unable to open file in binary write mode
93
+ // -2 : Unable to open file in binary read mode
94
+ // -3 : Invalid parameters
95
+ // -4 : File does not exist
96
+ // -5 : Filename is too long (max. 255)
97
+ // -6 : Not a valid zip file
98
+ // -7 : Invalid extracted file size
99
+ // -8 : Unable to create directory
100
+ // -9 : Invalid archive extension
101
+ // -10 : Invalid archive format
102
+ // -11 : Unable to delete file (unlink)
103
+ // -12 : Unable to rename file (rename)
104
+ // -13 : Invalid header checksum
105
+ // -14 : Invalid archive size
106
+ define( 'PCLZIP_ERR_USER_ABORTED', 2 );
107
+ define( 'PCLZIP_ERR_NO_ERROR', 0 );
108
+ define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
109
+ define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
110
+ define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
111
+ define( 'PCLZIP_ERR_MISSING_FILE', -4 );
112
+ define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
113
+ define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
114
+ define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
115
+ define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
116
+ define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
117
+ define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
118
+ define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
119
+ define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
120
+ define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
121
+ define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
122
+ define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
123
+ define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
124
+ define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
125
+ define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
126
+ define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
127
+ define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
128
+ define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
129
+
130
+ // ----- Options values
131
+ define( 'PCLZIP_OPT_PATH', 77001 );
132
+ define( 'PCLZIP_OPT_ADD_PATH', 77002 );
133
+ define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
134
+ define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
135
+ define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
136
+ define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
137
+ define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
138
+ define( 'PCLZIP_OPT_BY_NAME', 77008 );
139
+ define( 'PCLZIP_OPT_BY_INDEX', 77009 );
140
+ define( 'PCLZIP_OPT_BY_EREG', 77010 );
141
+ define( 'PCLZIP_OPT_BY_PREG', 77011 );
142
+ define( 'PCLZIP_OPT_COMMENT', 77012 );
143
+ define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
144
+ define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
145
+ define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
146
+ define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
147
+ define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
148
+ // Having big trouble with crypt. Need to multiply 2 long int
149
+ // which is not correctly supported by PHP ...
150
+ //define( 'PCLZIP_OPT_CRYPT', 77018 );
151
+ define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
152
+ define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
153
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
154
+ define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
155
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
156
+ define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
157
+ define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
158
+
159
+ // ----- File description attributes
160
+ define( 'PCLZIP_ATT_FILE_NAME', 79001 );
161
+ define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
162
+ define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
163
+ define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
164
+ define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
165
+ define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
166
+
167
+ // ----- Call backs values
168
+ define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
169
+ define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
170
+ define( 'PCLZIP_CB_PRE_ADD', 78003 );
171
+ define( 'PCLZIP_CB_POST_ADD', 78004 );
172
+ /* For futur use
173
+ define( 'PCLZIP_CB_PRE_LIST', 78005 );
174
+ define( 'PCLZIP_CB_POST_LIST', 78006 );
175
+ define( 'PCLZIP_CB_PRE_DELETE', 78007 );
176
+ define( 'PCLZIP_CB_POST_DELETE', 78008 );
177
+ */
178
+
179
+ // --------------------------------------------------------------------------------
180
+ // Class : PclZip
181
+ // Description :
182
+ // PclZip is the class that represent a Zip archive.
183
+ // The public methods allow the manipulation of the archive.
184
+ // Attributes :
185
+ // Attributes must not be accessed directly.
186
+ // Methods :
187
+ // PclZip() : Object creator
188
+ // create() : Creates the Zip archive
189
+ // listContent() : List the content of the Zip archive
190
+ // extract() : Extract the content of the archive
191
+ // properties() : List the properties of the archive
192
+ // --------------------------------------------------------------------------------
193
+ class PclZip
194
+ {
195
+ // ----- Filename of the zip file
196
+ var $zipname = '';
197
+
198
+ // ----- File descriptor of the zip file
199
+ var $zip_fd = 0;
200
+
201
+ // ----- Internal error handling
202
+ var $error_code = 1;
203
+ var $error_string = '';
204
+
205
+ // ----- Current status of the magic_quotes_runtime
206
+ // This value store the php configuration for magic_quotes
207
+ // The class can then disable the magic_quotes and reset it after
208
+ var $magic_quotes_status;
209
+
210
+ // --------------------------------------------------------------------------------
211
+ // Function : PclZip()
212
+ // Description :
213
+ // Creates a PclZip object and set the name of the associated Zip archive
214
+ // filename.
215
+ // Note that no real action is taken, if the archive does not exist it is not
216
+ // created. Use create() for that.
217
+ // --------------------------------------------------------------------------------
218
+ function PclZip($p_zipname)
219
+ {
220
+
221
+ // ----- Tests the zlib
222
+ if (!function_exists('gzopen'))
223
+ {
224
+ die('Abort '.basename(__FILE__).' : Missing zlib extensions');
225
+ }
226
+
227
+ // ----- Set the attributes
228
+ $this->zipname = $p_zipname;
229
+ $this->zip_fd = 0;
230
+ $this->magic_quotes_status = -1;
231
+
232
+ // ----- Return
233
+ return;
234
+ }
235
+ // --------------------------------------------------------------------------------
236
+
237
+ // --------------------------------------------------------------------------------
238
+ // Function :
239
+ // create($p_filelist, $p_add_dir="", $p_remove_dir="")
240
+ // create($p_filelist, $p_option, $p_option_value, ...)
241
+ // Description :
242
+ // This method supports two different synopsis. The first one is historical.
243
+ // This method creates a Zip Archive. The Zip file is created in the
244
+ // filesystem. The files and directories indicated in $p_filelist
245
+ // are added in the archive. See the parameters description for the
246
+ // supported format of $p_filelist.
247
+ // When a directory is in the list, the directory and its content is added
248
+ // in the archive.
249
+ // In this synopsis, the function takes an optional variable list of
250
+ // options. See bellow the supported options.
251
+ // Parameters :
252
+ // $p_filelist : An array containing file or directory names, or
253
+ // a string containing one filename or one directory name, or
254
+ // a string containing a list of filenames and/or directory
255
+ // names separated by spaces.
256
+ // $p_add_dir : A path to add before the real path of the archived file,
257
+ // in order to have it memorized in the archive.
258
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
259
+ // in order to have a shorter path memorized in the archive.
260
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
261
+ // is removed first, before $p_add_dir is added.
262
+ // Options :
263
+ // PCLZIP_OPT_ADD_PATH :
264
+ // PCLZIP_OPT_REMOVE_PATH :
265
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
266
+ // PCLZIP_OPT_COMMENT :
267
+ // PCLZIP_CB_PRE_ADD :
268
+ // PCLZIP_CB_POST_ADD :
269
+ // Return Values :
270
+ // 0 on failure,
271
+ // The list of the added files, with a status of the add action.
272
+ // (see PclZip::listContent() for list entry format)
273
+ // --------------------------------------------------------------------------------
274
+ function create($p_filelist)
275
+ {
276
+ $v_result=1;
277
+
278
+ // ----- Reset the error handler
279
+ $this->privErrorReset();
280
+
281
+ // ----- Set default values
282
+ $v_options = array();
283
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
284
+
285
+ // ----- Look for variable options arguments
286
+ $v_size = func_num_args();
287
+
288
+ // ----- Look for arguments
289
+ if ($v_size > 1) {
290
+ // ----- Get the arguments
291
+ $v_arg_list = func_get_args();
292
+
293
+ // ----- Remove from the options list the first argument
294
+ array_shift($v_arg_list);
295
+ $v_size--;
296
+
297
+ // ----- Look for first arg
298
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
299
+
300
+ // ----- Parse the options
301
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
302
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
303
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
304
+ PCLZIP_OPT_ADD_PATH => 'optional',
305
+ PCLZIP_CB_PRE_ADD => 'optional',
306
+ PCLZIP_CB_POST_ADD => 'optional',
307
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
308
+ PCLZIP_OPT_COMMENT => 'optional',
309
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
310
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
311
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
312
+ //, PCLZIP_OPT_CRYPT => 'optional'
313
+ ));
314
+ if ($v_result != 1) {
315
+ return 0;
316
+ }
317
+ }
318
+
319
+ // ----- Look for 2 args
320
+ // Here we need to support the first historic synopsis of the
321
+ // method.
322
+ else {
323
+
324
+ // ----- Get the first argument
325
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
326
+
327
+ // ----- Look for the optional second argument
328
+ if ($v_size == 2) {
329
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
330
+ }
331
+ else if ($v_size > 2) {
332
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
333
+ "Invalid number / type of arguments");
334
+ return 0;
335
+ }
336
+ }
337
+ }
338
+
339
+ // ----- Look for default option values
340
+ $this->privOptionDefaultThreshold($v_options);
341
+
342
+ // ----- Init
343
+ $v_string_list = array();
344
+ $v_att_list = array();
345
+ $v_filedescr_list = array();
346
+ $p_result_list = array();
347
+
348
+ // ----- Look if the $p_filelist is really an array
349
+ if (is_array($p_filelist)) {
350
+
351
+ // ----- Look if the first element is also an array
352
+ // This will mean that this is a file description entry
353
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
354
+ $v_att_list = $p_filelist;
355
+ }
356
+
357
+ // ----- The list is a list of string names
358
+ else {
359
+ $v_string_list = $p_filelist;
360
+ }
361
+ }
362
+
363
+ // ----- Look if the $p_filelist is a string
364
+ else if (is_string($p_filelist)) {
365
+ // ----- Create a list from the string
366
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
367
+ }
368
+
369
+ // ----- Invalid variable type for $p_filelist
370
+ else {
371
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
372
+ return 0;
373
+ }
374
+
375
+ // ----- Reformat the string list
376
+ if (sizeof($v_string_list) != 0) {
377
+ foreach ($v_string_list as $v_string) {
378
+ if ($v_string != '') {
379
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
380
+ }
381
+ else {
382
+ }
383
+ }
384
+ }
385
+
386
+ // ----- For each file in the list check the attributes
387
+ $v_supported_attributes
388
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
389
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
390
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
391
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
392
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
393
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
394
+ );
395
+ foreach ($v_att_list as $v_entry) {
396
+ $v_result = $this->privFileDescrParseAtt($v_entry,
397
+ $v_filedescr_list[],
398
+ $v_options,
399
+ $v_supported_attributes);
400
+ if ($v_result != 1) {
401
+ return 0;
402
+ }
403
+ }
404
+
405
+ // ----- Expand the filelist (expand directories)
406
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
407
+ if ($v_result != 1) {
408
+ return 0;
409
+ }
410
+
411
+ // ----- Call the create fct
412
+ $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
413
+ if ($v_result != 1) {
414
+ return 0;
415
+ }
416
+
417
+ // ----- Return
418
+ return $p_result_list;
419
+ }
420
+ // --------------------------------------------------------------------------------
421
+
422
+ // --------------------------------------------------------------------------------
423
+ // Function :
424
+ // add($p_filelist, $p_add_dir="", $p_remove_dir="")
425
+ // add($p_filelist, $p_option, $p_option_value, ...)
426
+ // Description :
427
+ // This method supports two synopsis. The first one is historical.
428
+ // This methods add the list of files in an existing archive.
429
+ // If a file with the same name already exists, it is added at the end of the
430
+ // archive, the first one is still present.
431
+ // If the archive does not exist, it is created.
432
+ // Parameters :
433
+ // $p_filelist : An array containing file or directory names, or
434
+ // a string containing one filename or one directory name, or
435
+ // a string containing a list of filenames and/or directory
436
+ // names separated by spaces.
437
+ // $p_add_dir : A path to add before the real path of the archived file,
438
+ // in order to have it memorized in the archive.
439
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
440
+ // in order to have a shorter path memorized in the archive.
441
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
442
+ // is removed first, before $p_add_dir is added.
443
+ // Options :
444
+ // PCLZIP_OPT_ADD_PATH :
445
+ // PCLZIP_OPT_REMOVE_PATH :
446
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
447
+ // PCLZIP_OPT_COMMENT :
448
+ // PCLZIP_OPT_ADD_COMMENT :
449
+ // PCLZIP_OPT_PREPEND_COMMENT :
450
+ // PCLZIP_CB_PRE_ADD :
451
+ // PCLZIP_CB_POST_ADD :
452
+ // Return Values :
453
+ // 0 on failure,
454
+ // The list of the added files, with a status of the add action.
455
+ // (see PclZip::listContent() for list entry format)
456
+ // --------------------------------------------------------------------------------
457
+ function add($p_filelist)
458
+ {
459
+ $v_result=1;
460
+
461
+ // ----- Reset the error handler
462
+ $this->privErrorReset();
463
+
464
+ // ----- Set default values
465
+ $v_options = array();
466
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
467
+
468
+ // ----- Look for variable options arguments
469
+ $v_size = func_num_args();
470
+
471
+ // ----- Look for arguments
472
+ if ($v_size > 1) {
473
+ // ----- Get the arguments
474
+ $v_arg_list = func_get_args();
475
+
476
+ // ----- Remove form the options list the first argument
477
+ array_shift($v_arg_list);
478
+ $v_size--;
479
+
480
+ // ----- Look for first arg
481
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
482
+
483
+ // ----- Parse the options
484
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
485
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
486
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
487
+ PCLZIP_OPT_ADD_PATH => 'optional',
488
+ PCLZIP_CB_PRE_ADD => 'optional',
489
+ PCLZIP_CB_POST_ADD => 'optional',
490
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
491
+ PCLZIP_OPT_COMMENT => 'optional',
492
+ PCLZIP_OPT_ADD_COMMENT => 'optional',
493
+ PCLZIP_OPT_PREPEND_COMMENT => 'optional',
494
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
495
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
496
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
497
+ //, PCLZIP_OPT_CRYPT => 'optional'
498
+ ));
499
+ if ($v_result != 1) {
500
+ return 0;
501
+ }
502
+ }
503
+
504
+ // ----- Look for 2 args
505
+ // Here we need to support the first historic synopsis of the
506
+ // method.
507
+ else {
508
+
509
+ // ----- Get the first argument
510
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
511
+
512
+ // ----- Look for the optional second argument
513
+ if ($v_size == 2) {
514
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
515
+ }
516
+ else if ($v_size > 2) {
517
+ // ----- Error log
518
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
519
+
520
+ // ----- Return
521
+ return 0;
522
+ }
523
+ }
524
+ }
525
+
526
+ // ----- Look for default option values
527
+ $this->privOptionDefaultThreshold($v_options);
528
+
529
+ // ----- Init
530
+ $v_string_list = array();
531
+ $v_att_list = array();
532
+ $v_filedescr_list = array();
533
+ $p_result_list = array();
534
+
535
+ // ----- Look if the $p_filelist is really an array
536
+ if (is_array($p_filelist)) {
537
+
538
+ // ----- Look if the first element is also an array
539
+ // This will mean that this is a file description entry
540
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
541
+ $v_att_list = $p_filelist;
542
+ }
543
+
544
+ // ----- The list is a list of string names
545
+ else {
546
+ $v_string_list = $p_filelist;
547
+ }
548
+ }
549
+
550
+ // ----- Look if the $p_filelist is a string
551
+ else if (is_string($p_filelist)) {
552
+ // ----- Create a list from the string
553
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
554
+ }
555
+
556
+ // ----- Invalid variable type for $p_filelist
557
+ else {
558
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
559
+ return 0;
560
+ }
561
+
562
+ // ----- Reformat the string list
563
+ if (sizeof($v_string_list) != 0) {
564
+ foreach ($v_string_list as $v_string) {
565
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
566
+ }
567
+ }
568
+
569
+ // ----- For each file in the list check the attributes
570
+ $v_supported_attributes
571
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
572
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
573
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
574
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
575
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
576
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
577
+ );
578
+ foreach ($v_att_list as $v_entry) {
579
+ $v_result = $this->privFileDescrParseAtt($v_entry,
580
+ $v_filedescr_list[],
581
+ $v_options,
582
+ $v_supported_attributes);
583
+ if ($v_result != 1) {
584
+ return 0;
585
+ }
586
+ }
587
+
588
+ // ----- Expand the filelist (expand directories)
589
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
590
+ if ($v_result != 1) {
591
+ return 0;
592
+ }
593
+
594
+ // ----- Call the create fct
595
+ $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
596
+ if ($v_result != 1) {
597
+ return 0;
598
+ }
599
+
600
+ // ----- Return
601
+ return $p_result_list;
602
+ }
603
+ // --------------------------------------------------------------------------------
604
+
605
+ // --------------------------------------------------------------------------------
606
+ // Function : listContent()
607
+ // Description :
608
+ // This public method, gives the list of the files and directories, with their
609
+ // properties.
610
+ // The properties of each entries in the list are (used also in other functions) :
611
+ // filename : Name of the file. For a create or add action it is the filename
612
+ // given by the user. For an extract function it is the filename
613
+ // of the extracted file.
614
+ // stored_filename : Name of the file / directory stored in the archive.
615
+ // size : Size of the stored file.
616
+ // compressed_size : Size of the file's data compressed in the archive
617
+ // (without the headers overhead)
618
+ // mtime : Last known modification date of the file (UNIX timestamp)
619
+ // comment : Comment associated with the file
620
+ // folder : true | false
621
+ // index : index of the file in the archive
622
+ // status : status of the action (depending of the action) :
623
+ // Values are :
624
+ // ok : OK !
625
+ // filtered : the file / dir is not extracted (filtered by user)
626
+ // already_a_directory : the file can not be extracted because a
627
+ // directory with the same name already exists
628
+ // write_protected : the file can not be extracted because a file
629
+ // with the same name already exists and is
630
+ // write protected
631
+ // newer_exist : the file was not extracted because a newer file exists
632
+ // path_creation_fail : the file is not extracted because the folder
633
+ // does not exist and can not be created
634
+ // write_error : the file was not extracted because there was a
635
+ // error while writing the file
636
+ // read_error : the file was not extracted because there was a error
637
+ // while reading the file
638
+ // invalid_header : the file was not extracted because of an archive
639
+ // format error (bad file header)
640
+ // Note that each time a method can continue operating when there
641
+ // is an action error on a file, the error is only logged in the file status.
642
+ // Return Values :
643
+ // 0 on an unrecoverable failure,
644
+ // The list of the files in the archive.
645
+ // --------------------------------------------------------------------------------
646
+ function listContent()
647
+ {
648
+ $v_result=1;
649
+
650
+ // ----- Reset the error handler
651
+ $this->privErrorReset();
652
+
653
+ // ----- Check archive
654
+ if (!$this->privCheckFormat()) {
655
+ return(0);
656
+ }
657
+
658
+ // ----- Call the extracting fct
659
+ $p_list = array();
660
+ if (($v_result = $this->privList($p_list)) != 1)
661
+ {
662
+ unset($p_list);
663
+ return(0);
664
+ }
665
+
666
+ // ----- Return
667
+ return $p_list;
668
+ }
669
+ // --------------------------------------------------------------------------------
670
+
671
+ // --------------------------------------------------------------------------------
672
+ // Function :
673
+ // extract($p_path="./", $p_remove_path="")
674
+ // extract([$p_option, $p_option_value, ...])
675
+ // Description :
676
+ // This method supports two synopsis. The first one is historical.
677
+ // This method extract all the files / directories from the archive to the
678
+ // folder indicated in $p_path.
679
+ // If you want to ignore the 'root' part of path of the memorized files
680
+ // you can indicate this in the optional $p_remove_path parameter.
681
+ // By default, if a newer file with the same name already exists, the
682
+ // file is not extracted.
683
+ //
684
+ // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
685
+ // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
686
+ // at the end of the path value of PCLZIP_OPT_PATH.
687
+ // Parameters :
688
+ // $p_path : Path where the files and directories are to be extracted
689
+ // $p_remove_path : First part ('root' part) of the memorized path
690
+ // (if any similar) to remove while extracting.
691
+ // Options :
692
+ // PCLZIP_OPT_PATH :
693
+ // PCLZIP_OPT_ADD_PATH :
694
+ // PCLZIP_OPT_REMOVE_PATH :
695
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
696
+ // PCLZIP_CB_PRE_EXTRACT :
697
+ // PCLZIP_CB_POST_EXTRACT :
698
+ // Return Values :
699
+ // 0 or a negative value on failure,
700
+ // The list of the extracted files, with a status of the action.
701
+ // (see PclZip::listContent() for list entry format)
702
+ // --------------------------------------------------------------------------------
703
+ function extract()
704
+ {
705
+ $v_result=1;
706
+
707
+ // ----- Reset the error handler
708
+ $this->privErrorReset();
709
+
710
+ // ----- Check archive
711
+ if (!$this->privCheckFormat()) {
712
+ return(0);
713
+ }
714
+
715
+ // ----- Set default values
716
+ $v_options = array();
717
+ // $v_path = "./";
718
+ $v_path = '';
719
+ $v_remove_path = "";
720
+ $v_remove_all_path = false;
721
+
722
+ // ----- Look for variable options arguments
723
+ $v_size = func_num_args();
724
+
725
+ // ----- Default values for option
726
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
727
+
728
+ // ----- Look for arguments
729
+ if ($v_size > 0) {
730
+ // ----- Get the arguments
731
+ $v_arg_list = func_get_args();
732
+
733
+ // ----- Look for first arg
734
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
735
+
736
+ // ----- Parse the options
737
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
738
+ array (PCLZIP_OPT_PATH => 'optional',
739
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
740
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
741
+ PCLZIP_OPT_ADD_PATH => 'optional',
742
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
743
+ PCLZIP_CB_POST_EXTRACT => 'optional',
744
+ PCLZIP_OPT_SET_CHMOD => 'optional',
745
+ PCLZIP_OPT_BY_NAME => 'optional',
746
+ PCLZIP_OPT_BY_EREG => 'optional',
747
+ PCLZIP_OPT_BY_PREG => 'optional',
748
+ PCLZIP_OPT_BY_INDEX => 'optional',
749
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
750
+ PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
751
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
752
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
753
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
754
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
755
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
756
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
757
+ ));
758
+ if ($v_result != 1) {
759
+ return 0;
760
+ }
761
+
762
+ // ----- Set the arguments
763
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
764
+ $v_path = $v_options[PCLZIP_OPT_PATH];
765
+ }
766
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
767
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
768
+ }
769
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
770
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
771
+ }
772
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
773
+ // ----- Check for '/' in last path char
774
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
775
+ $v_path .= '/';
776
+ }
777
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
778
+ }
779
+ }
780
+
781
+ // ----- Look for 2 args
782
+ // Here we need to support the first historic synopsis of the
783
+ // method.
784
+ else {
785
+
786
+ // ----- Get the first argument
787
+ $v_path = $v_arg_list[0];
788
+
789
+ // ----- Look for the optional second argument
790
+ if ($v_size == 2) {
791
+ $v_remove_path = $v_arg_list[1];
792
+ }
793
+ else if ($v_size > 2) {
794
+ // ----- Error log
795
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
796
+
797
+ // ----- Return
798
+ return 0;
799
+ }
800
+ }
801
+ }
802
+
803
+ // ----- Look for default option values
804
+ $this->privOptionDefaultThreshold($v_options);
805
+
806
+ // ----- Trace
807
+
808
+ // ----- Call the extracting fct
809
+ $p_list = array();
810
+ $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
811
+ $v_remove_all_path, $v_options);
812
+ if ($v_result < 1) {
813
+ unset($p_list);
814
+ return(0);
815
+ }
816
+
817
+ // ----- Return
818
+ return $p_list;
819
+ }
820
+ // --------------------------------------------------------------------------------
821
+
822
+
823
+ // --------------------------------------------------------------------------------
824
+ // Function :
825
+ // extractByIndex($p_index, $p_path="./", $p_remove_path="")
826
+ // extractByIndex($p_index, [$p_option, $p_option_value, ...])
827
+ // Description :
828
+ // This method supports two synopsis. The first one is historical.
829
+ // This method is doing a partial extract of the archive.
830
+ // The extracted files or folders are identified by their index in the
831
+ // archive (from 0 to n).
832
+ // Note that if the index identify a folder, only the folder entry is
833
+ // extracted, not all the files included in the archive.
834
+ // Parameters :
835
+ // $p_index : A single index (integer) or a string of indexes of files to
836
+ // extract. The form of the string is "0,4-6,8-12" with only numbers
837
+ // and '-' for range or ',' to separate ranges. No spaces or ';'
838
+ // are allowed.
839
+ // $p_path : Path where the files and directories are to be extracted
840
+ // $p_remove_path : First part ('root' part) of the memorized path
841
+ // (if any similar) to remove while extracting.
842
+ // Options :
843
+ // PCLZIP_OPT_PATH :
844
+ // PCLZIP_OPT_ADD_PATH :
845
+ // PCLZIP_OPT_REMOVE_PATH :
846
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
847
+ // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
848
+ // not as files.
849
+ // The resulting content is in a new field 'content' in the file
850
+ // structure.
851
+ // This option must be used alone (any other options are ignored).
852
+ // PCLZIP_CB_PRE_EXTRACT :
853
+ // PCLZIP_CB_POST_EXTRACT :
854
+ // Return Values :
855
+ // 0 on failure,
856
+ // The list of the extracted files, with a status of the action.
857
+ // (see PclZip::listContent() for list entry format)
858
+ // --------------------------------------------------------------------------------
859
+ //function extractByIndex($p_index, options...)
860
+ function extractByIndex($p_index)
861
+ {
862
+ $v_result=1;
863
+
864
+ // ----- Reset the error handler
865
+ $this->privErrorReset();
866
+
867
+ // ----- Check archive
868
+ if (!$this->privCheckFormat()) {
869
+ return(0);
870
+ }
871
+
872
+ // ----- Set default values
873
+ $v_options = array();
874
+ // $v_path = "./";
875
+ $v_path = '';
876
+ $v_remove_path = "";
877
+ $v_remove_all_path = false;
878
+
879
+ // ----- Look for variable options arguments
880
+ $v_size = func_num_args();
881
+
882
+ // ----- Default values for option
883
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
884
+
885
+ // ----- Look for arguments
886
+ if ($v_size > 1) {
887
+ // ----- Get the arguments
888
+ $v_arg_list = func_get_args();
889
+
890
+ // ----- Remove form the options list the first argument
891
+ array_shift($v_arg_list);
892
+ $v_size--;
893
+
894
+ // ----- Look for first arg
895
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
896
+
897
+ // ----- Parse the options
898
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
899
+ array (PCLZIP_OPT_PATH => 'optional',
900
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
901
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
902
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
903
+ PCLZIP_OPT_ADD_PATH => 'optional',
904
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
905
+ PCLZIP_CB_POST_EXTRACT => 'optional',
906
+ PCLZIP_OPT_SET_CHMOD => 'optional',
907
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
908
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
909
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
910
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
911
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
912
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
913
+ ));
914
+ if ($v_result != 1) {
915
+ return 0;
916
+ }
917
+
918
+ // ----- Set the arguments
919
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
920
+ $v_path = $v_options[PCLZIP_OPT_PATH];
921
+ }
922
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
923
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
924
+ }
925
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
926
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
927
+ }
928
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
929
+ // ----- Check for '/' in last path char
930
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
931
+ $v_path .= '/';
932
+ }
933
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
934
+ }
935
+ if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
936
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
937
+ }
938
+ else {
939
+ }
940
+ }
941
+
942
+ // ----- Look for 2 args
943
+ // Here we need to support the first historic synopsis of the
944
+ // method.
945
+ else {
946
+
947
+ // ----- Get the first argument
948
+ $v_path = $v_arg_list[0];
949
+
950
+ // ----- Look for the optional second argument
951
+ if ($v_size == 2) {
952
+ $v_remove_path = $v_arg_list[1];
953
+ }
954
+ else if ($v_size > 2) {
955
+ // ----- Error log
956
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
957
+
958
+ // ----- Return
959
+ return 0;
960
+ }
961
+ }
962
+ }
963
+
964
+ // ----- Trace
965
+
966
+ // ----- Trick
967
+ // Here I want to reuse extractByRule(), so I need to parse the $p_index
968
+ // with privParseOptions()
969
+ $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
970
+ $v_options_trick = array();
971
+ $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
972
+ array (PCLZIP_OPT_BY_INDEX => 'optional' ));
973
+ if ($v_result != 1) {
974
+ return 0;
975
+ }
976
+ $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
977
+
978
+ // ----- Look for default option values
979
+ $this->privOptionDefaultThreshold($v_options);
980
+
981
+ // ----- Call the extracting fct
982
+ if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
983
+ return(0);
984
+ }
985
+
986
+ // ----- Return
987
+ return $p_list;
988
+ }
989
+ // --------------------------------------------------------------------------------
990
+
991
+ // --------------------------------------------------------------------------------
992
+ // Function :
993
+ // delete([$p_option, $p_option_value, ...])
994
+ // Description :
995
+ // This method removes files from the archive.
996
+ // If no parameters are given, then all the archive is emptied.
997
+ // Parameters :
998
+ // None or optional arguments.
999
+ // Options :
1000
+ // PCLZIP_OPT_BY_INDEX :
1001
+ // PCLZIP_OPT_BY_NAME :
1002
+ // PCLZIP_OPT_BY_EREG :
1003
+ // PCLZIP_OPT_BY_PREG :
1004
+ // Return Values :
1005
+ // 0 on failure,
1006
+ // The list of the files which are still present in the archive.
1007
+ // (see PclZip::listContent() for list entry format)
1008
+ // --------------------------------------------------------------------------------
1009
+ function delete()
1010
+ {
1011
+ $v_result=1;
1012
+
1013
+ // ----- Reset the error handler
1014
+ $this->privErrorReset();
1015
+
1016
+ // ----- Check archive
1017
+ if (!$this->privCheckFormat()) {
1018
+ return(0);
1019
+ }
1020
+
1021
+ // ----- Set default values
1022
+ $v_options = array();
1023
+
1024
+ // ----- Look for variable options arguments
1025
+ $v_size = func_num_args();
1026
+
1027
+ // ----- Look for arguments
1028
+ if ($v_size > 0) {
1029
+ // ----- Get the arguments
1030
+ $v_arg_list = func_get_args();
1031
+
1032
+ // ----- Parse the options
1033
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1034
+ array (PCLZIP_OPT_BY_NAME => 'optional',
1035
+ PCLZIP_OPT_BY_EREG => 'optional',
1036
+ PCLZIP_OPT_BY_PREG => 'optional',
1037
+ PCLZIP_OPT_BY_INDEX => 'optional' ));
1038
+ if ($v_result != 1) {
1039
+ return 0;
1040
+ }
1041
+ }
1042
+
1043
+ // ----- Magic quotes trick
1044
+ $this->privDisableMagicQuotes();
1045
+
1046
+ // ----- Call the delete fct
1047
+ $v_list = array();
1048
+ if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1049
+ $this->privSwapBackMagicQuotes();
1050
+ unset($v_list);
1051
+ return(0);
1052
+ }
1053
+
1054
+ // ----- Magic quotes trick
1055
+ $this->privSwapBackMagicQuotes();
1056
+
1057
+ // ----- Return
1058
+ return $v_list;
1059
+ }
1060
+ // --------------------------------------------------------------------------------
1061
+
1062
+ // --------------------------------------------------------------------------------
1063
+ // Function : deleteByIndex()
1064
+ // Description :
1065
+ // ***** Deprecated *****
1066
+ // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1067
+ // --------------------------------------------------------------------------------
1068
+ function deleteByIndex($p_index)
1069
+ {
1070
+
1071
+ $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1072
+
1073
+ // ----- Return
1074
+ return $p_list;
1075
+ }
1076
+ // --------------------------------------------------------------------------------
1077
+
1078
+ // --------------------------------------------------------------------------------
1079
+ // Function : properties()
1080
+ // Description :
1081
+ // This method gives the properties of the archive.
1082
+ // The properties are :
1083
+ // nb : Number of files in the archive
1084
+ // comment : Comment associated with the archive file
1085
+ // status : not_exist, ok
1086
+ // Parameters :
1087
+ // None
1088
+ // Return Values :
1089
+ // 0 on failure,
1090
+ // An array with the archive properties.
1091
+ // --------------------------------------------------------------------------------
1092
+ function properties()
1093
+ {
1094
+
1095
+ // ----- Reset the error handler
1096
+ $this->privErrorReset();
1097
+
1098
+ // ----- Magic quotes trick
1099
+ $this->privDisableMagicQuotes();
1100
+
1101
+ // ----- Check archive
1102
+ if (!$this->privCheckFormat()) {
1103
+ $this->privSwapBackMagicQuotes();
1104
+ return(0);
1105
+ }
1106
+
1107
+ // ----- Default properties
1108
+ $v_prop = array();
1109
+ $v_prop['comment'] = '';
1110
+ $v_prop['nb'] = 0;
1111
+ $v_prop['status'] = 'not_exist';
1112
+
1113
+ // ----- Look if file exists
1114
+ if (@is_file($this->zipname))
1115
+ {
1116
+ // ----- Open the zip file
1117
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1118
+ {
1119
+ $this->privSwapBackMagicQuotes();
1120
+
1121
+ // ----- Error log
1122
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1123
+
1124
+ // ----- Return
1125
+ return 0;
1126
+ }
1127
+
1128
+ // ----- Read the central directory informations
1129
+ $v_central_dir = array();
1130
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1131
+ {
1132
+ $this->privSwapBackMagicQuotes();
1133
+ return 0;
1134
+ }
1135
+
1136
+ // ----- Close the zip file
1137
+ $this->privCloseFd();
1138
+
1139
+ // ----- Set the user attributes
1140
+ $v_prop['comment'] = $v_central_dir['comment'];
1141
+ $v_prop['nb'] = $v_central_dir['entries'];
1142
+ $v_prop['status'] = 'ok';
1143
+ }
1144
+
1145
+ // ----- Magic quotes trick
1146
+ $this->privSwapBackMagicQuotes();
1147
+
1148
+ // ----- Return
1149
+ return $v_prop;
1150
+ }
1151
+ // --------------------------------------------------------------------------------
1152
+
1153
+ // --------------------------------------------------------------------------------
1154
+ // Function : duplicate()
1155
+ // Description :
1156
+ // This method creates an archive by copying the content of an other one. If
1157
+ // the archive already exist, it is replaced by the new one without any warning.
1158
+ // Parameters :
1159
+ // $p_archive : The filename of a valid archive, or
1160
+ // a valid PclZip object.
1161
+ // Return Values :
1162
+ // 1 on success.
1163
+ // 0 or a negative value on error (error code).
1164
+ // --------------------------------------------------------------------------------
1165
+ function duplicate($p_archive)
1166
+ {
1167
+ $v_result = 1;
1168
+
1169
+ // ----- Reset the error handler
1170
+ $this->privErrorReset();
1171
+
1172
+ // ----- Look if the $p_archive is a PclZip object
1173
+ if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1174
+ {
1175
+
1176
+ // ----- Duplicate the archive
1177
+ $v_result = $this->privDuplicate($p_archive->zipname);
1178
+ }
1179
+
1180
+ // ----- Look if the $p_archive is a string (so a filename)
1181
+ else if (is_string($p_archive))
1182
+ {
1183
+
1184
+ // ----- Check that $p_archive is a valid zip file
1185
+ // TBC : Should also check the archive format
1186
+ if (!is_file($p_archive)) {
1187
+ // ----- Error log
1188
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1189
+ $v_result = PCLZIP_ERR_MISSING_FILE;
1190
+ }
1191
+ else {
1192
+ // ----- Duplicate the archive
1193
+ $v_result = $this->privDuplicate($p_archive);
1194
+ }
1195
+ }
1196
+
1197
+ // ----- Invalid variable
1198
+ else
1199
+ {
1200
+ // ----- Error log
1201
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1202
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1203
+ }
1204
+
1205
+ // ----- Return
1206
+ return $v_result;
1207
+ }
1208
+ // --------------------------------------------------------------------------------
1209
+
1210
+ // --------------------------------------------------------------------------------
1211
+ // Function : merge()
1212
+ // Description :
1213
+ // This method merge the $p_archive_to_add archive at the end of the current
1214
+ // one ($this).
1215
+ // If the archive ($this) does not exist, the merge becomes a duplicate.
1216
+ // If the $p_archive_to_add archive does not exist, the merge is a success.
1217
+ // Parameters :
1218
+ // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1219
+ // or a PclZip object archive.
1220
+ // Return Values :
1221
+ // 1 on success,
1222
+ // 0 or negative values on error (see below).
1223
+ // --------------------------------------------------------------------------------
1224
+ function merge($p_archive_to_add)
1225
+ {
1226
+ $v_result = 1;
1227
+
1228
+ // ----- Reset the error handler
1229
+ $this->privErrorReset();
1230
+
1231
+ // ----- Check archive
1232
+ if (!$this->privCheckFormat()) {
1233
+ return(0);
1234
+ }
1235
+
1236
+ // ----- Look if the $p_archive_to_add is a PclZip object
1237
+ if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1238
+ {
1239
+
1240
+ // ----- Merge the archive
1241
+ $v_result = $this->privMerge($p_archive_to_add);
1242
+ }
1243
+
1244
+ // ----- Look if the $p_archive_to_add is a string (so a filename)
1245
+ else if (is_string($p_archive_to_add))
1246
+ {
1247
+
1248
+ // ----- Create a temporary archive
1249
+ $v_object_archive = new PclZip($p_archive_to_add);
1250
+
1251
+ // ----- Merge the archive
1252
+ $v_result = $this->privMerge($v_object_archive);
1253
+ }
1254
+
1255
+ // ----- Invalid variable
1256
+ else
1257
+ {
1258
+ // ----- Error log
1259
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1260
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1261
+ }
1262
+
1263
+ // ----- Return
1264
+ return $v_result;
1265
+ }
1266
+ // --------------------------------------------------------------------------------
1267
+
1268
+
1269
+
1270
+ // --------------------------------------------------------------------------------
1271
+ // Function : errorCode()
1272
+ // Description :
1273
+ // Parameters :
1274
+ // --------------------------------------------------------------------------------
1275
+ function errorCode()
1276
+ {
1277
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
1278
+ return(PclErrorCode());
1279
+ }
1280
+ else {
1281
+ return($this->error_code);
1282
+ }
1283
+ }
1284
+ // --------------------------------------------------------------------------------
1285
+
1286
+ // --------------------------------------------------------------------------------
1287
+ // Function : errorName()
1288
+ // Description :
1289
+ // Parameters :
1290
+ // --------------------------------------------------------------------------------
1291
+ function errorName($p_with_code=false)
1292
+ {
1293
+ $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1294
+ PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1295
+ PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1296
+ PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1297
+ PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1298
+ PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1299
+ PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1300
+ PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1301
+ PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1302
+ PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1303
+ PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1304
+ PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1305
+ PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1306
+ PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1307
+ PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1308
+ PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1309
+ PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1310
+ PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1311
+ PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1312
+ ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1313
+ ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1314
+ );
1315
+
1316
+ if (isset($v_name[$this->error_code])) {
1317
+ $v_value = $v_name[$this->error_code];
1318
+ }
1319
+ else {
1320
+ $v_value = 'NoName';
1321
+ }
1322
+
1323
+ if ($p_with_code) {
1324
+ return($v_value.' ('.$this->error_code.')');
1325
+ }
1326
+ else {
1327
+ return($v_value);
1328
+ }
1329
+ }
1330
+ // --------------------------------------------------------------------------------
1331
+
1332
+ // --------------------------------------------------------------------------------
1333
+ // Function : errorInfo()
1334
+ // Description :
1335
+ // Parameters :
1336
+ // --------------------------------------------------------------------------------
1337
+ function errorInfo($p_full=false)
1338
+ {
1339
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
1340
+ return(PclErrorString());
1341
+ }
1342
+ else {
1343
+ if ($p_full) {
1344
+ return($this->errorName(true)." : ".$this->error_string);
1345
+ }
1346
+ else {
1347
+ return($this->error_string." [code ".$this->error_code."]");
1348
+ }
1349
+ }
1350
+ }
1351
+ // --------------------------------------------------------------------------------
1352
+
1353
+
1354
+ // --------------------------------------------------------------------------------
1355
+ // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1356
+ // ***** *****
1357
+ // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1358
+ // --------------------------------------------------------------------------------
1359
+
1360
+
1361
+
1362
+ // --------------------------------------------------------------------------------
1363
+ // Function : privCheckFormat()
1364
+ // Description :
1365
+ // This method check that the archive exists and is a valid zip archive.
1366
+ // Several level of check exists. (futur)
1367
+ // Parameters :
1368
+ // $p_level : Level of check. Default 0.
1369
+ // 0 : Check the first bytes (magic codes) (default value))
1370
+ // 1 : 0 + Check the central directory (futur)
1371
+ // 2 : 1 + Check each file header (futur)
1372
+ // Return Values :
1373
+ // true on success,
1374
+ // false on error, the error code is set.
1375
+ // --------------------------------------------------------------------------------
1376
+ function privCheckFormat($p_level=0)
1377
+ {
1378
+ $v_result = true;
1379
+
1380
+ // ----- Reset the file system cache
1381
+ clearstatcache();
1382
+
1383
+ // ----- Reset the error handler
1384
+ $this->privErrorReset();
1385
+
1386
+ // ----- Look if the file exits
1387
+ if (!is_file($this->zipname)) {
1388
+ // ----- Error log
1389
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1390
+ return(false);
1391
+ }
1392
+
1393
+ // ----- Check that the file is readeable
1394
+ if (!is_readable($this->zipname)) {
1395
+ // ----- Error log
1396
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1397
+ return(false);
1398
+ }
1399
+
1400
+ // ----- Check the magic code
1401
+ // TBC
1402
+
1403
+ // ----- Check the central header
1404
+ // TBC
1405
+
1406
+ // ----- Check each file header
1407
+ // TBC
1408
+
1409
+ // ----- Return
1410
+ return $v_result;
1411
+ }
1412
+ // --------------------------------------------------------------------------------
1413
+
1414
+ // --------------------------------------------------------------------------------
1415
+ // Function : privParseOptions()
1416
+ // Description :
1417
+ // This internal methods reads the variable list of arguments ($p_options_list,
1418
+ // $p_size) and generate an array with the options and values ($v_result_list).
1419
+ // $v_requested_options contains the options that can be present and those that
1420
+ // must be present.
1421
+ // $v_requested_options is an array, with the option value as key, and 'optional',
1422
+ // or 'mandatory' as value.
1423
+ // Parameters :
1424
+ // See above.
1425
+ // Return Values :
1426
+ // 1 on success.
1427
+ // 0 on failure.
1428
+ // --------------------------------------------------------------------------------
1429
+ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1430
+ {
1431
+ $v_result=1;
1432
+
1433
+ // ----- Read the options
1434
+ $i=0;
1435
+ while ($i<$p_size) {
1436
+
1437
+ // ----- Check if the option is supported
1438
+ if (!isset($v_requested_options[$p_options_list[$i]])) {
1439
+ // ----- Error log
1440
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1441
+
1442
+ // ----- Return
1443
+ return PclZip::errorCode();
1444
+ }
1445
+
1446
+ // ----- Look for next option
1447
+ switch ($p_options_list[$i]) {
1448
+ // ----- Look for options that request a path value
1449
+ case PCLZIP_OPT_PATH :
1450
+ case PCLZIP_OPT_REMOVE_PATH :
1451
+ case PCLZIP_OPT_ADD_PATH :
1452
+ // ----- Check the number of parameters
1453
+ if (($i+1) >= $p_size) {
1454
+ // ----- Error log
1455
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1456
+
1457
+ // ----- Return
1458
+ return PclZip::errorCode();
1459
+ }
1460
+
1461
+ // ----- Get the value
1462
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1463
+ $i++;
1464
+ break;
1465
+
1466
+ case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
1467
+ // ----- Check the number of parameters
1468
+ if (($i+1) >= $p_size) {
1469
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1470
+ return PclZip::errorCode();
1471
+ }
1472
+
1473
+ // ----- Check for incompatible options
1474
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1475
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1476
+ return PclZip::errorCode();
1477
+ }
1478
+
1479
+ // ----- Check the value
1480
+ $v_value = $p_options_list[$i+1];
1481
+ if ((!is_integer($v_value)) || ($v_value<0)) {
1482
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1483
+ return PclZip::errorCode();
1484
+ }
1485
+
1486
+ // ----- Get the value (and convert it in bytes)
1487
+ $v_result_list[$p_options_list[$i]] = $v_value*1048576;
1488
+ $i++;
1489
+ break;
1490
+
1491
+ case PCLZIP_OPT_TEMP_FILE_ON :
1492
+ // ----- Check for incompatible options
1493
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
1494
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
1495
+ return PclZip::errorCode();
1496
+ }
1497
+
1498
+ $v_result_list[$p_options_list[$i]] = true;
1499
+ break;
1500
+
1501
+ case PCLZIP_OPT_TEMP_FILE_OFF :
1502
+ // ----- Check for incompatible options
1503
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
1504
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
1505
+ return PclZip::errorCode();
1506
+ }
1507
+ // ----- Check for incompatible options
1508
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1509
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
1510
+ return PclZip::errorCode();
1511
+ }
1512
+
1513
+ $v_result_list[$p_options_list[$i]] = true;
1514
+ break;
1515
+
1516
+ case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1517
+ // ----- Check the number of parameters
1518
+ if (($i+1) >= $p_size) {
1519
+ // ----- Error log
1520
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1521
+
1522
+ // ----- Return
1523
+ return PclZip::errorCode();
1524
+ }
1525
+
1526
+ // ----- Get the value
1527
+ if ( is_string($p_options_list[$i+1])
1528
+ && ($p_options_list[$i+1] != '')) {
1529
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
1530
+ $i++;
1531
+ }
1532
+ else {
1533
+ }
1534
+ break;
1535
+
1536
+ // ----- Look for options that request an array of string for value
1537
+ case PCLZIP_OPT_BY_NAME :
1538
+ // ----- Check the number of parameters
1539
+ if (($i+1) >= $p_size) {
1540
+ // ----- Error log
1541
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1542
+
1543
+ // ----- Return
1544
+ return PclZip::errorCode();
1545
+ }
1546
+
1547
+ // ----- Get the value
1548
+ if (is_string($p_options_list[$i+1])) {
1549
+ $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1550
+ }
1551
+ else if (is_array($p_options_list[$i+1])) {
1552
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1553
+ }
1554
+ else {
1555
+ // ----- Error log
1556
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1557
+
1558
+ // ----- Return
1559
+ return PclZip::errorCode();
1560
+ }
1561
+ $i++;
1562
+ break;
1563
+
1564
+ // ----- Look for options that request an EREG or PREG expression
1565
+ case PCLZIP_OPT_BY_EREG :
1566
+ // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
1567
+ // to PCLZIP_OPT_BY_PREG
1568
+ $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
1569
+ case PCLZIP_OPT_BY_PREG :
1570
+ //case PCLZIP_OPT_CRYPT :
1571
+ // ----- Check the number of parameters
1572
+ if (($i+1) >= $p_size) {
1573
+ // ----- Error log
1574
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1575
+
1576
+ // ----- Return
1577
+ return PclZip::errorCode();
1578
+ }
1579
+
1580
+ // ----- Get the value
1581
+ if (is_string($p_options_list[$i+1])) {
1582
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1583
+ }
1584
+ else {
1585
+ // ----- Error log
1586
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1587
+
1588
+ // ----- Return
1589
+ return PclZip::errorCode();
1590
+ }
1591
+ $i++;
1592
+ break;
1593
+
1594
+ // ----- Look for options that takes a string
1595
+ case PCLZIP_OPT_COMMENT :
1596
+ case PCLZIP_OPT_ADD_COMMENT :
1597
+ case PCLZIP_OPT_PREPEND_COMMENT :
1598
+ // ----- Check the number of parameters
1599
+ if (($i+1) >= $p_size) {
1600
+ // ----- Error log
1601
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1602
+ "Missing parameter value for option '"
1603
+ .PclZipUtilOptionText($p_options_list[$i])
1604
+ ."'");
1605
+
1606
+ // ----- Return
1607
+ return PclZip::errorCode();
1608
+ }
1609
+
1610
+ // ----- Get the value
1611
+ if (is_string($p_options_list[$i+1])) {
1612
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1613
+ }
1614
+ else {
1615
+ // ----- Error log
1616
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1617
+ "Wrong parameter value for option '"
1618
+ .PclZipUtilOptionText($p_options_list[$i])
1619
+ ."'");
1620
+
1621
+ // ----- Return
1622
+ return PclZip::errorCode();
1623
+ }
1624
+ $i++;
1625
+ break;
1626
+
1627
+ // ----- Look for options that request an array of index
1628
+ case PCLZIP_OPT_BY_INDEX :
1629
+ // ----- Check the number of parameters
1630
+ if (($i+1) >= $p_size) {
1631
+ // ----- Error log
1632
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1633
+
1634
+ // ----- Return
1635
+ return PclZip::errorCode();
1636
+ }
1637
+
1638
+ // ----- Get the value
1639
+ $v_work_list = array();
1640
+ if (is_string($p_options_list[$i+1])) {
1641
+
1642
+ // ----- Remove spaces
1643
+ $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1644
+
1645
+ // ----- Parse items
1646
+ $v_work_list = explode(",", $p_options_list[$i+1]);
1647
+ }
1648
+ else if (is_integer($p_options_list[$i+1])) {
1649
+ $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1650
+ }
1651
+ else if (is_array($p_options_list[$i+1])) {
1652
+ $v_work_list = $p_options_list[$i+1];
1653
+ }
1654
+ else {
1655
+ // ----- Error log
1656
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1657
+
1658
+ // ----- Return
1659
+ return PclZip::errorCode();
1660
+ }
1661
+
1662
+ // ----- Reduce the index list
1663
+ // each index item in the list must be a couple with a start and
1664
+ // an end value : [0,3], [5-5], [8-10], ...
1665
+ // ----- Check the format of each item
1666
+ $v_sort_flag=false;
1667
+ $v_sort_value=0;
1668
+ for ($j=0; $j<sizeof($v_work_list); $j++) {
1669
+ // ----- Explode the item
1670
+ $v_item_list = explode("-", $v_work_list[$j]);
1671
+ $v_size_item_list = sizeof($v_item_list);
1672
+
1673
+ // ----- TBC : Here we might check that each item is a
1674
+ // real integer ...
1675
+
1676
+ // ----- Look for single value
1677
+ if ($v_size_item_list == 1) {
1678
+ // ----- Set the option value
1679
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1680
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1681
+ }
1682
+ elseif ($v_size_item_list == 2) {
1683
+ // ----- Set the option value
1684
+ $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1685
+ $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1686
+ }
1687
+ else {
1688
+ // ----- Error log
1689
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1690
+
1691
+ // ----- Return
1692
+ return PclZip::errorCode();
1693
+ }
1694
+
1695
+
1696
+ // ----- Look for list sort
1697
+ if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1698
+ $v_sort_flag=true;
1699
+
1700
+ // ----- TBC : An automatic sort should be writen ...
1701
+ // ----- Error log
1702
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1703
+
1704
+ // ----- Return
1705
+ return PclZip::errorCode();
1706
+ }
1707
+ $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1708
+ }
1709
+
1710
+ // ----- Sort the items
1711
+ if ($v_sort_flag) {
1712
+ // TBC : To Be Completed
1713
+ }
1714
+
1715
+ // ----- Next option
1716
+ $i++;
1717
+ break;
1718
+
1719
+ // ----- Look for options that request no value
1720
+ case PCLZIP_OPT_REMOVE_ALL_PATH :
1721
+ case PCLZIP_OPT_EXTRACT_AS_STRING :
1722
+ case PCLZIP_OPT_NO_COMPRESSION :
1723
+ case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1724
+ case PCLZIP_OPT_REPLACE_NEWER :
1725
+ case PCLZIP_OPT_STOP_ON_ERROR :
1726
+ $v_result_list[$p_options_list[$i]] = true;
1727
+ break;
1728
+
1729
+ // ----- Look for options that request an octal value
1730
+ case PCLZIP_OPT_SET_CHMOD :
1731
+ // ----- Check the number of parameters
1732
+ if (($i+1) >= $p_size) {
1733
+ // ----- Error log
1734
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1735
+
1736
+ // ----- Return
1737
+ return PclZip::errorCode();
1738
+ }
1739
+
1740
+ // ----- Get the value
1741
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1742
+ $i++;
1743
+ break;
1744
+
1745
+ // ----- Look for options that request a call-back
1746
+ case PCLZIP_CB_PRE_EXTRACT :
1747
+ case PCLZIP_CB_POST_EXTRACT :
1748
+ case PCLZIP_CB_PRE_ADD :
1749
+ case PCLZIP_CB_POST_ADD :
1750
+ /* for futur use
1751
+ case PCLZIP_CB_PRE_DELETE :
1752
+ case PCLZIP_CB_POST_DELETE :
1753
+ case PCLZIP_CB_PRE_LIST :
1754
+ case PCLZIP_CB_POST_LIST :
1755
+ */
1756
+ // ----- Check the number of parameters
1757
+ if (($i+1) >= $p_size) {
1758
+ // ----- Error log
1759
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1760
+
1761
+ // ----- Return
1762
+ return PclZip::errorCode();
1763
+ }
1764
+
1765
+ // ----- Get the value
1766
+ $v_function_name = $p_options_list[$i+1];
1767
+
1768
+ // ----- Check that the value is a valid existing function
1769
+ if (!function_exists($v_function_name)) {
1770
+ // ----- Error log
1771
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1772
+
1773
+ // ----- Return
1774
+ return PclZip::errorCode();
1775
+ }
1776
+
1777
+ // ----- Set the attribute
1778
+ $v_result_list[$p_options_list[$i]] = $v_function_name;
1779
+ $i++;
1780
+ break;
1781
+
1782
+ default :
1783
+ // ----- Error log
1784
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1785
+ "Unknown parameter '"
1786
+ .$p_options_list[$i]."'");
1787
+
1788
+ // ----- Return
1789
+ return PclZip::errorCode();
1790
+ }
1791
+
1792
+ // ----- Next options
1793
+ $i++;
1794
+ }
1795
+
1796
+ // ----- Look for mandatory options
1797
+ if ($v_requested_options !== false) {
1798
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1799
+ // ----- Look for mandatory option
1800
+ if ($v_requested_options[$key] == 'mandatory') {
1801
+ // ----- Look if present
1802
+ if (!isset($v_result_list[$key])) {
1803
+ // ----- Error log
1804
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1805
+
1806
+ // ----- Return
1807
+ return PclZip::errorCode();
1808
+ }
1809
+ }
1810
+ }
1811
+ }
1812
+
1813
+ // ----- Look for default values
1814
+ if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1815
+
1816
+ }
1817
+
1818
+ // ----- Return
1819
+ return $v_result;
1820
+ }
1821
+ // --------------------------------------------------------------------------------
1822
+
1823
+ // --------------------------------------------------------------------------------
1824
+ // Function : privOptionDefaultThreshold()
1825
+ // Description :
1826
+ // Parameters :
1827
+ // Return Values :
1828
+ // --------------------------------------------------------------------------------
1829
+ function privOptionDefaultThreshold(&$p_options)
1830
+ {
1831
+ $v_result=1;
1832
+
1833
+ if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1834
+ || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1835
+ return $v_result;
1836
+ }
1837
+
1838
+ // ----- Get 'memory_limit' configuration value
1839
+ $v_memory_limit = ini_get('memory_limit');
1840
+ $v_memory_limit = trim($v_memory_limit);
1841
+ $last = strtolower(substr($v_memory_limit, -1));
1842
+
1843
+ if($last == 'g')
1844
+ //$v_memory_limit = $v_memory_limit*1024*1024*1024;
1845
+ $v_memory_limit = $v_memory_limit*1073741824;
1846
+ if($last == 'm')
1847
+ //$v_memory_limit = $v_memory_limit*1024*1024;
1848
+ $v_memory_limit = $v_memory_limit*1048576;
1849
+ if($last == 'k')
1850
+ $v_memory_limit = $v_memory_limit*1024;
1851
+
1852
+ $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1853
+
1854
+
1855
+ // ----- Sanity check : No threshold if value lower than 1M
1856
+ if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1857
+ unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1858
+ }
1859
+
1860
+ // ----- Return
1861
+ return $v_result;
1862
+ }
1863
+ // --------------------------------------------------------------------------------
1864
+
1865
+ // --------------------------------------------------------------------------------
1866
+ // Function : privFileDescrParseAtt()
1867
+ // Description :
1868
+ // Parameters :
1869
+ // Return Values :
1870
+ // 1 on success.
1871
+ // 0 on failure.
1872
+ // --------------------------------------------------------------------------------
1873
+ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1874
+ {
1875
+ $v_result=1;
1876
+
1877
+ // ----- For each file in the list check the attributes
1878
+ foreach ($p_file_list as $v_key => $v_value) {
1879
+
1880
+ // ----- Check if the option is supported
1881
+ if (!isset($v_requested_options[$v_key])) {
1882
+ // ----- Error log
1883
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1884
+
1885
+ // ----- Return
1886
+ return PclZip::errorCode();
1887
+ }
1888
+
1889
+ // ----- Look for attribute
1890
+ switch ($v_key) {
1891
+ case PCLZIP_ATT_FILE_NAME :
1892
+ if (!is_string($v_value)) {
1893
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1894
+ return PclZip::errorCode();
1895
+ }
1896
+
1897
+ $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1898
+
1899
+ if ($p_filedescr['filename'] == '') {
1900
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1901
+ return PclZip::errorCode();
1902
+ }
1903
+
1904
+ break;
1905
+
1906
+ case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1907
+ if (!is_string($v_value)) {
1908
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1909
+ return PclZip::errorCode();
1910
+ }
1911
+
1912
+ $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1913
+
1914
+ if ($p_filedescr['new_short_name'] == '') {
1915
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1916
+ return PclZip::errorCode();
1917
+ }
1918
+ break;
1919
+
1920
+ case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1921
+ if (!is_string($v_value)) {
1922
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1923
+ return PclZip::errorCode();
1924
+ }
1925
+
1926
+ $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1927
+
1928
+ if ($p_filedescr['new_full_name'] == '') {
1929
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1930
+ return PclZip::errorCode();
1931
+ }
1932
+ break;
1933
+
1934
+ // ----- Look for options that takes a string
1935
+ case PCLZIP_ATT_FILE_COMMENT :
1936
+ if (!is_string($v_value)) {
1937
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1938
+ return PclZip::errorCode();
1939
+ }
1940
+
1941
+ $p_filedescr['comment'] = $v_value;
1942
+ break;
1943
+
1944
+ case PCLZIP_ATT_FILE_MTIME :
1945
+ if (!is_integer($v_value)) {
1946
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1947
+ return PclZip::errorCode();
1948
+ }
1949
+
1950
+ $p_filedescr['mtime'] = $v_value;
1951
+ break;
1952
+
1953
+ case PCLZIP_ATT_FILE_CONTENT :
1954
+ $p_filedescr['content'] = $v_value;
1955
+ break;
1956
+
1957
+ default :
1958
+ // ----- Error log
1959
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1960
+ "Unknown parameter '".$v_key."'");
1961
+
1962
+ // ----- Return
1963
+ return PclZip::errorCode();
1964
+ }
1965
+
1966
+ // ----- Look for mandatory options
1967
+ if ($v_requested_options !== false) {
1968
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1969
+ // ----- Look for mandatory option
1970
+ if ($v_requested_options[$key] == 'mandatory') {
1971
+ // ----- Look if present
1972
+ if (!isset($p_file_list[$key])) {
1973
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1974
+ return PclZip::errorCode();
1975
+ }
1976
+ }
1977
+ }
1978
+ }
1979
+
1980
+ // end foreach
1981
+ }
1982
+
1983
+ // ----- Return
1984
+ return $v_result;
1985
+ }
1986
+ // --------------------------------------------------------------------------------
1987
+
1988
+ // --------------------------------------------------------------------------------
1989
+ // Function : privFileDescrExpand()
1990
+ // Description :
1991
+ // This method look for each item of the list to see if its a file, a folder
1992
+ // or a string to be added as file. For any other type of files (link, other)
1993
+ // just ignore the item.
1994
+ // Then prepare the information that will be stored for that file.
1995
+ // When its a folder, expand the folder with all the files that are in that
1996
+ // folder (recursively).
1997
+ // Parameters :
1998
+ // Return Values :
1999
+ // 1 on success.
2000
+ // 0 on failure.
2001
+ // --------------------------------------------------------------------------------
2002
+ function privFileDescrExpand(&$p_filedescr_list, &$p_options)
2003
+ {
2004
+ $v_result=1;
2005
+
2006
+ // ----- Create a result list
2007
+ $v_result_list = array();
2008
+
2009
+ // ----- Look each entry
2010
+ for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
2011
+
2012
+ // ----- Get filedescr
2013
+ $v_descr = $p_filedescr_list[$i];
2014
+
2015
+ // ----- Reduce the filename
2016
+ $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
2017
+ $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
2018
+
2019
+ // ----- Look for real file or folder
2020
+ if (file_exists($v_descr['filename'])) {
2021
+ if (@is_file($v_descr['filename'])) {
2022
+ $v_descr['type'] = 'file';
2023
+ }
2024
+ else if (@is_dir($v_descr['filename'])) {
2025
+ $v_descr['type'] = 'folder';
2026
+ }
2027
+ else if (@is_link($v_descr['filename'])) {
2028
+ // skip
2029
+ continue;
2030
+ }
2031
+ else {
2032
+ // skip
2033
+ continue;
2034
+ }
2035
+ }
2036
+
2037
+ // ----- Look for string added as file
2038
+ else if (isset($v_descr['content'])) {
2039
+ $v_descr['type'] = 'virtual_file';
2040
+ }
2041
+
2042
+ // ----- Missing file
2043
+ else {
2044
+ // ----- Error log
2045
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
2046
+
2047
+ // ----- Return
2048
+ return PclZip::errorCode();
2049
+ }
2050
+
2051
+ // ----- Calculate the stored filename
2052
+ $this->privCalculateStoredFilename($v_descr, $p_options);
2053
+
2054
+ // ----- Add the descriptor in result list
2055
+ $v_result_list[sizeof($v_result_list)] = $v_descr;
2056
+
2057
+ // ----- Look for folder
2058
+ if ($v_descr['type'] == 'folder') {
2059
+ // ----- List of items in folder
2060
+ $v_dirlist_descr = array();
2061
+ $v_dirlist_nb = 0;
2062
+ if ($v_folder_handler = @opendir($v_descr['filename'])) {
2063
+ while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2064
+
2065
+ // ----- Skip '.' and '..'
2066
+ if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2067
+ continue;
2068
+ }
2069
+
2070
+ // ----- Compose the full filename
2071
+ $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2072
+
2073
+ // ----- Look for different stored filename
2074
+ // Because the name of the folder was changed, the name of the
2075
+ // files/sub-folders also change
2076
+ if (($v_descr['stored_filename'] != $v_descr['filename'])
2077
+ && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2078
+ if ($v_descr['stored_filename'] != '') {
2079
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2080
+ }
2081
+ else {
2082
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
2083
+ }
2084
+ }
2085
+
2086
+ $v_dirlist_nb++;
2087
+ }
2088
+
2089
+ @closedir($v_folder_handler);
2090
+ }
2091
+ else {
2092
+ // TBC : unable to open folder in read mode
2093
+ }
2094
+
2095
+ // ----- Expand each element of the list
2096
+ if ($v_dirlist_nb != 0) {
2097
+ // ----- Expand
2098
+ if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2099
+ return $v_result;
2100
+ }
2101
+
2102
+ // ----- Concat the resulting list
2103
+ $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2104
+ }
2105
+ else {
2106
+ }
2107
+
2108
+ // ----- Free local array
2109
+ unset($v_dirlist_descr);
2110
+ }
2111
+ }
2112
+
2113
+ // ----- Get the result list
2114
+ $p_filedescr_list = $v_result_list;
2115
+
2116
+ // ----- Return
2117
+ return $v_result;
2118
+ }
2119
+ // --------------------------------------------------------------------------------
2120
+
2121
+ // --------------------------------------------------------------------------------
2122
+ // Function : privCreate()
2123
+ // Description :
2124
+ // Parameters :
2125
+ // Return Values :
2126
+ // --------------------------------------------------------------------------------
2127
+ function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2128
+ {
2129
+ $v_result=1;
2130
+ $v_list_detail = array();
2131
+
2132
+ // ----- Magic quotes trick
2133
+ $this->privDisableMagicQuotes();
2134
+
2135
+ // ----- Open the file in write mode
2136
+ if (($v_result = $this->privOpenFd('wb')) != 1)
2137
+ {
2138
+ // ----- Return
2139
+ return $v_result;
2140
+ }
2141
+
2142
+ // ----- Add the list of files
2143
+ $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2144
+
2145
+ // ----- Close
2146
+ $this->privCloseFd();
2147
+
2148
+ // ----- Magic quotes trick
2149
+ $this->privSwapBackMagicQuotes();
2150
+
2151
+ // ----- Return
2152
+ return $v_result;
2153
+ }
2154
+ // --------------------------------------------------------------------------------
2155
+
2156
+ // --------------------------------------------------------------------------------
2157
+ // Function : privAdd()
2158
+ // Description :
2159
+ // Parameters :
2160
+ // Return Values :
2161
+ // --------------------------------------------------------------------------------
2162
+ function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2163
+ {
2164
+ $v_result=1;
2165
+ $v_list_detail = array();
2166
+
2167
+ // ----- Look if the archive exists or is empty
2168
+ if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2169
+ {
2170
+
2171
+ // ----- Do a create
2172
+ $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2173
+
2174
+ // ----- Return
2175
+ return $v_result;
2176
+ }
2177
+ // ----- Magic quotes trick
2178
+ $this->privDisableMagicQuotes();
2179
+
2180
+ // ----- Open the zip file
2181
+ if (($v_result=$this->privOpenFd('rb')) != 1)
2182
+ {
2183
+ // ----- Magic quotes trick
2184
+ $this->privSwapBackMagicQuotes();
2185
+
2186
+ // ----- Return
2187
+ return $v_result;
2188
+ }
2189
+
2190
+ // ----- Read the central directory informations
2191
+ $v_central_dir = array();
2192
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2193
+ {
2194
+ $this->privCloseFd();
2195
+ $this->privSwapBackMagicQuotes();
2196
+ return $v_result;
2197
+ }
2198
+
2199
+ // ----- Go to beginning of File
2200
+ @rewind($this->zip_fd);
2201
+
2202
+ // ----- Creates a temporay file
2203
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2204
+
2205
+ // ----- Open the temporary file in write mode
2206
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2207
+ {
2208
+ $this->privCloseFd();
2209
+ $this->privSwapBackMagicQuotes();
2210
+
2211
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2212
+
2213
+ // ----- Return
2214
+ return PclZip::errorCode();
2215
+ }
2216
+
2217
+ // ----- Copy the files from the archive to the temporary file
2218
+ // TBC : Here I should better append the file and go back to erase the central dir
2219
+ $v_size = $v_central_dir['offset'];
2220
+ while ($v_size != 0)
2221
+ {
2222
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2223
+ $v_buffer = fread($this->zip_fd, $v_read_size);
2224
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2225
+ $v_size -= $v_read_size;
2226
+ }
2227
+
2228
+ // ----- Swap the file descriptor
2229
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2230
+ // the following methods on the temporary fil and not the real archive
2231
+ $v_swap = $this->zip_fd;
2232
+ $this->zip_fd = $v_zip_temp_fd;
2233
+ $v_zip_temp_fd = $v_swap;
2234
+
2235
+ // ----- Add the files
2236
+ $v_header_list = array();
2237
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2238
+ {
2239
+ fclose($v_zip_temp_fd);
2240
+ $this->privCloseFd();
2241
+ @unlink($v_zip_temp_name);
2242
+ $this->privSwapBackMagicQuotes();
2243
+
2244
+ // ----- Return
2245
+ return $v_result;
2246
+ }
2247
+
2248
+ // ----- Store the offset of the central dir
2249
+ $v_offset = @ftell($this->zip_fd);
2250
+
2251
+ // ----- Copy the block of file headers from the old archive
2252
+ $v_size = $v_central_dir['size'];
2253
+ while ($v_size != 0)
2254
+ {
2255
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2256
+ $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2257
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2258
+ $v_size -= $v_read_size;
2259
+ }
2260
+
2261
+ // ----- Create the Central Dir files header
2262
+ for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2263
+ {
2264
+ // ----- Create the file header
2265
+ if ($v_header_list[$i]['status'] == 'ok') {
2266
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2267
+ fclose($v_zip_temp_fd);
2268
+ $this->privCloseFd();
2269
+ @unlink($v_zip_temp_name);
2270
+ $this->privSwapBackMagicQuotes();
2271
+
2272
+ // ----- Return
2273
+ return $v_result;
2274
+ }
2275
+ $v_count++;
2276
+ }
2277
+
2278
+ // ----- Transform the header to a 'usable' info
2279
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2280
+ }
2281
+
2282
+ // ----- Zip file comment
2283
+ $v_comment = $v_central_dir['comment'];
2284
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2285
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2286
+ }
2287
+ if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2288
+ $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2289
+ }
2290
+ if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2291
+ $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2292
+ }
2293
+
2294
+ // ----- Calculate the size of the central header
2295
+ $v_size = @ftell($this->zip_fd)-$v_offset;
2296
+
2297
+ // ----- Create the central dir footer
2298
+ if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2299
+ {
2300
+ // ----- Reset the file list
2301
+ unset($v_header_list);
2302
+ $this->privSwapBackMagicQuotes();
2303
+
2304
+ // ----- Return
2305
+ return $v_result;
2306
+ }
2307
+
2308
+ // ----- Swap back the file descriptor
2309
+ $v_swap = $this->zip_fd;
2310
+ $this->zip_fd = $v_zip_temp_fd;
2311
+ $v_zip_temp_fd = $v_swap;
2312
+
2313
+ // ----- Close
2314
+ $this->privCloseFd();
2315
+
2316
+ // ----- Close the temporary file
2317
+ @fclose($v_zip_temp_fd);
2318
+
2319
+ // ----- Magic quotes trick
2320
+ $this->privSwapBackMagicQuotes();
2321
+
2322
+ // ----- Delete the zip file
2323
+ // TBC : I should test the result ...
2324
+ @unlink($this->zipname);
2325
+
2326
+ // ----- Rename the temporary file
2327
+ // TBC : I should test the result ...
2328
+ //@rename($v_zip_temp_name, $this->zipname);
2329
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
2330
+
2331
+ // ----- Return
2332
+ return $v_result;
2333
+ }
2334
+ // --------------------------------------------------------------------------------
2335
+
2336
+ // --------------------------------------------------------------------------------
2337
+ // Function : privOpenFd()
2338
+ // Description :
2339
+ // Parameters :
2340
+ // --------------------------------------------------------------------------------
2341
+ function privOpenFd($p_mode)
2342
+ {
2343
+ $v_result=1;
2344
+
2345
+ // ----- Look if already open
2346
+ if ($this->zip_fd != 0)
2347
+ {
2348
+ // ----- Error log
2349
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2350
+
2351
+ // ----- Return
2352
+ return PclZip::errorCode();
2353
+ }
2354
+
2355
+ // ----- Open the zip file
2356
+ if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2357
+ {
2358
+ // ----- Error log
2359
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2360
+
2361
+ // ----- Return
2362
+ return PclZip::errorCode();
2363
+ }
2364
+
2365
+ // ----- Return
2366
+ return $v_result;
2367
+ }
2368
+ // --------------------------------------------------------------------------------
2369
+
2370
+ // --------------------------------------------------------------------------------
2371
+ // Function : privCloseFd()
2372
+ // Description :
2373
+ // Parameters :
2374
+ // --------------------------------------------------------------------------------
2375
+ function privCloseFd()
2376
+ {
2377
+ $v_result=1;
2378
+
2379
+ if ($this->zip_fd != 0)
2380
+ @fclose($this->zip_fd);
2381
+ $this->zip_fd = 0;
2382
+
2383
+ // ----- Return
2384
+ return $v_result;
2385
+ }
2386
+ // --------------------------------------------------------------------------------
2387
+
2388
+ // --------------------------------------------------------------------------------
2389
+ // Function : privAddList()
2390
+ // Description :
2391
+ // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2392
+ // different from the real path of the file. This is usefull if you want to have PclTar
2393
+ // running in any directory, and memorize relative path from an other directory.
2394
+ // Parameters :
2395
+ // $p_list : An array containing the file or directory names to add in the tar
2396
+ // $p_result_list : list of added files with their properties (specially the status field)
2397
+ // $p_add_dir : Path to add in the filename path archived
2398
+ // $p_remove_dir : Path to remove in the filename path archived
2399
+ // Return Values :
2400
+ // --------------------------------------------------------------------------------
2401
+ // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2402
+ function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2403
+ {
2404
+ $v_result=1;
2405
+
2406
+ // ----- Add the files
2407
+ $v_header_list = array();
2408
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2409
+ {
2410
+ // ----- Return
2411
+ return $v_result;
2412
+ }
2413
+
2414
+ // ----- Store the offset of the central dir
2415
+ $v_offset = @ftell($this->zip_fd);
2416
+
2417
+ // ----- Create the Central Dir files header
2418
+ for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2419
+ {
2420
+ // ----- Create the file header
2421
+ if ($v_header_list[$i]['status'] == 'ok') {
2422
+ if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2423
+ // ----- Return
2424
+ return $v_result;
2425
+ }
2426
+ $v_count++;
2427
+ }
2428
+
2429
+ // ----- Transform the header to a 'usable' info
2430
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2431
+ }
2432
+
2433
+ // ----- Zip file comment
2434
+ $v_comment = '';
2435
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2436
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2437
+ }
2438
+
2439
+ // ----- Calculate the size of the central header
2440
+ $v_size = @ftell($this->zip_fd)-$v_offset;
2441
+
2442
+ // ----- Create the central dir footer
2443
+ if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2444
+ {
2445
+ // ----- Reset the file list
2446
+ unset($v_header_list);
2447
+
2448
+ // ----- Return
2449
+ return $v_result;
2450
+ }
2451
+
2452
+ // ----- Return
2453
+ return $v_result;
2454
+ }
2455
+ // --------------------------------------------------------------------------------
2456
+
2457
+ // --------------------------------------------------------------------------------
2458
+ // Function : privAddFileList()
2459
+ // Description :
2460
+ // Parameters :
2461
+ // $p_filedescr_list : An array containing the file description
2462
+ // or directory names to add in the zip
2463
+ // $p_result_list : list of added files with their properties (specially the status field)
2464
+ // Return Values :
2465
+ // --------------------------------------------------------------------------------
2466
+ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2467
+ {
2468
+ $v_result=1;
2469
+ $v_header = array();
2470
+
2471
+ // ----- Recuperate the current number of elt in list
2472
+ $v_nb = sizeof($p_result_list);
2473
+
2474
+ // ----- Loop on the files
2475
+ for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2476
+ // ----- Format the filename
2477
+ $p_filedescr_list[$j]['filename']
2478
+ = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2479
+
2480
+
2481
+ // ----- Skip empty file names
2482
+ // TBC : Can this be possible ? not checked in DescrParseAtt ?
2483
+ if ($p_filedescr_list[$j]['filename'] == "") {
2484
+ continue;
2485
+ }
2486
+
2487
+ // ----- Check the filename
2488
+ if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
2489
+ && (!file_exists($p_filedescr_list[$j]['filename']))) {
2490
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
2491
+ return PclZip::errorCode();
2492
+ }
2493
+
2494
+ // ----- Look if it is a file or a dir with no all path remove option
2495
+ // or a dir with all its path removed
2496
+ // if ( (is_file($p_filedescr_list[$j]['filename']))
2497
+ // || ( is_dir($p_filedescr_list[$j]['filename'])
2498
+ if ( ($p_filedescr_list[$j]['type'] == 'file')
2499
+ || ($p_filedescr_list[$j]['type'] == 'virtual_file')
2500
+ || ( ($p_filedescr_list[$j]['type'] == 'folder')
2501
+ && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2502
+ || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
2503
+ ) {
2504
+
2505
+ // ----- Add the file
2506
+ $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2507
+ $p_options);
2508
+ if ($v_result != 1) {
2509
+ return $v_result;
2510
+ }
2511
+
2512
+ // ----- Store the file infos
2513
+ $p_result_list[$v_nb++] = $v_header;
2514
+ }
2515
+ }
2516
+
2517
+ // ----- Return
2518
+ return $v_result;
2519
+ }
2520
+ // --------------------------------------------------------------------------------
2521
+
2522
+ // --------------------------------------------------------------------------------
2523
+ // Function : privAddFile()
2524
+ // Description :
2525
+ // Parameters :
2526
+ // Return Values :
2527
+ // --------------------------------------------------------------------------------
2528
+ function privAddFile($p_filedescr, &$p_header, &$p_options)
2529
+ {
2530
+ $v_result=1;
2531
+
2532
+ // ----- Working variable
2533
+ $p_filename = $p_filedescr['filename'];
2534
+
2535
+ // TBC : Already done in the fileAtt check ... ?
2536
+ if ($p_filename == "") {
2537
+ // ----- Error log
2538
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2539
+
2540
+ // ----- Return
2541
+ return PclZip::errorCode();
2542
+ }
2543
+
2544
+ // ----- Look for a stored different filename
2545
+ /* TBC : Removed
2546
+ if (isset($p_filedescr['stored_filename'])) {
2547
+ $v_stored_filename = $p_filedescr['stored_filename'];
2548
+ }
2549
+ else {
2550
+ $v_stored_filename = $p_filedescr['stored_filename'];
2551
+ }
2552
+ */
2553
+
2554
+ // ----- Set the file properties
2555
+ clearstatcache();
2556
+ $p_header['version'] = 20;
2557
+ $p_header['version_extracted'] = 10;
2558
+ $p_header['flag'] = 0;
2559
+ $p_header['compression'] = 0;
2560
+ $p_header['crc'] = 0;
2561
+ $p_header['compressed_size'] = 0;
2562
+ $p_header['filename_len'] = strlen($p_filename);
2563
+ $p_header['extra_len'] = 0;
2564
+ $p_header['disk'] = 0;
2565
+ $p_header['internal'] = 0;
2566
+ $p_header['offset'] = 0;
2567
+ $p_header['filename'] = $p_filename;
2568
+ // TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
2569
+ $p_header['stored_filename'] = $p_filedescr['stored_filename'];
2570
+ $p_header['extra'] = '';
2571
+ $p_header['status'] = 'ok';
2572
+ $p_header['index'] = -1;
2573
+
2574
+ // ----- Look for regular file
2575
+ if ($p_filedescr['type']=='file') {
2576
+ $p_header['external'] = 0x00000000;
2577
+ $p_header['size'] = filesize($p_filename);
2578
+ }
2579
+
2580
+ // ----- Look for regular folder
2581
+ else if ($p_filedescr['type']=='folder') {
2582
+ $p_header['external'] = 0x00000010;
2583
+ $p_header['mtime'] = filemtime($p_filename);
2584
+ $p_header['size'] = filesize($p_filename);
2585
+ }
2586
+
2587
+ // ----- Look for virtual file
2588
+ else if ($p_filedescr['type'] == 'virtual_file') {
2589
+ $p_header['external'] = 0x00000000;
2590
+ $p_header['size'] = strlen($p_filedescr['content']);
2591
+ }
2592
+
2593
+
2594
+ // ----- Look for filetime
2595
+ if (isset($p_filedescr['mtime'])) {
2596
+ $p_header['mtime'] = $p_filedescr['mtime'];
2597
+ }
2598
+ else if ($p_filedescr['type'] == 'virtual_file') {
2599
+ $p_header['mtime'] = time();
2600
+ }
2601
+ else {
2602
+ $p_header['mtime'] = filemtime($p_filename);
2603
+ }
2604
+
2605
+ // ------ Look for file comment
2606
+ if (isset($p_filedescr['comment'])) {
2607
+ $p_header['comment_len'] = strlen($p_filedescr['comment']);
2608
+ $p_header['comment'] = $p_filedescr['comment'];
2609
+ }
2610
+ else {
2611
+ $p_header['comment_len'] = 0;
2612
+ $p_header['comment'] = '';
2613
+ }
2614
+
2615
+ // ----- Look for pre-add callback
2616
+ if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2617
+
2618
+ // ----- Generate a local information
2619
+ $v_local_header = array();
2620
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2621
+
2622
+ // ----- Call the callback
2623
+ // Here I do not use call_user_func() because I need to send a reference to the
2624
+ // header.
2625
+ // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2626
+ $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
2627
+ if ($v_result == 0) {
2628
+ // ----- Change the file status
2629
+ $p_header['status'] = "skipped";
2630
+ $v_result = 1;
2631
+ }
2632
+
2633
+ // ----- Update the informations
2634
+ // Only some fields can be modified
2635
+ if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2636
+ $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2637
+ }
2638
+ }
2639
+
2640
+ // ----- Look for empty stored filename
2641
+ if ($p_header['stored_filename'] == "") {
2642
+ $p_header['status'] = "filtered";
2643
+ }
2644
+
2645
+ // ----- Check the path length
2646
+ if (strlen($p_header['stored_filename']) > 0xFF) {
2647
+ $p_header['status'] = 'filename_too_long';
2648
+ }
2649
+
2650
+ // ----- Look if no error, or file not skipped
2651
+ if ($p_header['status'] == 'ok') {
2652
+
2653
+ // ----- Look for a file
2654
+ if ($p_filedescr['type'] == 'file') {
2655
+ // ----- Look for using temporary file to zip
2656
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
2657
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2658
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2659
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
2660
+ $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
2661
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
2662
+ return $v_result;
2663
+ }
2664
+ }
2665
+
2666
+ // ----- Use "in memory" zip algo
2667
+ else {
2668
+
2669
+ // ----- Open the source file
2670
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
2671
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2672
+ return PclZip::errorCode();
2673
+ }
2674
+
2675
+ // ----- Read the file content
2676
+ $v_content = @fread($v_file, $p_header['size']);
2677
+
2678
+ // ----- Close the file
2679
+ @fclose($v_file);
2680
+
2681
+ // ----- Calculate the CRC
2682
+ $p_header['crc'] = @crc32($v_content);
2683
+
2684
+ // ----- Look for no compression
2685
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2686
+ // ----- Set header parameters
2687
+ $p_header['compressed_size'] = $p_header['size'];
2688
+ $p_header['compression'] = 0;
2689
+ }
2690
+
2691
+ // ----- Look for normal compression
2692
+ else {
2693
+ // ----- Compress the content
2694
+ $v_content = @gzdeflate($v_content);
2695
+
2696
+ // ----- Set header parameters
2697
+ $p_header['compressed_size'] = strlen($v_content);
2698
+ $p_header['compression'] = 8;
2699
+ }
2700
+
2701
+ // ----- Call the header generation
2702
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2703
+ @fclose($v_file);
2704
+ return $v_result;
2705
+ }
2706
+
2707
+ // ----- Write the compressed (or not) content
2708
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2709
+
2710
+ }
2711
+
2712
+ }
2713
+
2714
+ // ----- Look for a virtual file (a file from string)
2715
+ else if ($p_filedescr['type'] == 'virtual_file') {
2716
+
2717
+ $v_content = $p_filedescr['content'];
2718
+
2719
+ // ----- Calculate the CRC
2720
+ $p_header['crc'] = @crc32($v_content);
2721
+
2722
+ // ----- Look for no compression
2723
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2724
+ // ----- Set header parameters
2725
+ $p_header['compressed_size'] = $p_header['size'];
2726
+ $p_header['compression'] = 0;
2727
+ }
2728
+
2729
+ // ----- Look for normal compression
2730
+ else {
2731
+ // ----- Compress the content
2732
+ $v_content = @gzdeflate($v_content);
2733
+
2734
+ // ----- Set header parameters
2735
+ $p_header['compressed_size'] = strlen($v_content);
2736
+ $p_header['compression'] = 8;
2737
+ }
2738
+
2739
+ // ----- Call the header generation
2740
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2741
+ @fclose($v_file);
2742
+ return $v_result;
2743
+ }
2744
+
2745
+ // ----- Write the compressed (or not) content
2746
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
2747
+ }
2748
+
2749
+ // ----- Look for a directory
2750
+ else if ($p_filedescr['type'] == 'folder') {
2751
+ // ----- Look for directory last '/'
2752
+ if (@substr($p_header['stored_filename'], -1) != '/') {
2753
+ $p_header['stored_filename'] .= '/';
2754
+ }
2755
+
2756
+ // ----- Set the file properties
2757
+ $p_header['size'] = 0;
2758
+ //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2759
+ $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2760
+
2761
+ // ----- Call the header generation
2762
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2763
+ {
2764
+ return $v_result;
2765
+ }
2766
+ }
2767
+ }
2768
+
2769
+ // ----- Look for post-add callback
2770
+ if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2771
+
2772
+ // ----- Generate a local information
2773
+ $v_local_header = array();
2774
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2775
+
2776
+ // ----- Call the callback
2777
+ // Here I do not use call_user_func() because I need to send a reference to the
2778
+ // header.
2779
+ // eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2780
+ $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
2781
+ if ($v_result == 0) {
2782
+ // ----- Ignored
2783
+ $v_result = 1;
2784
+ }
2785
+
2786
+ // ----- Update the informations
2787
+ // Nothing can be modified
2788
+ }
2789
+
2790
+ // ----- Return
2791
+ return $v_result;
2792
+ }
2793
+ // --------------------------------------------------------------------------------
2794
+
2795
+ // --------------------------------------------------------------------------------
2796
+ // Function : privAddFileUsingTempFile()
2797
+ // Description :
2798
+ // Parameters :
2799
+ // Return Values :
2800
+ // --------------------------------------------------------------------------------
2801
+ function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
2802
+ {
2803
+ $v_result=PCLZIP_ERR_NO_ERROR;
2804
+
2805
+ // ----- Working variable
2806
+ $p_filename = $p_filedescr['filename'];
2807
+
2808
+
2809
+ // ----- Open the source file
2810
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
2811
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2812
+ return PclZip::errorCode();
2813
+ }
2814
+
2815
+ // ----- Creates a compressed temporary file
2816
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2817
+ if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
2818
+ fclose($v_file);
2819
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2820
+ return PclZip::errorCode();
2821
+ }
2822
+
2823
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2824
+ $v_size = filesize($p_filename);
2825
+ while ($v_size != 0) {
2826
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2827
+ $v_buffer = @fread($v_file, $v_read_size);
2828
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2829
+ @gzputs($v_file_compressed, $v_buffer, $v_read_size);
2830
+ $v_size -= $v_read_size;
2831
+ }
2832
+
2833
+ // ----- Close the file
2834
+ @fclose($v_file);
2835
+ @gzclose($v_file_compressed);
2836
+
2837
+ // ----- Check the minimum file size
2838
+ if (filesize($v_gzip_temp_name) < 18) {
2839
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
2840
+ return PclZip::errorCode();
2841
+ }
2842
+
2843
+ // ----- Extract the compressed attributes
2844
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
2845
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2846
+ return PclZip::errorCode();
2847
+ }
2848
+
2849
+ // ----- Read the gzip file header
2850
+ $v_binary_data = @fread($v_file_compressed, 10);
2851
+ $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
2852
+
2853
+ // ----- Check some parameters
2854
+ $v_data_header['os'] = bin2hex($v_data_header['os']);
2855
+
2856
+ // ----- Read the gzip file footer
2857
+ @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
2858
+ $v_binary_data = @fread($v_file_compressed, 8);
2859
+ $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
2860
+
2861
+ // ----- Set the attributes
2862
+ $p_header['compression'] = ord($v_data_header['cm']);
2863
+ //$p_header['mtime'] = $v_data_header['mtime'];
2864
+ $p_header['crc'] = $v_data_footer['crc'];
2865
+ $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
2866
+
2867
+ // ----- Close the file
2868
+ @fclose($v_file_compressed);
2869
+
2870
+ // ----- Call the header generation
2871
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2872
+ return $v_result;
2873
+ }
2874
+
2875
+ // ----- Add the compressed data
2876
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
2877
+ {
2878
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2879
+ return PclZip::errorCode();
2880
+ }
2881
+
2882
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
2883
+ fseek($v_file_compressed, 10);
2884
+ $v_size = $p_header['compressed_size'];
2885
+ while ($v_size != 0)
2886
+ {
2887
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2888
+ $v_buffer = @fread($v_file_compressed, $v_read_size);
2889
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
2890
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2891
+ $v_size -= $v_read_size;
2892
+ }
2893
+
2894
+ // ----- Close the file
2895
+ @fclose($v_file_compressed);
2896
+
2897
+ // ----- Unlink the temporary file
2898
+ @unlink($v_gzip_temp_name);
2899
+
2900
+ // ----- Return
2901
+ return $v_result;
2902
+ }
2903
+ // --------------------------------------------------------------------------------
2904
+
2905
+ // --------------------------------------------------------------------------------
2906
+ // Function : privCalculateStoredFilename()
2907
+ // Description :
2908
+ // Based on file descriptor properties and global options, this method
2909
+ // calculate the filename that will be stored in the archive.
2910
+ // Parameters :
2911
+ // Return Values :
2912
+ // --------------------------------------------------------------------------------
2913
+ function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2914
+ {
2915
+ $v_result=1;
2916
+
2917
+ // ----- Working variables
2918
+ $p_filename = $p_filedescr['filename'];
2919
+ if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2920
+ $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2921
+ }
2922
+ else {
2923
+ $p_add_dir = '';
2924
+ }
2925
+ if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2926
+ $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2927
+ }
2928
+ else {
2929
+ $p_remove_dir = '';
2930
+ }
2931
+ if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2932
+ $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2933
+ }
2934
+ else {
2935
+ $p_remove_all_dir = 0;
2936
+ }
2937
+
2938
+
2939
+ // ----- Look for full name change
2940
+ if (isset($p_filedescr['new_full_name'])) {
2941
+ // ----- Remove drive letter if any
2942
+ $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
2943
+ }
2944
+
2945
+ // ----- Look for path and/or short name change
2946
+ else {
2947
+
2948
+ // ----- Look for short name change
2949
+ // Its when we cahnge just the filename but not the path
2950
+ if (isset($p_filedescr['new_short_name'])) {
2951
+ $v_path_info = pathinfo($p_filename);
2952
+ $v_dir = '';
2953
+ if ($v_path_info['dirname'] != '') {
2954
+ $v_dir = $v_path_info['dirname'].'/';
2955
+ }
2956
+ $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2957
+ }
2958
+ else {
2959
+ // ----- Calculate the stored filename
2960
+ $v_stored_filename = $p_filename;
2961
+ }
2962
+
2963
+ // ----- Look for all path to remove
2964
+ if ($p_remove_all_dir) {
2965
+ $v_stored_filename = basename($p_filename);
2966
+ }
2967
+ // ----- Look for partial path remove
2968
+ else if ($p_remove_dir != "") {
2969
+ if (substr($p_remove_dir, -1) != '/')
2970
+ $p_remove_dir .= "/";
2971
+
2972
+ if ( (substr($p_filename, 0, 2) == "./")
2973
+ || (substr($p_remove_dir, 0, 2) == "./")) {
2974
+
2975
+ if ( (substr($p_filename, 0, 2) == "./")
2976
+ && (substr($p_remove_dir, 0, 2) != "./")) {
2977
+ $p_remove_dir = "./".$p_remove_dir;
2978
+ }
2979
+ if ( (substr($p_filename, 0, 2) != "./")
2980
+ && (substr($p_remove_dir, 0, 2) == "./")) {
2981
+ $p_remove_dir = substr($p_remove_dir, 2);
2982
+ }
2983
+ }
2984
+
2985
+ $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2986
+ $v_stored_filename);
2987
+ if ($v_compare > 0) {
2988
+ if ($v_compare == 2) {
2989
+ $v_stored_filename = "";
2990
+ }
2991
+ else {
2992
+ $v_stored_filename = substr($v_stored_filename,
2993
+ strlen($p_remove_dir));
2994
+ }
2995
+ }
2996
+ }
2997
+
2998
+ // ----- Remove drive letter if any
2999
+ $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
3000
+
3001
+ // ----- Look for path to add
3002
+ if ($p_add_dir != "") {
3003
+ if (substr($p_add_dir, -1) == "/")
3004
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
3005
+ else
3006
+ $v_stored_filename = $p_add_dir."/".$v_stored_filename;
3007
+ }
3008
+ }
3009
+
3010
+ // ----- Filename (reduce the path of stored name)
3011
+ $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
3012
+ $p_filedescr['stored_filename'] = $v_stored_filename;
3013
+
3014
+ // ----- Return
3015
+ return $v_result;
3016
+ }
3017
+ // --------------------------------------------------------------------------------
3018
+
3019
+ // --------------------------------------------------------------------------------
3020
+ // Function : privWriteFileHeader()
3021
+ // Description :
3022
+ // Parameters :
3023
+ // Return Values :
3024
+ // --------------------------------------------------------------------------------
3025
+ function privWriteFileHeader(&$p_header)
3026
+ {
3027
+ $v_result=1;
3028
+
3029
+ // ----- Store the offset position of the file
3030
+ $p_header['offset'] = ftell($this->zip_fd);
3031
+
3032
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
3033
+ $v_date = getdate($p_header['mtime']);
3034
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3035
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3036
+
3037
+ // ----- Packed data
3038
+ $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
3039
+ $p_header['version_extracted'], $p_header['flag'],
3040
+ $p_header['compression'], $v_mtime, $v_mdate,
3041
+ $p_header['crc'], $p_header['compressed_size'],
3042
+ $p_header['size'],
3043
+ strlen($p_header['stored_filename']),
3044
+ $p_header['extra_len']);
3045
+
3046
+ // ----- Write the first 148 bytes of the header in the archive
3047
+ fputs($this->zip_fd, $v_binary_data, 30);
3048
+
3049
+ // ----- Write the variable fields
3050
+ if (strlen($p_header['stored_filename']) != 0)
3051
+ {
3052
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3053
+ }
3054
+ if ($p_header['extra_len'] != 0)
3055
+ {
3056
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3057
+ }
3058
+
3059
+ // ----- Return
3060
+ return $v_result;
3061
+ }
3062
+ // --------------------------------------------------------------------------------
3063
+
3064
+ // --------------------------------------------------------------------------------
3065
+ // Function : privWriteCentralFileHeader()
3066
+ // Description :
3067
+ // Parameters :
3068
+ // Return Values :
3069
+ // --------------------------------------------------------------------------------
3070
+ function privWriteCentralFileHeader(&$p_header)
3071
+ {
3072
+ $v_result=1;
3073
+
3074
+ // TBC
3075
+ //for(reset($p_header); $key = key($p_header); next($p_header)) {
3076
+ //}
3077
+
3078
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
3079
+ $v_date = getdate($p_header['mtime']);
3080
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
3081
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
3082
+
3083
+
3084
+ // ----- Packed data
3085
+ $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
3086
+ $p_header['version'], $p_header['version_extracted'],
3087
+ $p_header['flag'], $p_header['compression'],
3088
+ $v_mtime, $v_mdate, $p_header['crc'],
3089
+ $p_header['compressed_size'], $p_header['size'],
3090
+ strlen($p_header['stored_filename']),
3091
+ $p_header['extra_len'], $p_header['comment_len'],
3092
+ $p_header['disk'], $p_header['internal'],
3093
+ $p_header['external'], $p_header['offset']);
3094
+
3095
+ // ----- Write the 42 bytes of the header in the zip file
3096
+ fputs($this->zip_fd, $v_binary_data, 46);
3097
+
3098
+ // ----- Write the variable fields
3099
+ if (strlen($p_header['stored_filename']) != 0)
3100
+ {
3101
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
3102
+ }
3103
+ if ($p_header['extra_len'] != 0)
3104
+ {
3105
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
3106
+ }
3107
+ if ($p_header['comment_len'] != 0)
3108
+ {
3109
+ fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
3110
+ }
3111
+
3112
+ // ----- Return
3113
+ return $v_result;
3114
+ }
3115
+ // --------------------------------------------------------------------------------
3116
+
3117
+ // --------------------------------------------------------------------------------
3118
+ // Function : privWriteCentralHeader()
3119
+ // Description :
3120
+ // Parameters :
3121
+ // Return Values :
3122
+ // --------------------------------------------------------------------------------
3123
+ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
3124
+ {
3125
+ $v_result=1;
3126
+
3127
+ // ----- Packed data
3128
+ $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
3129
+ $p_nb_entries, $p_size,
3130
+ $p_offset, strlen($p_comment));
3131
+
3132
+ // ----- Write the 22 bytes of the header in the zip file
3133
+ fputs($this->zip_fd, $v_binary_data, 22);
3134
+
3135
+ // ----- Write the variable fields
3136
+ if (strlen($p_comment) != 0)
3137
+ {
3138
+ fputs($this->zip_fd, $p_comment, strlen($p_comment));
3139
+ }
3140
+
3141
+ // ----- Return
3142
+ return $v_result;
3143
+ }
3144
+ // --------------------------------------------------------------------------------
3145
+
3146
+ // --------------------------------------------------------------------------------
3147
+ // Function : privList()
3148
+ // Description :
3149
+ // Parameters :
3150
+ // Return Values :
3151
+ // --------------------------------------------------------------------------------
3152
+ function privList(&$p_list)
3153
+ {
3154
+ $v_result=1;
3155
+
3156
+ // ----- Magic quotes trick
3157
+ $this->privDisableMagicQuotes();
3158
+
3159
+ // ----- Open the zip file
3160
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
3161
+ {
3162
+ // ----- Magic quotes trick
3163
+ $this->privSwapBackMagicQuotes();
3164
+
3165
+ // ----- Error log
3166
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
3167
+
3168
+ // ----- Return
3169
+ return PclZip::errorCode();
3170
+ }
3171
+
3172
+ // ----- Read the central directory informations
3173
+ $v_central_dir = array();
3174
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3175
+ {
3176
+ $this->privSwapBackMagicQuotes();
3177
+ return $v_result;
3178
+ }
3179
+
3180
+ // ----- Go to beginning of Central Dir
3181
+ @rewind($this->zip_fd);
3182
+ if (@fseek($this->zip_fd, $v_central_dir['offset']))
3183
+ {
3184
+ $this->privSwapBackMagicQuotes();
3185
+
3186
+ // ----- Error log
3187
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3188
+
3189
+ // ----- Return
3190
+ return PclZip::errorCode();
3191
+ }
3192
+
3193
+ // ----- Read each entry
3194
+ for ($i=0; $i<$v_central_dir['entries']; $i++)
3195
+ {
3196
+ // ----- Read the file header
3197
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3198
+ {
3199
+ $this->privSwapBackMagicQuotes();
3200
+ return $v_result;
3201
+ }
3202
+ $v_header['index'] = $i;
3203
+
3204
+ // ----- Get the only interesting attributes
3205
+ $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3206
+ unset($v_header);
3207
+ }
3208
+
3209
+ // ----- Close the zip file
3210
+ $this->privCloseFd();
3211
+
3212
+ // ----- Magic quotes trick
3213
+ $this->privSwapBackMagicQuotes();
3214
+
3215
+ // ----- Return
3216
+ return $v_result;
3217
+ }
3218
+ // --------------------------------------------------------------------------------
3219
+
3220
+ // --------------------------------------------------------------------------------
3221
+ // Function : privConvertHeader2FileInfo()
3222
+ // Description :
3223
+ // This function takes the file informations from the central directory
3224
+ // entries and extract the interesting parameters that will be given back.
3225
+ // The resulting file infos are set in the array $p_info
3226
+ // $p_info['filename'] : Filename with full path. Given by user (add),
3227
+ // extracted in the filesystem (extract).
3228
+ // $p_info['stored_filename'] : Stored filename in the archive.
3229
+ // $p_info['size'] = Size of the file.
3230
+ // $p_info['compressed_size'] = Compressed size of the file.
3231
+ // $p_info['mtime'] = Last modification date of the file.
3232
+ // $p_info['comment'] = Comment associated with the file.
3233
+ // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3234
+ // $p_info['status'] = status of the action on the file.
3235
+ // $p_info['crc'] = CRC of the file content.
3236
+ // Parameters :
3237
+ // Return Values :
3238
+ // --------------------------------------------------------------------------------
3239
+ function privConvertHeader2FileInfo($p_header, &$p_info)
3240
+ {
3241
+ $v_result=1;
3242
+
3243
+ // ----- Get the interesting attributes
3244
+ $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
3245
+ $p_info['filename'] = $v_temp_path;
3246
+ $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
3247
+ $p_info['stored_filename'] = $v_temp_path;
3248
+ $p_info['size'] = $p_header['size'];
3249
+ $p_info['compressed_size'] = $p_header['compressed_size'];
3250
+ $p_info['mtime'] = $p_header['mtime'];
3251
+ $p_info['comment'] = $p_header['comment'];
3252
+ $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3253
+ $p_info['index'] = $p_header['index'];
3254
+ $p_info['status'] = $p_header['status'];
3255
+ $p_info['crc'] = $p_header['crc'];
3256
+
3257
+ // ----- Return
3258
+ return $v_result;
3259
+ }
3260
+ // --------------------------------------------------------------------------------
3261
+
3262
+ // --------------------------------------------------------------------------------
3263
+ // Function : privExtractByRule()
3264
+ // Description :
3265
+ // Extract a file or directory depending of rules (by index, by name, ...)
3266
+ // Parameters :
3267
+ // $p_file_list : An array where will be placed the properties of each
3268
+ // extracted file
3269
+ // $p_path : Path to add while writing the extracted files
3270
+ // $p_remove_path : Path to remove (from the file memorized path) while writing the
3271
+ // extracted files. If the path does not match the file path,
3272
+ // the file is extracted with its memorized path.
3273
+ // $p_remove_path does not apply to 'list' mode.
3274
+ // $p_path and $p_remove_path are commulative.
3275
+ // Return Values :
3276
+ // 1 on success,0 or less on error (see error code list)
3277
+ // --------------------------------------------------------------------------------
3278
+ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3279
+ {
3280
+ $v_result=1;
3281
+
3282
+ // ----- Magic quotes trick
3283
+ $this->privDisableMagicQuotes();
3284
+
3285
+ // ----- Check the path
3286
+ if ( ($p_path == "")
3287
+ || ( (substr($p_path, 0, 1) != "/")
3288
+ && (substr($p_path, 0, 3) != "../")
3289
+ && (substr($p_path,1,2)!=":/")))
3290
+ $p_path = "./".$p_path;
3291
+
3292
+ // ----- Reduce the path last (and duplicated) '/'
3293
+ if (($p_path != "./") && ($p_path != "/"))
3294
+ {
3295
+ // ----- Look for the path end '/'
3296
+ while (substr($p_path, -1) == "/")
3297
+ {
3298
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
3299
+ }
3300
+ }
3301
+
3302
+ // ----- Look for path to remove format (should end by /)
3303
+ if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3304
+ {
3305
+ $p_remove_path .= '/';
3306
+ }
3307
+ $p_remove_path_size = strlen($p_remove_path);
3308
+
3309
+ // ----- Open the zip file
3310
+ if (($v_result = $this->privOpenFd('rb')) != 1)
3311
+ {
3312
+ $this->privSwapBackMagicQuotes();
3313
+ return $v_result;
3314
+ }
3315
+
3316
+ // ----- Read the central directory informations
3317
+ $v_central_dir = array();
3318
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3319
+ {
3320
+ // ----- Close the zip file
3321
+ $this->privCloseFd();
3322
+ $this->privSwapBackMagicQuotes();
3323
+
3324
+ return $v_result;
3325
+ }
3326
+
3327
+ // ----- Start at beginning of Central Dir
3328
+ $v_pos_entry = $v_central_dir['offset'];
3329
+
3330
+ // ----- Read each entry
3331
+ $j_start = 0;
3332
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3333
+ {
3334
+
3335
+ // ----- Read next Central dir entry
3336
+ @rewind($this->zip_fd);
3337
+ if (@fseek($this->zip_fd, $v_pos_entry))
3338
+ {
3339
+ // ----- Close the zip file
3340
+ $this->privCloseFd();
3341
+ $this->privSwapBackMagicQuotes();
3342
+
3343
+ // ----- Error log
3344
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3345
+
3346
+ // ----- Return
3347
+ return PclZip::errorCode();
3348
+ }
3349
+
3350
+ // ----- Read the file header
3351
+ $v_header = array();
3352
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3353
+ {
3354
+ // ----- Close the zip file
3355
+ $this->privCloseFd();
3356
+ $this->privSwapBackMagicQuotes();
3357
+
3358
+ return $v_result;
3359
+ }
3360
+
3361
+ // ----- Store the index
3362
+ $v_header['index'] = $i;
3363
+
3364
+ // ----- Store the file position
3365
+ $v_pos_entry = ftell($this->zip_fd);
3366
+
3367
+ // ----- Look for the specific extract rules
3368
+ $v_extract = false;
3369
+
3370
+ // ----- Look for extract by name rule
3371
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
3372
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3373
+
3374
+ // ----- Look if the filename is in the list
3375
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3376
+
3377
+ // ----- Look for a directory
3378
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3379
+
3380
+ // ----- Look if the directory is in the filename path
3381
+ if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3382
+ && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3383
+ $v_extract = true;
3384
+ }
3385
+ }
3386
+ // ----- Look for a filename
3387
+ elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3388
+ $v_extract = true;
3389
+ }
3390
+ }
3391
+ }
3392
+
3393
+ // ----- Look for extract by ereg rule
3394
+ // ereg() is deprecated with PHP 5.3
3395
+ /*
3396
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
3397
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3398
+
3399
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3400
+ $v_extract = true;
3401
+ }
3402
+ }
3403
+ */
3404
+
3405
+ // ----- Look for extract by preg rule
3406
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
3407
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3408
+
3409
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3410
+ $v_extract = true;
3411
+ }
3412
+ }
3413
+
3414
+ // ----- Look for extract by index rule
3415
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3416
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3417
+
3418
+ // ----- Look if the index is in the list
3419
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3420
+
3421
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3422
+ $v_extract = true;
3423
+ }
3424
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3425
+ $j_start = $j+1;
3426
+ }
3427
+
3428
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3429
+ break;
3430
+ }
3431
+ }
3432
+ }
3433
+
3434
+ // ----- Look for no rule, which means extract all the archive
3435
+ else {
3436
+ $v_extract = true;
3437
+ }
3438
+
3439
+ // ----- Check compression method
3440
+ if ( ($v_extract)
3441
+ && ( ($v_header['compression'] != 8)
3442
+ && ($v_header['compression'] != 0))) {
3443
+ $v_header['status'] = 'unsupported_compression';
3444
+
3445
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3446
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3447
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3448
+
3449
+ $this->privSwapBackMagicQuotes();
3450
+
3451
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3452
+ "Filename '".$v_header['stored_filename']."' is "
3453
+ ."compressed by an unsupported compression "
3454
+ ."method (".$v_header['compression'].") ");
3455
+
3456
+ return PclZip::errorCode();
3457
+ }
3458
+ }
3459
+
3460
+ // ----- Check encrypted files
3461
+ if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3462
+ $v_header['status'] = 'unsupported_encryption';
3463
+
3464
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3465
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3466
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3467
+
3468
+ $this->privSwapBackMagicQuotes();
3469
+
3470
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3471
+ "Unsupported encryption for "
3472
+ ." filename '".$v_header['stored_filename']
3473
+ ."'");
3474
+
3475
+ return PclZip::errorCode();
3476
+ }
3477
+ }
3478
+
3479
+ // ----- Look for real extraction
3480
+ if (($v_extract) && ($v_header['status'] != 'ok')) {
3481
+ $v_result = $this->privConvertHeader2FileInfo($v_header,
3482
+ $p_file_list[$v_nb_extracted++]);
3483
+ if ($v_result != 1) {
3484
+ $this->privCloseFd();
3485
+ $this->privSwapBackMagicQuotes();
3486
+ return $v_result;
3487
+ }
3488
+
3489
+ $v_extract = false;
3490
+ }
3491
+
3492
+ // ----- Look for real extraction
3493
+ if ($v_extract)
3494
+ {
3495
+
3496
+ // ----- Go to the file position
3497
+ @rewind($this->zip_fd);
3498
+ if (@fseek($this->zip_fd, $v_header['offset']))
3499
+ {
3500
+ // ----- Close the zip file
3501
+ $this->privCloseFd();
3502
+
3503
+ $this->privSwapBackMagicQuotes();
3504
+
3505
+ // ----- Error log
3506
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3507
+
3508
+ // ----- Return
3509
+ return PclZip::errorCode();
3510
+ }
3511
+
3512
+ // ----- Look for extraction as string
3513
+ if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3514
+
3515
+ $v_string = '';
3516
+
3517
+ // ----- Extracting the file
3518
+ $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
3519
+ if ($v_result1 < 1) {
3520
+ $this->privCloseFd();
3521
+ $this->privSwapBackMagicQuotes();
3522
+ return $v_result1;
3523
+ }
3524
+
3525
+ // ----- Get the only interesting attributes
3526
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3527
+ {
3528
+ // ----- Close the zip file
3529
+ $this->privCloseFd();
3530
+ $this->privSwapBackMagicQuotes();
3531
+
3532
+ return $v_result;
3533
+ }
3534
+
3535
+ // ----- Set the file content
3536
+ $p_file_list[$v_nb_extracted]['content'] = $v_string;
3537
+
3538
+ // ----- Next extracted file
3539
+ $v_nb_extracted++;
3540
+
3541
+ // ----- Look for user callback abort
3542
+ if ($v_result1 == 2) {
3543
+ break;
3544
+ }
3545
+ }
3546
+ // ----- Look for extraction in standard output
3547
+ elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3548
+ && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3549
+ // ----- Extracting the file in standard output
3550
+ $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3551
+ if ($v_result1 < 1) {
3552
+ $this->privCloseFd();
3553
+ $this->privSwapBackMagicQuotes();
3554
+ return $v_result1;
3555
+ }
3556
+
3557
+ // ----- Get the only interesting attributes
3558
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3559
+ $this->privCloseFd();
3560
+ $this->privSwapBackMagicQuotes();
3561
+ return $v_result;
3562
+ }
3563
+
3564
+ // ----- Look for user callback abort
3565
+ if ($v_result1 == 2) {
3566
+ break;
3567
+ }
3568
+ }
3569
+ // ----- Look for normal extraction
3570
+ else {
3571
+ // ----- Extracting the file
3572
+ $v_result1 = $this->privExtractFile($v_header,
3573
+ $p_path, $p_remove_path,
3574
+ $p_remove_all_path,
3575
+ $p_options);
3576
+ if ($v_result1 < 1) {
3577
+ $this->privCloseFd();
3578
+ $this->privSwapBackMagicQuotes();
3579
+ return $v_result1;
3580
+ }
3581
+
3582
+ // ----- Get the only interesting attributes
3583
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3584
+ {
3585
+ // ----- Close the zip file
3586
+ $this->privCloseFd();
3587
+ $this->privSwapBackMagicQuotes();
3588
+
3589
+ return $v_result;
3590
+ }
3591
+
3592
+ // ----- Look for user callback abort
3593
+ if ($v_result1 == 2) {
3594
+ break;
3595
+ }
3596
+ }
3597
+ }
3598
+ }
3599
+
3600
+ // ----- Close the zip file
3601
+ $this->privCloseFd();
3602
+ $this->privSwapBackMagicQuotes();
3603
+
3604
+ // ----- Return
3605
+ return $v_result;
3606
+ }
3607
+ // --------------------------------------------------------------------------------
3608
+
3609
+ // --------------------------------------------------------------------------------
3610
+ // Function : privExtractFile()
3611
+ // Description :
3612
+ // Parameters :
3613
+ // Return Values :
3614
+ //
3615
+ // 1 : ... ?
3616
+ // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3617
+ // --------------------------------------------------------------------------------
3618
+ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3619
+ {
3620
+ $v_result=1;
3621
+
3622
+ // ----- Read the file header
3623
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3624
+ {
3625
+ // ----- Return
3626
+ return $v_result;
3627
+ }
3628
+
3629
+
3630
+ // ----- Check that the file header is coherent with $p_entry info
3631
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3632
+ // TBC
3633
+ }
3634
+
3635
+ // ----- Look for all path to remove
3636
+ if ($p_remove_all_path == true) {
3637
+ // ----- Look for folder entry that not need to be extracted
3638
+ if (($p_entry['external']&0x00000010)==0x00000010) {
3639
+
3640
+ $p_entry['status'] = "filtered";
3641
+
3642
+ return $v_result;
3643
+ }
3644
+
3645
+ // ----- Get the basename of the path
3646
+ $p_entry['filename'] = basename($p_entry['filename']);
3647
+ }
3648
+
3649
+ // ----- Look for path to remove
3650
+ else if ($p_remove_path != "")
3651
+ {
3652
+ if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3653
+ {
3654
+
3655
+ // ----- Change the file status
3656
+ $p_entry['status'] = "filtered";
3657
+
3658
+ // ----- Return
3659
+ return $v_result;
3660
+ }
3661
+
3662
+ $p_remove_path_size = strlen($p_remove_path);
3663
+ if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3664
+ {
3665
+
3666
+ // ----- Remove the path
3667
+ $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3668
+
3669
+ }
3670
+ }
3671
+
3672
+ // ----- Add the path
3673
+ if ($p_path != '') {
3674
+ $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3675
+ }
3676
+
3677
+ // ----- Check a base_dir_restriction
3678
+ if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3679
+ $v_inclusion
3680
+ = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3681
+ $p_entry['filename']);
3682
+ if ($v_inclusion == 0) {
3683
+
3684
+ PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3685
+ "Filename '".$p_entry['filename']."' is "
3686
+ ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3687
+
3688
+ return PclZip::errorCode();
3689
+ }
3690
+ }
3691
+
3692
+ // ----- Look for pre-extract callback
3693
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3694
+
3695
+ // ----- Generate a local information
3696
+ $v_local_header = array();
3697
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3698
+
3699
+ // ----- Call the callback
3700
+ // Here I do not use call_user_func() because I need to send a reference to the
3701
+ // header.
3702
+ // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3703
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
3704
+ if ($v_result == 0) {
3705
+ // ----- Change the file status
3706
+ $p_entry['status'] = "skipped";
3707
+ $v_result = 1;
3708
+ }
3709
+
3710
+ // ----- Look for abort result
3711
+ if ($v_result == 2) {
3712
+ // ----- This status is internal and will be changed in 'skipped'
3713
+ $p_entry['status'] = "aborted";
3714
+ $v_result = PCLZIP_ERR_USER_ABORTED;
3715
+ }
3716
+
3717
+ // ----- Update the informations
3718
+ // Only some fields can be modified
3719
+ $p_entry['filename'] = $v_local_header['filename'];
3720
+ }
3721
+
3722
+
3723
+ // ----- Look if extraction should be done
3724
+ if ($p_entry['status'] == 'ok') {
3725
+
3726
+ // ----- Look for specific actions while the file exist
3727
+ if (file_exists($p_entry['filename']))
3728
+ {
3729
+
3730
+ // ----- Look if file is a directory
3731
+ if (is_dir($p_entry['filename']))
3732
+ {
3733
+
3734
+ // ----- Change the file status
3735
+ $p_entry['status'] = "already_a_directory";
3736
+
3737
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3738
+ // For historical reason first PclZip implementation does not stop
3739
+ // when this kind of error occurs.
3740
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3741
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3742
+
3743
+ PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3744
+ "Filename '".$p_entry['filename']."' is "
3745
+ ."already used by an existing directory");
3746
+
3747
+ return PclZip::errorCode();
3748
+ }
3749
+ }
3750
+ // ----- Look if file is write protected
3751
+ else if (!is_writeable($p_entry['filename']))
3752
+ {
3753
+
3754
+ // ----- Change the file status
3755
+ $p_entry['status'] = "write_protected";
3756
+
3757
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3758
+ // For historical reason first PclZip implementation does not stop
3759
+ // when this kind of error occurs.
3760
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3761
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3762
+
3763
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3764
+ "Filename '".$p_entry['filename']."' exists "
3765
+ ."and is write protected");
3766
+
3767
+ return PclZip::errorCode();
3768
+ }
3769
+ }
3770
+
3771
+ // ----- Look if the extracted file is older
3772
+ else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3773
+ {
3774
+ // ----- Change the file status
3775
+ if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3776
+ && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3777
+ }
3778
+ else {
3779
+ $p_entry['status'] = "newer_exist";
3780
+
3781
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3782
+ // For historical reason first PclZip implementation does not stop
3783
+ // when this kind of error occurs.
3784
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3785
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3786
+
3787
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3788
+ "Newer version of '".$p_entry['filename']."' exists "
3789
+ ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3790
+
3791
+ return PclZip::errorCode();
3792
+ }
3793
+ }
3794
+ }
3795
+ else {
3796
+ }
3797
+ }
3798
+
3799
+ // ----- Check the directory availability and create it if necessary
3800
+ else {
3801
+ if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3802
+ $v_dir_to_check = $p_entry['filename'];
3803
+ else if (!strstr($p_entry['filename'], "/"))
3804
+ $v_dir_to_check = "";
3805
+ else
3806
+ $v_dir_to_check = dirname($p_entry['filename']);
3807
+
3808
+ if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3809
+
3810
+ // ----- Change the file status
3811
+ $p_entry['status'] = "path_creation_fail";
3812
+
3813
+ // ----- Return
3814
+ //return $v_result;
3815
+ $v_result = 1;
3816
+ }
3817
+ }
3818
+ }
3819
+
3820
+ // ----- Look if extraction should be done
3821
+ if ($p_entry['status'] == 'ok') {
3822
+
3823
+ // ----- Do the extraction (if not a folder)
3824
+ if (!(($p_entry['external']&0x00000010)==0x00000010))
3825
+ {
3826
+ // ----- Look for not compressed file
3827
+ if ($p_entry['compression'] == 0) {
3828
+
3829
+ // ----- Opening destination file
3830
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3831
+ {
3832
+
3833
+ // ----- Change the file status
3834
+ $p_entry['status'] = "write_error";
3835
+
3836
+ // ----- Return
3837
+ return $v_result;
3838
+ }
3839
+
3840
+
3841
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3842
+ $v_size = $p_entry['compressed_size'];
3843
+ while ($v_size != 0)
3844
+ {
3845
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3846
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
3847
+ /* Try to speed up the code
3848
+ $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3849
+ @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3850
+ */
3851
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
3852
+ $v_size -= $v_read_size;
3853
+ }
3854
+
3855
+ // ----- Closing the destination file
3856
+ fclose($v_dest_file);
3857
+
3858
+ // ----- Change the file mtime
3859
+ touch($p_entry['filename'], $p_entry['mtime']);
3860
+
3861
+
3862
+ }
3863
+ else {
3864
+ // ----- TBC
3865
+ // Need to be finished
3866
+ if (($p_entry['flag'] & 1) == 1) {
3867
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
3868
+ return PclZip::errorCode();
3869
+ }
3870
+
3871
+
3872
+ // ----- Look for using temporary file to unzip
3873
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
3874
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
3875
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
3876
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
3877
+ $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
3878
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
3879
+ return $v_result;
3880
+ }
3881
+ }
3882
+
3883
+ // ----- Look for extract in memory
3884
+ else {
3885
+
3886
+
3887
+ // ----- Read the compressed file in a buffer (one shot)
3888
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3889
+
3890
+ // ----- Decompress the file
3891
+ $v_file_content = @gzinflate($v_buffer);
3892
+ unset($v_buffer);
3893
+ if ($v_file_content === FALSE) {
3894
+
3895
+ // ----- Change the file status
3896
+ // TBC
3897
+ $p_entry['status'] = "error";
3898
+
3899
+ return $v_result;
3900
+ }
3901
+
3902
+ // ----- Opening destination file
3903
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3904
+
3905
+ // ----- Change the file status
3906
+ $p_entry['status'] = "write_error";
3907
+
3908
+ return $v_result;
3909
+ }
3910
+
3911
+ // ----- Write the uncompressed data
3912
+ @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3913
+ unset($v_file_content);
3914
+
3915
+ // ----- Closing the destination file
3916
+ @fclose($v_dest_file);
3917
+
3918
+ }
3919
+
3920
+ // ----- Change the file mtime
3921
+ @touch($p_entry['filename'], $p_entry['mtime']);
3922
+ }
3923
+
3924
+ // ----- Look for chmod option
3925
+ if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3926
+
3927
+ // ----- Change the mode of the file
3928
+ @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3929
+ }
3930
+
3931
+ }
3932
+ }
3933
+
3934
+ // ----- Change abort status
3935
+ if ($p_entry['status'] == "aborted") {
3936
+ $p_entry['status'] = "skipped";
3937
+ }
3938
+
3939
+ // ----- Look for post-extract callback
3940
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3941
+
3942
+ // ----- Generate a local information
3943
+ $v_local_header = array();
3944
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3945
+
3946
+ // ----- Call the callback
3947
+ // Here I do not use call_user_func() because I need to send a reference to the
3948
+ // header.
3949
+ // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3950
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
3951
+
3952
+ // ----- Look for abort result
3953
+ if ($v_result == 2) {
3954
+ $v_result = PCLZIP_ERR_USER_ABORTED;
3955
+ }
3956
+ }
3957
+
3958
+ // ----- Return
3959
+ return $v_result;
3960
+ }
3961
+ // --------------------------------------------------------------------------------
3962
+
3963
+ // --------------------------------------------------------------------------------
3964
+ // Function : privExtractFileUsingTempFile()
3965
+ // Description :
3966
+ // Parameters :
3967
+ // Return Values :
3968
+ // --------------------------------------------------------------------------------
3969
+ function privExtractFileUsingTempFile(&$p_entry, &$p_options)
3970
+ {
3971
+ $v_result=1;
3972
+
3973
+ // ----- Creates a temporary file
3974
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
3975
+ if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
3976
+ fclose($v_file);
3977
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
3978
+ return PclZip::errorCode();
3979
+ }
3980
+
3981
+
3982
+ // ----- Write gz file format header
3983
+ $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
3984
+ @fwrite($v_dest_file, $v_binary_data, 10);
3985
+
3986
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3987
+ $v_size = $p_entry['compressed_size'];
3988
+ while ($v_size != 0)
3989
+ {
3990
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3991
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
3992
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
3993
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
3994
+ $v_size -= $v_read_size;
3995
+ }
3996
+
3997
+ // ----- Write gz file format footer
3998
+ $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
3999
+ @fwrite($v_dest_file, $v_binary_data, 8);
4000
+
4001
+ // ----- Close the temporary file
4002
+ @fclose($v_dest_file);
4003
+
4004
+ // ----- Opening destination file
4005
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
4006
+ $p_entry['status'] = "write_error";
4007
+ return $v_result;
4008
+ }
4009
+
4010
+ // ----- Open the temporary gz file
4011
+ if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
4012
+ @fclose($v_dest_file);
4013
+ $p_entry['status'] = "read_error";
4014
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
4015
+ return PclZip::errorCode();
4016
+ }
4017
+
4018
+
4019
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
4020
+ $v_size = $p_entry['size'];
4021
+ while ($v_size != 0) {
4022
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4023
+ $v_buffer = @gzread($v_src_file, $v_read_size);
4024
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
4025
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
4026
+ $v_size -= $v_read_size;
4027
+ }
4028
+ @fclose($v_dest_file);
4029
+ @gzclose($v_src_file);
4030
+
4031
+ // ----- Delete the temporary file
4032
+ @unlink($v_gzip_temp_name);
4033
+
4034
+ // ----- Return
4035
+ return $v_result;
4036
+ }
4037
+ // --------------------------------------------------------------------------------
4038
+
4039
+ // --------------------------------------------------------------------------------
4040
+ // Function : privExtractFileInOutput()
4041
+ // Description :
4042
+ // Parameters :
4043
+ // Return Values :
4044
+ // --------------------------------------------------------------------------------
4045
+ function privExtractFileInOutput(&$p_entry, &$p_options)
4046
+ {
4047
+ $v_result=1;
4048
+
4049
+ // ----- Read the file header
4050
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
4051
+ return $v_result;
4052
+ }
4053
+
4054
+
4055
+ // ----- Check that the file header is coherent with $p_entry info
4056
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4057
+ // TBC
4058
+ }
4059
+
4060
+ // ----- Look for pre-extract callback
4061
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4062
+
4063
+ // ----- Generate a local information
4064
+ $v_local_header = array();
4065
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4066
+
4067
+ // ----- Call the callback
4068
+ // Here I do not use call_user_func() because I need to send a reference to the
4069
+ // header.
4070
+ // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4071
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4072
+ if ($v_result == 0) {
4073
+ // ----- Change the file status
4074
+ $p_entry['status'] = "skipped";
4075
+ $v_result = 1;
4076
+ }
4077
+
4078
+ // ----- Look for abort result
4079
+ if ($v_result == 2) {
4080
+ // ----- This status is internal and will be changed in 'skipped'
4081
+ $p_entry['status'] = "aborted";
4082
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4083
+ }
4084
+
4085
+ // ----- Update the informations
4086
+ // Only some fields can be modified
4087
+ $p_entry['filename'] = $v_local_header['filename'];
4088
+ }
4089
+
4090
+ // ----- Trace
4091
+
4092
+ // ----- Look if extraction should be done
4093
+ if ($p_entry['status'] == 'ok') {
4094
+
4095
+ // ----- Do the extraction (if not a folder)
4096
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4097
+ // ----- Look for not compressed file
4098
+ if ($p_entry['compressed_size'] == $p_entry['size']) {
4099
+
4100
+ // ----- Read the file in a buffer (one shot)
4101
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4102
+
4103
+ // ----- Send the file to the output
4104
+ echo $v_buffer;
4105
+ unset($v_buffer);
4106
+ }
4107
+ else {
4108
+
4109
+ // ----- Read the compressed file in a buffer (one shot)
4110
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
4111
+
4112
+ // ----- Decompress the file
4113
+ $v_file_content = gzinflate($v_buffer);
4114
+ unset($v_buffer);
4115
+
4116
+ // ----- Send the file to the output
4117
+ echo $v_file_content;
4118
+ unset($v_file_content);
4119
+ }
4120
+ }
4121
+ }
4122
+
4123
+ // ----- Change abort status
4124
+ if ($p_entry['status'] == "aborted") {
4125
+ $p_entry['status'] = "skipped";
4126
+ }
4127
+
4128
+ // ----- Look for post-extract callback
4129
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4130
+
4131
+ // ----- Generate a local information
4132
+ $v_local_header = array();
4133
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4134
+
4135
+ // ----- Call the callback
4136
+ // Here I do not use call_user_func() because I need to send a reference to the
4137
+ // header.
4138
+ // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4139
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4140
+
4141
+ // ----- Look for abort result
4142
+ if ($v_result == 2) {
4143
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4144
+ }
4145
+ }
4146
+
4147
+ return $v_result;
4148
+ }
4149
+ // --------------------------------------------------------------------------------
4150
+
4151
+ // --------------------------------------------------------------------------------
4152
+ // Function : privExtractFileAsString()
4153
+ // Description :
4154
+ // Parameters :
4155
+ // Return Values :
4156
+ // --------------------------------------------------------------------------------
4157
+ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
4158
+ {
4159
+ $v_result=1;
4160
+
4161
+ // ----- Read the file header
4162
+ $v_header = array();
4163
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4164
+ {
4165
+ // ----- Return
4166
+ return $v_result;
4167
+ }
4168
+
4169
+
4170
+ // ----- Check that the file header is coherent with $p_entry info
4171
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4172
+ // TBC
4173
+ }
4174
+
4175
+ // ----- Look for pre-extract callback
4176
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
4177
+
4178
+ // ----- Generate a local information
4179
+ $v_local_header = array();
4180
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4181
+
4182
+ // ----- Call the callback
4183
+ // Here I do not use call_user_func() because I need to send a reference to the
4184
+ // header.
4185
+ // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
4186
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
4187
+ if ($v_result == 0) {
4188
+ // ----- Change the file status
4189
+ $p_entry['status'] = "skipped";
4190
+ $v_result = 1;
4191
+ }
4192
+
4193
+ // ----- Look for abort result
4194
+ if ($v_result == 2) {
4195
+ // ----- This status is internal and will be changed in 'skipped'
4196
+ $p_entry['status'] = "aborted";
4197
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4198
+ }
4199
+
4200
+ // ----- Update the informations
4201
+ // Only some fields can be modified
4202
+ $p_entry['filename'] = $v_local_header['filename'];
4203
+ }
4204
+
4205
+
4206
+ // ----- Look if extraction should be done
4207
+ if ($p_entry['status'] == 'ok') {
4208
+
4209
+ // ----- Do the extraction (if not a folder)
4210
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
4211
+ // ----- Look for not compressed file
4212
+ // if ($p_entry['compressed_size'] == $p_entry['size'])
4213
+ if ($p_entry['compression'] == 0) {
4214
+
4215
+ // ----- Reading the file
4216
+ $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4217
+ }
4218
+ else {
4219
+
4220
+ // ----- Reading the file
4221
+ $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4222
+
4223
+ // ----- Decompress the file
4224
+ if (($p_string = @gzinflate($v_data)) === FALSE) {
4225
+ // TBC
4226
+ }
4227
+ }
4228
+
4229
+ // ----- Trace
4230
+ }
4231
+ else {
4232
+ // TBC : error : can not extract a folder in a string
4233
+ }
4234
+
4235
+ }
4236
+
4237
+ // ----- Change abort status
4238
+ if ($p_entry['status'] == "aborted") {
4239
+ $p_entry['status'] = "skipped";
4240
+ }
4241
+
4242
+ // ----- Look for post-extract callback
4243
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
4244
+
4245
+ // ----- Generate a local information
4246
+ $v_local_header = array();
4247
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
4248
+
4249
+ // ----- Swap the content to header
4250
+ $v_local_header['content'] = $p_string;
4251
+ $p_string = '';
4252
+
4253
+ // ----- Call the callback
4254
+ // Here I do not use call_user_func() because I need to send a reference to the
4255
+ // header.
4256
+ // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
4257
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
4258
+
4259
+ // ----- Swap back the content to header
4260
+ $p_string = $v_local_header['content'];
4261
+ unset($v_local_header['content']);
4262
+
4263
+ // ----- Look for abort result
4264
+ if ($v_result == 2) {
4265
+ $v_result = PCLZIP_ERR_USER_ABORTED;
4266
+ }
4267
+ }
4268
+
4269
+ // ----- Return
4270
+ return $v_result;
4271
+ }
4272
+ // --------------------------------------------------------------------------------
4273
+
4274
+ // --------------------------------------------------------------------------------
4275
+ // Function : privReadFileHeader()
4276
+ // Description :
4277
+ // Parameters :
4278
+ // Return Values :
4279
+ // --------------------------------------------------------------------------------
4280
+ function privReadFileHeader(&$p_header)
4281
+ {
4282
+ $v_result=1;
4283
+
4284
+ // ----- Read the 4 bytes signature
4285
+ $v_binary_data = @fread($this->zip_fd, 4);
4286
+ $v_data = unpack('Vid', $v_binary_data);
4287
+
4288
+ // ----- Check signature
4289
+ if ($v_data['id'] != 0x04034b50)
4290
+ {
4291
+
4292
+ // ----- Error log
4293
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4294
+
4295
+ // ----- Return
4296
+ return PclZip::errorCode();
4297
+ }
4298
+
4299
+ // ----- Read the first 42 bytes of the header
4300
+ $v_binary_data = fread($this->zip_fd, 26);
4301
+
4302
+ // ----- Look for invalid block size
4303
+ if (strlen($v_binary_data) != 26)
4304
+ {
4305
+ $p_header['filename'] = "";
4306
+ $p_header['status'] = "invalid_header";
4307
+
4308
+ // ----- Error log
4309
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4310
+
4311
+ // ----- Return
4312
+ return PclZip::errorCode();
4313
+ }
4314
+
4315
+ // ----- Extract the values
4316
+ $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4317
+
4318
+ // ----- Get filename
4319
+ $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4320
+
4321
+ // ----- Get extra_fields
4322
+ if ($v_data['extra_len'] != 0) {
4323
+ $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4324
+ }
4325
+ else {
4326
+ $p_header['extra'] = '';
4327
+ }
4328
+
4329
+ // ----- Extract properties
4330
+ $p_header['version_extracted'] = $v_data['version'];
4331
+ $p_header['compression'] = $v_data['compression'];
4332
+ $p_header['size'] = $v_data['size'];
4333
+ $p_header['compressed_size'] = $v_data['compressed_size'];
4334
+ $p_header['crc'] = $v_data['crc'];
4335
+ $p_header['flag'] = $v_data['flag'];
4336
+ $p_header['filename_len'] = $v_data['filename_len'];
4337
+
4338
+ // ----- Recuperate date in UNIX format
4339
+ $p_header['mdate'] = $v_data['mdate'];
4340
+ $p_header['mtime'] = $v_data['mtime'];
4341
+ if ($p_header['mdate'] && $p_header['mtime'])
4342
+ {
4343
+ // ----- Extract time
4344
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4345
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4346
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4347
+
4348
+ // ----- Extract date
4349
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4350
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4351
+ $v_day = $p_header['mdate'] & 0x001F;
4352
+
4353
+ // ----- Get UNIX date format
4354
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4355
+
4356
+ }
4357
+ else
4358
+ {
4359
+ $p_header['mtime'] = time();
4360
+ }
4361
+
4362
+ // TBC
4363
+ //for(reset($v_data); $key = key($v_data); next($v_data)) {
4364
+ //}
4365
+
4366
+ // ----- Set the stored filename
4367
+ $p_header['stored_filename'] = $p_header['filename'];
4368
+
4369
+ // ----- Set the status field
4370
+ $p_header['status'] = "ok";
4371
+
4372
+ // ----- Return
4373
+ return $v_result;
4374
+ }
4375
+ // --------------------------------------------------------------------------------
4376
+
4377
+ // --------------------------------------------------------------------------------
4378
+ // Function : privReadCentralFileHeader()
4379
+ // Description :
4380
+ // Parameters :
4381
+ // Return Values :
4382
+ // --------------------------------------------------------------------------------
4383
+ function privReadCentralFileHeader(&$p_header)
4384
+ {
4385
+ $v_result=1;
4386
+
4387
+ // ----- Read the 4 bytes signature
4388
+ $v_binary_data = @fread($this->zip_fd, 4);
4389
+ $v_data = unpack('Vid', $v_binary_data);
4390
+
4391
+ // ----- Check signature
4392
+ if ($v_data['id'] != 0x02014b50)
4393
+ {
4394
+
4395
+ // ----- Error log
4396
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4397
+
4398
+ // ----- Return
4399
+ return PclZip::errorCode();
4400
+ }
4401
+
4402
+ // ----- Read the first 42 bytes of the header
4403
+ $v_binary_data = fread($this->zip_fd, 42);
4404
+
4405
+ // ----- Look for invalid block size
4406
+ if (strlen($v_binary_data) != 42)
4407
+ {
4408
+ $p_header['filename'] = "";
4409
+ $p_header['status'] = "invalid_header";
4410
+
4411
+ // ----- Error log
4412
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4413
+
4414
+ // ----- Return
4415
+ return PclZip::errorCode();
4416
+ }
4417
+
4418
+ // ----- Extract the values
4419
+ $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
4420
+
4421
+ // ----- Get filename
4422
+ if ($p_header['filename_len'] != 0)
4423
+ $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4424
+ else
4425
+ $p_header['filename'] = '';
4426
+
4427
+ // ----- Get extra
4428
+ if ($p_header['extra_len'] != 0)
4429
+ $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4430
+ else
4431
+ $p_header['extra'] = '';
4432
+
4433
+ // ----- Get comment
4434
+ if ($p_header['comment_len'] != 0)
4435
+ $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4436
+ else
4437
+ $p_header['comment'] = '';
4438
+
4439
+ // ----- Extract properties
4440
+
4441
+ // ----- Recuperate date in UNIX format
4442
+ //if ($p_header['mdate'] && $p_header['mtime'])
4443
+ // TBC : bug : this was ignoring time with 0/0/0
4444
+ if (1)
4445
+ {
4446
+ // ----- Extract time
4447
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4448
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4449
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4450
+
4451
+ // ----- Extract date
4452
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4453
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4454
+ $v_day = $p_header['mdate'] & 0x001F;
4455
+
4456
+ // ----- Get UNIX date format
4457
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4458
+
4459
+ }
4460
+ else
4461
+ {
4462
+ $p_header['mtime'] = time();
4463
+ }
4464
+
4465
+ // ----- Set the stored filename
4466
+ $p_header['stored_filename'] = $p_header['filename'];
4467
+
4468
+ // ----- Set default status to ok
4469
+ $p_header['status'] = 'ok';
4470
+
4471
+ // ----- Look if it is a directory
4472
+ if (substr($p_header['filename'], -1) == '/') {
4473
+ //$p_header['external'] = 0x41FF0010;
4474
+ $p_header['external'] = 0x00000010;
4475
+ }
4476
+
4477
+
4478
+ // ----- Return
4479
+ return $v_result;
4480
+ }
4481
+ // --------------------------------------------------------------------------------
4482
+
4483
+ // --------------------------------------------------------------------------------
4484
+ // Function : privCheckFileHeaders()
4485
+ // Description :
4486
+ // Parameters :
4487
+ // Return Values :
4488
+ // 1 on success,
4489
+ // 0 on error;
4490
+ // --------------------------------------------------------------------------------
4491
+ function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4492
+ {
4493
+ $v_result=1;
4494
+
4495
+ // ----- Check the static values
4496
+ // TBC
4497
+ if ($p_local_header['filename'] != $p_central_header['filename']) {
4498
+ }
4499
+ if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4500
+ }
4501
+ if ($p_local_header['flag'] != $p_central_header['flag']) {
4502
+ }
4503
+ if ($p_local_header['compression'] != $p_central_header['compression']) {
4504
+ }
4505
+ if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4506
+ }
4507
+ if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4508
+ }
4509
+
4510
+ // ----- Look for flag bit 3
4511
+ if (($p_local_header['flag'] & 8) == 8) {
4512
+ $p_local_header['size'] = $p_central_header['size'];
4513
+ $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4514
+ $p_local_header['crc'] = $p_central_header['crc'];
4515
+ }
4516
+
4517
+ // ----- Return
4518
+ return $v_result;
4519
+ }
4520
+ // --------------------------------------------------------------------------------
4521
+
4522
+ // --------------------------------------------------------------------------------
4523
+ // Function : privReadEndCentralDir()
4524
+ // Description :
4525
+ // Parameters :
4526
+ // Return Values :
4527
+ // --------------------------------------------------------------------------------
4528
+ function privReadEndCentralDir(&$p_central_dir)
4529
+ {
4530
+ $v_result=1;
4531
+
4532
+ // ----- Go to the end of the zip file
4533
+ $v_size = filesize($this->zipname);
4534
+ @fseek($this->zip_fd, $v_size);
4535
+ if (@ftell($this->zip_fd) != $v_size)
4536
+ {
4537
+ // ----- Error log
4538
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4539
+
4540
+ // ----- Return
4541
+ return PclZip::errorCode();
4542
+ }
4543
+
4544
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
4545
+ // in this case the end of central dir is at 22 bytes of the file end
4546
+ $v_found = 0;
4547
+ if ($v_size > 26) {
4548
+ @fseek($this->zip_fd, $v_size-22);
4549
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4550
+ {
4551
+ // ----- Error log
4552
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4553
+
4554
+ // ----- Return
4555
+ return PclZip::errorCode();
4556
+ }
4557
+
4558
+ // ----- Read for bytes
4559
+ $v_binary_data = @fread($this->zip_fd, 4);
4560
+ $v_data = @unpack('Vid', $v_binary_data);
4561
+
4562
+ // ----- Check signature
4563
+ if ($v_data['id'] == 0x06054b50) {
4564
+ $v_found = 1;
4565
+ }
4566
+
4567
+ $v_pos = ftell($this->zip_fd);
4568
+ }
4569
+
4570
+ // ----- Go back to the maximum possible size of the Central Dir End Record
4571
+ if (!$v_found) {
4572
+ $v_maximum_size = 65557; // 0xFFFF + 22;
4573
+ if ($v_maximum_size > $v_size)
4574
+ $v_maximum_size = $v_size;
4575
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
4576
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4577
+ {
4578
+ // ----- Error log
4579
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4580
+
4581
+ // ----- Return
4582
+ return PclZip::errorCode();
4583
+ }
4584
+
4585
+ // ----- Read byte per byte in order to find the signature
4586
+ $v_pos = ftell($this->zip_fd);
4587
+ $v_bytes = 0x00000000;
4588
+ while ($v_pos < $v_size)
4589
+ {
4590
+ // ----- Read a byte
4591
+ $v_byte = @fread($this->zip_fd, 1);
4592
+
4593
+ // ----- Add the byte
4594
+ //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
4595
+ // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
4596
+ // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
4597
+ $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4598
+
4599
+ // ----- Compare the bytes
4600
+ if ($v_bytes == 0x504b0506)
4601
+ {
4602
+ $v_pos++;
4603
+ break;
4604
+ }
4605
+
4606
+ $v_pos++;
4607
+ }
4608
+
4609
+ // ----- Look if not found end of central dir
4610
+ if ($v_pos == $v_size)
4611
+ {
4612
+
4613
+ // ----- Error log
4614
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4615
+
4616
+ // ----- Return
4617
+ return PclZip::errorCode();
4618
+ }
4619
+ }
4620
+
4621
+ // ----- Read the first 18 bytes of the header
4622
+ $v_binary_data = fread($this->zip_fd, 18);
4623
+
4624
+ // ----- Look for invalid block size
4625
+ if (strlen($v_binary_data) != 18)
4626
+ {
4627
+
4628
+ // ----- Error log
4629
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4630
+
4631
+ // ----- Return
4632
+ return PclZip::errorCode();
4633
+ }
4634
+
4635
+ // ----- Extract the values
4636
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4637
+
4638
+ // ----- Check the global size
4639
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4640
+
4641
+ // ----- Removed in release 2.2 see readme file
4642
+ // The check of the file size is a little too strict.
4643
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4644
+ // While decrypted, zip has training 0 bytes
4645
+ if (0) {
4646
+ // ----- Error log
4647
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4648
+ 'The central dir is not at the end of the archive.'
4649
+ .' Some trailing bytes exists after the archive.');
4650
+
4651
+ // ----- Return
4652
+ return PclZip::errorCode();
4653
+ }
4654
+ }
4655
+
4656
+ // ----- Get comment
4657
+ if ($v_data['comment_size'] != 0) {
4658
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4659
+ }
4660
+ else
4661
+ $p_central_dir['comment'] = '';
4662
+
4663
+ $p_central_dir['entries'] = $v_data['entries'];
4664
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4665
+ $p_central_dir['offset'] = $v_data['offset'];
4666
+ $p_central_dir['size'] = $v_data['size'];
4667
+ $p_central_dir['disk'] = $v_data['disk'];
4668
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
4669
+
4670
+ // TBC
4671
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4672
+ //}
4673
+
4674
+ // ----- Return
4675
+ return $v_result;
4676
+ }
4677
+ // --------------------------------------------------------------------------------
4678
+
4679
+ // --------------------------------------------------------------------------------
4680
+ // Function : privDeleteByRule()
4681
+ // Description :
4682
+ // Parameters :
4683
+ // Return Values :
4684
+ // --------------------------------------------------------------------------------
4685
+ function privDeleteByRule(&$p_result_list, &$p_options)
4686
+ {
4687
+ $v_result=1;
4688
+ $v_list_detail = array();
4689
+
4690
+ // ----- Open the zip file
4691
+ if (($v_result=$this->privOpenFd('rb')) != 1)
4692
+ {
4693
+ // ----- Return
4694
+ return $v_result;
4695
+ }
4696
+
4697
+ // ----- Read the central directory informations
4698
+ $v_central_dir = array();
4699
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4700
+ {
4701
+ $this->privCloseFd();
4702
+ return $v_result;
4703
+ }
4704
+
4705
+ // ----- Go to beginning of File
4706
+ @rewind($this->zip_fd);
4707
+
4708
+ // ----- Scan all the files
4709
+ // ----- Start at beginning of Central Dir
4710
+ $v_pos_entry = $v_central_dir['offset'];
4711
+ @rewind($this->zip_fd);
4712
+ if (@fseek($this->zip_fd, $v_pos_entry))
4713
+ {
4714
+ // ----- Close the zip file
4715
+ $this->privCloseFd();
4716
+
4717
+ // ----- Error log
4718
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4719
+
4720
+ // ----- Return
4721
+ return PclZip::errorCode();
4722
+ }
4723
+
4724
+ // ----- Read each entry
4725
+ $v_header_list = array();
4726
+ $j_start = 0;
4727
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4728
+ {
4729
+
4730
+ // ----- Read the file header
4731
+ $v_header_list[$v_nb_extracted] = array();
4732
+ if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4733
+ {
4734
+ // ----- Close the zip file
4735
+ $this->privCloseFd();
4736
+
4737
+ return $v_result;
4738
+ }
4739
+
4740
+
4741
+ // ----- Store the index
4742
+ $v_header_list[$v_nb_extracted]['index'] = $i;
4743
+
4744
+ // ----- Look for the specific extract rules
4745
+ $v_found = false;
4746
+
4747
+ // ----- Look for extract by name rule
4748
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
4749
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4750
+
4751
+ // ----- Look if the filename is in the list
4752
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4753
+
4754
+ // ----- Look for a directory
4755
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4756
+
4757
+ // ----- Look if the directory is in the filename path
4758
+ if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4759
+ && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4760
+ $v_found = true;
4761
+ }
4762
+ elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4763
+ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4764
+ $v_found = true;
4765
+ }
4766
+ }
4767
+ // ----- Look for a filename
4768
+ elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4769
+ $v_found = true;
4770
+ }
4771
+ }
4772
+ }
4773
+
4774
+ // ----- Look for extract by ereg rule
4775
+ // ereg() is deprecated with PHP 5.3
4776
+ /*
4777
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
4778
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4779
+
4780
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4781
+ $v_found = true;
4782
+ }
4783
+ }
4784
+ */
4785
+
4786
+ // ----- Look for extract by preg rule
4787
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
4788
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4789
+
4790
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4791
+ $v_found = true;
4792
+ }
4793
+ }
4794
+
4795
+ // ----- Look for extract by index rule
4796
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4797
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4798
+
4799
+ // ----- Look if the index is in the list
4800
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4801
+
4802
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4803
+ $v_found = true;
4804
+ }
4805
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4806
+ $j_start = $j+1;
4807
+ }
4808
+
4809
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4810
+ break;
4811
+ }
4812
+ }
4813
+ }
4814
+ else {
4815
+ $v_found = true;
4816
+ }
4817
+
4818
+ // ----- Look for deletion
4819
+ if ($v_found)
4820
+ {
4821
+ unset($v_header_list[$v_nb_extracted]);
4822
+ }
4823
+ else
4824
+ {
4825
+ $v_nb_extracted++;
4826
+ }
4827
+ }
4828
+
4829
+ // ----- Look if something need to be deleted
4830
+ if ($v_nb_extracted > 0) {
4831
+
4832
+ // ----- Creates a temporay file
4833
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4834
+
4835
+ // ----- Creates a temporary zip archive
4836
+ $v_temp_zip = new PclZip($v_zip_temp_name);
4837
+
4838
+ // ----- Open the temporary zip file in write mode
4839
+ if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4840
+ $this->privCloseFd();
4841
+
4842
+ // ----- Return
4843
+ return $v_result;
4844
+ }
4845
+
4846
+ // ----- Look which file need to be kept
4847
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
4848
+
4849
+ // ----- Calculate the position of the header
4850
+ @rewind($this->zip_fd);
4851
+ if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4852
+ // ----- Close the zip file
4853
+ $this->privCloseFd();
4854
+ $v_temp_zip->privCloseFd();
4855
+ @unlink($v_zip_temp_name);
4856
+
4857
+ // ----- Error log
4858
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4859
+
4860
+ // ----- Return
4861
+ return PclZip::errorCode();
4862
+ }
4863
+
4864
+ // ----- Read the file header
4865
+ $v_local_header = array();
4866
+ if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4867
+ // ----- Close the zip file
4868
+ $this->privCloseFd();
4869
+ $v_temp_zip->privCloseFd();
4870
+ @unlink($v_zip_temp_name);
4871
+
4872
+ // ----- Return
4873
+ return $v_result;
4874
+ }
4875
+
4876
+ // ----- Check that local file header is same as central file header
4877
+ if ($this->privCheckFileHeaders($v_local_header,
4878
+ $v_header_list[$i]) != 1) {
4879
+ // TBC
4880
+ }
4881
+ unset($v_local_header);
4882
+
4883
+ // ----- Write the file header
4884
+ if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4885
+ // ----- Close the zip file
4886
+ $this->privCloseFd();
4887
+ $v_temp_zip->privCloseFd();
4888
+ @unlink($v_zip_temp_name);
4889
+
4890
+ // ----- Return
4891
+ return $v_result;
4892
+ }
4893
+
4894
+ // ----- Read/write the data block
4895
+ if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4896
+ // ----- Close the zip file
4897
+ $this->privCloseFd();
4898
+ $v_temp_zip->privCloseFd();
4899
+ @unlink($v_zip_temp_name);
4900
+
4901
+ // ----- Return
4902
+ return $v_result;
4903
+ }
4904
+ }
4905
+
4906
+ // ----- Store the offset of the central dir
4907
+ $v_offset = @ftell($v_temp_zip->zip_fd);
4908
+
4909
+ // ----- Re-Create the Central Dir files header
4910
+ for ($i=0; $i<sizeof($v_header_list); $i++) {
4911
+ // ----- Create the file header
4912
+ if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4913
+ $v_temp_zip->privCloseFd();
4914
+ $this->privCloseFd();
4915
+ @unlink($v_zip_temp_name);
4916
+
4917
+ // ----- Return
4918
+ return $v_result;
4919
+ }
4920
+
4921
+ // ----- Transform the header to a 'usable' info
4922
+ $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4923
+ }
4924
+
4925
+
4926
+ // ----- Zip file comment
4927
+ $v_comment = '';
4928
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4929
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4930
+ }
4931
+
4932
+ // ----- Calculate the size of the central header
4933
+ $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4934
+
4935
+ // ----- Create the central dir footer
4936
+ if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4937
+ // ----- Reset the file list
4938
+ unset($v_header_list);
4939
+ $v_temp_zip->privCloseFd();
4940
+ $this->privCloseFd();
4941
+ @unlink($v_zip_temp_name);
4942
+
4943
+ // ----- Return
4944
+ return $v_result;
4945
+ }
4946
+
4947
+ // ----- Close
4948
+ $v_temp_zip->privCloseFd();
4949
+ $this->privCloseFd();
4950
+
4951
+ // ----- Delete the zip file
4952
+ // TBC : I should test the result ...
4953
+ @unlink($this->zipname);
4954
+
4955
+ // ----- Rename the temporary file
4956
+ // TBC : I should test the result ...
4957
+ //@rename($v_zip_temp_name, $this->zipname);
4958
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
4959
+
4960
+ // ----- Destroy the temporary archive
4961
+ unset($v_temp_zip);
4962
+ }
4963
+
4964
+ // ----- Remove every files : reset the file
4965
+ else if ($v_central_dir['entries'] != 0) {
4966
+ $this->privCloseFd();
4967
+
4968
+ if (($v_result = $this->privOpenFd('wb')) != 1) {
4969
+ return $v_result;
4970
+ }
4971
+
4972
+ if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4973
+ return $v_result;
4974
+ }
4975
+
4976
+ $this->privCloseFd();
4977
+ }
4978
+
4979
+ // ----- Return
4980
+ return $v_result;
4981
+ }
4982
+ // --------------------------------------------------------------------------------
4983
+
4984
+ // --------------------------------------------------------------------------------
4985
+ // Function : privDirCheck()
4986
+ // Description :
4987
+ // Check if a directory exists, if not it creates it and all the parents directory
4988
+ // which may be useful.
4989
+ // Parameters :
4990
+ // $p_dir : Directory path to check.
4991
+ // Return Values :
4992
+ // 1 : OK
4993
+ // -1 : Unable to create directory
4994
+ // --------------------------------------------------------------------------------
4995
+ function privDirCheck($p_dir, $p_is_dir=false)
4996
+ {
4997
+ $v_result = 1;
4998
+
4999
+
5000
+ // ----- Remove the final '/'
5001
+ if (($p_is_dir) && (substr($p_dir, -1)=='/'))
5002
+ {
5003
+ $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5004
+ }
5005
+
5006
+ // ----- Check the directory availability
5007
+ if ((is_dir($p_dir)) || ($p_dir == ""))
5008
+ {
5009
+ return 1;
5010
+ }
5011
+
5012
+ // ----- Extract parent directory
5013
+ $p_parent_dir = dirname($p_dir);
5014
+
5015
+ // ----- Just a check
5016
+ if ($p_parent_dir != $p_dir)
5017
+ {
5018
+ // ----- Look for parent directory
5019
+ if ($p_parent_dir != "")
5020
+ {
5021
+ if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
5022
+ {
5023
+ return $v_result;
5024
+ }
5025
+ }
5026
+ }
5027
+
5028
+ // ----- Create the directory
5029
+ if (!@mkdir($p_dir, 0777))
5030
+ {
5031
+ // ----- Error log
5032
+ PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
5033
+
5034
+ // ----- Return
5035
+ return PclZip::errorCode();
5036
+ }
5037
+
5038
+ // ----- Return
5039
+ return $v_result;
5040
+ }
5041
+ // --------------------------------------------------------------------------------
5042
+
5043
+ // --------------------------------------------------------------------------------
5044
+ // Function : privMerge()
5045
+ // Description :
5046
+ // If $p_archive_to_add does not exist, the function exit with a success result.
5047
+ // Parameters :
5048
+ // Return Values :
5049
+ // --------------------------------------------------------------------------------
5050
+ function privMerge(&$p_archive_to_add)
5051
+ {
5052
+ $v_result=1;
5053
+
5054
+ // ----- Look if the archive_to_add exists
5055
+ if (!is_file($p_archive_to_add->zipname))
5056
+ {
5057
+
5058
+ // ----- Nothing to merge, so merge is a success
5059
+ $v_result = 1;
5060
+
5061
+ // ----- Return
5062
+ return $v_result;
5063
+ }
5064
+
5065
+ // ----- Look if the archive exists
5066
+ if (!is_file($this->zipname))
5067
+ {
5068
+
5069
+ // ----- Do a duplicate
5070
+ $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5071
+
5072
+ // ----- Return
5073
+ return $v_result;
5074
+ }
5075
+
5076
+ // ----- Open the zip file
5077
+ if (($v_result=$this->privOpenFd('rb')) != 1)
5078
+ {
5079
+ // ----- Return
5080
+ return $v_result;
5081
+ }
5082
+
5083
+ // ----- Read the central directory informations
5084
+ $v_central_dir = array();
5085
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5086
+ {
5087
+ $this->privCloseFd();
5088
+ return $v_result;
5089
+ }
5090
+
5091
+ // ----- Go to beginning of File
5092
+ @rewind($this->zip_fd);
5093
+
5094
+ // ----- Open the archive_to_add file
5095
+ if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5096
+ {
5097
+ $this->privCloseFd();
5098
+
5099
+ // ----- Return
5100
+ return $v_result;
5101
+ }
5102
+
5103
+ // ----- Read the central directory informations
5104
+ $v_central_dir_to_add = array();
5105
+ if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5106
+ {
5107
+ $this->privCloseFd();
5108
+ $p_archive_to_add->privCloseFd();
5109
+
5110
+ return $v_result;
5111
+ }
5112
+
5113
+ // ----- Go to beginning of File
5114
+ @rewind($p_archive_to_add->zip_fd);
5115
+
5116
+ // ----- Creates a temporay file
5117
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5118
+
5119
+ // ----- Open the temporary file in write mode
5120
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5121
+ {
5122
+ $this->privCloseFd();
5123
+ $p_archive_to_add->privCloseFd();
5124
+
5125
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5126
+
5127
+ // ----- Return
5128
+ return PclZip::errorCode();
5129
+ }
5130
+
5131
+ // ----- Copy the files from the archive to the temporary file
5132
+ // TBC : Here I should better append the file and go back to erase the central dir
5133
+ $v_size = $v_central_dir['offset'];
5134
+ while ($v_size != 0)
5135
+ {
5136
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5137
+ $v_buffer = fread($this->zip_fd, $v_read_size);
5138
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5139
+ $v_size -= $v_read_size;
5140
+ }
5141
+
5142
+ // ----- Copy the files from the archive_to_add into the temporary file
5143
+ $v_size = $v_central_dir_to_add['offset'];
5144
+ while ($v_size != 0)
5145
+ {
5146
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5147
+ $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5148
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5149
+ $v_size -= $v_read_size;
5150
+ }
5151
+
5152
+ // ----- Store the offset of the central dir
5153
+ $v_offset = @ftell($v_zip_temp_fd);
5154
+
5155
+ // ----- Copy the block of file headers from the old archive
5156
+ $v_size = $v_central_dir['size'];
5157
+ while ($v_size != 0)
5158
+ {
5159
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5160
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
5161
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5162
+ $v_size -= $v_read_size;
5163
+ }
5164
+
5165
+ // ----- Copy the block of file headers from the archive_to_add
5166
+ $v_size = $v_central_dir_to_add['size'];
5167
+ while ($v_size != 0)
5168
+ {
5169
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5170
+ $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5171
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5172
+ $v_size -= $v_read_size;
5173
+ }
5174
+
5175
+ // ----- Merge the file comments
5176
+ $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5177
+
5178
+ // ----- Calculate the size of the (new) central header
5179
+ $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5180
+
5181
+ // ----- Swap the file descriptor
5182
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5183
+ // the following methods on the temporary fil and not the real archive fd
5184
+ $v_swap = $this->zip_fd;
5185
+ $this->zip_fd = $v_zip_temp_fd;
5186
+ $v_zip_temp_fd = $v_swap;
5187
+
5188
+ // ----- Create the central dir footer
5189
+ if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5190
+ {
5191
+ $this->privCloseFd();
5192
+ $p_archive_to_add->privCloseFd();
5193
+ @fclose($v_zip_temp_fd);
5194
+ $this->zip_fd = null;
5195
+
5196
+ // ----- Reset the file list
5197
+ unset($v_header_list);
5198
+
5199
+ // ----- Return
5200
+ return $v_result;
5201
+ }
5202
+
5203
+ // ----- Swap back the file descriptor
5204
+ $v_swap = $this->zip_fd;
5205
+ $this->zip_fd = $v_zip_temp_fd;
5206
+ $v_zip_temp_fd = $v_swap;
5207
+
5208
+ // ----- Close
5209
+ $this->privCloseFd();
5210
+ $p_archive_to_add->privCloseFd();
5211
+
5212
+ // ----- Close the temporary file
5213
+ @fclose($v_zip_temp_fd);
5214
+
5215
+ // ----- Delete the zip file
5216
+ // TBC : I should test the result ...
5217
+ @unlink($this->zipname);
5218
+
5219
+ // ----- Rename the temporary file
5220
+ // TBC : I should test the result ...
5221
+ //@rename($v_zip_temp_name, $this->zipname);
5222
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
5223
+
5224
+ // ----- Return
5225
+ return $v_result;
5226
+ }
5227
+ // --------------------------------------------------------------------------------
5228
+
5229
+ // --------------------------------------------------------------------------------
5230
+ // Function : privDuplicate()
5231
+ // Description :
5232
+ // Parameters :
5233
+ // Return Values :
5234
+ // --------------------------------------------------------------------------------
5235
+ function privDuplicate($p_archive_filename)
5236
+ {
5237
+ $v_result=1;
5238
+
5239
+ // ----- Look if the $p_archive_filename exists
5240
+ if (!is_file($p_archive_filename))
5241
+ {
5242
+
5243
+ // ----- Nothing to duplicate, so duplicate is a success.
5244
+ $v_result = 1;
5245
+
5246
+ // ----- Return
5247
+ return $v_result;
5248
+ }
5249
+
5250
+ // ----- Open the zip file
5251
+ if (($v_result=$this->privOpenFd('wb')) != 1)
5252
+ {
5253
+ // ----- Return
5254
+ return $v_result;
5255
+ }
5256
+
5257
+ // ----- Open the temporary file in write mode
5258
+ if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5259
+ {
5260
+ $this->privCloseFd();
5261
+
5262
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5263
+
5264
+ // ----- Return
5265
+ return PclZip::errorCode();
5266
+ }
5267
+
5268
+ // ----- Copy the files from the archive to the temporary file
5269
+ // TBC : Here I should better append the file and go back to erase the central dir
5270
+ $v_size = filesize($p_archive_filename);
5271
+ while ($v_size != 0)
5272
+ {
5273
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5274
+ $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5275
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
5276
+ $v_size -= $v_read_size;
5277
+ }
5278
+
5279
+ // ----- Close
5280
+ $this->privCloseFd();
5281
+
5282
+ // ----- Close the temporary file
5283
+ @fclose($v_zip_temp_fd);
5284
+
5285
+ // ----- Return
5286
+ return $v_result;
5287
+ }
5288
+ // --------------------------------------------------------------------------------
5289
+
5290
+ // --------------------------------------------------------------------------------
5291
+ // Function : privErrorLog()
5292
+ // Description :
5293
+ // Parameters :
5294
+ // --------------------------------------------------------------------------------
5295
+ function privErrorLog($p_error_code=0, $p_error_string='')
5296
+ {
5297
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
5298
+ PclError($p_error_code, $p_error_string);
5299
+ }
5300
+ else {
5301
+ $this->error_code = $p_error_code;
5302
+ $this->error_string = $p_error_string;
5303
+ }
5304
+ }
5305
+ // --------------------------------------------------------------------------------
5306
+
5307
+ // --------------------------------------------------------------------------------
5308
+ // Function : privErrorReset()
5309
+ // Description :
5310
+ // Parameters :
5311
+ // --------------------------------------------------------------------------------
5312
+ function privErrorReset()
5313
+ {
5314
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
5315
+ PclErrorReset();
5316
+ }
5317
+ else {
5318
+ $this->error_code = 0;
5319
+ $this->error_string = '';
5320
+ }
5321
+ }
5322
+ // --------------------------------------------------------------------------------
5323
+
5324
+ // --------------------------------------------------------------------------------
5325
+ // Function : privDisableMagicQuotes()
5326
+ // Description :
5327
+ // Parameters :
5328
+ // Return Values :
5329
+ // --------------------------------------------------------------------------------
5330
+ function privDisableMagicQuotes()
5331
+ {
5332
+ $v_result=1;
5333
+
5334
+ // ----- Look if function exists
5335
+ if ( (!function_exists("get_magic_quotes_runtime"))
5336
+ || (!function_exists("set_magic_quotes_runtime"))) {
5337
+ return $v_result;
5338
+ }
5339
+
5340
+ // ----- Look if already done
5341
+ if ($this->magic_quotes_status != -1) {
5342
+ return $v_result;
5343
+ }
5344
+
5345
+ // ----- Get and memorize the magic_quote value
5346
+ $this->magic_quotes_status = @get_magic_quotes_runtime();
5347
+
5348
+ // ----- Disable magic_quotes
5349
+ if ($this->magic_quotes_status == 1) {
5350
+ @set_magic_quotes_runtime(0);
5351
+ }
5352
+
5353
+ // ----- Return
5354
+ return $v_result;
5355
+ }
5356
+ // --------------------------------------------------------------------------------
5357
+
5358
+ // --------------------------------------------------------------------------------
5359
+ // Function : privSwapBackMagicQuotes()
5360
+ // Description :
5361
+ // Parameters :
5362
+ // Return Values :
5363
+ // --------------------------------------------------------------------------------
5364
+ function privSwapBackMagicQuotes()
5365
+ {
5366
+ $v_result=1;
5367
+
5368
+ // ----- Look if function exists
5369
+ if ( (!function_exists("get_magic_quotes_runtime"))
5370
+ || (!function_exists("set_magic_quotes_runtime"))) {
5371
+ return $v_result;
5372
+ }
5373
+
5374
+ // ----- Look if something to do
5375
+ if ($this->magic_quotes_status != -1) {
5376
+ return $v_result;
5377
+ }
5378
+
5379
+ // ----- Swap back magic_quotes
5380
+ if ($this->magic_quotes_status == 1) {
5381
+ @set_magic_quotes_runtime($this->magic_quotes_status);
5382
+ }
5383
+
5384
+ // ----- Return
5385
+ return $v_result;
5386
+ }
5387
+ // --------------------------------------------------------------------------------
5388
+
5389
+ }
5390
+ // End of class
5391
+ // --------------------------------------------------------------------------------
5392
+
5393
+ // --------------------------------------------------------------------------------
5394
+ // Function : PclZipUtilPathReduction()
5395
+ // Description :
5396
+ // Parameters :
5397
+ // Return Values :
5398
+ // --------------------------------------------------------------------------------
5399
+ function PclZipUtilPathReduction($p_dir)
5400
+ {
5401
+ $v_result = "";
5402
+
5403
+ // ----- Look for not empty path
5404
+ if ($p_dir != "") {
5405
+ // ----- Explode path by directory names
5406
+ $v_list = explode("/", $p_dir);
5407
+
5408
+ // ----- Study directories from last to first
5409
+ $v_skip = 0;
5410
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5411
+ // ----- Look for current path
5412
+ if ($v_list[$i] == ".") {
5413
+ // ----- Ignore this directory
5414
+ // Should be the first $i=0, but no check is done
5415
+ }
5416
+ else if ($v_list[$i] == "..") {
5417
+ $v_skip++;
5418
+ }
5419
+ else if ($v_list[$i] == "") {
5420
+ // ----- First '/' i.e. root slash
5421
+ if ($i == 0) {
5422
+ $v_result = "/".$v_result;
5423
+ if ($v_skip > 0) {
5424
+ // ----- It is an invalid path, so the path is not modified
5425
+ // TBC
5426
+ $v_result = $p_dir;
5427
+ $v_skip = 0;
5428
+ }
5429
+ }
5430
+ // ----- Last '/' i.e. indicates a directory
5431
+ else if ($i == (sizeof($v_list)-1)) {
5432
+ $v_result = $v_list[$i];
5433
+ }
5434
+ // ----- Double '/' inside the path
5435
+ else {
5436
+ // ----- Ignore only the double '//' in path,
5437
+ // but not the first and last '/'
5438
+ }
5439
+ }
5440
+ else {
5441
+ // ----- Look for item to skip
5442
+ if ($v_skip > 0) {
5443
+ $v_skip--;
5444
+ }
5445
+ else {
5446
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5447
+ }
5448
+ }
5449
+ }
5450
+
5451
+ // ----- Look for skip
5452
+ if ($v_skip > 0) {
5453
+ while ($v_skip > 0) {
5454
+ $v_result = '../'.$v_result;
5455
+ $v_skip--;
5456
+ }
5457
+ }
5458
+ }
5459
+
5460
+ // ----- Return
5461
+ return $v_result;
5462
+ }
5463
+ // --------------------------------------------------------------------------------
5464
+
5465
+ // --------------------------------------------------------------------------------
5466
+ // Function : PclZipUtilPathInclusion()
5467
+ // Description :
5468
+ // This function indicates if the path $p_path is under the $p_dir tree. Or,
5469
+ // said in an other way, if the file or sub-dir $p_path is inside the dir
5470
+ // $p_dir.
5471
+ // The function indicates also if the path is exactly the same as the dir.
5472
+ // This function supports path with duplicated '/' like '//', but does not
5473
+ // support '.' or '..' statements.
5474
+ // Parameters :
5475
+ // Return Values :
5476
+ // 0 if $p_path is not inside directory $p_dir
5477
+ // 1 if $p_path is inside directory $p_dir
5478
+ // 2 if $p_path is exactly the same as $p_dir
5479
+ // --------------------------------------------------------------------------------
5480
+ function PclZipUtilPathInclusion($p_dir, $p_path)
5481
+ {
5482
+ $v_result = 1;
5483
+
5484
+ // ----- Look for path beginning by ./
5485
+ if ( ($p_dir == '.')
5486
+ || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5487
+ $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5488
+ }
5489
+ if ( ($p_path == '.')
5490
+ || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5491
+ $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5492
+ }
5493
+
5494
+ // ----- Explode dir and path by directory separator
5495
+ $v_list_dir = explode("/", $p_dir);
5496
+ $v_list_dir_size = sizeof($v_list_dir);
5497
+ $v_list_path = explode("/", $p_path);
5498
+ $v_list_path_size = sizeof($v_list_path);
5499
+
5500
+ // ----- Study directories paths
5501
+ $i = 0;
5502
+ $j = 0;
5503
+ while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5504
+
5505
+ // ----- Look for empty dir (path reduction)
5506
+ if ($v_list_dir[$i] == '') {
5507
+ $i++;
5508
+ continue;
5509
+ }
5510
+ if ($v_list_path[$j] == '') {
5511
+ $j++;
5512
+ continue;
5513
+ }
5514
+
5515
+ // ----- Compare the items
5516
+ if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
5517
+ $v_result = 0;
5518
+ }
5519
+
5520
+ // ----- Next items
5521
+ $i++;
5522
+ $j++;
5523
+ }
5524
+
5525
+ // ----- Look if everything seems to be the same
5526
+ if ($v_result) {
5527
+ // ----- Skip all the empty items
5528
+ while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5529
+ while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5530
+
5531
+ if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5532
+ // ----- There are exactly the same
5533
+ $v_result = 2;
5534
+ }
5535
+ else if ($i < $v_list_dir_size) {
5536
+ // ----- The path is shorter than the dir
5537
+ $v_result = 0;
5538
+ }
5539
+ }
5540
+
5541
+ // ----- Return
5542
+ return $v_result;
5543
+ }
5544
+ // --------------------------------------------------------------------------------
5545
+
5546
+ // --------------------------------------------------------------------------------
5547
+ // Function : PclZipUtilCopyBlock()
5548
+ // Description :
5549
+ // Parameters :
5550
+ // $p_mode : read/write compression mode
5551
+ // 0 : src & dest normal
5552
+ // 1 : src gzip, dest normal
5553
+ // 2 : src normal, dest gzip
5554
+ // 3 : src & dest gzip
5555
+ // Return Values :
5556
+ // --------------------------------------------------------------------------------
5557
+ function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5558
+ {
5559
+ $v_result = 1;
5560
+
5561
+ if ($p_mode==0)
5562
+ {
5563
+ while ($p_size != 0)
5564
+ {
5565
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5566
+ $v_buffer = @fread($p_src, $v_read_size);
5567
+ @fwrite($p_dest, $v_buffer, $v_read_size);
5568
+ $p_size -= $v_read_size;
5569
+ }
5570
+ }
5571
+ else if ($p_mode==1)
5572
+ {
5573
+ while ($p_size != 0)
5574
+ {
5575
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5576
+ $v_buffer = @gzread($p_src, $v_read_size);
5577
+ @fwrite($p_dest, $v_buffer, $v_read_size);
5578
+ $p_size -= $v_read_size;
5579
+ }
5580
+ }
5581
+ else if ($p_mode==2)
5582
+ {
5583
+ while ($p_size != 0)
5584
+ {
5585
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5586
+ $v_buffer = @fread($p_src, $v_read_size);
5587
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
5588
+ $p_size -= $v_read_size;
5589
+ }
5590
+ }
5591
+ else if ($p_mode==3)
5592
+ {
5593
+ while ($p_size != 0)
5594
+ {
5595
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5596
+ $v_buffer = @gzread($p_src, $v_read_size);
5597
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
5598
+ $p_size -= $v_read_size;
5599
+ }
5600
+ }
5601
+
5602
+ // ----- Return
5603
+ return $v_result;
5604
+ }
5605
+ // --------------------------------------------------------------------------------
5606
+
5607
+ // --------------------------------------------------------------------------------
5608
+ // Function : PclZipUtilRename()
5609
+ // Description :
5610
+ // This function tries to do a simple rename() function. If it fails, it
5611
+ // tries to copy the $p_src file in a new $p_dest file and then unlink the
5612
+ // first one.
5613
+ // Parameters :
5614
+ // $p_src : Old filename
5615
+ // $p_dest : New filename
5616
+ // Return Values :
5617
+ // 1 on success, 0 on failure.
5618
+ // --------------------------------------------------------------------------------
5619
+ function PclZipUtilRename($p_src, $p_dest)
5620
+ {
5621
+ $v_result = 1;
5622
+
5623
+ // ----- Try to rename the files
5624
+ if (!@rename($p_src, $p_dest)) {
5625
+
5626
+ // ----- Try to copy & unlink the src
5627
+ if (!@copy($p_src, $p_dest)) {
5628
+ $v_result = 0;
5629
+ }
5630
+ else if (!@unlink($p_src)) {
5631
+ $v_result = 0;
5632
+ }
5633
+ }
5634
+
5635
+ // ----- Return
5636
+ return $v_result;
5637
+ }
5638
+ // --------------------------------------------------------------------------------
5639
+
5640
+ // --------------------------------------------------------------------------------
5641
+ // Function : PclZipUtilOptionText()
5642
+ // Description :
5643
+ // Translate option value in text. Mainly for debug purpose.
5644
+ // Parameters :
5645
+ // $p_option : the option value.
5646
+ // Return Values :
5647
+ // The option text value.
5648
+ // --------------------------------------------------------------------------------
5649
+ function PclZipUtilOptionText($p_option)
5650
+ {
5651
+
5652
+ $v_list = get_defined_constants();
5653
+ for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5654
+ $v_prefix = substr($v_key, 0, 10);
5655
+ if (( ($v_prefix == 'PCLZIP_OPT')
5656
+ || ($v_prefix == 'PCLZIP_CB_')
5657
+ || ($v_prefix == 'PCLZIP_ATT'))
5658
+ && ($v_list[$v_key] == $p_option)) {
5659
+ return $v_key;
5660
+ }
5661
+ }
5662
+
5663
+ $v_result = 'Unknown';
5664
+
5665
+ return $v_result;
5666
+ }
5667
+ // --------------------------------------------------------------------------------
5668
+
5669
+ // --------------------------------------------------------------------------------
5670
+ // Function : PclZipUtilTranslateWinPath()
5671
+ // Description :
5672
+ // Translate windows path by replacing '\' by '/' and optionally removing
5673
+ // drive letter.
5674
+ // Parameters :
5675
+ // $p_path : path to translate.
5676
+ // $p_remove_disk_letter : true | false
5677
+ // Return Values :
5678
+ // The path translated.
5679
+ // --------------------------------------------------------------------------------
5680
+ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5681
+ {
5682
+ if (stristr(php_uname(), 'windows')) {
5683
+ // ----- Look for potential disk letter
5684
+ if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
5685
+ $p_path = substr($p_path, $v_position+1);
5686
+ }
5687
+ // ----- Change potential windows directory separator
5688
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5689
+ $p_path = strtr($p_path, '\\', '/');
5690
+ }
5691
+ }
5692
+ return $p_path;
5693
+ }
5694
+ // --------------------------------------------------------------------------------
5695
+
5696
+
5697
+ ?>
models/file/list.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
-
3
- class PMXI_File_List extends PMXI_Model_List {
4
- public function __construct() {
5
- parent::__construct();
6
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'files');
7
- }
8
-
9
- /**
10
- * Sweep history files in accordance with plugin settings
11
- * @return PMXI_File_List
12
- * @chainable
13
- */
14
- public function sweepHistory() {
15
- $age = PMXI_Plugin::getInstance()->getOption('history_file_age');
16
- if ($age > 0) {
17
- $date = new DateTime(); $date->modify('-' . $age . ' day');
18
- foreach ($this->getBy('registered_on <', $date->format('Y-m-d'))->convertRecords() as $f) {
19
- $f->delete();
20
- }
21
- }
22
- $count = PMXI_Plugin::getInstance()->getOption('history_file_count');
23
- if ($count > 0) {
24
- $count_actual = $this->countBy();
25
- if ($count_actual > $count) foreach ($this->getBy(NULL, 'registered_on', 1, $count_actual - $count)->convertRecords() as $f) {
26
- $f->delete();
27
- }
28
- }
29
-
30
- return $this;
31
- }
32
  }
1
+ <?php
2
+
3
+ class PMXI_File_List extends PMXI_Model_List {
4
+ public function __construct() {
5
+ parent::__construct();
6
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'files');
7
+ }
8
+
9
+ /**
10
+ * Sweep history files in accordance with plugin settings
11
+ * @return PMXI_File_List
12
+ * @chainable
13
+ */
14
+ public function sweepHistory() {
15
+ $age = PMXI_Plugin::getInstance()->getOption('history_file_age');
16
+ if ($age > 0) {
17
+ $date = new DateTime(); $date->modify('-' . $age . ' day');
18
+ foreach ($this->getBy('registered_on <', $date->format('Y-m-d'))->convertRecords() as $f) {
19
+ $f->delete();
20
+ }
21
+ }
22
+ $count = PMXI_Plugin::getInstance()->getOption('history_file_count');
23
+ if ($count > 0) {
24
+ $count_actual = $this->countBy();
25
+ if ($count_actual > $count) foreach ($this->getBy(NULL, 'registered_on', 1, $count_actual - $count)->convertRecords() as $f) {
26
+ $f->delete();
27
+ }
28
+ }
29
+
30
+ return $this;
31
+ }
32
  }
models/file/record.php CHANGED
@@ -1,84 +1,84 @@
1
- <?php
2
-
3
- class PMXI_File_Record extends PMXI_Model_Record {
4
- /**
5
- * Initialize model instance
6
- * @param array[optional] $data Array of record data to initialize object with
7
- */
8
- public function __construct($data = array()) {
9
- parent::__construct($data);
10
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'files');
11
- }
12
-
13
- /**
14
- * @see PMXI_Model_Record::insert()
15
- */
16
- public function insert() {
17
- $file_contents = NULL;
18
- if ($this->offsetExists('contents')) {
19
- $file_contents = $this['contents'];
20
- unset($this->contents);
21
- }
22
-
23
- parent::insert();
24
-
25
- $uploads = wp_upload_dir();
26
-
27
- if (isset($this->id) and ! is_null($file_contents)) {
28
- file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
29
- }
30
-
31
- $list = new PMXI_File_List();
32
- $list->sweepHistory();
33
- return $this;
34
- }
35
-
36
- /**
37
- * @see PMXI_Model_Record::update()
38
- */
39
- public function update() {
40
- $file_contents = NULL;
41
- if ($this->offsetExists('contents')) {
42
- $file_contents = $this['contents'];
43
- unset($this->contents);
44
- }
45
-
46
- parent::update();
47
-
48
- if (isset($this->id) and ! is_null($file_contents)) {
49
- $uploads = wp_upload_dir();
50
- file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
51
- }
52
-
53
- return $this;
54
- }
55
-
56
- public function __isset($field) {
57
- if ('contents' == $field and ! $this->offsetExists($field)) {
58
- $uploads = wp_upload_dir();
59
- return isset($this->id) and file_exists($uploads['basedir'] . '/wpallimport_history/' . $this->id);
60
- }
61
- return parent::__isset($field);
62
- }
63
-
64
- public function __get($field) {
65
- if ('contents' == $field and ! $this->offsetExists('contents')) {
66
- if (isset($this->contents)) {
67
- $uploads = wp_upload_dir();
68
- $this['contents'] = file_get_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id);
69
- } else {
70
- $this->contents = NULL;
71
- }
72
- }
73
- return parent::__get($field);
74
- }
75
-
76
- public function delete() {
77
- if ($this->id) { // delete history file first
78
- $uploads = wp_upload_dir();
79
- $file_name = $uploads['basedir'] . '/wpallimport_history/' . $this->id;
80
- is_file($file_name) and unlink($file_name);
81
- }
82
- return parent::delete();
83
- }
84
  }
1
+ <?php
2
+
3
+ class PMXI_File_Record extends PMXI_Model_Record {
4
+ /**
5
+ * Initialize model instance
6
+ * @param array[optional] $data Array of record data to initialize object with
7
+ */
8
+ public function __construct($data = array()) {
9
+ parent::__construct($data);
10
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'files');
11
+ }
12
+
13
+ /**
14
+ * @see PMXI_Model_Record::insert()
15
+ */
16
+ public function insert() {
17
+ $file_contents = NULL;
18
+ if ($this->offsetExists('contents')) {
19
+ $file_contents = $this['contents'];
20
+ unset($this->contents);
21
+ }
22
+
23
+ parent::insert();
24
+
25
+ $uploads = wp_upload_dir();
26
+
27
+ if (isset($this->id) and ! is_null($file_contents)) {
28
+ file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
29
+ }
30
+
31
+ $list = new PMXI_File_List();
32
+ $list->sweepHistory();
33
+ return $this;
34
+ }
35
+
36
+ /**
37
+ * @see PMXI_Model_Record::update()
38
+ */
39
+ public function update() {
40
+ $file_contents = NULL;
41
+ if ($this->offsetExists('contents')) {
42
+ $file_contents = $this['contents'];
43
+ unset($this->contents);
44
+ }
45
+
46
+ parent::update();
47
+
48
+ if (isset($this->id) and ! is_null($file_contents)) {
49
+ $uploads = wp_upload_dir();
50
+ file_put_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id, $file_contents);
51
+ }
52
+
53
+ return $this;
54
+ }
55
+
56
+ public function __isset($field) {
57
+ if ('contents' == $field and ! $this->offsetExists($field)) {
58
+ $uploads = wp_upload_dir();
59
+ return isset($this->id) and file_exists($uploads['basedir'] . '/wpallimport_history/' . $this->id);
60
+ }
61
+ return parent::__isset($field);
62
+ }
63
+
64
+ public function __get($field) {
65
+ if ('contents' == $field and ! $this->offsetExists('contents')) {
66
+ if (isset($this->contents)) {
67
+ $uploads = wp_upload_dir();
68
+ $this['contents'] = file_get_contents($uploads['basedir'] . '/wpallimport_history/' . $this->id);
69
+ } else {
70
+ $this->contents = NULL;
71
+ }
72
+ }
73
+ return parent::__get($field);
74
+ }
75
+
76
+ public function delete() {
77
+ if ($this->id) { // delete history file first
78
+ $uploads = wp_upload_dir();
79
+ $file_name = $uploads['basedir'] . '/wpallimport_history/' . $this->id;
80
+ is_file($file_name) and unlink($file_name);
81
+ }
82
+ return parent::delete();
83
+ }
84
  }
models/import/list.php CHANGED
@@ -1,8 +1,8 @@
1
- <?php
2
-
3
- class PMXI_Import_List extends PMXI_Model_List {
4
- public function __construct() {
5
- parent::__construct();
6
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
7
- }
8
  }
1
+ <?php
2
+
3
+ class PMXI_Import_List extends PMXI_Model_List {
4
+ public function __construct() {
5
+ parent::__construct();
6
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
7
+ }
8
  }
models/import/record.php CHANGED
@@ -69,20 +69,24 @@ class PMXI_Import_Record extends PMXI_Model_Record {
69
  add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
70
 
71
  $this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
72
- // If import process NOT in large file mode the save history file
73
-
74
  $avoid_pingbacks = PMXI_Plugin::getInstance()->getOption('pingbacks');
75
  $legacy_handling = PMXI_Plugin::getInstance()->getOption('legacy_special_character_handling');
76
 
77
  if ( $avoid_pingbacks and ! defined( 'WP_IMPORTING' ) ) define( 'WP_IMPORTING', true );
78
 
79
- $postRecord = new PMXI_Post_Record();
 
 
 
80
 
81
  $tmp_files = array();
82
  // compose records to import
83
  $records = array();
84
  $chunk_records = array();
 
85
  if ($this->options['is_import_specified']) {
 
86
  foreach (preg_split('% *, *%', $this->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) {
87
  if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
88
  $records = array_merge($records, range(intval($mtch[1]), intval($mtch[2])));
@@ -95,7 +99,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
95
 
96
  if ($this->large_import == 'Yes' and !empty($records)){
97
 
98
- PMXI_Plugin::$session['pmxi_import']['count'] = count($records);
99
 
100
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
101
 
@@ -105,13 +109,14 @@ class PMXI_Import_Record extends PMXI_Model_Record {
105
  ))->save();
106
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
107
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
108
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
109
  // Time Elapsed
110
  if ( ! $is_cron ){
111
- $progress_msg = '<p class="import_process_bar"> Created ' . $this->created . ' / Updated ' . $this->updated . ' of '. PMXI_Plugin::$session->data['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/PMXI_Plugin::$session['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session['pmxi_import']['errors'] . '</span>';
112
  $logger and call_user_func($logger, $progress_msg);
113
  }
114
- PMXI_Plugin::$session['pmxi_import']['chunk_number'] = PMXI_Plugin::$session->data['pmxi_import']['chunk_number']++;
 
115
  return;
116
  }
117
  else $records = array();
@@ -121,7 +126,8 @@ class PMXI_Import_Record extends PMXI_Model_Record {
121
 
122
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
123
  $titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
124
- if ($this->large_import != 'Yes') PMXI_Plugin::$session['pmxi_import']['count'] = count($titles);
 
125
 
126
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing excerpts...', 'pmxi_plugin'));
127
  $post_excerpt = array();
@@ -132,6 +138,17 @@ class PMXI_Import_Record extends PMXI_Model_Record {
132
  count($titles) and $post_excerpt = array_fill(0, count($titles), '');
133
  }
134
 
 
 
 
 
 
 
 
 
 
 
 
135
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing authors...', 'pmxi_plugin'));
136
  $post_author = array();
137
  $current_user = wp_get_current_user();
@@ -172,7 +189,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
172
  $time = strtotime($d);
173
  if (FALSE === $time) {
174
  in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $d));
175
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
176
  $time = time();
177
  }
178
  $dates[$i] = date('Y-m-d H:i:s', $time);
@@ -185,13 +202,13 @@ class PMXI_Import_Record extends PMXI_Model_Record {
185
  $time_start = strtotime($dates_start[$i]);
186
  if (FALSE === $time_start) {
187
  in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_start[$i]));
188
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
189
  $time_start = time();
190
  }
191
  $time_end = strtotime($dates_end[$i]);
192
  if (FALSE === $time_end) {
193
  in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_end[$i]));
194
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
195
  $time_end = time();
196
  }
197
  $dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
@@ -232,9 +249,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
232
  if (empty($cats[$i])) $cats[$i] = array();
233
  $count_cats = count($cats[$i]);
234
 
235
- $delimeted_categories = explode(html_entity_decode($this->options['categories_delim']), html_entity_decode($c_raw));
236
-
237
- if ('' != $c_raw) foreach (explode(html_entity_decode($this->options['categories_delim']), html_entity_decode($c_raw)) as $j => $cc) if ('' != $cc) {
238
  $cat = get_term_by('name', trim($cc), 'category') or $cat = get_term_by('slug', trim($cc), 'category') or ctype_digit($cc) and $cat = get_term_by('id', trim($cc), 'category');
239
  if ( !empty($category->parent_id) ) {
240
  foreach ($categories_hierarchy as $key => $value){
@@ -283,9 +300,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
283
  count($titles) and $cats = array_fill(0, count($titles), '');
284
  }
285
 
286
- }
287
- // [/posts categories]
288
-
289
  // [custom taxonomies]
290
  $taxonomies = array();
291
  $taxonomies_param = $this->options['type'].'_taxonomies';
@@ -299,7 +316,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
299
 
300
  if (!empty($this->options[$taxonomies_param]) and is_array($this->options[$taxonomies_param])): foreach ($this->options[$taxonomies_param] as $tx_name => $tx_template) if ('' != $tx_template) {
301
  $tx = get_taxonomy($tx_name);
302
-
303
  if (!empty($tx->object_type) and in_array($taxonomies_object_type, $tx->object_type)) {
304
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, sprintf(__('Composing terms for `%s` taxonomy...', 'pmxi_plugin'), $tx->labels->name));
305
  $txes = array();
@@ -313,9 +330,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
313
  if (empty($taxonomies[$tx_name][$i])) $taxonomies[$tx_name][$i] = array();
314
  $count_cats = count($taxonomies[$tx_name][$i]);
315
 
316
- $delimeted_taxonomies = explode((!empty($taxonomy->delim)) ? html_entity_decode($taxonomy->delim) : ',', html_entity_decode($tx_raw));
317
 
318
- if ('' != $tx_raw) foreach (explode((!empty($taxonomy->delim)) ? html_entity_decode($taxonomy->delim) : ',', html_entity_decode($tx_raw)) as $j => $cc) if ('' != $cc) {
319
 
320
  $cat = get_term_by('name', trim($cc), $tx_name) or $cat = get_term_by('slug', trim($cc), $tx_name) or ctype_digit($cc) and $cat = get_term_by('id', $cc, $tx_name);
321
  if (!empty($taxonomy->parent_id)) {
@@ -363,19 +380,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
363
  }
364
  }
365
  }; endif;
366
- // [/custom taxonomies]
367
 
368
  // serialized featured images
369
  if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
370
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
371
  $logger and call_user_func($logger, __('<b>WARNING</b>: No featured images will be created', 'pmxi_plugin'));
372
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
373
  } else {
374
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for featured images...', 'pmxi_plugin'));
375
  $featured_images = array();
376
  if ($this->options['featured_image']) {
377
- // Detect if images is separated by comma
378
- $imgs = explode(',',$this->options['featured_image']);
379
  if (!empty($imgs)){
380
  $parse_multiple = true;
381
  foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
@@ -385,18 +402,135 @@ class PMXI_Import_Record extends PMXI_Model_Record {
385
  foreach($imgs as $img)
386
  {
387
  $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
388
- foreach($posts_images as $i => $val) $featured_images[$i][] = $val;
389
  }
390
  }
391
  else
392
  {
393
- $featured_images = XmlImportParser::factory($xml, $this->xpath, $this->options['featured_image'], $file)->parse($records); $tmp_files[] = $file;
394
  }
395
  }
396
 
397
  } else {
398
  count($titles) and $featured_images = array_fill(0, count($titles), '');
399
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  }
401
 
402
  // Composing images suffix
@@ -407,16 +541,17 @@ class PMXI_Import_Record extends PMXI_Model_Record {
407
  }
408
  else{
409
  count($titles) and $auto_rename_images = array_fill(0, count($titles), '');
410
- }
411
 
412
  // serialized attachments
413
  if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
414
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
415
  $logger and call_user_func($logger, __('<b>WARNING</b>: No attachments will be created', 'pmxi_plugin'));
416
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
417
  } else {
418
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for attachments files...', 'pmxi_plugin'));
419
  $attachments = array();
 
420
  if ($this->options['attachments']) {
421
  // Detect if attachments is separated by comma
422
  $atchs = explode(',', $this->options['attachments']);
@@ -425,10 +560,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
425
  foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
426
 
427
  if ($parse_multiple)
428
- {
429
  foreach($atchs as $atch)
430
  {
431
- $posts_attachments = XmlImportParser::factory($xml, $this->xpath, trim($atch), $file)->parse($records); $tmp_files[] = $file;
432
  foreach($posts_attachments as $i => $val) $attachments[$i][] = $val;
433
  }
434
  }
@@ -452,7 +587,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
452
  $post_type = $this->options['custom_type'];
453
  } else {
454
  $post_type = $this->options['type'];
455
- }
456
 
457
  // Import WooCommerce products
458
  if ( $post_type == "product" and class_exists('PMWI_Plugin')) {
@@ -461,10 +596,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
461
 
462
  extract( $product->process($this, count($titles), $xml, $logger, $chunk) );
463
 
464
- }
465
 
466
  $current_post_ids = array();
467
- foreach ($titles as $i => $void) {
468
 
469
  if (empty($titles[$i])) {
470
  if (class_exists('PMWI_Plugin') and !empty($single_product_parent_ID[$i])){
@@ -472,25 +607,31 @@ class PMXI_Import_Record extends PMXI_Model_Record {
472
  }
473
  else{
474
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by empty title', 'pmxi_plugin'));
475
- PMXI_Plugin::$session['pmxi_import']['chunk_number'] = PMXI_Plugin::$session->data['pmxi_import']['chunk_number']++;
476
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
477
  $this->set(array(
478
  'skipped' => $this->skipped + 1
479
  ))->save();
480
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
 
 
 
 
 
 
481
  continue;
482
  }
483
  }
484
 
485
  $articleData = array(
486
  'post_type' => $post_type,
487
- 'post_status' => $this->options['status'],
488
  'comment_status' => $this->options['comment_status'],
489
  'ping_status' => $this->options['ping_status'],
490
- 'post_title' => ($this->template['fix_characters']) ? utf8_encode(( ! $legacy_handling) ? html_entity_decode($titles[$i]) : htmlspecialchars_decode($titles[$i])) : (($this->template['is_leave_html']) ? (( ! $legacy_handling) ? html_entity_decode($titles[$i]) : htmlspecialchars_decode($titles[$i])) : $titles[$i]),
491
- 'post_excerpt' => ($this->template['fix_characters']) ? utf8_encode(( ! $legacy_handling) ? html_entity_decode($post_excerpt[$i]) : htmlspecialchars_decode($post_excerpt[$i])) : (($this->template['is_leave_html']) ? (( ! $legacy_handling) ? html_entity_decode($post_excerpt[$i]) : htmlspecialchars_decode($post_excerpt[$i])) : $post_excerpt[$i]),
492
  'post_name' => $post_slug[$i],
493
- 'post_content' => ($this->template['fix_characters']) ? utf8_encode(( ! $legacy_handling) ? html_entity_decode($contents[$i]) : htmlspecialchars_decode($contents[$i])) : (($this->template['is_leave_html']) ? (( ! $legacy_handling) ? html_entity_decode($contents[$i]) : htmlspecialchars_decode($contents[$i])) : $contents[$i]),
494
  'post_date' => $dates[$i],
495
  'post_date_gmt' => get_gmt_from_date($dates[$i]),
496
  'post_author' => $post_author[$i] ,
@@ -537,7 +678,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
537
  }
538
 
539
  // handle duplicates according to import settings
540
- if ($duplicates = $this->findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i], $this->options['duplicate_indicator'])) {
541
  $duplicate_id = array_shift($duplicates);
542
  if ($duplicate_id) {
543
  $post_to_update = get_post($post_to_update_id = $duplicate_id);
@@ -551,10 +692,12 @@ class PMXI_Import_Record extends PMXI_Model_Record {
551
  if ("yes" == $this->options['is_keep_former_posts']) {
552
 
553
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
554
- $tmp_array[] = $post_to_update_id;
555
- $this->set(array(
556
- 'current_post_ids' => json_encode($tmp_array)
557
- ))->save();
 
 
558
 
559
  // Do not update product variations
560
  if ($post_type == "product" and class_exists('PMWI_Plugin')){
@@ -571,11 +714,12 @@ class PMXI_Import_Record extends PMXI_Model_Record {
571
  foreach ( $children as $child ) {
572
 
573
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
574
- $tmp_array[] = $child;
575
- $this->set(array(
576
- 'current_post_ids' => json_encode($tmp_array)
577
- ))->save();
578
-
 
579
  }
580
  }
581
  }
@@ -584,13 +728,14 @@ class PMXI_Import_Record extends PMXI_Model_Record {
584
  ))->save();
585
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
586
  $logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
587
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
588
  if ( ! $is_cron ){
589
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
590
- $progress_msg = '<p class="import_process_bar"> ' . __('Created', 'pmxi_plugin') . ' ' . $this->created . ' / ' . __('Updated','pmxi_plugin') . ' ' . $this->updated . ' of '. PMXI_Plugin::$session->data['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/PMXI_Plugin::$session->data['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
591
  $logger and call_user_func($logger, $progress_msg);
592
  }
593
- PMXI_Plugin::$session['pmxi_import']['chunk_number']++;
 
594
  continue;
595
  }
596
 
@@ -601,7 +746,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
601
  $existing_cats = array();
602
  if (is_wp_error($cats_list)) {
603
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current categories for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
604
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
605
  } else {
606
  $cats_new = array();
607
  foreach ($cats_list as $c) {
@@ -613,7 +758,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
613
  $tags_list = get_the_tags($articleData['ID']);
614
  if (is_wp_error($tags_list)) {
615
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current tags for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
616
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
617
  } else {
618
  $tags_new = array();
619
  if ($tags_list) foreach ($tags_list as $t) {
@@ -626,7 +771,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
626
  $txes_list = get_the_terms($articleData['ID'], $tx_name);
627
  if (is_wp_error($txes_list)) {
628
  $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', 'pmxi_plugin'), $articleData['ID']));
629
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
630
  } else {
631
  $txes_new = array();
632
  if (!empty($txes_list)):
@@ -636,7 +781,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
636
  endif;
637
  $existing_taxonomies[$tx_name][$i] = $txes_new;
638
  }
639
- }
 
 
 
640
  }
641
  if ($this->options['is_keep_dates']) { // preserve date of already existing article when duplicate is found
642
  $articleData['post_date'] = $post_to_update->post_date;
@@ -661,8 +809,8 @@ class PMXI_Import_Record extends PMXI_Model_Record {
661
  $articleData['post_parent'] = $post_to_update->post_parent;
662
  }
663
  // handle obsolete attachments (i.e. delete or keep) according to import settings
664
- if ( ! $this->options['is_keep_images'] and ! $this->options['is_keep_attachments_on_update'] and ! $this->options['no_create_featured_image'] ){
665
- wp_delete_attachments($articleData['ID']);
666
  }
667
 
668
  }
@@ -675,7 +823,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
675
 
676
  // no new records are created. it will only update posts it finds matching duplicates for
677
  if ($this->options['not_create_records'] and empty($articleData['ID'])){
678
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
679
  $this->set(array(
680
  'skipped' => $this->skipped + 1
681
  ))->save();
@@ -683,10 +831,11 @@ class PMXI_Import_Record extends PMXI_Model_Record {
683
  $logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: by "Not add new records" option for `%s`', 'pmxi_plugin'), $articleData['post_title']));
684
  if ( ! $is_cron ){
685
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
686
- $progress_msg = '<p class="import_process_bar"> '. __('Created','pmxi_plugin') . ' ' . $this->created . ' / ' . __('Updated','pmxi_plugin') . ' ' . $this->updated . ' of '. PMXI_Plugin::$session->data['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/PMXI_Plugin::$session->data['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
687
  $logger and call_user_func($logger, $progress_msg);
688
  }
689
- PMXI_Plugin::$session['pmxi_import']['chunk_number'] = PMXI_Plugin::$session->data['pmxi_import']['chunk_number']++;
 
690
  continue;
691
  }
692
 
@@ -755,7 +904,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
755
  $dest->insert();
756
  } else {
757
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create cloaked link for %s', 'pmxi_plugin'), $url));
758
- PMXI_Plugin::$session['pmxi_import']['warnings']++;
759
  $link = NULL;
760
  }
761
  }
@@ -772,14 +921,16 @@ class PMXI_Import_Record extends PMXI_Model_Record {
772
 
773
  if (is_wp_error($pid)) {
774
  $logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
775
- PMXI_Plugin::$session['pmxi_import']['errors'] = PMXI_Plugin::$session->data['pmxi_import']['errors']++;
776
  } else {
777
-
778
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
779
- $tmp_array[] = $pid;
780
- $this->set(array(
781
- 'current_post_ids' => json_encode($tmp_array)
782
- ))->save();
 
 
783
 
784
  if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
785
  // associate post with import
@@ -787,9 +938,15 @@ class PMXI_Import_Record extends PMXI_Model_Record {
787
  'post_id' => $pid,
788
  'import_id' => $this->id,
789
  'unique_key' => $unique_keys[$i],
790
- 'product_key' => (class_exists('PMWI_Plugin')) ? $single_product_ID[$i] : ''
791
  ))->insert();
792
- }
 
 
 
 
 
 
793
 
794
  // Woocommerce add-on
795
  if ( $post_type == "product" and class_exists('PMWI_Plugin')){
@@ -798,26 +955,46 @@ class PMXI_Import_Record extends PMXI_Model_Record {
798
 
799
  }
800
 
801
- if ('post' != $articleData['post_type'] and !empty($this->options['page_template'])) update_post_meta($pid, '_wp_page_template', $this->options['page_template']);
802
-
803
  // [featured image]
804
- if ( ! empty($uploads) and false === $uploads['error'] and !empty($featured_images[$i]) and (empty($articleData['ID']) or empty($this->options['is_keep_images']))) {
805
 
806
  require_once(ABSPATH . 'wp-admin/includes/image.php');
807
 
808
  if ( ! is_array($featured_images[$i]) ) $featured_images[$i] = array($featured_images[$i]);
 
 
 
809
  $post_thumbnail = false;
810
  $success_images = false;
811
  $gallery_attachment_ids = array();
812
- foreach ($featured_images[$i] as $featured_image)
 
 
 
813
  {
814
- $imgs = str_getcsv($featured_image, $this->options['featured_delim']);
815
- if (!empty($imgs)) {
816
- foreach ($imgs as $img_url) { if (empty($img_url)) continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
817
  $create_image = false;
818
  $download_image = true;
819
- if (base64_decode($img_url, true) !== false){
820
- $img = @imagecreatefromstring(base64_decode($img_url));
 
821
  if($img)
822
  {
823
  $image_filename = md5(time()) . '.jpg';
@@ -825,17 +1002,14 @@ class PMXI_Import_Record extends PMXI_Model_Record {
825
  imagejpeg($img, $image_filepath);
826
  if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
827
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $image_filepath));
828
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
829
  } else {
830
  $create_image = true;
831
- }
832
  }
833
  }
834
- else {
835
-
836
- $img_ext = pmxi_get_remote_image_ext($img_url);
837
 
838
- $image_name = (($this->options['auto_rename_images'] and "" != $auto_rename_images[$i]) ? url_title($auto_rename_images[$i] . '_' . (($this->options['images_name'] != 'auto') ? basename($img_url) : uniqid())) : (($this->options['images_name'] != 'auto') ? basename($img_url) : uniqid())) . (("" != $img_ext and $this->options['images_name'] == 'auto') ? '.'.$img_ext : '');
839
  $image_filename = wp_unique_filename($uploads['path'], $image_name);
840
  $image_filepath = $uploads['path'] . '/' . url_title($image_filename);
841
 
@@ -858,24 +1032,54 @@ class PMXI_Import_Record extends PMXI_Model_Record {
858
  }
859
  }
860
 
861
- if ($download_image){
862
 
863
- $img_url = str_replace(" ", "%20", trim($img_url));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
864
 
865
- if ( ! get_file_curl($img_url, $image_filepath) and ! @file_put_contents($image_filepath, @file_get_contents($img_url))) {
866
- $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s cannot be saved locally as %s', 'pmxi_plugin'), $img_url, $image_filepath));
867
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
868
- unlink($image_filepath); // delete file since failed upload may result in empty file created
869
- } elseif( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
870
- $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $img_url));
871
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
872
- } else {
873
- $create_image = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874
  }
875
  }
876
  }
877
 
878
  if ($create_image){
 
879
  $attachment = array(
880
  'post_mime_type' => image_type_to_mime_type($image_info[2]),
881
  'guid' => $uploads['url'] . '/' . $image_filename,
@@ -888,15 +1092,33 @@ class PMXI_Import_Record extends PMXI_Model_Record {
888
  if (trim($image_meta['caption']))
889
  $attachment['post_content'] = $image_meta['caption'];
890
  }
891
- $attid = wp_insert_attachment($attachment, $image_filepath, $pid);
 
 
892
  if (is_wp_error($attid)) {
893
- $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
894
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
895
  } else {
896
  // you must first include the image.php file
897
  // for the function wp_generate_attachment_metadata() to work
898
  require_once(ABSPATH . 'wp-admin/includes/image.php');
899
- wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $image_filepath));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  $success_images = true;
901
  if ( ! $post_thumbnail ) {
902
  if ( ! $this->options['no_create_featured_image'] or ! has_post_thumbnail($pid)){
@@ -907,18 +1129,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
907
  }
908
  else $gallery_attachment_ids[] = $attid;
909
  }
910
- }
911
  }
912
  }
913
- }
 
914
  // Set product gallery images
915
- if ( $post_type == "product" and class_exists('PMWI_Plugin') and !empty($gallery_attachment_ids))
916
  update_post_meta($pid, '_product_image_gallery', implode(',', $gallery_attachment_ids));
917
  // Create entry as Draft if no images are downloaded successfully
918
- if ( ! $success_images and "yes" == $this->options['create_draft'] ) wp_update_post(array('ID' => $pid, 'post_status' => 'draft'));
919
  }
920
  // [/featured image]
921
-
922
  // [attachments]
923
  if ( ! empty($uploads) and false === $uploads['error'] and !empty($attachments[$i])) {
924
 
@@ -940,13 +1163,13 @@ class PMXI_Import_Record extends PMXI_Model_Record {
940
 
941
  if ( ! get_file_curl(trim($atch_url), $attachment_filepath) and ! @file_put_contents($attachment_filepath, @file_get_contents(trim($atch_url)))) {
942
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Attachment file %s cannot be saved locally as %s', 'pmxi_plugin'), trim($atch_url), $attachment_filepath));
943
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
944
  unlink($attachment_filepath); // delete file since failed upload may result in empty file created
945
  } elseif( ! $wp_filetype = wp_check_filetype(basename($attachment_filename), null )) {
946
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Can\'t detect attachment file type %s', 'pmxi_plugin'), trim($atch_url)));
947
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
948
  } else {
949
-
950
  $attachment_data = array(
951
  'guid' => $uploads['baseurl'] . '/' . _wp_relative_upload_path( $attachment_filepath ),
952
  'post_mime_type' => $wp_filetype['type'],
@@ -958,8 +1181,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
958
 
959
  if (is_wp_error($attach_id)) {
960
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
961
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
962
  } else {
 
963
  wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attachment_filepath));
964
  }
965
  }
@@ -967,11 +1191,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
967
  }
968
  }
969
  }
970
- // [/attachments]
971
-
972
  // [custom taxonomies]
973
- if (!empty($taxonomies)){
974
-
975
  foreach ($taxonomies as $tx_name => $txes) {
976
 
977
  if ( empty($articleData['ID']) or !$this->options['is_keep_categories'] or ( $this->options['is_keep_categories'] and $this->options['is_add_newest_categories'] ) ){
@@ -983,42 +1206,46 @@ class PMXI_Import_Record extends PMXI_Model_Record {
983
  unset($existing_taxonomies[$tx_name][$i]);
984
  }
985
 
986
- // create term if not exists
987
- foreach ($txes[$i] as $key => $single_tax) {
988
- if (is_array($single_tax)){
989
-
990
- $parent_id = (!empty($single_tax['parent'])) ? $this->recursion_taxes($single_tax['parent'], $tx_name, $txes[$i], $key) : '';
991
-
992
- $term = term_exists( trim(htmlspecialchars($single_tax['name'])), $tx_name, $parent_id );
993
 
994
- if ( empty($term) and !is_wp_error($term) ){
995
- $term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
996
- $term = wp_insert_term(
997
- $single_tax['name'], // the term
998
- $tx_name, // the taxonomy
999
- $term_attr
1000
- );
1001
- }
1002
-
1003
- if ( is_wp_error($term) ){
1004
- $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
1005
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1006
- }
1007
- elseif (!empty($term)) {
1008
- $cat_id = $term['term_id'];
1009
- if ($cat_id and $single_tax['assign'])
1010
- {
1011
- $term = get_term_by('id', $cat_id, $tx_name);
1012
- $assign_taxes[] = $term->slug;
 
 
 
 
 
1013
  }
1014
- }
 
 
 
 
 
 
 
 
1015
  }
1016
- }
1017
- // associate taxes with post
1018
- $term_ids = wp_set_object_terms($pid, $assign_taxes, $tx_name);
1019
- if (is_wp_error($term_ids)) {
1020
- $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
1021
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1022
  }
1023
  }
1024
  }
@@ -1028,13 +1255,13 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1028
  $term_ids = wp_set_object_terms($pid, $txes[$i], $tx_name);
1029
  if (is_wp_error($term_ids)) {
1030
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
1031
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1032
  }
1033
  }
1034
  }
1035
  }
1036
- }
1037
- // [/custom taxonomies]
1038
 
1039
  // [categories]
1040
  if (!empty($cats[$i])) {
@@ -1057,9 +1284,10 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1057
 
1058
  $parent_id = (!empty($single_cat['parent'])) ? $this->recursion_taxes($single_cat['parent'], 'category', $cats[$i], $key) : '';
1059
 
1060
- $term = term_exists( trim(htmlspecialchars($single_cat['name'])), 'category', $parent_id );
1061
-
1062
- if ( empty($term) and !is_wp_error($term) ){
 
1063
  $term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
1064
  $term = wp_insert_term(
1065
  $single_cat['name'], // the term
@@ -1070,7 +1298,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1070
 
1071
  if ( is_wp_error($term) ){
1072
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
1073
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1074
  }
1075
  elseif ( ! empty($term) ) {
1076
  $cat_id = $term['term_id'];
@@ -1087,7 +1315,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1087
  $cats_ids = wp_set_object_terms($pid, $assign_cats, 'category');
1088
  if (is_wp_error($cats_ids)) {
1089
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
1090
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1091
  }
1092
  }
1093
  }
@@ -1097,7 +1325,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1097
 
1098
  if (is_wp_error($cats_ids)) {
1099
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
1100
- PMXI_Plugin::$session['pmxi_import']['warnings'] = PMXI_Plugin::$session->data['pmxi_import']['warnings']++;
1101
  }
1102
  }
1103
  // [/categories]
@@ -1117,29 +1345,30 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1117
  'imported' => $this->imported + 1,
1118
  'created' => (empty($articleData['ID'])) ? $this->created + 1 : $this->created,
1119
  'updated' => (empty($articleData['ID'])) ? $this->updated : $this->updated + 1
1120
- ))->save();
1121
- PMXI_Plugin::$session['pmxi_import']['chunk_number'] = PMXI_Plugin::$session->data['pmxi_import']['chunk_number']++;
1122
  }
1123
 
1124
  $records_count = 0;
1125
 
1126
  // Time Elapsed
1127
- if ( ! $is_cron){
1128
-
1129
- if ($this->large_import == 'No') PMXI_Plugin::$session['pmxi_import']['count'] = count($titles);
1130
 
1131
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
1132
 
1133
- $progress_msg = '<p class="import_process_bar"> '.__('Created','pmxi_plugin'). ' ' . $this->created . ' / '.__('Updated','pmxi_plugin') . ' ' . $this->updated . ' of '. PMXI_Plugin::$session->data['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/PMXI_Plugin::$session->data['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
1134
  $logger and call_user_func($logger, $progress_msg);
1135
  }
1136
 
1137
- }
1138
 
1139
  wp_cache_flush();
1140
- }
 
 
1141
 
1142
- $is_import_complete = ($records_count == PMXI_Plugin::$session->data['pmxi_import']['count']);
 
 
1143
 
1144
  if ( ! $is_cron and $is_import_complete and ! empty($this->options['is_delete_missing'])) { // delete posts which are not in current import set
1145
 
@@ -1162,6 +1391,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1162
  }
1163
 
1164
  if (!empty($missing_ids)){
 
 
 
1165
  $sql = "delete a,b,c
1166
  FROM ".$this->wpdb->posts." a
1167
  LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
@@ -1171,7 +1403,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1171
  $this->wpdb->query(
1172
  $this->wpdb->prepare($sql, '')
1173
  );
1174
- }
1175
 
1176
  }
1177
 
@@ -1201,7 +1433,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1201
 
1202
  } catch (XmlImportException $e) {
1203
  $logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
1204
- PMXI_Plugin::$session['pmxi_import']['errors'] = PMXI_Plugin::$session->data['pmxi_import']['errors']++;
1205
  }
1206
 
1207
  $this->set('registered_on', date('Y-m-d H:i:s'))->save(); // specify execution is successful
@@ -1213,8 +1445,20 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1213
 
1214
  if (($is_cron or $is_import_complete) and $this->options['is_delete_source']) {
1215
  $logger and call_user_func($logger, __('Deleting source XML file...', 'pmxi_plugin'));
1216
- if ( ! @unlink($this->path)) {
1217
- $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
 
 
 
 
 
 
 
 
 
 
 
 
1218
  }
1219
  }
1220
  if ( ! $is_cron and $is_import_complete ){
@@ -1230,24 +1474,31 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1230
  remove_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // return any filtering rules back if they has been disabled for import procedure
1231
 
1232
  return $this;
1233
- }
1234
 
1235
  public function recursion_taxes($parent, $tx_name, $txes, $key){
 
1236
  if (is_array($parent)){
1237
  $parent['name'] = sanitize_text_field($parent['name']);
1238
  if (empty($parent['parent'])){
1239
- $term = term_exists( htmlspecialchars($parent['name']), $tx_name);
 
 
 
1240
  if ( empty($term) and !is_wp_error($term) ){
1241
  $term = wp_insert_term(
1242
  $parent['name'], // the term
1243
  $tx_name // the taxonomy
1244
  );
1245
  }
1246
- return ( ! is_wp_error($term)) ? $term['term_id'] : '';
1247
  }
1248
  else{
1249
  $parent_id = $this->recursion_taxes($parent['parent'], $tx_name, $txes, $key);
1250
- $term = term_exists( htmlspecialchars($parent['name']), $tx_name, $parent_id);
 
 
 
1251
  if ( empty($term) and !is_wp_error($term) ){
1252
  $term = wp_insert_term(
1253
  $parent, // the term
@@ -1255,15 +1506,17 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1255
  array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
1256
  );
1257
  }
1258
- return ( ! is_wp_error($term)) ? $term['term_id'] : '';
1259
  }
1260
  }
1261
  else{
1262
 
1263
- if ( !empty($txes[$key - 1]) and !empty($txes[$key - 1]['parent'])) {
1264
  $parent_id = $this->recursion_taxes($txes[$key - 1]['parent'], $tx_name, $txes, $key - 1);
1265
 
1266
- $term = term_exists( htmlspecialchars($parent), $tx_name, $parent_id);
 
 
1267
  if ( empty($term) and !is_wp_error($term) ){
1268
  $term = wp_insert_term(
1269
  $parent, // the term
@@ -1271,21 +1524,21 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1271
  array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
1272
  );
1273
  }
1274
- return ( ! is_wp_error($term)) ? $term['term_id'] : '';
1275
  }
1276
  else{
1277
- $term = term_exists( htmlspecialchars($parent), $tx_name);
 
1278
  if ( empty($term) and !is_wp_error($term) ){
1279
  $term = wp_insert_term(
1280
  $parent, // the term
1281
  $tx_name // the taxonomy
1282
  );
1283
- }
1284
-
1285
- return ( ! is_wp_error($term)) ? $term['term_id'] : '';
1286
  }
1287
  }
1288
- }
1289
 
1290
  public function _filter_has_cap_unfiltered_html($caps)
1291
  {
@@ -1340,29 +1593,33 @@ class PMXI_Import_Record extends PMXI_Model_Record {
1340
  * @chainable
1341
  */
1342
  public function deletePosts($keepPosts = TRUE) {
1343
- $post = new PMXI_Post_List();
1344
- if ($keepPosts) {
1345
- $this->wpdb->query($this->wpdb->prepare('DELETE FROM ' . $post->getTable() . ' WHERE import_id = %s', $this->id));
1346
- } else {
1347
  $ids = array();
1348
  foreach ($post->getBy('import_id', $this->id)->convertRecords() as $p) {
1349
- empty($this->options['is_keep_attachments']) and empty($this->options['is_keep_images']) and wp_delete_attachments($p->post_id);
1350
- $ids[] = $p->post_id;
1351
- //wp_delete_post($p->post_id, TRUE);
1352
  }
1353
  if (!empty($ids)){
1354
 
 
 
1355
  $sql = "delete a,b,c
1356
  FROM ".$this->wpdb->posts." a
1357
  LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
1358
- LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
 
1359
  WHERE a.ID IN (".implode(',', $ids).");";
1360
 
1361
  $this->wpdb->query(
1362
  $this->wpdb->prepare($sql, '')
1363
- );
1364
- }
 
1365
  }
 
 
 
1366
  return $this;
1367
  }
1368
  /**
69
  add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
70
 
71
  $this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
72
+
 
73
  $avoid_pingbacks = PMXI_Plugin::getInstance()->getOption('pingbacks');
74
  $legacy_handling = PMXI_Plugin::getInstance()->getOption('legacy_special_character_handling');
75
 
76
  if ( $avoid_pingbacks and ! defined( 'WP_IMPORTING' ) ) define( 'WP_IMPORTING', true );
77
 
78
+ in_array($this->type, array('ftp')) and ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Reading files for import...', 'pmxi_plugin'));
79
+ in_array($this->type, array('ftp')) and ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, sprintf(_n('%s file found', '%s files found', count(PMXI_Plugin::$session->data['pmxi_import']['local_paths']), 'pmxi_plugin'), count(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])));
80
+
81
+ $postRecord = new PMXI_Post_Record();
82
 
83
  $tmp_files = array();
84
  // compose records to import
85
  $records = array();
86
  $chunk_records = array();
87
+
88
  if ($this->options['is_import_specified']) {
89
+
90
  foreach (preg_split('% *, *%', $this->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) {
91
  if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
92
  $records = array_merge($records, range(intval($mtch[1]), intval($mtch[2])));
99
 
100
  if ($this->large_import == 'Yes' and !empty($records)){
101
 
102
+ $this->set(array('count' => count($records)))->save();
103
 
104
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
105
 
109
  ))->save();
110
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
111
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
112
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
113
  // Time Elapsed
114
  if ( ! $is_cron ){
115
+ $progress_msg = '<p class="import_process_bar"> Created ' . $this->created . ' / Updated ' . $this->updated . ' of '. $this->count .' records.</p><span class="import_percent">' . ceil(($records_count/$this->count) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session['pmxi_import']['errors'] . '</span>';
116
  $logger and call_user_func($logger, $progress_msg);
117
  }
118
+ PMXI_Plugin::$session['pmxi_import']['chunk_number'] = ++PMXI_Plugin::$session->data['pmxi_import']['chunk_number'];
119
+ pmxi_session_commit();
120
  return;
121
  }
122
  else $records = array();
126
 
127
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
128
  $titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
129
+ if ($this->large_import != 'Yes')
130
+ $this->set(array('count' => count($titles)))->save();
131
 
132
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing excerpts...', 'pmxi_plugin'));
133
  $post_excerpt = array();
138
  count($titles) and $post_excerpt = array_fill(0, count($titles), '');
139
  }
140
 
141
+ if ( "xpath" == $this->options['status'] ){
142
+ ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing statuses...', 'pmxi_plugin'));
143
+ $post_status = array();
144
+ if (!empty($this->options['status_xpath'])){
145
+ $post_status = XmlImportParser::factory($xml, $this->xpath, $this->options['status_xpath'], $file)->parse($records); $tmp_files[] = $file;
146
+ }
147
+ else{
148
+ count($titles) and $post_status = array_fill(0, count($titles), '');
149
+ }
150
+ }
151
+
152
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing authors...', 'pmxi_plugin'));
153
  $post_author = array();
154
  $current_user = wp_get_current_user();
189
  $time = strtotime($d);
190
  if (FALSE === $time) {
191
  in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $d));
192
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
193
  $time = time();
194
  }
195
  $dates[$i] = date('Y-m-d H:i:s', $time);
202
  $time_start = strtotime($dates_start[$i]);
203
  if (FALSE === $time_start) {
204
  in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_start[$i]));
205
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
206
  $time_start = time();
207
  }
208
  $time_end = strtotime($dates_end[$i]);
209
  if (FALSE === $time_end) {
210
  in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_end[$i]));
211
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
212
  $time_end = time();
213
  }
214
  $dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
249
  if (empty($cats[$i])) $cats[$i] = array();
250
  $count_cats = count($cats[$i]);
251
 
252
+ $delimeted_categories = explode($this->options['categories_delim'], $c_raw);
253
+
254
+ if ('' != $c_raw) foreach (explode($this->options['categories_delim'], $c_raw) as $j => $cc) if ('' != $cc) {
255
  $cat = get_term_by('name', trim($cc), 'category') or $cat = get_term_by('slug', trim($cc), 'category') or ctype_digit($cc) and $cat = get_term_by('id', trim($cc), 'category');
256
  if ( !empty($category->parent_id) ) {
257
  foreach ($categories_hierarchy as $key => $value){
300
  count($titles) and $cats = array_fill(0, count($titles), '');
301
  }
302
 
303
+ }
304
+ // [/posts categories]
305
+
306
  // [custom taxonomies]
307
  $taxonomies = array();
308
  $taxonomies_param = $this->options['type'].'_taxonomies';
316
 
317
  if (!empty($this->options[$taxonomies_param]) and is_array($this->options[$taxonomies_param])): foreach ($this->options[$taxonomies_param] as $tx_name => $tx_template) if ('' != $tx_template) {
318
  $tx = get_taxonomy($tx_name);
319
+ $taxonomies[$tx_name] = array();
320
  if (!empty($tx->object_type) and in_array($taxonomies_object_type, $tx->object_type)) {
321
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, sprintf(__('Composing terms for `%s` taxonomy...', 'pmxi_plugin'), $tx->labels->name));
322
  $txes = array();
330
  if (empty($taxonomies[$tx_name][$i])) $taxonomies[$tx_name][$i] = array();
331
  $count_cats = count($taxonomies[$tx_name][$i]);
332
 
333
+ $delimeted_taxonomies = explode((!empty($taxonomy->delim)) ? $taxonomy->delim : ',', $tx_raw);
334
 
335
+ if ('' != $tx_raw) foreach (explode((!empty($taxonomy->delim)) ? $taxonomy->delim : ',', $tx_raw) as $j => $cc) if ('' != $cc) {
336
 
337
  $cat = get_term_by('name', trim($cc), $tx_name) or $cat = get_term_by('slug', trim($cc), $tx_name) or ctype_digit($cc) and $cat = get_term_by('id', $cc, $tx_name);
338
  if (!empty($taxonomy->parent_id)) {
380
  }
381
  }
382
  }; endif;
383
+ // [/custom taxonomies]
384
 
385
  // serialized featured images
386
  if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
387
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
388
  $logger and call_user_func($logger, __('<b>WARNING</b>: No featured images will be created', 'pmxi_plugin'));
389
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
390
  } else {
391
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for featured images...', 'pmxi_plugin'));
392
  $featured_images = array();
393
  if ($this->options['featured_image']) {
394
+ // Detect if images is separated by comma
395
+ $imgs = ( "" == $this->options['featured_delim']) ? explode("\n", $this->options['featured_image']) : explode(',',$this->options['featured_image']);
396
  if (!empty($imgs)){
397
  $parse_multiple = true;
398
  foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
402
  foreach($imgs as $img)
403
  {
404
  $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
405
+ foreach($posts_images as $i => $val) $featured_images[$i][] = $val;
406
  }
407
  }
408
  else
409
  {
410
+ $featured_images = XmlImportParser::factory($xml, $this->xpath, $this->options['featured_image'], $file)->parse($records); $tmp_files[] = $file;
411
  }
412
  }
413
 
414
  } else {
415
  count($titles) and $featured_images = array_fill(0, count($titles), '');
416
  }
417
+ }
418
+
419
+ // serialized images meta data
420
+ if ( $this->options['set_image_meta_data'] ){
421
+ $uploads = wp_upload_dir();
422
+
423
+ // serialized images meta titles
424
+ ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing image meta data (titles)...', 'pmxi_plugin'));
425
+ $image_meta_titles = array();
426
+
427
+ if ($this->options['image_meta_title']) {
428
+ // Detect if images is separated by comma
429
+ $imgs = ( "" == $this->options['image_meta_title_delim']) ? explode("\n",$this->options['image_meta_title']) : explode(',',$this->options['image_meta_title']);
430
+
431
+ if (!empty($imgs)){
432
+ $parse_multiple = true;
433
+ foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
434
+
435
+ if ($parse_multiple)
436
+ {
437
+ foreach($imgs as $img)
438
+ {
439
+ $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
440
+ foreach($posts_images as $i => $val) $image_meta_titles[$i][] = $val;
441
+ }
442
+ }
443
+ else
444
+ {
445
+ $image_meta_titles = XmlImportParser::factory($xml, $this->xpath, $this->options['image_meta_title'], $file)->parse($records); $tmp_files[] = $file;
446
+ }
447
+ }
448
+
449
+ } else {
450
+ count($titles) and $image_meta_titles = array_fill(0, count($titles), '');
451
+ }
452
+
453
+ // serialized images meta captions
454
+ ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing image meta data (captions)...', 'pmxi_plugin'));
455
+ $image_meta_captions = array();
456
+ if ($this->options['image_meta_caption']) {
457
+ // Detect if images is separated by comma
458
+ $imgs = ( "" == $this->options['image_meta_caption_delim']) ? explode("\n",$this->options['image_meta_caption']) : explode(',',$this->options['image_meta_caption']);
459
+ if (!empty($imgs)){
460
+ $parse_multiple = true;
461
+ foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
462
+
463
+ if ($parse_multiple)
464
+ {
465
+ foreach($imgs as $img)
466
+ {
467
+ $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
468
+ foreach($posts_images as $i => $val) $image_meta_captions[$i][] = $val;
469
+ }
470
+ }
471
+ else
472
+ {
473
+ $image_meta_captions = XmlImportParser::factory($xml, $this->xpath, $this->options['image_meta_caption'], $file)->parse($records); $tmp_files[] = $file;
474
+ }
475
+ }
476
+
477
+ } else {
478
+ count($titles) and $image_meta_captions = array_fill(0, count($titles), '');
479
+ }
480
+ // serialized images meta alt text
481
+ ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing image meta data (alt text)...', 'pmxi_plugin'));
482
+ $image_meta_alts = array();
483
+ if ($this->options['image_meta_alt']) {
484
+ // Detect if images is separated by comma
485
+ $imgs = ( "" == $this->options['image_meta_alt_delim']) ? explode("\n",$this->options['image_meta_alt']) : explode(',',$this->options['image_meta_alt']);
486
+ if (!empty($imgs)){
487
+ $parse_multiple = true;
488
+ foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
489
+
490
+ if ($parse_multiple)
491
+ {
492
+ foreach($imgs as $img)
493
+ {
494
+ $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
495
+ foreach($posts_images as $i => $val) $image_meta_alts[$i][] = $val;
496
+ }
497
+ }
498
+ else
499
+ {
500
+ $image_meta_alts = XmlImportParser::factory($xml, $this->xpath, $this->options['image_meta_alt'], $file)->parse($records); $tmp_files[] = $file;
501
+ }
502
+ }
503
+
504
+ } else {
505
+ count($titles) and $image_meta_alts = array_fill(0, count($titles), '');
506
+ }
507
+ // serialized images meta description
508
+ ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing image meta data (description)...', 'pmxi_plugin'));
509
+ $image_meta_descriptions = array();
510
+ if ($this->options['image_meta_description']) {
511
+ // Detect if images is separated by comma
512
+ $imgs = ( "" == $this->options['image_meta_description_delim']) ? explode("\n",$this->options['image_meta_description']) : explode(',',$this->options['image_meta_description']);
513
+ if (!empty($imgs)){
514
+ $parse_multiple = true;
515
+ foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
516
+
517
+ if ($parse_multiple)
518
+ {
519
+ foreach($imgs as $img)
520
+ {
521
+ $posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
522
+ foreach($posts_images as $i => $val) $image_meta_descriptions[$i][] = $val;
523
+ }
524
+ }
525
+ else
526
+ {
527
+ $image_meta_descriptions = XmlImportParser::factory($xml, $this->xpath, $this->options['image_meta_description'], $file)->parse($records); $tmp_files[] = $file;
528
+ }
529
+ }
530
+
531
+ } else {
532
+ count($titles) and $image_meta_descriptions = array_fill(0, count($titles), '');
533
+ }
534
  }
535
 
536
  // Composing images suffix
541
  }
542
  else{
543
  count($titles) and $auto_rename_images = array_fill(0, count($titles), '');
544
+ }
545
 
546
  // serialized attachments
547
  if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
548
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
549
  $logger and call_user_func($logger, __('<b>WARNING</b>: No attachments will be created', 'pmxi_plugin'));
550
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session['pmxi_import']['warnings'];
551
  } else {
552
  ($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for attachments files...', 'pmxi_plugin'));
553
  $attachments = array();
554
+
555
  if ($this->options['attachments']) {
556
  // Detect if attachments is separated by comma
557
  $atchs = explode(',', $this->options['attachments']);
560
  foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
561
 
562
  if ($parse_multiple)
563
+ {
564
  foreach($atchs as $atch)
565
  {
566
+ $posts_attachments = XmlImportParser::factory($xml, $this->xpath, trim($atch), $file)->parse($records); $tmp_files[] = $file;
567
  foreach($posts_attachments as $i => $val) $attachments[$i][] = $val;
568
  }
569
  }
587
  $post_type = $this->options['custom_type'];
588
  } else {
589
  $post_type = $this->options['type'];
590
+ }
591
 
592
  // Import WooCommerce products
593
  if ( $post_type == "product" and class_exists('PMWI_Plugin')) {
596
 
597
  extract( $product->process($this, count($titles), $xml, $logger, $chunk) );
598
 
599
+ }
600
 
601
  $current_post_ids = array();
602
+ foreach ($titles as $i => $void) {
603
 
604
  if (empty($titles[$i])) {
605
  if (class_exists('PMWI_Plugin') and !empty($single_product_parent_ID[$i])){
607
  }
608
  else{
609
  $logger and call_user_func($logger, __('<b>SKIPPED</b>: by empty title', 'pmxi_plugin'));
610
+ PMXI_Plugin::$session['pmxi_import']['chunk_number'] = ++PMXI_Plugin::$session->data['pmxi_import']['chunk_number'];
611
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
612
  $this->set(array(
613
  'skipped' => $this->skipped + 1
614
  ))->save();
615
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
616
+ if ( ! $is_cron ){
617
+ $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
618
+ $progress_msg = '<p class="import_process_bar"> ' . __('Created', 'pmxi_plugin') . ' ' . $this->created . ' / ' . __('Updated','pmxi_plugin') . ' ' . $this->updated . ' ' . __('of', 'pmxi_plugin') . ' '. $this->count .' ' . __('records', 'pmxi_plugin') . '.</p><span class="import_percent">' . ceil(($records_count/$this->count) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
619
+ $logger and call_user_func($logger, $progress_msg);
620
+ }
621
+ pmxi_session_commit();
622
  continue;
623
  }
624
  }
625
 
626
  $articleData = array(
627
  'post_type' => $post_type,
628
+ 'post_status' => ("xpath" == $this->options['status']) ? $post_status[$i] : $this->options['status'],
629
  'comment_status' => $this->options['comment_status'],
630
  'ping_status' => $this->options['ping_status'],
631
+ 'post_title' => ($this->template['is_leave_html']) ? html_entity_decode($titles[$i]) : $titles[$i],
632
+ 'post_excerpt' => ($this->template['is_leave_html']) ? html_entity_decode($post_excerpt[$i]) : $post_excerpt[$i],
633
  'post_name' => $post_slug[$i],
634
+ 'post_content' => ($this->template['is_leave_html']) ? html_entity_decode($contents[$i]) : $contents[$i],
635
  'post_date' => $dates[$i],
636
  'post_date_gmt' => get_gmt_from_date($dates[$i]),
637
  'post_author' => $post_author[$i] ,
678
  }
679
 
680
  // handle duplicates according to import settings
681
+ if ($duplicates = $this->findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i], $this->options['duplicate_indicator'])) {
682
  $duplicate_id = array_shift($duplicates);
683
  if ($duplicate_id) {
684
  $post_to_update = get_post($post_to_update_id = $duplicate_id);
692
  if ("yes" == $this->options['is_keep_former_posts']) {
693
 
694
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
695
+ if ( ! in_array($post_to_update_id, $tmp_array) ){
696
+ $tmp_array[] = $post_to_update_id;
697
+ $this->set(array(
698
+ 'current_post_ids' => json_encode($tmp_array)
699
+ ))->save();
700
+ }
701
 
702
  // Do not update product variations
703
  if ($post_type == "product" and class_exists('PMWI_Plugin')){
714
  foreach ( $children as $child ) {
715
 
716
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
717
+ if ( ! in_array($child, $tmp_array)){
718
+ $tmp_array[] = $child;
719
+ $this->set(array(
720
+ 'current_post_ids' => json_encode($tmp_array)
721
+ ))->save();
722
+ }
723
  }
724
  }
725
  }
728
  ))->save();
729
  PMXI_Plugin::$session['pmxi_import']['skipped_records'] = $this->skipped;
730
  $logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
731
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
732
  if ( ! $is_cron ){
733
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
734
+ $progress_msg = '<p class="import_process_bar"> ' . __('Created', 'pmxi_plugin') . ' ' . $this->created . ' / ' . __('Updated','pmxi_plugin') . ' ' . $this->updated . ' ' . __('of', 'pmxi_plugin') . ' '. $this->count .' ' . __('records', 'pmxi_plugin') . '.</p><span class="import_percent">' . ceil(($records_count/$this->count) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
735
  $logger and call_user_func($logger, $progress_msg);
736
  }
737
+ PMXI_Plugin::$session['pmxi_import']['chunk_number'] = ++PMXI_Plugin::$session->data['pmxi_import']['chunk_number'];
738
+ pmxi_session_commit();
739
  continue;
740
  }
741
 
746
  $existing_cats = array();
747
  if (is_wp_error($cats_list)) {
748
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current categories for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
749
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
750
  } else {
751
  $cats_new = array();
752
  foreach ($cats_list as $c) {
758
  $tags_list = get_the_tags($articleData['ID']);
759
  if (is_wp_error($tags_list)) {
760
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current tags for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
761
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
762
  } else {
763
  $tags_new = array();
764
  if ($tags_list) foreach ($tags_list as $t) {
771
  $txes_list = get_the_terms($articleData['ID'], $tx_name);
772
  if (is_wp_error($txes_list)) {
773
  $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', 'pmxi_plugin'), $articleData['ID']));
774
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
775
  } else {
776
  $txes_new = array();
777
  if (!empty($txes_list)):
781
  endif;
782
  $existing_taxonomies[$tx_name][$i] = $txes_new;
783
  }
784
+ }
785
+ }
786
+ else{
787
+ foreach (array_keys($taxonomies) as $tx_name) wp_set_object_terms($articleData['ID'], NULL, $tx_name);
788
  }
789
  if ($this->options['is_keep_dates']) { // preserve date of already existing article when duplicate is found
790
  $articleData['post_date'] = $post_to_update->post_date;
809
  $articleData['post_parent'] = $post_to_update->post_parent;
810
  }
811
  // handle obsolete attachments (i.e. delete or keep) according to import settings
812
+ if ( ! $this->options['is_keep_images'] and ! $this->options['is_keep_attachments_on_update'] and ! $this->options['no_create_featured_image']){
813
+ wp_delete_attachments($articleData['ID'], $this->options['download_images']);
814
  }
815
 
816
  }
823
 
824
  // no new records are created. it will only update posts it finds matching duplicates for
825
  if ($this->options['not_create_records'] and empty($articleData['ID'])){
826
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
827
  $this->set(array(
828
  'skipped' => $this->skipped + 1
829
  ))->save();
831
  $logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: by "Not add new records" option for `%s`', 'pmxi_plugin'), $articleData['post_title']));
832
  if ( ! $is_cron ){
833
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
834
+ $progress_msg = '<p class="import_process_bar"> '. __('Created','pmxi_plugin') . ' ' . $this->created . ' / ' . __('Updated','pmxi_plugin') . ' ' . $this->updated . ' ' . __('of', 'pmxi_plugin') . ' '. $this->count .' ' . __('records', 'pmxi_plugin') . '.</p><span class="import_percent">' . ceil(($records_count/$this->count) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
835
  $logger and call_user_func($logger, $progress_msg);
836
  }
837
+ PMXI_Plugin::$session['pmxi_import']['chunk_number'] = ++PMXI_Plugin::$session->data['pmxi_import']['chunk_number'];
838
+ pmxi_session_commit();
839
  continue;
840
  }
841
 
904
  $dest->insert();
905
  } else {
906
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create cloaked link for %s', 'pmxi_plugin'), $url));
907
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
908
  $link = NULL;
909
  }
910
  }
921
 
922
  if (is_wp_error($pid)) {
923
  $logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
924
+ PMXI_Plugin::$session['pmxi_import']['errors'] = ++PMXI_Plugin::$session->data['pmxi_import']['errors'];
925
  } else {
926
+
927
  $tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
928
+ if ( ! in_array($pid, $tmp_array)){
929
+ $tmp_array[] = $pid;
930
+ $this->set(array(
931
+ 'current_post_ids' => json_encode($tmp_array)
932
+ ))->save();
933
+ }
934
 
935
  if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
936
  // associate post with import
938
  'post_id' => $pid,
939
  'import_id' => $this->id,
940
  'unique_key' => $unique_keys[$i],
941
+ 'product_key' => (class_exists('PMWI_Plugin')) ? $single_product_ID[$i] : null
942
  ))->insert();
943
+ }
944
+
945
+ // [post format]
946
+ if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post_type, 'post-formats' ) ){
947
+ set_post_format($pid, $this->options['post_format'] );
948
+ }
949
+ // [/post format]
950
 
951
  // Woocommerce add-on
952
  if ( $post_type == "product" and class_exists('PMWI_Plugin')){
955
 
956
  }
957
 
958
+ if ('post' != $articleData['post_type'] and !empty($this->options['page_template'])) update_post_meta($pid, '_wp_page_template', $this->options['page_template']);
959
+
960
  // [featured image]
961
+ if ( ! empty($uploads) and false === $uploads['error'] and !empty($featured_images[$i]) and (empty($articleData['ID']) or empty($this->options['is_keep_images']) or ! has_post_thumbnail($pid))) {
962
 
963
  require_once(ABSPATH . 'wp-admin/includes/image.php');
964
 
965
  if ( ! is_array($featured_images[$i]) ) $featured_images[$i] = array($featured_images[$i]);
966
+ if ( ! is_array($image_meta_titles[$i]) ) $image_meta_titles[$i] = array($image_meta_titles[$i]);
967
+ if ( ! is_array($image_meta_captions[$i]) ) $image_meta_captions[$i] = array($image_meta_captions[$i]);
968
+ if ( ! is_array($image_meta_descriptions[$i]) ) $image_meta_descriptions[$i] = array($image_meta_descriptions[$i]);
969
  $post_thumbnail = false;
970
  $success_images = false;
971
  $gallery_attachment_ids = array();
972
+
973
+ $_pmxi_images = array();
974
+
975
+ foreach ($featured_images[$i] as $k => $featured_image)
976
  {
977
+ $imgs = ( ! empty($this->options['featured_delim']) ) ? str_getcsv($featured_image, $this->options['featured_delim']) : explode("\n", $featured_image);
978
+ if ( $this->options['set_image_meta_data'] ){
979
+ $img_titles = ( ! empty($this->options['image_meta_title_delim']) ) ? str_getcsv($image_meta_titles[$i][$k], $this->options['image_meta_title_delim']) : array($image_meta_titles[$i][$k]);
980
+ $img_captions = ( ! empty($this->options['image_meta_caption_delim']) ) ? str_getcsv($image_meta_captions[$i][$k], $this->options['image_meta_caption_delim']) : array($image_meta_captions[$i][$k]);
981
+ $img_alts = ( ! empty($this->options['image_meta_alt_delim']) ) ? str_getcsv($image_meta_alts[$i][$k], $this->options['image_meta_alt_delim']) : array($image_meta_alts[$i][$k]);
982
+ $img_descriptions = ( ! empty($this->options['image_meta_description_delim']) ) ? str_getcsv($image_meta_descriptions[$i][$k], $this->options['image_meta_description_delim']) : array($image_meta_descriptions[$i][$k]);
983
+ }
984
+ if (!empty($imgs)) {
985
+
986
+ foreach ($imgs as $img_key => $img_url) { if (empty($img_url)) continue;
987
+
988
+ $url = str_replace(" ", "%20", trim(pmxi_convert_encoding($img_url)));
989
+ $img_ext = pmxi_get_remote_image_ext($url);
990
+ $image_name = (($this->options['auto_rename_images'] and "" != $auto_rename_images[$i]) ? url_title($auto_rename_images[$i] . '_' . (($this->options['images_name'] != 'auto') ? array_shift(explode('?', basename($url))) : uniqid())) : (($this->options['images_name'] != 'auto') ? array_shift(explode('?', basename($url))) : uniqid())) . (("" != $img_ext and $this->options['images_name'] == 'auto') ? '.'.$img_ext : '');
991
+
992
+ // if wizard store image data to custom field
993
  $create_image = false;
994
  $download_image = true;
995
+
996
+ if (base64_decode($url, true) !== false){
997
+ $img = @imagecreatefromstring(base64_decode($url));
998
  if($img)
999
  {
1000
  $image_filename = md5(time()) . '.jpg';
1002
  imagejpeg($img, $image_filepath);
1003
  if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
1004
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $image_filepath));
1005
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1006
  } else {
1007
  $create_image = true;
1008
+ }
1009
  }
1010
  }
1011
+ else {
 
 
1012
 
 
1013
  $image_filename = wp_unique_filename($uploads['path'], $image_name);
1014
  $image_filepath = $uploads['path'] . '/' . url_title($image_filename);
1015
 
1032
  }
1033
  }
1034
 
1035
+ if ($download_image){
1036
 
1037
+ // do not download images
1038
+ if ( ! $this->options['download_images'] ){
1039
+
1040
+ $image_filepath = $uploads['path'] . '/' . url_title( $image_filename = $image_name );
1041
+
1042
+ if ( @file_exists($image_filepath) ){
1043
+ $download_image = false;
1044
+ if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
1045
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $image_filepath));
1046
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1047
+ } else {
1048
+ $create_image = true;
1049
+ }
1050
+ }
1051
+ }
1052
 
1053
+ if ($download_image){
1054
+
1055
+ if ( ! get_file_curl($url, $image_filepath) and ! @file_put_contents($image_filepath, @file_get_contents($url))) {
1056
+ unlink($image_filepath); // delete file since failed upload may result in empty file created
1057
+ } elseif( ($image_info = @getimagesize($image_filepath)) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
1058
+ $create_image = true;
1059
+ }
1060
+
1061
+ if ( ! $create_image ){
1062
+
1063
+ $url = str_replace(" ", "%20", trim($img_url));
1064
+
1065
+ if ( ! get_file_curl($url, $image_filepath) and ! @file_put_contents($image_filepath, @file_get_contents($url))) {
1066
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s cannot be saved locally as %s', 'pmxi_plugin'), $url, $image_filepath));
1067
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1068
+ unlink($image_filepath); // delete file since failed upload may result in empty file created
1069
+ } elseif( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
1070
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $url));
1071
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1072
+ } else {
1073
+ $create_image = true;
1074
+ }
1075
+
1076
+ }
1077
  }
1078
  }
1079
  }
1080
 
1081
  if ($create_image){
1082
+
1083
  $attachment = array(
1084
  'post_mime_type' => image_type_to_mime_type($image_info[2]),
1085
  'guid' => $uploads['url'] . '/' . $image_filename,
1092
  if (trim($image_meta['caption']))
1093
  $attachment['post_content'] = $image_meta['caption'];
1094
  }
1095
+
1096
+ $attid = wp_insert_attachment($attachment, $image_filepath, $pid);
1097
+
1098
  if (is_wp_error($attid)) {
1099
+ $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $attid->get_error_message());
1100
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1101
  } else {
1102
  // you must first include the image.php file
1103
  // for the function wp_generate_attachment_metadata() to work
1104
  require_once(ABSPATH . 'wp-admin/includes/image.php');
1105
+ wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $image_filepath));
1106
+
1107
+ if ( $this->options['set_image_meta_data'] ){
1108
+ $update_attachment_meta = array();
1109
+ if ( ! empty($img_titles[$img_key]) ) $update_attachment_meta['post_title'] = $img_titles[$img_key];
1110
+ if ( ! empty($img_captions[$img_key]) ) $update_attachment_meta['post_excerpt'] = $img_captions[$img_key];
1111
+ if ( ! empty($img_descriptions[$img_key]) ) $update_attachment_meta['post_content'] = $img_descriptions[$img_key];
1112
+ if ( ! empty($img_alts[$img_key]) ) update_post_meta($attid, '_wp_attachment_image_alt', $img_alts[$img_key]);
1113
+
1114
+ if ( ! empty($update_attachment_meta)){
1115
+ $update_attachment_meta['ID'] = $attid;
1116
+ wp_update_post($update_attachment_meta);
1117
+ }
1118
+ }
1119
+
1120
+ do_action( 'pmxi_gallery_image', $pid, $attid, $image_filepath);
1121
+
1122
  $success_images = true;
1123
  if ( ! $post_thumbnail ) {
1124
  if ( ! $this->options['no_create_featured_image'] or ! has_post_thumbnail($pid)){
1129
  }
1130
  else $gallery_attachment_ids[] = $attid;
1131
  }
1132
+ }
1133
  }
1134
  }
1135
+ }
1136
+ //if (!$is_cron) update_post_meta($pid, '_pmxi_images', $_pmxi_images);
1137
  // Set product gallery images
1138
+ if ( $post_type == "product" and !empty($gallery_attachment_ids) )
1139
  update_post_meta($pid, '_product_image_gallery', implode(',', $gallery_attachment_ids));
1140
  // Create entry as Draft if no images are downloaded successfully
1141
+ if ( ! $success_images and "yes" == $this->options['create_draft'] ) wp_update_post(array('ID' => $pid, 'post_status' => 'draft'));
1142
  }
1143
  // [/featured image]
1144
+
1145
  // [attachments]
1146
  if ( ! empty($uploads) and false === $uploads['error'] and !empty($attachments[$i])) {
1147
 
1163
 
1164
  if ( ! get_file_curl(trim($atch_url), $attachment_filepath) and ! @file_put_contents($attachment_filepath, @file_get_contents(trim($atch_url)))) {
1165
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Attachment file %s cannot be saved locally as %s', 'pmxi_plugin'), trim($atch_url), $attachment_filepath));
1166
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1167
  unlink($attachment_filepath); // delete file since failed upload may result in empty file created
1168
  } elseif( ! $wp_filetype = wp_check_filetype(basename($attachment_filename), null )) {
1169
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Can\'t detect attachment file type %s', 'pmxi_plugin'), trim($atch_url)));
1170
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1171
  } else {
1172
+
1173
  $attachment_data = array(
1174
  'guid' => $uploads['baseurl'] . '/' . _wp_relative_upload_path( $attachment_filepath ),
1175
  'post_mime_type' => $wp_filetype['type'],
1181
 
1182
  if (is_wp_error($attach_id)) {
1183
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
1184
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1185
  } else {
1186
+ do_action( 'pmxi_attachment_uploaded', $pid, $attid, $image_filepath);
1187
  wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attachment_filepath));
1188
  }
1189
  }
1191
  }
1192
  }
1193
  }
1194
+ // [/attachments]
1195
+
1196
  // [custom taxonomies]
1197
+ if (!empty($taxonomies)){
 
1198
  foreach ($taxonomies as $tx_name => $txes) {
1199
 
1200
  if ( empty($articleData['ID']) or !$this->options['is_keep_categories'] or ( $this->options['is_keep_categories'] and $this->options['is_add_newest_categories'] ) ){
1206
  unset($existing_taxonomies[$tx_name][$i]);
1207
  }
1208
 
1209
+ // create term if not exists
1210
+ if (!empty($txes[$i])):
1211
+ foreach ($txes[$i] as $key => $single_tax) {
1212
+ if (is_array($single_tax)){
 
 
 
1213
 
1214
+ $parent_id = (!empty($single_tax['parent'])) ? $this->recursion_taxes($single_tax['parent'], $tx_name, $txes[$i], $key) : '';
1215
+
1216
+ $term = is_exists_term($tx_name, $single_tax['name'], (int)$parent_id);
1217
+
1218
+ if ( empty($term) and !is_wp_error($term) ){
1219
+ $term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
1220
+ $term = wp_insert_term(
1221
+ $single_tax['name'], // the term
1222
+ $tx_name, // the taxonomy
1223
+ $term_attr
1224
+ );
1225
+ }
1226
+
1227
+ if ( is_wp_error($term) ){
1228
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
1229
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1230
+ }
1231
+ elseif (!empty($term)) {
1232
+ $cat_id = $term['term_id'];
1233
+ if ($cat_id and $single_tax['assign'])
1234
+ {
1235
+ $term = get_term_by('id', $cat_id, $tx_name);
1236
+ if (!in_array($term->slug, $assign_taxes)) $assign_taxes[] = $term->slug;
1237
+ }
1238
  }
1239
+ }
1240
+ }
1241
+ endif;
1242
+ if (!empty($assign_taxes)){
1243
+ // associate taxes with post
1244
+ $term_ids = wp_set_object_terms($pid, $assign_taxes, $tx_name);
1245
+ if (is_wp_error($term_ids)) {
1246
+ $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
1247
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1248
  }
 
 
 
 
 
 
1249
  }
1250
  }
1251
  }
1255
  $term_ids = wp_set_object_terms($pid, $txes[$i], $tx_name);
1256
  if (is_wp_error($term_ids)) {
1257
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
1258
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1259
  }
1260
  }
1261
  }
1262
  }
1263
+ }
1264
+ // [/custom taxonomies]
1265
 
1266
  // [categories]
1267
  if (!empty($cats[$i])) {
1284
 
1285
  $parent_id = (!empty($single_cat['parent'])) ? $this->recursion_taxes($single_cat['parent'], 'category', $cats[$i], $key) : '';
1286
 
1287
+ //$term = term_exists( trim($single_cat['name']), 'category', $parent_id );
1288
+ $term = is_exists_term('category', $single_cat['name'], (int)$parent_id);
1289
+
1290
+ if ( empty($term) and !is_wp_error($term) ){
1291
  $term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
1292
  $term = wp_insert_term(
1293
  $single_cat['name'], // the term
1298
 
1299
  if ( is_wp_error($term) ){
1300
  $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
1301
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1302
  }
1303
  elseif ( ! empty($term) ) {
1304
  $cat_id = $term['term_id'];
1315
  $cats_ids = wp_set_object_terms($pid, $assign_cats, 'category');
1316
  if (is_wp_error($cats_ids)) {
1317
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
1318
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1319
  }
1320
  }
1321
  }
1325
 
1326
  if (is_wp_error($cats_ids)) {
1327
  $logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
1328
+ PMXI_Plugin::$session['pmxi_import']['warnings'] = ++PMXI_Plugin::$session->data['pmxi_import']['warnings'];
1329
  }
1330
  }
1331
  // [/categories]
1345
  'imported' => $this->imported + 1,
1346
  'created' => (empty($articleData['ID'])) ? $this->created + 1 : $this->created,
1347
  'updated' => (empty($articleData['ID'])) ? $this->updated : $this->updated + 1
1348
+ ))->save();
 
1349
  }
1350
 
1351
  $records_count = 0;
1352
 
1353
  // Time Elapsed
1354
+ if ( ! $is_cron){
 
 
1355
 
1356
  $records_count = $this->created + $this->updated + $this->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'];
1357
 
1358
+ $progress_msg = '<p class="import_process_bar"> '.__('Created','pmxi_plugin'). ' ' . $this->created . ' / '.__('Updated','pmxi_plugin') . ' ' . $this->updated . ' ' . __('of','pmxi_plugin') . ' '. $this->count .' ' . __('records', 'pmxi_plugin') . '.</p><span class="import_percent">' . ceil(($records_count/$this->count) * 100) . '</span><span class="warnings_count">' . PMXI_Plugin::$session->data['pmxi_import']['warnings'] . '</span><span class="errors_count">' . PMXI_Plugin::$session->data['pmxi_import']['errors'] . '</span>';
1359
  $logger and call_user_func($logger, $progress_msg);
1360
  }
1361
 
1362
+ }
1363
 
1364
  wp_cache_flush();
1365
+ }
1366
+
1367
+ if ($this->large_import == 'Yes' and $chunk) PMXI_Plugin::$session['pmxi_import']['chunk_number'] = ++PMXI_Plugin::$session->data['pmxi_import']['chunk_number'];
1368
 
1369
+ pmxi_session_commit();
1370
+
1371
+ $is_import_complete = ($records_count == $this->count);
1372
 
1373
  if ( ! $is_cron and $is_import_complete and ! empty($this->options['is_delete_missing'])) { // delete posts which are not in current import set
1374
 
1391
  }
1392
 
1393
  if (!empty($missing_ids)){
1394
+
1395
+ foreach ($missing_ids as $id) wp_delete_object_term_relationships($id, get_object_taxonomies('' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post'));
1396
+
1397
  $sql = "delete a,b,c
1398
  FROM ".$this->wpdb->posts." a
1399
  LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
1403
  $this->wpdb->query(
1404
  $this->wpdb->prepare($sql, '')
1405
  );
1406
+ }
1407
 
1408
  }
1409
 
1433
 
1434
  } catch (XmlImportException $e) {
1435
  $logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
1436
+ PMXI_Plugin::$session['pmxi_import']['errors'] = ++PMXI_Plugin::$session->data['pmxi_import']['errors'];
1437
  }
1438
 
1439
  $this->set('registered_on', date('Y-m-d H:i:s'))->save(); // specify execution is successful
1445
 
1446
  if (($is_cron or $is_import_complete) and $this->options['is_delete_source']) {
1447
  $logger and call_user_func($logger, __('Deleting source XML file...', 'pmxi_plugin'));
1448
+ if ($this->type != "ftp"){
1449
+ if ( ! @unlink($this->path)) {
1450
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
1451
+ }
1452
+ }
1453
+ else{
1454
+ $file_path_array = PMXI_Helper::safe_glob($this->path, PMXI_Helper::GLOB_NODIR | PMXI_Helper::GLOB_PATH);
1455
+ if (!empty($file_path_array)){
1456
+ foreach ($file_path_array as $path) {
1457
+ if ( ! @unlink($path)) {
1458
+ $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $path));
1459
+ }
1460
+ }
1461
+ }
1462
  }
1463
  }
1464
  if ( ! $is_cron and $is_import_complete ){
1474
  remove_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // return any filtering rules back if they has been disabled for import procedure
1475
 
1476
  return $this;
1477
+ }
1478
 
1479
  public function recursion_taxes($parent, $tx_name, $txes, $key){
1480
+
1481
  if (is_array($parent)){
1482
  $parent['name'] = sanitize_text_field($parent['name']);
1483
  if (empty($parent['parent'])){
1484
+ //$term = term_exists( htmlspecialchars($parent['name']), $tx_name);
1485
+
1486
+ $term = is_exists_term($tx_name, $parent['name']);
1487
+
1488
  if ( empty($term) and !is_wp_error($term) ){
1489
  $term = wp_insert_term(
1490
  $parent['name'], // the term
1491
  $tx_name // the taxonomy
1492
  );
1493
  }
1494
+ return ( ! is_wp_error($term)) ? $term['term_id'] : 0;
1495
  }
1496
  else{
1497
  $parent_id = $this->recursion_taxes($parent['parent'], $tx_name, $txes, $key);
1498
+ //$term = term_exists( htmlspecialchars($parent['name']), $tx_name, $parent_id);
1499
+
1500
+ $term = is_exists_term($tx_name, $parent['name'], (int)$parent_id);
1501
+
1502
  if ( empty($term) and !is_wp_error($term) ){
1503
  $term = wp_insert_term(
1504
  $parent, // the term
1506
  array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
1507
  );
1508
  }
1509
+ return ( ! is_wp_error($term)) ? $term['term_id'] : 0;
1510
  }
1511
  }
1512
  else{
1513
 
1514
+ if ( !empty($txes[$key - 1]) and !empty($txes[$key - 1]['parent']) and $parent != $txes[$key - 1]['parent']) {
1515
  $parent_id = $this->recursion_taxes($txes[$key - 1]['parent'], $tx_name, $txes, $key - 1);
1516
 
1517
+ //$term = term_exists( htmlspecialchars($parent), $tx_name, $parent_id);
1518
+ $term = is_exists_term($tx_name, $parent, (int)$parent_id);
1519
+
1520
  if ( empty($term) and !is_wp_error($term) ){
1521
  $term = wp_insert_term(
1522
  $parent, // the term
1524
  array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
1525
  );
1526
  }
1527
+ return ( ! is_wp_error($term)) ? $term['term_id'] : 0;
1528
  }
1529
  else{
1530
+ //$term = term_exists( htmlspecialchars($parent), $tx_name);
1531
+ $term = is_exists_term($tx_name, $parent);
1532
  if ( empty($term) and !is_wp_error($term) ){
1533
  $term = wp_insert_term(
1534
  $parent, // the term
1535
  $tx_name // the taxonomy
1536
  );
1537
+ }
1538
+ return ( ! is_wp_error($term)) ? $term['term_id'] : 0;
 
1539
  }
1540
  }
1541
+ }
1542
 
1543
  public function _filter_has_cap_unfiltered_html($caps)
1544
  {
1593
  * @chainable
1594
  */
1595
  public function deletePosts($keepPosts = TRUE) {
1596
+ $post = new PMXI_Post_List();
1597
+ if ( ! $keepPosts) {
 
 
1598
  $ids = array();
1599
  foreach ($post->getBy('import_id', $this->id)->convertRecords() as $p) {
1600
+ empty($this->options['is_keep_attachments']) and wp_delete_attachments($p->post_id);
1601
+ $ids[] = $p->post_id;
 
1602
  }
1603
  if (!empty($ids)){
1604
 
1605
+ foreach ($ids as $id) wp_delete_object_term_relationships($id, get_object_taxonomies('' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post'));
1606
+
1607
  $sql = "delete a,b,c
1608
  FROM ".$this->wpdb->posts." a
1609
  LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
1610
+ LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
1611
+ LEFT JOIN ".$this->wpdb->posts." d ON ( a.ID = d.post_parent )
1612
  WHERE a.ID IN (".implode(',', $ids).");";
1613
 
1614
  $this->wpdb->query(
1615
  $this->wpdb->prepare($sql, '')
1616
+ );
1617
+
1618
+ }
1619
  }
1620
+
1621
+ $this->wpdb->query($this->wpdb->prepare('DELETE FROM ' . $post->getTable() . ' WHERE import_id = %s', $this->id));
1622
+
1623
  return $this;
1624
  }
1625
  /**
models/model/list.php CHANGED
@@ -1,149 +1,149 @@
1
- <?php
2
- /**
3
- * Incapsulates behavior for list of database records
4
- *
5
- * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
- */
7
- class PMXI_Model_List extends PMXI_Model {
8
-
9
- /**
10
- * Total number of records in database which correspond last getBy rule without paging
11
- * @var int
12
- */
13
- protected $total = 0;
14
-
15
- /**
16
- * Joined tables
17
- * @var array
18
- */
19
- protected $joined = array();
20
- /**
21
- * Columns to select from database
22
- * @var string
23
- */
24
- protected $what = '*';
25
- /**
26
- * Sets table to use in conjuction with primary list table
27
- * @param string $table Table to join
28
- * @param string $on Condition to join
29
- * @param string $type Join type (INNER, OUTER, etc)
30
- * @return PMXI_Model_List
31
- */
32
- public function join($table, $on, $type = 'INNER') {
33
- $this->joined[] = ( ! is_null($type) ? $type . ' ' : '') . 'JOIN ' . $table . ' ON ' . $on;
34
- return $this;
35
- }
36
-
37
- /**
38
- * Set columns to be selected from database
39
- * @param array $columns
40
- * @return PMXI_Model_List
41
- */
42
- public function setColumns($columns) {
43
- is_array($columns) or $columns = func_get_args();
44
- $this->what = implode(', ', $columns);
45
- return $this;
46
- }
47
-
48
- /**
49
- * Read records from database by specified fields and values
50
- * When 1st parameter is an array, it's expected to be an associative array of field => value pairs to read data by
51
- * When 2nd parameter is a scalar, it's expected to be a field name and second parameter - it's value
52
- *
53
- * @param string|array[optional] $field
54
- * @param mixed[optional] $value
55
- * @param string[optional] $orderBy Ordering rule
56
- * @param int[optional] $page Paging paramter used to limit number of records returned
57
- * @param int[optional] $perPage Page size when paging parameter is used (20 by default)
58
- * @return PMXI_Model_List
59
- */
60
- public function getBy($field = NULL, $value = NULL, $orderBy = NULL, $page = NULL, $perPage = NULL, $groupBy = NULL) {
61
- if (is_array($field) or is_null($field)) { // when associative array is submitted, do not expect second paramter to be $value, but act as if there is no $value parameter at all
62
- $groupBy = $perPage; $perPage = $page; $page = $orderBy; $orderBy = $value; $value = NULL;
63
- }
64
- ! is_null($perPage) or $perPage = 20; // set default value for page length
65
- $page = intval($page);
66
-
67
- $sql = "FROM $this->table ";
68
- $sql .= implode(' ', $this->joined);
69
- if ( ! is_null($field)) {
70
- $sql .= " WHERE " . $this->buildWhere($field, $value);
71
- }
72
- if ( ! is_null($groupBy)) {
73
- $sql .= " GROUP BY $groupBy";
74
- }
75
- is_null($orderBy) and $orderBy = implode(', ', $this->primary); // default sort order is by primary key
76
- $sql .= " ORDER BY $orderBy";
77
- if ($page > 0) {
78
- $sql = "SELECT SQL_CALC_FOUND_ROWS $this->what $sql LIMIT " . intval(($page - 1) * $perPage) . ", " . intval($perPage);
79
- } else {
80
- $sql = "SELECT $this->what $sql";
81
- }
82
- $result = $this->wpdb->get_results($sql, ARRAY_A);
83
- if (is_array($result)) {
84
- foreach ($result as $i => $row) {
85
- foreach ($row as $k => $v) {
86
- if (is_serialized($v)) {
87
- $result[$i][$k] = unserialize($v);
88
- }
89
- }
90
- }
91
- if ($page > 0) {
92
- $this->total = intval($this->wpdb->get_var('SELECT FOUND_ROWS()'));
93
- } else {
94
- $this->total = count($result);
95
- }
96
- $this->exchangeArray($result);
97
- } else {
98
- $this->total = 0;
99
- $this->clear();
100
- }
101
- return $this;
102
- }
103
-
104
- /**
105
- * Count records in table
106
- * @param string|array $field
107
- * @param mixed[optional] $value
108
- * @return int
109
- */
110
- public function countBy($field = NULL, $value = NULL) {
111
- $sql = "SELECT COUNT(*) FROM $this->table ";
112
- $sql .= implode(' ', $this->joined);
113
- if ( ! is_null($field)) {
114
- $sql .= " WHERE " . $this->buildWhere($field, $value);
115
- }
116
- return intval($this->wpdb->get_var($sql));
117
- }
118
-
119
- /**
120
- * Method returns number of rows in database which correspond last getBy query
121
- * @return int
122
- */
123
- public function total() {
124
- return $this->total;
125
- }
126
-
127
- /**
128
- * Converts elements to instances of specifield class. If includeFields are provided only fields listed are included
129
- * @param string[optoinal] $elementClass
130
- * @param array[optional] $includeFields
131
- * @return PMXI_Model_List
132
- */
133
- public function convertRecords($elementClass = NULL, $includeFields = NULL) {
134
- ! is_null($elementClass) or $elementClass = preg_replace('%List$%', 'Record', get_class($this));
135
- if ( ! is_subclass_of($elementClass, PMXI_Plugin::PREFIX . 'Model_Record')) {
136
- throw new Exception("Provideded class name $elementClass must be a subclass of " . PMXI_Plugin::PREFIX . 'Model_Record');
137
- }
138
- $records = $this->exchangeArray(array());
139
- foreach ($records as $r) {
140
- $data = (array)$r;
141
- if ( ! is_null($includeFields)) {
142
- $data = array_intersect_key($data, array_flip($includeFields));
143
- }
144
- $this[] = new $elementClass($data);
145
- }
146
- return $this;
147
- }
148
-
149
  }
1
+ <?php
2
+ /**
3
+ * Incapsulates behavior for list of database records
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXI_Model_List extends PMXI_Model {
8
+
9
+ /**
10
+ * Total number of records in database which correspond last getBy rule without paging
11
+ * @var int
12
+ */
13
+ protected $total = 0;
14
+
15
+ /**
16
+ * Joined tables
17
+ * @var array
18
+ */
19
+ protected $joined = array();
20
+ /**
21
+ * Columns to select from database
22
+ * @var string
23
+ */
24
+ protected $what = '*';
25
+ /**
26
+ * Sets table to use in conjuction with primary list table
27
+ * @param string $table Table to join
28
+ * @param string $on Condition to join
29
+ * @param string $type Join type (INNER, OUTER, etc)
30
+ * @return PMXI_Model_List
31
+ */
32
+ public function join($table, $on, $type = 'INNER') {
33
+ $this->joined[] = ( ! is_null($type) ? $type . ' ' : '') . 'JOIN ' . $table . ' ON ' . $on;
34
+ return $this;
35
+ }
36
+
37
+ /**
38
+ * Set columns to be selected from database
39
+ * @param array $columns
40
+ * @return PMXI_Model_List
41
+ */
42
+ public function setColumns($columns) {
43
+ is_array($columns) or $columns = func_get_args();
44
+ $this->what = implode(', ', $columns);
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Read records from database by specified fields and values
50
+ * When 1st parameter is an array, it's expected to be an associative array of field => value pairs to read data by
51
+ * When 2nd parameter is a scalar, it's expected to be a field name and second parameter - it's value
52
+ *
53
+ * @param string|array[optional] $field
54
+ * @param mixed[optional] $value
55
+ * @param string[optional] $orderBy Ordering rule
56
+ * @param int[optional] $page Paging paramter used to limit number of records returned
57
+ * @param int[optional] $perPage Page size when paging parameter is used (20 by default)
58
+ * @return PMXI_Model_List
59
+ */
60
+ public function getBy($field = NULL, $value = NULL, $orderBy = NULL, $page = NULL, $perPage = NULL, $groupBy = NULL) {
61
+ if (is_array($field) or is_null($field)) { // when associative array is submitted, do not expect second paramter to be $value, but act as if there is no $value parameter at all
62
+ $groupBy = $perPage; $perPage = $page; $page = $orderBy; $orderBy = $value; $value = NULL;
63
+ }
64
+ ! is_null($perPage) or $perPage = 20; // set default value for page length
65
+ $page = intval($page);
66
+
67
+ $sql = "FROM $this->table ";
68
+ $sql .= implode(' ', $this->joined);
69
+ if ( ! is_null($field)) {
70
+ $sql .= " WHERE " . $this->buildWhere($field, $value);
71
+ }
72
+ if ( ! is_null($groupBy)) {
73
+ $sql .= " GROUP BY $groupBy";
74
+ }
75
+ is_null($orderBy) and $orderBy = implode(', ', $this->primary); // default sort order is by primary key
76
+ $sql .= " ORDER BY $orderBy";
77
+ if ($page > 0) {
78
+ $sql = "SELECT SQL_CALC_FOUND_ROWS $this->what $sql LIMIT " . intval(($page - 1) * $perPage) . ", " . intval($perPage);
79
+ } else {
80
+ $sql = "SELECT $this->what $sql";
81
+ }
82
+ $result = $this->wpdb->get_results($sql, ARRAY_A);
83
+ if (is_array($result)) {
84
+ foreach ($result as $i => $row) {
85
+ foreach ($row as $k => $v) {
86
+ if (is_serialized($v)) {
87
+ $result[$i][$k] = unserialize($v);
88
+ }
89
+ }
90
+ }
91
+ if ($page > 0) {
92
+ $this->total = intval($this->wpdb->get_var('SELECT FOUND_ROWS()'));
93
+ } else {
94
+ $this->total = count($result);
95
+ }
96
+ $this->exchangeArray($result);
97
+ } else {
98
+ $this->total = 0;
99
+ $this->clear();
100
+ }
101
+ return $this;
102
+ }
103
+
104
+ /**
105
+ * Count records in table
106
+ * @param string|array $field
107
+ * @param mixed[optional] $value
108
+ * @return int
109
+ */
110
+ public function countBy($field = NULL, $value = NULL) {
111
+ $sql = "SELECT COUNT(*) FROM $this->table ";
112
+ $sql .= implode(' ', $this->joined);
113
+ if ( ! is_null($field)) {
114
+ $sql .= " WHERE " . $this->buildWhere($field, $value);
115
+ }
116
+ return intval($this->wpdb->get_var($sql));
117
+ }
118
+
119
+ /**
120
+ * Method returns number of rows in database which correspond last getBy query
121
+ * @return int
122
+ */
123
+ public function total() {
124
+ return $this->total;
125
+ }
126
+
127
+ /**
128
+ * Converts elements to instances of specifield class. If includeFields are provided only fields listed are included
129
+ * @param string[optoinal] $elementClass
130
+ * @param array[optional] $includeFields
131
+ * @return PMXI_Model_List
132
+ */
133
+ public function convertRecords($elementClass = NULL, $includeFields = NULL) {
134
+ ! is_null($elementClass) or $elementClass = preg_replace('%List$%', 'Record', get_class($this));
135
+ if ( ! is_subclass_of($elementClass, PMXI_Plugin::PREFIX . 'Model_Record')) {
136
+ throw new Exception("Provideded class name $elementClass must be a subclass of " . PMXI_Plugin::PREFIX . 'Model_Record');
137
+ }
138
+ $records = $this->exchangeArray(array());
139
+ foreach ($records as $r) {
140
+ $data = (array)$r;
141
+ if ( ! is_null($includeFields)) {
142
+ $data = array_intersect_key($data, array_flip($includeFields));
143
+ }
144
+ $this[] = new $elementClass($data);
145
+ }
146
+ return $this;
147
+ }
148
+
149
  }
models/model/record.php CHANGED
@@ -82,12 +82,12 @@ class PMXI_Model_Record extends PMXI_Model {
82
  * Update record in database
83
  * @return PMXI_Model_Record
84
  */
85
- public function update() {
86
- $record = $this->toArray(TRUE);
87
- $this->wpdb->update($this->table, $record, array_intersect_key($record, array_flip($this->primary)));
88
  if ($this->wpdb->last_error) {
89
  throw new Exception($this->wpdb->last_error);
90
- }
91
  return $this;
92
  }
93
 
@@ -98,7 +98,7 @@ class PMXI_Model_Record extends PMXI_Model {
98
  public function delete() {
99
  if ($this->wpdb->query("DELETE FROM $this->table WHERE " . $this->buildWhere(array_intersect_key($this->toArray(TRUE), array_flip($this->primary))))) {
100
  return $this;
101
- } else {
102
  throw new Exception($this->wpdb->last_error);
103
  }
104
  }
82
  * Update record in database
83
  * @return PMXI_Model_Record
84
  */
85
+ public function update() {
86
+ $record = $this->toArray(TRUE);
87
+ $this->wpdb->update($this->table, $record, array_intersect_key($record, array_flip($this->primary)));
88
  if ($this->wpdb->last_error) {
89
  throw new Exception($this->wpdb->last_error);
90
+ }
91
  return $this;
92
  }
93
 
98
  public function delete() {
99
  if ($this->wpdb->query("DELETE FROM $this->table WHERE " . $this->buildWhere(array_intersect_key($this->toArray(TRUE), array_flip($this->primary))))) {
100
  return $this;
101
+ } elseif ($this->wpdb->last_error) {
102
  throw new Exception($this->wpdb->last_error);
103
  }
104
  }
models/post/list.php CHANGED
@@ -1,10 +1,10 @@
1
- <?php
2
-
3
- class PMXI_Post_List extends PMXI_Model_List {
4
- protected $primary = array('post_id');
5
-
6
- public function __construct() {
7
- parent::__construct();
8
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'posts');
9
- }
10
  }
1
+ <?php
2
+
3
+ class PMXI_Post_List extends PMXI_Model_List {
4
+ protected $primary = array('post_id');
5
+
6
+ public function __construct() {
7
+ parent::__construct();
8
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'posts');
9
+ }
10
  }
models/post/record.php CHANGED
@@ -1,15 +1,15 @@
1
- <?php
2
-
3
- class PMXI_Post_Record extends PMXI_Model_Record {
4
- protected $primary = array('post_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() . 'posts');
13
- }
14
-
15
  }
1
+ <?php
2
+
3
+ class PMXI_Post_Record extends PMXI_Model_Record {
4
+ protected $primary = array('post_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() . 'posts');
13
+ }
14
+
15
  }
models/template/list.php CHANGED
@@ -1,8 +1,8 @@
1
- <?php
2
-
3
- class PMXI_Template_List extends PMXI_Model_List {
4
- public function __construct() {
5
- parent::__construct();
6
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'templates');
7
- }
8
  }
1
+ <?php
2
+
3
+ class PMXI_Template_List extends PMXI_Model_List {
4
+ public function __construct() {
5
+ parent::__construct();
6
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'templates');
7
+ }
8
  }
models/template/record.php CHANGED
@@ -1,13 +1,13 @@
1
- <?php
2
-
3
- class PMXI_Template_Record extends PMXI_Model_Record {
4
- /**
5
- * Initialize model instance
6
- * @param array[optional] $data Array of record data to initialize object with
7
- */
8
- public function __construct($data = array()) {
9
- parent::__construct($data);
10
- $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'templates');
11
- }
12
-
13
  }
1
+ <?php
2
+
3
+ class PMXI_Template_Record extends PMXI_Model_Record {
4
+ /**
5
+ * Initialize model instance
6
+ * @param array[optional] $data Array of record data to initialize object with
7
+ */
8
+ public function __construct($data = array()) {
9
+ parent::__construct($data);
10
+ $this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'templates');
11
+ }
12
+
13
  }
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. Perform scheduled updates and overwrite of existing import jobs. Free lite edition.
6
- Version: 3.0.2
7
  Author: Soflyy
8
  */
9
 
@@ -28,7 +28,7 @@ define('PMXI_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
28
  */
29
  define('PMXI_PREFIX', 'pmxi_');
30
 
31
- define('PMXI_VERSION', '3.01');
32
 
33
  define('PMXI_EDITION', 'free');
34
 
@@ -78,6 +78,12 @@ final class PMXI_Plugin {
78
  const LARGE_SIZE = 0; // all files will importing in large import mode
79
 
80
  public static $session;
 
 
 
 
 
 
81
 
82
  /**
83
  * Return singletone instance
@@ -227,26 +233,7 @@ final class PMXI_Plugin {
227
  }
228
 
229
  // register admin page pre-dispatcher
230
- add_action('admin_init', array($this, '__adminInit'));
231
-
232
- global $wpdb;
233
-
234
- if (function_exists('is_multisite') && is_multisite()) {
235
- // check if it is a network activation - if so, run the activation function for each blog id
236
- if (isset($_GET['networkwide']) && ($_GET['networkwide'] == 1)) {
237
- $old_blog = $wpdb->blogid;
238
- // Get all blog ids
239
- $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
240
- foreach ($blogids as $blog_id) {
241
- switch_to_blog($blog_id);
242
- $this->__add_feed_type_fix(); // feature to version 2.22
243
- }
244
- switch_to_blog($old_blog);
245
- return;
246
- }
247
- }
248
-
249
- $this->__add_feed_type_fix(); // feature to version 2.22
250
 
251
  }
252
 
@@ -420,7 +407,8 @@ final class PMXI_Plugin {
420
  // create plugin options
421
  $option_name = get_class($this) . '_Options';
422
  $options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
423
- update_option($option_name, $options_default);
 
424
 
425
  // create/update required database tables
426
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
@@ -437,7 +425,7 @@ final class PMXI_Plugin {
437
  switch_to_blog($blog_id);
438
  require self::ROOT_DIR . '/schema.php';
439
  dbDelta($plugin_queries);
440
- $this->__ver_1_04_transition_fix();
441
 
442
  // sync data between plugin tables and wordpress (mostly for the case when plugin is reactivated)
443
 
@@ -460,6 +448,20 @@ final class PMXI_Plugin {
460
 
461
  }
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  /**
464
  * Method perfoms transition from version when file uploads has been stored in dabase to the solution when it stored on disk
465
  * NOTE: the function can be removed when plugin version progress and it's sure matter nobody has ver 1.03
@@ -492,85 +494,7 @@ final class PMXI_Plugin {
492
  break;
493
  }
494
  }
495
- }
496
-
497
- public function __add_feed_type_fix(){
498
-
499
- $table = $this->getTablePrefix() . 'imports';
500
- global $wpdb;
501
- $tablefields = $wpdb->get_results("DESCRIBE {$table};");
502
- $large_import = false;
503
- $root_element = false;
504
- $processing = false;
505
- $triggered = false;
506
- $queue_chunk_number = false;
507
- $current_post_ids = false;
508
- $first_import = false;
509
- $count = false;
510
- $friendly_name = false;
511
- $imported = false;
512
- $created = false;
513
- $updated = false;
514
- $skipped = false;
515
- $fix_characters = false;
516
- $feed_type = false;
517
-
518
- // Check if field exists
519
- foreach ($tablefields as $tablefield) {
520
- if ('feed_type' == $tablefield->Field) $feed_type = true;
521
- if ('large_import' == $tablefield->Field) $large_import = true;
522
- if ('root_element' == $tablefield->Field) $root_element = true;
523
- if ('processing' == $tablefield->Field) $processing = true;
524
- if ('triggered' == $tablefield->Field) $triggered = true;
525
- if ('current_post_ids' == $tablefield->Field) $current_post_ids = true;
526
- if ('queue_chunk_number' == $tablefield->Field) $queue_chunk_number = true;
527
- if ('first_import' == $tablefield->Field) $first_import = true;
528
- if ('count' == $tablefield->Field) $count = true;
529
- if ('friendly_name' == $tablefield->Field) $friendly_name = true;
530
- if ('imported' == $tablefield->Field) $imported = true;
531
- if ('created' == $tablefield->Field) $created = true;
532
- if ('updated' == $tablefield->Field) $updated = true;
533
- if ('skipped' == $tablefield->Field) $skipped = true;
534
- }
535
- if ($feed_type) $wpdb->query("ALTER TABLE {$table} CHANGE `feed_type` `feed_type` ENUM( 'xml', 'csv', 'zip', 'gz', '' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';");
536
- if (!$feed_type) $wpdb->query("ALTER TABLE {$table} ADD `feed_type` ENUM( 'xml','csv','zip','gz','' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';");
537
- if (!$large_import) $wpdb->query("ALTER TABLE {$table} ADD `large_import` ENUM( 'Yes', 'No' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'No';");
538
- if (!$root_element) $wpdb->query("ALTER TABLE {$table} ADD `root_element` VARCHAR(255) NOT NULL DEFAULT '';");
539
- if (!$processing) $wpdb->query("ALTER TABLE {$table} ADD `processing` BOOL NOT NULL DEFAULT 0;");
540
- if (!$triggered) $wpdb->query("ALTER TABLE {$table} ADD `triggered` BOOL NOT NULL DEFAULT 0;");
541
- if (!$queue_chunk_number) $wpdb->query("ALTER TABLE {$table} ADD `queue_chunk_number` BIGINT(20) NOT NULL DEFAULT 0;");
542
- if (!$current_post_ids) $wpdb->query("ALTER TABLE {$table} ADD `current_post_ids` TEXT;");
543
- if (!$first_import) $wpdb->query("ALTER TABLE {$table} ADD `first_import` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;");
544
- if (!$count) $wpdb->query("ALTER TABLE {$table} ADD `count` BIGINT(20) NOT NULL DEFAULT 0;");
545
- if (!$imported) $wpdb->query("ALTER TABLE {$table} ADD `imported` BIGINT(20) NOT NULL DEFAULT 0;");
546
- if (!$created) $wpdb->query("ALTER TABLE {$table} ADD `created` BIGINT(20) NOT NULL DEFAULT 0;");
547
- if (!$updated) $wpdb->query("ALTER TABLE {$table} ADD `updated` BIGINT(20) NOT NULL DEFAULT 0;");
548
- if (!$skipped) $wpdb->query("ALTER TABLE {$table} ADD `skipped` BIGINT(20) NOT NULL DEFAULT 0;");
549
- if (!$friendly_name) $wpdb->query("ALTER TABLE {$table} ADD `friendly_name` VARCHAR(255) NOT NULL DEFAULT '';");
550
-
551
- $table = $this->getTablePrefix() . 'templates';
552
- global $wpdb;
553
- $tablefields = $wpdb->get_results("DESCRIBE {$table};");
554
- $is_leave_html = false;
555
- // Check if field exists
556
- foreach ($tablefields as $tablefield) {
557
- if ('is_leave_html' == $tablefield->Field) $is_leave_html = true;
558
- if ('fix_characters' == $tablefield->Field) $fix_characters = true;
559
- }
560
- if (!$is_leave_html) $wpdb->query("ALTER TABLE {$table} ADD `is_leave_html` TINYINT( 1 ) NOT NULL DEFAULT 0;");
561
- if (!$fix_characters) $wpdb->query("ALTER TABLE {$table} ADD `fix_characters` TINYINT( 1 ) NOT NULL DEFAULT 0;");
562
-
563
- $table = $this->getTablePrefix() . 'posts';
564
- global $wpdb;
565
- $tablefields = $wpdb->get_results("DESCRIBE {$table};");
566
- $product_key = false;
567
- // Check if field exists
568
- foreach ($tablefields as $tablefield) {
569
- if ('product_key' == $tablefield->Field) $product_key = true;
570
- }
571
- if (!$product_key) $wpdb->query("ALTER TABLE {$table} ADD `product_key` TEXT NOT NULL DEFAULT '';");
572
-
573
- }
574
 
575
  /**
576
  * Method returns default import options, main utility of the method is to avoid warnings when new
@@ -585,7 +509,7 @@ final class PMXI_Plugin {
585
  'tags_delim' => ',',
586
  'categories_delim' => ',',
587
  'categories_auto_nested' => 0,
588
- 'featured_delim' => ',',
589
  'atch_delim' => ',',
590
  'post_taxonomies' => array(),
591
  'parent' => '',
@@ -613,6 +537,7 @@ final class PMXI_Plugin {
613
  'feed_type' => 'auto',
614
 
615
  'is_delete_missing' => 0,
 
616
  'is_keep_former_posts' => 'no',
617
  'is_keep_status' => 0,
618
  'is_keep_content' => 0,
@@ -624,6 +549,8 @@ final class PMXI_Plugin {
624
  'is_duplicates' => 0,
625
  'is_keep_dates' => 0,
626
  'is_keep_menu_order' => 0,
 
 
627
  'records_per_request' => 10,
628
  'not_create_records' => 0,
629
  'no_create_featured_image' => 0,
@@ -637,6 +564,7 @@ final class PMXI_Plugin {
637
  'post_slug' => '',
638
  'keep_custom_fields' => 0,
639
  'keep_custom_fields_specific' => '',
 
640
  'friendly_name' => '',
641
  'custom_duplicate_name' => '',
642
  'custom_duplicate_value' => '',
@@ -646,8 +574,22 @@ final class PMXI_Plugin {
646
  'update_missing_cf_value' => '',
647
  'auto_rename_images' => 0,
648
  'auto_rename_images_suffix' => '',
649
- 'images_name' => 'auto',
650
- 'is_add_newest_categories' => 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651
  );
652
  }
653
 
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. Perform scheduled updates and overwrite of existing import jobs. Free lite edition.
6
+ Version: 3.0.4
7
  Author: Soflyy
8
  */
9
 
28
  */
29
  define('PMXI_PREFIX', 'pmxi_');
30
 
31
+ define('PMXI_VERSION', '3.0.4');
32
 
33
  define('PMXI_EDITION', 'free');
34
 
78
  const LARGE_SIZE = 0; // all files will importing in large import mode
79
 
80
  public static $session;
81
+
82
+ public static $encodings = array('UTF-8','UTF-16','Windows-1250','Windows-1251','Windows-1252','Windows-1253','Windows-1254','Windows-1255','Windows-1256','Windows-1257','Windows-1258','ISO-8859-1','ISO-8859-2','ISO-8859-3','ISO-8859-4','ISO-8859-5','ISO-8859-6','ISO-8859-7','ISO-8859-8','ISO-8859-9','ISO-8859-10', 'KOI8-R', 'KOI8-U');
83
+
84
+ public static $is_csv = false;
85
+
86
+ public static $csv_path = false;
87
 
88
  /**
89
  * Return singletone instance
233
  }
234
 
235
  // register admin page pre-dispatcher
236
+ add_action('admin_init', array($this, '__adminInit'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
  }
239
 
407
  // create plugin options
408
  $option_name = get_class($this) . '_Options';
409
  $options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
410
+ $wpai_options = get_option($option_name, false);
411
+ if ( ! $wpai_options ) update_option($option_name, $options_default);
412
 
413
  // create/update required database tables
414
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
425
  switch_to_blog($blog_id);
426
  require self::ROOT_DIR . '/schema.php';
427
  dbDelta($plugin_queries);
428
+ //$this->__ver_1_04_transition_fix();
429
 
430
  // sync data between plugin tables and wordpress (mostly for the case when plugin is reactivated)
431
 
448
 
449
  }
450
 
451
+ /**
452
+ * Load Localisation files.
453
+ *
454
+ * Note: the first-loaded translation file overrides any following ones if the same translation is present
455
+ *
456
+ * @access public
457
+ * @return void
458
+ */
459
+ public function load_plugin_textdomain() {
460
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'pmxi_plugin' );
461
+
462
+ load_plugin_textdomain( 'pmxi_plugin', false, dirname( plugin_basename( __FILE__ ) ) . "/i18n/languages" );
463
+ }
464
+
465
  /**
466
  * Method perfoms transition from version when file uploads has been stored in dabase to the solution when it stored on disk
467
  * NOTE: the function can be removed when plugin version progress and it's sure matter nobody has ver 1.03
494
  break;
495
  }
496
  }
497
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
 
499
  /**
500
  * Method returns default import options, main utility of the method is to avoid warnings when new
509
  'tags_delim' => ',',
510
  'categories_delim' => ',',
511
  'categories_auto_nested' => 0,
512
+ 'featured_delim' => '',
513
  'atch_delim' => ',',
514
  'post_taxonomies' => array(),
515
  'parent' => '',
537
  'feed_type' => 'auto',
538
 
539
  'is_delete_missing' => 0,
540
+ 'is_update_missing_cf' => 0,
541
  'is_keep_former_posts' => 'no',
542
  'is_keep_status' => 0,
543
  'is_keep_content' => 0,
549
  'is_duplicates' => 0,
550
  'is_keep_dates' => 0,
551
  'is_keep_menu_order' => 0,
552
+ 'is_keep_parent' => 0,
553
+ 'is_keep_attachments_on_update' => 0,
554
  'records_per_request' => 10,
555
  'not_create_records' => 0,
556
  'no_create_featured_image' => 0,
564
  'post_slug' => '',
565
  'keep_custom_fields' => 0,
566
  'keep_custom_fields_specific' => '',
567
+ 'keep_custom_fields_except' => '',
568
  'friendly_name' => '',
569
  'custom_duplicate_name' => '',
570
  'custom_duplicate_value' => '',
574
  'update_missing_cf_value' => '',
575
  'auto_rename_images' => 0,
576
  'auto_rename_images_suffix' => '',
577
+ 'images_name' => 'filename',
578
+ 'is_add_newest_categories' => 0,
579
+ 'post_format' => 'standard',
580
+ 'encoding' => 'UTF-8',
581
+ 'delimiter' => '',
582
+ 'set_image_meta_data' => 0,
583
+ 'image_meta_title' => '',
584
+ 'image_meta_title_delim' => '',
585
+ 'image_meta_caption' => '',
586
+ 'image_meta_caption_delim' => '',
587
+ 'image_meta_alt' => '',
588
+ 'image_meta_alt_delim' => '',
589
+ 'image_meta_description' => '',
590
+ 'image_meta_description_delim' => '',
591
+ 'status_xpath' => '',
592
+ 'download_images' => 1
593
  );
594
  }
595
 
readme.txt CHANGED
@@ -1,51 +1,51 @@
1
- === Import any XML or CSV File to WordPress ===
2
- Contributors: soflyy
3
- Tags: wordpress, xml, csv, datafeed, import
4
- Requires at least: 3.5
5
- Tested up to: 3.5.2
6
- Stable tag: 3.0.3
7
-
8
- WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
9
-
10
- == Description ==
11
-
12
- WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
13
-
14
- WP All Import has a four step import process and an intuitive drag & drop interface that makes complicated import tasks simple and fast.
15
-
16
- There are no special requirements that the elements in your file must be laid out in a certain way. WP All Import really can import any XML or CSV file.
17
-
18
- WP All Import can be used for everything from building a store with an affiliate datafeed to displaying live stock quotes or sports scores to building a real estate portal.
19
-
20
- = WP All Import Professional Edition =
21
- [youtube http://www.youtube.com/watch?v=3LfbN7uWcTA /]
22
-
23
- *WP All Import Pro* is a $99 upgrade that adds the following features to the free version of WP All Import:
24
-
25
- * Import to Custom Post Types - commonly used to import to Automotiv, OpenHouse, Listings, and WooCommerce, as well as any other theme or plugin that makes use of Custom Post Types.
26
-
27
- * Cron Job/Recurring Imports - WP All Import pro can check periodically check a file for updates, and add, edit, and delete to the imported posts accordingly.
28
-
29
- * Import data to Custom Fields - used by many themes, especially those using Custom Post Types - to store data associated with the posts.
30
-
31
- * Import images to the post media gallery - WP All Import can download images from URLs in an XML or CSV file and put them in the media gallery.
32
-
33
- * Import files from a URL or FTP server - Download and import files from external websites or FTP servers, even if they are password protected. FTP imports support wildcard patterns, i.e. *.xml, so for example you could download and import all XML files in a certain folder.
34
-
35
- * URL and FTP imports are integrated with the recurring/cron imports feature, so WP All Import can periodically re-download the files and add, edit, and delete posts accordingly.
36
-
37
- * Execution of Custom PHP Functions on data, i.e. use something like [my_function({xpath/to/a/field[1]})] in your template, to pass the value of {xpath/to/a/field[1]} to my_function and display whatever it returns.
38
-
39
- * Pro version customers also get access to our customer portal with documentation and tutorials, and e-mail technical support.
40
-
41
- [Upgrade to the professional edition of WP All Import.](http://www.wpallimport.com/upgrade-to-pro)
42
 
43
  Need to [import XML and CSV to WooCommerce?](http://wordpress.org/plugins/woocommerce-xml-csv-product-import/) Check out our WooCommerce add-on.
44
-
45
- == Premium Support ==
46
- Upgrade to the professional edition of WP All Import for premium support.
47
-
48
- E-mail: support@soflyy.com
49
 
50
  == Import To WooCommerce ==
51
 
@@ -53,53 +53,58 @@ Need to [import XML and CSV to WooCommerce?](http://wordpress.org/plugins/woocom
53
 
54
  [WooCommerce XML & CSV Import Pro Version](http://www.wpallimport.com/woocommerce-product-import)
55
 
56
-
57
- == Installation ==
58
-
59
- Either: -
60
-
61
- * Upload the plugin from the Plugins page in WordPress
62
- * Unzip wp-all-import.zip and upload the contents to /wp-content/plugins/, and then activate the plugin from the Plugins page in WordPress
63
-
64
-
65
- == Frequently Asked Questions ==
66
-
67
- *What Size Files Can WP All Import Handle?*
68
- With the release of WP All Import version 3, WP All Import can now handle files of any size and any number of records, as long as the web hosting provider can too. Typically, WP All Import can comfortably import files of 200Mb and larger in most shared hosting environments (HostGator, etc). Please see this page for more details: http://www.wpallimport.com/how-big
69
-
70
- *What are the benefits of the $99 professional version?*
71
- Support for Custom Post Types, Custom Taxonomies, Custom Fields, cron jobs/recurring imports, download and importing of images to the post media gallery, and URL/FTP server uploads.
72
-
73
- *The answer to all of the following questions is yes:*
74
-
75
- Does this really work with ANY XML or CSV file?
76
- Can WP All Import get ALL of the data out of the file? Even attributes?
77
- Does it work with special character encoding like Hebrew, Arabic, Chinese, etc?
78
-
79
- == Screenshots ==
80
-
81
- 1. Choose file.
82
- 2. Template designer.
83
- 3. Post options.
84
- 4. Manage imports.
85
-
86
- == Changelog ==
87
-
88
- = 3.0.3 =
89
- * Now using enhanced session functionality
90
-
91
- = 3.0.2 =
92
- * Added support for the WooCommerce add-on
93
-
94
- = 3.0 =
95
- * Free edition of 3.0 pro release
96
-
97
- = 2.14 =
98
- * Category list delimiter bug fix
99
-
100
- = 2.13 =
101
- * Tons of bug fixes, updates, and additional features.
102
-
103
-
104
- = 2.12 =
105
- * Initial release on WordPress.org.
 
 
 
 
 
1
+ === Import any XML or CSV File to WordPress ===
2
+ Contributors: soflyy
3
+ Tags: wordpress, xml, csv, datafeed, import
4
+ Requires at least: 3.6.1
5
+ Tested up to: 3.8
6
+ Stable tag: 3.0.4
7
+
8
+ WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
9
+
10
+ == Description ==
11
+
12
+ WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
13
+
14
+ WP All Import has a four step import process and an intuitive drag & drop interface that makes complicated import tasks simple and fast.
15
+
16
+ There are no special requirements that the elements in your file must be laid out in a certain way. WP All Import really can import any XML or CSV file.
17
+
18
+ WP All Import can be used for everything from building a store with an affiliate datafeed to displaying live stock quotes or sports scores to building a real estate portal.
19
+
20
+ = WP All Import Professional Edition =
21
+ [youtube http://www.youtube.com/watch?v=3LfbN7uWcTA /]
22
+
23
+ *WP All Import Pro* is a $99 upgrade that adds the following features to the free version of WP All Import:
24
+
25
+ * Import to Custom Post Types - commonly used to import to Automotiv, OpenHouse, Listings, and WooCommerce, as well as any other theme or plugin that makes use of Custom Post Types.
26
+
27
+ * Cron Job/Recurring Imports - WP All Import pro can check periodically check a file for updates, and add, edit, and delete to the imported posts accordingly.
28
+
29
+ * Import data to Custom Fields - used by many themes, especially those using Custom Post Types - to store data associated with the posts.
30
+
31
+ * Import images to the post media gallery - WP All Import can download images from URLs in an XML or CSV file and put them in the media gallery.
32
+
33
+ * Import files from a URL - Download and import files from external websites.
34
+
35
+ * URL imports are integrated with the recurring/cron imports feature, so WP All Import can periodically re-download the files and add, edit, and delete posts accordingly.
36
+
37
+ * Execution of Custom PHP Functions on data, i.e. use something like [my_function({xpath/to/a/field[1]})] in your template, to pass the value of {xpath/to/a/field[1]} to my_function and display whatever it returns.
38
+
39
+ * Pro version customers also get access to e-mail technical support.
40
+
41
+ [Upgrade to the professional edition of WP All Import.](http://www.wpallimport.com/upgrade-to-pro)
42
 
43
  Need to [import XML and CSV to WooCommerce?](http://wordpress.org/plugins/woocommerce-xml-csv-product-import/) Check out our WooCommerce add-on.
44
+
45
+ == Premium Support ==
46
+ Upgrade to the professional edition of WP All Import for premium support.
47
+
48
+ E-mail: support@soflyy.com
49
 
50
  == Import To WooCommerce ==
51
 
53
 
54
  [WooCommerce XML & CSV Import Pro Version](http://www.wpallimport.com/woocommerce-product-import)
55
 
56
+
57
+ == Installation ==
58
+
59
+ Either: -
60
+
61
+ * Upload the plugin from the Plugins page in WordPress
62
+ * Unzip wp-all-import.zip and upload the contents to /wp-content/plugins/, and then activate the plugin from the Plugins page in WordPress
63
+
64
+
65
+ == Frequently Asked Questions ==
66
+
67
+ *What Size Files Can WP All Import Handle?*
68
+ With the release of WP All Import version 3, WP All Import can now handle files of any size and any number of records, as long as the web hosting provider can too. Typically, WP All Import can comfortably import files of 200Mb and larger in most shared hosting environments (HostGator, etc). Please see this page for more details: http://www.wpallimport.com/how-big
69
+
70
+ *What are the benefits of the $99 professional version?*
71
+ Support for Custom Post Types, Custom Taxonomies, Custom Fields, cron jobs/recurring imports, download and importing of images to the post media gallery, and URL uploads.
72
+
73
+ *The answer to all of the following questions is yes:*
74
+
75
+ Does this really work with ANY XML or CSV file?
76
+ Can WP All Import get ALL of the data out of the file? Even attributes?
77
+ Does it work with special character encoding like Hebrew, Arabic, Chinese, etc?
78
+
79
+ == Screenshots ==
80
+
81
+ 1. Choose file.
82
+ 2. Template designer.
83
+ 3. Post options.
84
+ 4. Manage imports.
85
+
86
+ == Changelog ==
87
+
88
+ = 3.0.4 =
89
+ * Fixed import categories;
90
+ * Updated UI/UX;
91
+ * Added import/export templates feature;
92
+ * Added enhanced session functionality;
93
+ * Added option to set post status with XPath;
94
+ * Added feeds encoding feature;
95
+
96
+ = 3.0.2 =
97
+ * Added support for the WooCommerce add-on
98
+
99
+ = 3.0 =
100
+ * Too many changes to list. It’s basically a new product compared to v2.
101
+
102
+ = 2.14 =
103
+ * Category list delimiter bug fix
104
+
105
+ = 2.13 =
106
+ * Tons of bug fixes, updates, and additional features.
107
+
108
+
109
+ = 2.12 =
110
+ * Initial release on WordPress.org.
schema.php CHANGED
@@ -1,82 +1,83 @@
1
- <?php
2
- /**
3
- * Plugin database schema
4
- * WARNING:
5
- * dbDelta() doesn't like empty lines in schema string, so don't put them there;
6
- * WPDB doesn't like NULL values so better not to have them in the tables;
7
- */
8
-
9
- /**
10
- * The database character collate.
11
- * @var string
12
- * @global string
13
- * @name $charset_collate
14
- */
15
- $charset_collate = '';
16
-
17
- // Declare these as global in case schema.php is included from a function.
18
- global $wpdb, $plugin_queries;
19
-
20
- if ( ! empty($wpdb->charset))
21
- $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
22
- if ( ! empty($wpdb->collate))
23
- $charset_collate .= " COLLATE $wpdb->collate";
24
-
25
- $table_prefix = PMXI_Plugin::getInstance()->getTablePrefix();
26
-
27
- $plugin_queries = <<<SCHEMA
28
- CREATE TABLE {$table_prefix}templates (
29
- id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
30
- options TEXT,
31
- scheduled VARCHAR(64) NOT NULL DEFAULT '',
32
- name VARCHAR(200) NOT NULL DEFAULT '',
33
- title TEXT,
34
- content LONGTEXT,
35
- is_keep_linebreaks TINYINT(1) NOT NULL DEFAULT 0,
36
- is_leave_html TINYINT(1) NOT NULL DEFAULT 0,
37
- fix_characters TINYINT(1) NOT NULL DEFAULT 0,
38
- PRIMARY KEY (id)
39
- ) $charset_collate;
40
- CREATE TABLE {$table_prefix}imports (
41
- id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
42
- name VARCHAR(255) NOT NULL DEFAULT '',
43
- friendly_name VARCHAR(255) NOT NULL DEFAULT '',
44
- type VARCHAR(32) NOT NULL DEFAULT '',
45
- feed_type ENUM('xml','csv','zip','gz','') NOT NULL DEFAULT '',
46
- path TEXT,
47
- xpath VARCHAR(255) NOT NULL DEFAULT '',
48
- template LONGTEXT,
49
- options TEXT,
50
- scheduled VARCHAR(64) NOT NULL DEFAULT '',
51
- registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
52
- large_import ENUM('Yes','No') NOT NULL DEFAULT 'No',
53
- root_element VARCHAR(255) DEFAULT '',
54
- processing BOOL NOT NULL DEFAULT 0,
55
- triggered BOOL NOT NULL DEFAULT 0,
56
- queue_chunk_number BIGINT(20) NOT NULL DEFAULT 0,
57
- current_post_ids TEXT,
58
- first_import TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
59
- count BIGINT(20) NOT NULL DEFAULT 0,
60
- imported BIGINT(20) NOT NULL DEFAULT 0,
61
- created BIGINT(20) NOT NULL DEFAULT 0,
62
- updated BIGINT(20) NOT NULL DEFAULT 0,
63
- skipped BIGINT(20) NOT NULL DEFAULT 0,
64
- PRIMARY KEY (id)
65
- ) $charset_collate;
66
- CREATE TABLE {$table_prefix}posts (
67
- id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
68
- post_id BIGINT(20) UNSIGNED NOT NULL,
69
- import_id BIGINT(20) UNSIGNED NOT NULL,
70
- unique_key TEXT,
71
- product_key TEXT,
72
- PRIMARY KEY (id)
73
- ) $charset_collate;
74
- CREATE TABLE {$table_prefix}files (
75
- id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
76
- import_id BIGINT(20) UNSIGNED NOT NULL,
77
- name VARCHAR(255) NOT NULL DEFAULT '',
78
- path TEXT,
79
- registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
80
- PRIMARY KEY (id)
81
- ) $charset_collate;
82
- SCHEMA;
 
1
+ <?php
2
+ /**
3
+ * Plugin database schema
4
+ * WARNING:
5
+ * dbDelta() doesn't like empty lines in schema string, so don't put them there;
6
+ * WPDB doesn't like NULL values so better not to have them in the tables;
7
+ */
8
+
9
+ /**
10
+ * The database character collate.
11
+ * @var string
12
+ * @global string
13
+ * @name $charset_collate
14
+ */
15
+ $charset_collate = '';
16
+
17
+ // Declare these as global in case schema.php is included from a function.
18
+ global $wpdb, $plugin_queries;
19
+
20
+ if ( ! empty($wpdb->charset))
21
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
22
+ if ( ! empty($wpdb->collate))
23
+ $charset_collate .= " COLLATE $wpdb->collate";
24
+
25
+ $table_prefix = PMXI_Plugin::getInstance()->getTablePrefix();
26
+
27
+ $plugin_queries = <<<SCHEMA
28
+ CREATE TABLE {$table_prefix}templates (
29
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
30
+ options TEXT,
31
+ scheduled VARCHAR(64) NOT NULL DEFAULT '',
32
+ name VARCHAR(200) NOT NULL DEFAULT '',
33
+ title TEXT,
34
+ content LONGTEXT,
35
+ is_keep_linebreaks TINYINT(1) NOT NULL DEFAULT 0,
36
+ is_leave_html TINYINT(1) NOT NULL DEFAULT 0,
37
+ fix_characters TINYINT(1) NOT NULL DEFAULT 0,
38
+ meta LONGTEXT,
39
+ PRIMARY KEY (id)
40
+ ) $charset_collate;
41
+ CREATE TABLE {$table_prefix}imports (
42
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
43
+ name VARCHAR(255) NOT NULL DEFAULT '',
44
+ friendly_name VARCHAR(255) NOT NULL DEFAULT '',
45
+ type VARCHAR(32) NOT NULL DEFAULT '',
46
+ feed_type ENUM('xml','csv','zip','gz','') NOT NULL DEFAULT '',
47
+ path TEXT,
48
+ xpath TEXT,
49
+ template LONGTEXT,
50
+ options TEXT,
51
+ scheduled VARCHAR(64) NOT NULL DEFAULT '',
52
+ registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
53
+ large_import ENUM('Yes','No') NOT NULL DEFAULT 'No',
54
+ root_element VARCHAR(255) DEFAULT '',
55
+ processing BOOL NOT NULL DEFAULT 0,
56
+ triggered BOOL NOT NULL DEFAULT 0,
57
+ queue_chunk_number BIGINT(20) NOT NULL DEFAULT 0,
58
+ current_post_ids TEXT,
59
+ first_import TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
60
+ count BIGINT(20) NOT NULL DEFAULT 0,
61
+ imported BIGINT(20) NOT NULL DEFAULT 0,
62
+ created BIGINT(20) NOT NULL DEFAULT 0,
63
+ updated BIGINT(20) NOT NULL DEFAULT 0,
64
+ skipped BIGINT(20) NOT NULL DEFAULT 0,
65
+ PRIMARY KEY (id)
66
+ ) $charset_collate;
67
+ CREATE TABLE {$table_prefix}posts (
68
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
69
+ post_id BIGINT(20) UNSIGNED NOT NULL,
70
+ import_id BIGINT(20) UNSIGNED NOT NULL,
71
+ unique_key TEXT,
72
+ product_key TEXT,
73
+ PRIMARY KEY (id)
74
+ ) $charset_collate;
75
+ CREATE TABLE {$table_prefix}files (
76
+ id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
77
+ import_id BIGINT(20) UNSIGNED NOT NULL,
78
+ name VARCHAR(255) NOT NULL DEFAULT '',
79
+ path TEXT,
80
+ registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
81
+ PRIMARY KEY (id)
82
+ ) $charset_collate;
83
+ SCHEMA;
static/css/admin-ie.css CHANGED
@@ -1,13 +1,13 @@
1
- .pmxi_plugin .load-template a.help {
2
- margin-top: -10px;
3
- }
4
- .pmxi_plugin .wrap {
5
- margin-top: 5px;
6
- }
7
- .pmxi_plugin input.button-primary {
8
- vertical-align: middle;
9
- }
10
-
11
- .xml-expander {
12
- display: inline;
13
- }
1
+ .pmxi_plugin .load-template a.help {
2
+ margin-top: -10px;
3
+ }
4
+ .pmxi_plugin .wrap {
5
+ margin-top: 5px;
6
+ }
7
+ .pmxi_plugin input.button-primary {
8
+ vertical-align: middle;
9
+ }
10
+
11
+ .xml-expander {
12
+ display: inline;
13
+ }
static/css/admin.css CHANGED
@@ -81,7 +81,7 @@
81
  vertical-align: middle;
82
  }
83
  .pmxi_plugin .options input[type=text], .pmxi_plugin .options select {
84
- background: #fafafa !important;
85
  border: 1px solid #aaa !important;
86
  }
87
  .pmxi_plugin .note {
@@ -111,6 +111,7 @@
111
  padding: 0px 0 16px 20px;
112
  width: 25%;
113
  min-width: 260px;
 
114
  }
115
  .pmxi_plugin table.layout td.left > h2:first-child {
116
  margin-top: -22px;
@@ -122,6 +123,18 @@
122
  .pmxi_plugin.no-js table.layout td.left > h2:first-child {
123
  margin-top: 0px;
124
  }
 
 
 
 
 
 
 
 
 
 
 
 
125
  /*@*/
126
 
127
  /*@+ Setting Form */
@@ -155,7 +168,7 @@
155
  font-size: 12px;
156
  }
157
  .pmxi_plugin form.choose-file input[type="submit"].button {
158
- width: 150px;
159
  }
160
  .pmxi_plugin form.choose-file div.input {
161
  margin-top: 20px;
@@ -213,8 +226,8 @@
213
  }
214
  .pmxi_plugin .post-type-container.selected,
215
  .pmxi_plugin .file-type-container.selected {
216
- background-color: #F2FBD9;
217
- border: 1px solid #B5E61D;
218
  padding-bottom: 10px;
219
  }
220
  .pmxi_plugin .post-type-container h3,
@@ -246,7 +259,7 @@
246
  }
247
  .pmxi_plugin table.form-table td,
248
  .pmxi_plugin table.form-table th {
249
- padding: 2px 4px;
250
  vertical-align: top;
251
  }
252
  .pmxi_plugin .post-type-options table.form-table th {
@@ -270,8 +283,9 @@
270
  /*@+ XML representation */
271
  .pmxi_plugin .tag {
272
  background-color: #fff;
273
- position: fixed;
274
- width:22%;
 
275
  margin-top: 45px;
276
  border-top: 1px solid #DFDFDF;
277
  -moz-border-radius-topleft: 4px;
@@ -454,6 +468,7 @@ table.xml table {
454
  }
455
  .pmxi_plugin .ui-dialog {
456
  position: absolute !important; /* FIX: for wordpress 3.1 not to add empty space */
 
457
  }
458
  .pmxi_plugin .ui-autocomplete {
459
  position: absolute;
@@ -534,7 +549,7 @@ table.xml table {
534
  .pmxi_plugin .remove-ico{
535
  background: url("../img/ico-remove.png") no-repeat;
536
  top:1px;
537
- right:-8px;
538
  position: absolute;
539
  }
540
 
@@ -596,13 +611,16 @@ table.xml table {
596
  width: 580px;
597
  }
598
  .pmxi_plugin #pmxi_tabs{
599
- display: none;
600
  padding-bottom: 20px;
601
  -moz-border-radius: 4px;
602
  -khtml-border-radius: 4px;
603
  -webkit-border-radius: 4px;
604
  border-radius: 4px;
605
  }
 
 
 
606
  .pmxi_plugin .ui-widget-header{
607
  -moz-border-radius: 4px;
608
  -khtml-border-radius: 4px;
@@ -726,18 +744,18 @@ table.xml table {
726
  text-align: center;
727
  }
728
  .pmxi_plugin .col3{
729
- border-right: 1px solid #CCCCCC;
730
  float: left;
731
- height: 265px;
732
- width:30%;
733
  margin-bottom: 10px;
734
- padding: 0 1%;
735
  }
736
  .pmxi_plugin .col3.last{
737
  border: none;
738
  }
739
  .pmxi_plugin .col3 > div{
740
- margin-left: 20px;
741
  }
742
  .pmxi_plugin .col2{
743
  float: left;
@@ -755,7 +773,7 @@ table.xml table {
755
  }
756
  .pmxi_plugin .post_taxonomy{
757
  margin-bottom: 15px;
758
- /*overflow: hidden;*/
759
  padding-bottom: 15px;
760
  }
761
  .pmxi_plugin .post_taxonomy .delim{
@@ -815,8 +833,13 @@ table.xml table {
815
  font-size: 13px !important;
816
  }
817
  .pmxi_plugin .preview{
818
- float:none;
 
 
 
819
  text-decoration: none;
 
 
820
  }
821
  .pmxi_plugin .template-sidebar .tag{
822
  max-height:550px;
@@ -825,12 +848,13 @@ table.xml table {
825
  float: right;
826
  position: relative;
827
  text-align: right;
828
- top: 30px;
829
- right:-18px;
830
  }
831
  .pmxi_plugin .back{
832
- font-size: 16px;
833
- color:#21759B;
 
 
834
  }
835
  .pmxi_plugin .separated_by{
836
  float: right;
@@ -920,12 +944,13 @@ table.xml table {
920
  .pmxi_plugin #goto_element{
921
  display: block;
922
  float: left;
923
- height: 47px;
 
924
  margin-right: 10px;
925
- width: 70px !important;
926
  min-width: 70px;
 
927
  text-align: center;
928
- font-size: 18px;
929
  }
930
  .pmxi_plugin .choose-elements table tbody tr td{
931
  overflow: hidden;
@@ -941,17 +966,21 @@ table.xml table {
941
  display: none;
942
  }
943
  .pmxi_plugin label{
944
- -webkit-touch-callout: none;
945
  -webkit-user-select: none;
946
  -khtml-user-select: none;
947
  -moz-user-select: none;
948
  -ms-user-select: none;
949
- user-select: none;
950
  }
951
  .pmxi_plugin .large_button{
952
- margin-left: 10px;
953
  padding: 15px 25px;
954
- border: 1px solid #C5DBEC;
 
 
 
 
955
  }
956
  .pmxi_plugin .drag-element .assign_post{
957
  float: left;
@@ -963,7 +992,7 @@ table.xml table {
963
  .pmxi_plugin .upgrade_link{
964
  color: #21759B;
965
  }
966
- .pmxi_stars{
967
  display: inline-block;
968
  background: url("../img/stars.png") no-repeat;
969
  width: 125px;
@@ -971,7 +1000,7 @@ table.xml table {
971
  position: relative;
972
  top:10px;
973
  }
974
- .updated_bottom{
975
  background-color: #FFFFE0;
976
  border-color: #E6DB55;
977
  margin: 5px 0 15px;
@@ -992,6 +1021,130 @@ table.xml table {
992
  top: -35px;
993
  width: 100%;
994
  }
995
- .form-field textarea{
996
  width:80%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
997
  }
81
  vertical-align: middle;
82
  }
83
  .pmxi_plugin .options input[type=text], .pmxi_plugin .options select {
84
+ /*background: #fafafa !important;*/
85
  border: 1px solid #aaa !important;
86
  }
87
  .pmxi_plugin .note {
111
  padding: 0px 0 16px 20px;
112
  width: 25%;
113
  min-width: 260px;
114
+ position: relative;
115
  }
116
  .pmxi_plugin table.layout td.left > h2:first-child {
117
  margin-top: -22px;
123
  .pmxi_plugin.no-js table.layout td.left > h2:first-child {
124
  margin-top: 0px;
125
  }
126
+ .pmxi_plugin table.layout div.left {
127
+ min-width: 490px;
128
+ width: 70%;
129
+ float: left;
130
+ }
131
+ .pmxi_plugin table.layout div.right {
132
+ padding: 0px 0 16px 20px;
133
+ width: 25%;
134
+ /*min-width: 260px; */
135
+ position: relative;
136
+ float: right;
137
+ }
138
  /*@*/
139
 
140
  /*@+ Setting Form */
168
  font-size: 12px;
169
  }
170
  .pmxi_plugin form.choose-file input[type="submit"].button {
171
+ /*width: 150px;*/
172
  }
173
  .pmxi_plugin form.choose-file div.input {
174
  margin-top: 20px;
226
  }
227
  .pmxi_plugin .post-type-container.selected,
228
  .pmxi_plugin .file-type-container.selected {
229
+ background-color: #F1F1F1;
230
+ border: 1px solid #ccc;
231
  padding-bottom: 10px;
232
  }
233
  .pmxi_plugin .post-type-container h3,
259
  }
260
  .pmxi_plugin table.form-table td,
261
  .pmxi_plugin table.form-table th {
262
+ padding: 0;
263
  vertical-align: top;
264
  }
265
  .pmxi_plugin .post-type-options table.form-table th {
283
  /*@+ XML representation */
284
  .pmxi_plugin .tag {
285
  background-color: #fff;
286
+ position: absolute;
287
+ width:95%;
288
+ top: 0;
289
  margin-top: 45px;
290
  border-top: 1px solid #DFDFDF;
291
  -moz-border-radius-topleft: 4px;
468
  }
469
  .pmxi_plugin .ui-dialog {
470
  position: absolute !important; /* FIX: for wordpress 3.1 not to add empty space */
471
+ z-index: 999999;
472
  }
473
  .pmxi_plugin .ui-autocomplete {
474
  position: absolute;
549
  .pmxi_plugin .remove-ico{
550
  background: url("../img/ico-remove.png") no-repeat;
551
  top:1px;
552
+ right:0px;
553
  position: absolute;
554
  }
555
 
611
  width: 580px;
612
  }
613
  .pmxi_plugin #pmxi_tabs{
614
+ /*display: none;*/
615
  padding-bottom: 20px;
616
  -moz-border-radius: 4px;
617
  -khtml-border-radius: 4px;
618
  -webkit-border-radius: 4px;
619
  border-radius: 4px;
620
  }
621
+ .pmxi_plugin .pmxi_tab{
622
+ display: none;
623
+ }
624
  .pmxi_plugin .ui-widget-header{
625
  -moz-border-radius: 4px;
626
  -khtml-border-radius: 4px;
744
  text-align: center;
745
  }
746
  .pmxi_plugin .col3{
747
+ /*border-right: 1px solid #CCCCCC;*/
748
  float: left;
749
+ /*height: 265px;*/
750
+ width:33%;
751
  margin-bottom: 10px;
752
+ /*padding: 0 1%;*/
753
  }
754
  .pmxi_plugin .col3.last{
755
  border: none;
756
  }
757
  .pmxi_plugin .col3 > div{
758
+ /*margin-left: 20px;*/
759
  }
760
  .pmxi_plugin .col2{
761
  float: left;
773
  }
774
  .pmxi_plugin .post_taxonomy{
775
  margin-bottom: 15px;
776
+ overflow: hidden;
777
  padding-bottom: 15px;
778
  }
779
  .pmxi_plugin .post_taxonomy .delim{
833
  font-size: 13px !important;
834
  }
835
  .pmxi_plugin .preview{
836
+ float: none;
837
+ /*line-height: 32px;
838
+ position: relative;
839
+ text-align: center;
840
  text-decoration: none;
841
+ top: -1px;
842
+ vertical-align: middle;*/
843
  }
844
  .pmxi_plugin .template-sidebar .tag{
845
  max-height:550px;
848
  float: right;
849
  position: relative;
850
  text-align: right;
851
+ top: 10px;
 
852
  }
853
  .pmxi_plugin .back{
854
+ color: #21759B;
855
+ font-size: 20px;
856
+ position: relative;
857
+ top: 3px;
858
  }
859
  .pmxi_plugin .separated_by{
860
  float: right;
944
  .pmxi_plugin #goto_element{
945
  display: block;
946
  float: left;
947
+ font-size: 18px;
948
+ height: 46px;
949
  margin-right: 10px;
 
950
  min-width: 70px;
951
+ padding-top: 5px;
952
  text-align: center;
953
+ width: 70px !important;
954
  }
955
  .pmxi_plugin .choose-elements table tbody tr td{
956
  overflow: hidden;
966
  display: none;
967
  }
968
  .pmxi_plugin label{
969
+ /*-webkit-touch-callout: none;
970
  -webkit-user-select: none;
971
  -khtml-user-select: none;
972
  -moz-user-select: none;
973
  -ms-user-select: none;
974
+ user-select: none;*/
975
  }
976
  .pmxi_plugin .large_button{
977
+ /*margin-left: 10px;
978
  padding: 15px 25px;
979
+ border: 1px solid #C5DBEC;*/
980
+ height: 40px;
981
+ line-height: 39px;
982
+ margin-left: 10px;
983
+ /*width: 90px;*/
984
  }
985
  .pmxi_plugin .drag-element .assign_post{
986
  float: left;
992
  .pmxi_plugin .upgrade_link{
993
  color: #21759B;
994
  }
995
+ .pmxi_plugin .pmxi_stars{
996
  display: inline-block;
997
  background: url("../img/stars.png") no-repeat;
998
  width: 125px;
1000
  position: relative;
1001
  top:10px;
1002
  }
1003
+ .pmxi_plugin .updated_bottom{
1004
  background-color: #FFFFE0;
1005
  border-color: #E6DB55;
1006
  margin: 5px 0 15px;
1021
  top: -35px;
1022
  width: 100%;
1023
  }
1024
+ .pmxi_plugin .form-field textarea{
1025
  width:80%;
1026
+ }
1027
+ /* Tabs */
1028
+ .pmxi_plugin .nav-tab-wrapper{
1029
+ display: none;
1030
+ }
1031
+ .pmxi_plugin h2.nav-tab-wrapper, h3.nav-tab-wrapper{
1032
+ margin-bottom: 10px;
1033
+ }
1034
+ .pmxi_plugin .nav-tab{
1035
+ margin-right: 0px !important;
1036
+ }
1037
+ .pmxi_plugin h2 .nav-tab{
1038
+ font-size: 18px !important;
1039
+ }
1040
+ .pmxi_plugin #set_encoding{
1041
+ line-height: 25px;
1042
+ position: relative;
1043
+ text-align: center;
1044
+ top: -10px;
1045
+ margin-top: -55px;
1046
+ }
1047
+ .pmxi_plugin #add_encoding{
1048
+ display: none;
1049
+ }
1050
+ .pmxi_plugin #new_encoding{
1051
+ border: 1px solid #BBBBBB;
1052
+ -moz-border-radius: 3px;
1053
+ -khtml-border-radius: 3px;
1054
+ -webkit-border-radius: 3px;
1055
+ border-radius: 3px;
1056
+ }
1057
+ .pmxi_plugin .options #set_encoding{
1058
+ display: none;
1059
+ }
1060
+ .pmxi_plugin .set_csv_delimiter > li{
1061
+ float: left;
1062
+ padding: 0 3px;
1063
+ }
1064
+ /*.pmxi_plugin .set_csv_delimiter > li a.delimiter_selected{
1065
+ font-weight: bold;
1066
+ text-decoration: underline;
1067
+ }
1068
+ .pmxi_plugin .set_csv_delimiter{
1069
+ float: left;
1070
+ padding-top: 3px;
1071
+ }*/
1072
+ .pmxi_plugin .set_csv_delimiter{
1073
+ padding-top: 5px;
1074
+ }
1075
+ .pmxi_plugin input[name="delimiter"]{
1076
+ display: block;
1077
+ float: left;
1078
+ width: 25px !important;
1079
+ height: 25px;
1080
+ min-width: 25px !important;
1081
+ position: relative;
1082
+ top:-5px;
1083
+ padding: 0 3px;
1084
+ text-align: center;
1085
+ }
1086
+ .pmxi_plugin input[name="apply_delimiter"]{
1087
+ border: 1px solid #BBBBBB;
1088
+ -moz-border-radius: 3px;
1089
+ -khtml-border-radius: 3px;
1090
+ -webkit-border-radius: 3px;
1091
+ border-radius: 3px;
1092
+ padding: 3px 5px;
1093
+ margin-left: 10px;
1094
+ position: relative;
1095
+ top:-4px;
1096
+ cursor: pointer;
1097
+ }
1098
+ .pmxi_plugin .go_to{
1099
+ float: left;
1100
+ font-size: 23px;
1101
+ line-height: 38px;
1102
+ text-align: center;
1103
+ }
1104
+ .pmxi_plugin .fix_checkbox{
1105
+ position: relative;
1106
+ /*top: -2px;*/
1107
+ }
1108
+ .pmxi_plugin .newline{
1109
+ line-height: 16px;
1110
+ }
1111
+ .pmxi_plugin .button-primary:hover{
1112
+ font-weight: normal;
1113
+ }
1114
+ .pmxi_plugin .hndle{
1115
+ padding: 7px;
1116
+ margin-bottom: 0px;
1117
+ cursor: default !important;
1118
+ }
1119
+ .pmxi_plugin .inside{
1120
+ margin: 0;
1121
+ line-height: 20px;
1122
+ }
1123
+ .pmxi_plugin .inside input[type="text"]{
1124
+ background: #fff;
1125
+ }
1126
+ .pmxi_plugin .postbox{
1127
+ margin: 0;
1128
+ }
1129
+ .pmxi_plugin .txt_center{
1130
+ text-align: center;
1131
+ }
1132
+ .pmxi_plugin div.meta-options{
1133
+ padding: 10px 0px;
1134
+ }
1135
+ .pmxi_plugin input[name^="attribute_name"], .pmxi_plugin input[name^="variable_attribute_name"]{
1136
+ width: 95% !important;
1137
+ }
1138
+ .pmxi_plugin .widefat{
1139
+ background-color: #fff;
1140
+ border-color: #DFDFDF;
1141
+ }
1142
+ .pmxi_plugin #woocommerce-product-data{
1143
+ margin-bottom: 20px;
1144
+ }
1145
+ .pmxi_plugin .set_xpath{
1146
+ left: 0;
1147
+ padding-left: 15px;
1148
+ position: absolute;
1149
+ top: 0;
1150
  }
static/js/admin.js CHANGED
@@ -121,6 +121,7 @@
121
  // template form: preview button
122
  $('form.template').each(function () {
123
  var $form = $(this);
 
124
  var $modal = $('<div></div>').dialog({
125
  autoOpen: false,
126
  modal: true,
@@ -133,12 +134,34 @@
133
  });
134
  $form.find('.preview').click(function () {
135
  $modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
136
- tinyMCE.triggerSave(false, false);
137
  $.post('admin.php?page=pmxi-admin-import&action=preview', $form.serialize(), function (response) {
138
  $modal.removeClass('loading').html(response).dialog('option', 'position', 'center');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  });
140
  return false;
141
  });
 
 
 
 
 
142
  });
143
 
144
  // options form: highlight options of selected post type
@@ -306,6 +329,8 @@
306
  return this;
307
  };
308
 
 
 
309
  // selection logic
310
  $('form.choose-elements').each(function () {
311
  var $form = $(this);
@@ -316,6 +341,9 @@
316
  var $goto_element = $form.find('#goto_element');
317
  var $get_default_xpath = $form.find('#get_default_xpath');
318
  var $root_element = $form.find('#root_element');
 
 
 
319
 
320
  var $xml = $('.xml');
321
  $form.find('.xml-tag.opening').live('mousedown', function () {return false;}).live('dblclick', function () {
@@ -334,22 +362,36 @@
334
  $input.attr('readonly', true).unbind('change', xpathChanged).data('checkedValue', $input.val());
335
  $xml.css({'visibility':'hidden'});
336
  $xml.parents('fieldset:first').addClass('preload');
337
- $('.ajax-console').load('admin.php?page=pmxi-admin-import&action=evaluate', {xpath: $input.val(), show_element: $goto_element.val(), root_element:$root_element.val()}, function () {
338
- $input.attr('readonly', false).change(function(){$goto_element.val(1); xpathChanged();});
339
- $form.removeClass('loading');
340
- $xml.parents('fieldset:first').removeClass('preload');
341
- });
 
 
 
 
 
 
 
 
 
 
 
 
342
  };
343
- $next_element.click(function(){
344
- var show_element = Math.min((parseInt($goto_element.val()) + 1), parseInt($('.matches_count').html()));
 
345
  $goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
346
  });
347
- $prev_element.click(function(){
348
  var show_element = Math.max((parseInt($goto_element.val()) - 1), 1);
349
  $goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
350
  });
351
  $goto_element.change(function(){
352
- var show_element = Math.max(Math.min(parseInt($goto_element.val()), parseInt($('.matches_count').html())), 1);
 
353
  $goto_element.val(show_element); $input.data('checkedValue', ''); xpathChanged();
354
  });
355
  $get_default_xpath.click(function(){$root_element.val($(this).attr('root')); $goto_element.val(1); $input.val($(this).attr('rel')); xpathChanged();});
@@ -360,24 +402,43 @@
360
  $input.keyup(function (e) {
361
  if (13 == e.keyCode) $(this).change();
362
  });
 
 
 
 
 
 
 
363
  });
364
 
 
 
 
 
 
365
  // tag preview
366
  $.fn.tag = function () {
367
  this.each(function () {
368
  var $tag = $(this);
369
  $tag.xml('dragable');
370
  var tagno = parseInt($tag.find('input[name="tagno"]').val());
371
- $tag.find('.navigation a').click(function () {
372
- tagno += '#prev' == $(this).attr('href') ? -1 : 1;
373
  $tag.addClass('loading').css('opacity', 0.7);
374
  $.post('admin.php?page=pmxi-admin-import&action=tag', {tagno: tagno}, function (data) {
375
  var $indicator = $('<span />').insertBefore($tag);
376
  $tag.replaceWith(data);
377
  $indicator.next().tag().prevObject.remove();
378
- if ($('#variations_xpath').length){
379
  $('#variations_xpath').data('checkedValue', '').change();
380
  }
 
 
 
 
 
 
 
381
  }, 'html');
382
  return false;
383
  });
@@ -466,26 +527,7 @@
466
  $(this).parents('form:first').submit();
467
  });
468
 
469
- /* END Categories hierarchy */
470
-
471
- // manage screen: cron url
472
- $('.get_cron_url').each(function () {
473
- var $form = $(this);
474
- var $modal = $('<div></div>').dialog({
475
- autoOpen: false,
476
- modal: true,
477
- title: 'Cron URLs',
478
- width: 760,
479
- maxHeight: 600,
480
- open: function(event, ui) {
481
- $(this).dialog('option', 'height', 'auto').css({'max-height': $(this).dialog('option', 'maxHeight') - $(this).prev().height() - 24, 'overflow-y': 'auto'});
482
- }
483
- });
484
- $form.find('a').click(function () {
485
- $modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
486
- $modal.removeClass('loading').html('<textarea style="width:100%; height:100%;">' + $form.find('a').attr('rel') + '</textarea>').dialog('option', 'position', 'center');
487
- });
488
- });
489
 
490
  // chunk files upload
491
  if ($('#plupload-ui').length)
@@ -515,24 +557,50 @@
515
 
516
  $('#large_import_toggle').click(function(){
517
  $('#large_import_xpath').slideToggle();
518
- });
519
 
520
- // Step 4 - custom meta keys helper
 
 
 
 
 
521
 
522
  if ($('#pmxi_tabs').length){
523
  if ($('form.options').length){
 
524
  if ($('#selected_post_type').val() != ''){
525
  var post_type_founded = false;
 
526
  $('input[name=custom_type]').each(function(i){
527
- if ($(this).val() == $('#selected_post_type').val()) { $('#pmxi_tabs').tabs({ selected:i }).show(); post_type_founded = true; }
 
 
 
 
528
  });
529
  if ( ! post_type_founded){
530
- $('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
 
 
 
 
 
 
 
531
  }
532
  }
533
  else if ($('#selected_type').val() != ''){
534
- $('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
 
 
 
 
 
 
 
535
  }
 
536
  }
537
  else
538
  $('#pmxi_tabs').tabs().show();
@@ -552,10 +620,42 @@
552
  });
553
 
554
  $(document).scroll(function() {
555
- if ($(document).scrollTop() > 135)
556
- $('.tag').css({'top':'30px'});
557
- else
558
- $('.tag').css({'top':''});
559
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
 
561
  });})(jQuery);
121
  // template form: preview button
122
  $('form.template').each(function () {
123
  var $form = $(this);
124
+ var set_encoding = false;
125
  var $modal = $('<div></div>').dialog({
126
  autoOpen: false,
127
  modal: true,
134
  });
135
  $form.find('.preview').click(function () {
136
  $modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
137
+ if (tinyMCE != undefined) tinyMCE.triggerSave(false, false);
138
  $.post('admin.php?page=pmxi-admin-import&action=preview', $form.serialize(), function (response) {
139
  $modal.removeClass('loading').html(response).dialog('option', 'position', 'center');
140
+ if (set_encoding){
141
+ var $tag = $('.tag');
142
+ $tag.addClass('loading').css('opacity', 0.7);
143
+ $.post('admin.php?page=pmxi-admin-import&action=tag', {tagno: 0}, function (data) {
144
+ var $indicator = $('<span />').insertBefore($tag);
145
+ $tag.replaceWith(data);
146
+ $indicator.next().tag().prevObject.remove();
147
+ if ($('.layout').length){
148
+ var offset = $('.layout').offset();
149
+ if ($(document).scrollTop() > offset.top)
150
+ $('.tag').css({'top':(($(document).scrollTop() - offset.top) ? $(document).scrollTop() - offset.top : 0) + 'px'});
151
+ else
152
+ $('.tag').css({'top':''});
153
+ }
154
+ set_encoding = false;
155
+ }, 'html');
156
+ }
157
  });
158
  return false;
159
  });
160
+ $form.find('.set_encoding').live('click', function(e){
161
+ e.preventDefault();
162
+ set_encoding = true;
163
+ $form.find('input[type="button"].preview').click();
164
+ });
165
  });
166
 
167
  // options form: highlight options of selected post type
329
  return this;
330
  };
331
 
332
+ var go_to_template = false;
333
+
334
  // selection logic
335
  $('form.choose-elements').each(function () {
336
  var $form = $(this);
341
  var $goto_element = $form.find('#goto_element');
342
  var $get_default_xpath = $form.find('#get_default_xpath');
343
  var $root_element = $form.find('#root_element');
344
+ var $submit = $form.find('input[type="submit"]');
345
+ var $csv_delimiter = $form.find('input[name=delimiter]');
346
+ var $apply_delimiter = $form.find('input[name=apply_delimiter]');
347
 
348
  var $xml = $('.xml');
349
  $form.find('.xml-tag.opening').live('mousedown', function () {return false;}).live('dblclick', function () {
362
  $input.attr('readonly', true).unbind('change', xpathChanged).data('checkedValue', $input.val());
363
  $xml.css({'visibility':'hidden'});
364
  $xml.parents('fieldset:first').addClass('preload');
365
+ go_to_template = false;
366
+ $submit.hide();
367
+ var evaluate = function(pointer, chunk){
368
+ $.post('admin.php?page=pmxi-admin-import&action=evaluate', {xpath: $input.val(), show_element: $goto_element.val(), root_element:$root_element.val(), delimiter:$csv_delimiter.val(), pointer:pointer, chunk:chunk}, function (response) {
369
+ if (response.result){
370
+ $('.ajax-console').html(response.html);
371
+ $input.attr('readonly', false).change(function(){$goto_element.val(1); xpathChanged();});
372
+ $form.removeClass('loading');
373
+ $xml.parents('fieldset:first').removeClass('preload');
374
+ go_to_template = true;
375
+ $submit.show();
376
+ }
377
+ else evaluate(response.pointer, response.chunk);
378
+
379
+ }, "json");
380
+ }
381
+ evaluate(0, 0);
382
  };
383
+ $next_element.live('click', function(){
384
+ var matches_count = ($('.matches_count').length) ? parseInt($('.matches_count').html()) : 0;
385
+ var show_element = Math.min((parseInt($goto_element.val()) + 1), matches_count);
386
  $goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
387
  });
388
+ $prev_element.live('click', function(){
389
  var show_element = Math.max((parseInt($goto_element.val()) - 1), 1);
390
  $goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
391
  });
392
  $goto_element.change(function(){
393
+ var matches_count = ($('.matches_count').length) ? parseInt($('.matches_count').html()) : 0;
394
+ var show_element = Math.max(Math.min(parseInt($goto_element.val()), matches_count), 1);
395
  $goto_element.val(show_element); $input.data('checkedValue', ''); xpathChanged();
396
  });
397
  $get_default_xpath.click(function(){$root_element.val($(this).attr('root')); $goto_element.val(1); $input.val($(this).attr('rel')); xpathChanged();});
402
  $input.keyup(function (e) {
403
  if (13 == e.keyCode) $(this).change();
404
  });
405
+
406
+ $apply_delimiter.click(function(){
407
+ if ( ! $input.attr('readonly') ){
408
+ $('input[name="xpath"]').data('checkedValue','');
409
+ xpathChanged();
410
+ }
411
+ });
412
  });
413
 
414
+ $('form.choose-elements').find('input[type="submit"]').click(function(e){
415
+ e.preventDefault();
416
+ if (go_to_template) $(this).parents('form:first').submit();
417
+ });
418
+
419
  // tag preview
420
  $.fn.tag = function () {
421
  this.each(function () {
422
  var $tag = $(this);
423
  $tag.xml('dragable');
424
  var tagno = parseInt($tag.find('input[name="tagno"]').val());
425
+ $tag.find('.navigation a').live('click', function () {
426
+ tagno += '#prev' == $(this).attr('href') ? -1 : 1;
427
  $tag.addClass('loading').css('opacity', 0.7);
428
  $.post('admin.php?page=pmxi-admin-import&action=tag', {tagno: tagno}, function (data) {
429
  var $indicator = $('<span />').insertBefore($tag);
430
  $tag.replaceWith(data);
431
  $indicator.next().tag().prevObject.remove();
432
+ if ($('#variations_xpath').length){
433
  $('#variations_xpath').data('checkedValue', '').change();
434
  }
435
+ if ($('.layout').length){
436
+ var offset = $('.layout').offset();
437
+ if ($(document).scrollTop() > offset.top)
438
+ $('.tag').css({'top':(($(document).scrollTop() - offset.top) ? $(document).scrollTop() - offset.top : 0) + 'px'});
439
+ else
440
+ $('.tag').css({'top':''});
441
+ }
442
  }, 'html');
443
  return false;
444
  });
527
  $(this).parents('form:first').submit();
528
  });
529
 
530
+ /* END Categories hierarchy */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
 
532
  // chunk files upload
533
  if ($('#plupload-ui').length)
557
 
558
  $('#large_import_toggle').click(function(){
559
  $('#large_import_xpath').slideToggle();
560
+ });
561
 
562
+ $('.pmxi_plugin').find('.nav-tab').click(function(){
563
+ $('.nav-tab').removeClass('nav-tab-active');
564
+ $(this).addClass('nav-tab-active');
565
+ $('.pmxi_tab').hide();
566
+ $('div#' + $(this).attr('rel')).fadeIn();
567
+ });
568
 
569
  if ($('#pmxi_tabs').length){
570
  if ($('form.options').length){
571
+ $('.nav-tab').removeClass('nav-tab-active');
572
  if ($('#selected_post_type').val() != ''){
573
  var post_type_founded = false;
574
+ $('.pmxi_tab').hide();
575
  $('input[name=custom_type]').each(function(i){
576
+ if ($(this).val() == $('#selected_post_type').val()) {
577
+ $('.nav-tab[rel='+ $(this).val() +']').addClass('nav-tab-active');
578
+ $(this).parents('.pmxi_tab:first').show();
579
+ post_type_founded = true;
580
+ }
581
  });
582
  if ( ! post_type_founded){
583
+ if ($('#selected_type').val() == 'post'){
584
+ $('.nav-tab[rel=posts]').addClass('nav-tab-active');
585
+ $('div#posts').show();
586
+ }
587
+ else{
588
+ $('.nav-tab[rel=pages]').addClass('nav-tab-active');
589
+ $('div#pages').show();
590
+ }
591
  }
592
  }
593
  else if ($('#selected_type').val() != ''){
594
+ if ($('#selected_type').val() == 'post'){
595
+ $('.nav-tab[rel=posts]').addClass('nav-tab-active');
596
+ $('div#posts').show();
597
+ }
598
+ else{
599
+ $('.nav-tab[rel=pages]').addClass('nav-tab-active');
600
+ $('div#pages').show();
601
+ }
602
  }
603
+ $('.nav-tab-wrapper').show();
604
  }
605
  else
606
  $('#pmxi_tabs').tabs().show();
620
  });
621
 
622
  $(document).scroll(function() {
623
+ if ($('.layout').length){
624
+ var offset = $('.layout').offset();
625
+ if ($(document).scrollTop() > offset.top)
626
+ $('.tag').css({'top':(($(document).scrollTop() - offset.top) ? $(document).scrollTop() - offset.top : 0) + 'px'});
627
+ else
628
+ $('.tag').css({'top':''});
629
+ }
630
+ });
631
+
632
+ // Select Encoding
633
+ $('#import_encoding').live('change', function(){
634
+ if ($(this).val() == 'new'){
635
+ $('#select_encoding').hide();
636
+ $('#add_encoding').show();
637
+ }
638
+ });
639
+
640
+ $('#cancel_new_encoding').live('click', function(){
641
+ $('#add_encoding').hide();
642
+ $('#select_encoding').show();
643
+ $('#new_encoding').val('');
644
+ $('#import_encoding').prop('selectedIndex',0);
645
+ });
646
+
647
+ $('#add_new_encoding').live('click', function(){
648
+ var new_encoding = $('#new_encoding').val();
649
+ if ("" != new_encoding){
650
+ $('#import_encoding').prepend('<option value="'+new_encoding+'">' + new_encoding + '</option>');
651
+ $('#cancel_new_encoding').click();
652
+ $('#import_encoding').prop('selectedIndex',0);
653
+ }
654
+ else alert('Please enter encoding.');
655
+ });
656
+
657
+ $('input[name=keep_custom_fields]').click(function(){
658
+ $(this).parents('.input:first').find('.keep_except').slideToggle();
659
+ });
660
 
661
  });})(jQuery);
views/admin/home/index.php CHANGED
@@ -1,16 +1,16 @@
1
- <div class="wrap">
2
- <?php
3
- $homeurl = "http://www.wpallimport.com/adminpanel/index.php?v=".urlencode(PMXI_Plugin::getInstance()->getVersion());
4
- $contents = @file_get_contents($homeurl);
5
- if ( ! $contents) {
6
- ?>
7
- <iframe src='<?php echo $homeurl; ?>' width='600'></iframe><br />
8
- <?php
9
- } else {
10
- echo $contents;
11
- }
12
- ?>
13
- </div>
14
-
15
-
16
-
1
+ <div class="wrap">
2
+ <?php
3
+ $homeurl = "http://www.wpallimport.com/adminpanel/index.php?v=".urlencode(PMXI_Plugin::getInstance()->getVersion());
4
+ $contents = @file_get_contents($homeurl);
5
+ if ( ! $contents) {
6
+ ?>
7
+ <iframe src='<?php echo $homeurl; ?>' width='600'></iframe><br />
8
+ <?php
9
+ } else {
10
+ echo $contents;
11
+ }
12
+ ?>
13
+ </div>
14
+
15
+
16
+
views/admin/import/element_after.php CHANGED
@@ -14,11 +14,30 @@
14
  <fieldset class="widefat">
15
  <legend><?php _e('Current XML tree', 'pmxi_plugin');?></legend>
16
  <div class="action_buttons">
17
- <a href="javascript:void(0);" id="prev_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left;">&lang;&lang;</a>
18
- <a href="javascript:void(0);" id="next_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left; margin-right:15px;">&rang;&rang;</a>
19
  <div style="float:left;">
20
- <span style="font-size:18px; padding-top:15px; float:left; margin-right:10px;"><?php _e('Go to:','pmxi_plugin');?> </span><input type="text" id="goto_element" value="1"/>
21
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  </div>
23
  <div class="xml" style="min-height:400px;">
24
  <?php //$this->render_xml_element($dom->documentElement) ?>
@@ -52,7 +71,7 @@
52
  &nbsp;
53
  <input type="hidden" name="is_submitted" value="1" />
54
  <?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
55
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" />
56
  </p>
57
  </td>
58
  </tr>
14
  <fieldset class="widefat">
15
  <legend><?php _e('Current XML tree', 'pmxi_plugin');?></legend>
16
  <div class="action_buttons">
17
+ <a href="javascript:void(0);" id="prev_element" class="button button-primary button-hero large_button go_to">&laquo;</a>
18
+ <a href="javascript:void(0);" id="next_element" class="button button-primary button-hero large_button go_to" style="margin-right:15px;">&raquo;</a>
19
  <div style="float:left;">
20
+ <span style="font-size:20px; padding-top:17px; float:left; margin-right:10px;"><?php _e('Go to:','pmxi_plugin');?> </span><input type="text" id="goto_element" value="1"/>
21
+ </div>
22
+ <?php
23
+ if ($is_csv !== false){
24
+ ?>
25
+ <ul class="set_csv_delimiter">
26
+ <li>Set delimiter for CSV fields: </li>
27
+ <!--li> <a href="javascript:void(0);" rel="," <?php if ($is_csv == ','):?>class="delimiter_selected"<?php endif;?>><?php _e('comma', 'pmxi_plugin');?></a> </li>
28
+ <li> <a href="javascript:void(0);" rel=";" <?php if ($is_csv == ';'):?>class="delimiter_selected"<?php endif;?>><?php _e('semicolon', 'pmxi_plugin');?></a> </li>
29
+ <li> <a href="javascript:void(0);" rel="|" <?php if ($is_csv == '|'):?>class="delimiter_selected"<?php endif;?>><?php _e('pipe', 'pmxi_plugin');?></a> </li>
30
+ <li> <a href="javascript:void(0);" rel="\t" <?php if ($is_csv == '\t'):?>class="delimiter_selected"<?php endif;?>><?php _e('tabulation', 'pmxi_plugin');?></a> </li-->
31
+ <li> <input type="text" value="<?php echo $is_csv;?>" name="delimiter"/> <input type="button" name="apply_delimiter" value="Apply"/></li>
32
+ </ul>
33
+ <?php
34
+ }
35
+ else{
36
+ ?>
37
+ <input type="hidden" value="" name="delimiter"/>
38
+ <?php
39
+ }
40
+ ?>
41
  </div>
42
  <div class="xml" style="min-height:400px;">
43
  <?php //$this->render_xml_element($dom->documentElement) ?>
71
  &nbsp;
72
  <input type="hidden" name="is_submitted" value="1" />
73
  <?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
74
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" />
75
  </p>
76
  </td>
77
  </tr>
views/admin/import/error.php CHANGED
@@ -1,3 +1,3 @@
1
- <?php foreach ($errors as $msg): ?>
2
- <div class="error inline"><p><?php echo $msg ?></p></div>
3
  <?php endforeach ?>
1
+ <?php foreach ($errors as $msg): ?>
2
+ <div class="error inline"><p><?php echo $msg ?></p></div>
3
  <?php endforeach ?>
views/admin/import/index.php CHANGED
@@ -58,7 +58,7 @@ $l10n = array(
58
  <div>
59
  <h3 style="float:left; margin-top:5px;"><label><?php _e( 'Choose file to upload...' ); ?></label></h3>&nbsp;&nbsp;
60
  <input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
61
- <span><input id="select-files" type="button" value="<?php esc_attr_e('Select File'); ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" /></span>
62
  <div id="progress" class="progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible;"<?php endif;?>>
63
  <div id="upload_process" class="upload_process"></div>
64
  <div id="progressbar" class="progressbar"><?php if (!empty($post['filepath'])) _e( 'Import Complete - '.basename($post['filepath']).' 100%', 'pmxi_plugin'); ?></div>
@@ -115,7 +115,7 @@ $l10n = array(
115
  <p class="submit-buttons">
116
  <input type="hidden" name="is_submitted" value="1" />
117
  <?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
118
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" id="advanced_upload"/>
119
  </p>
120
  <br />
121
  <table><tr><td class="note"></td></tr></table>
58
  <div>
59
  <h3 style="float:left; margin-top:5px;"><label><?php _e( 'Choose file to upload...' ); ?></label></h3>&nbsp;&nbsp;
60
  <input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
61
+ <span><input id="select-files" type="button" class="button-primary" value="<?php esc_attr_e('Select File'); ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" /></span>
62
  <div id="progress" class="progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible;"<?php endif;?>>
63
  <div id="upload_process" class="upload_process"></div>
64
  <div id="progressbar" class="progressbar"><?php if (!empty($post['filepath'])) _e( 'Import Complete - '.basename($post['filepath']).' 100%', 'pmxi_plugin'); ?></div>
115
  <p class="submit-buttons">
116
  <input type="hidden" name="is_submitted" value="1" />
117
  <?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
118
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" id="advanced_upload"/>
119
  </p>
120
  <br />
121
  <table><tr><td class="note"></td></tr></table>
views/admin/import/options.php CHANGED
@@ -29,7 +29,6 @@
29
  }
30
  }
31
  ?>
32
- <?php $custom_types = get_post_types(array('_builtin' => false), 'objects'); ?>
33
  <input type="hidden" id="selected_post_type" value="<?php echo (!empty($post['custom_type'])) ? $post['custom_type'] : '';?>">
34
  <input type="hidden" id="selected_type" value="<?php echo (!empty($post['type'])) ? $post['type'] : '';?>">
35
  <h2>
@@ -49,7 +48,7 @@
49
 
50
  <table class="layout">
51
  <tr>
52
- <td class="left">
53
  <?php $templates = new PMXI_Template_List() ?>
54
  <form class="load_options options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
55
  <div class="load-template">
@@ -63,133 +62,138 @@
63
  </select>
64
  </div>
65
  </form>
66
- <div id="pmxi_tabs">
67
- <ul>
68
- <li><a href="#tabs-1">Posts</a></li>
69
- <li><a href="#tabs-2">Pages</a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  <!-- WooCommerce Add-On -->
71
  <?php
72
  if (class_exists('PMWI_Plugin')):
73
  ?>
74
- <li><a href="#tabs-woo-product">WooCommerce Products</a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  <?php
76
  endif;
77
  ?>
78
- </ul>
79
-
80
- <!-- Post Options -->
81
-
82
- <div id="tabs-1"> <!-- Basic -->
83
- <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
84
- <input type="hidden" name="type" value="post"/>
85
- <input type="hidden" name="custom_type" value=""/>
86
- <div class="post-type-options">
87
- <table class="form-table" style="max-width:none;">
88
- <?php
89
- $post_type = 'post';
90
- $entry = 'post';
91
- include( 'options/_main_options_template.php' );
92
- include( 'options/_taxonomies_template.php' );
93
- include( 'options/_categories_template.php' );
94
- include( 'options/_custom_fields_template.php' );
95
- include( 'options/_featured_template.php' );
96
- include( 'options/_author_template.php' );
97
- include( 'options/_reimport_template.php' );
98
- ?>
99
- </table>
100
- </div>
101
-
102
- <?php include( 'options/_buttons_template.php' ); ?>
103
-
104
- </form>
105
  </div>
106
-
107
- <!-- Page Options -->
108
-
109
- <div id="tabs-2">
110
- <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
111
- <input type="hidden" name="type" value="page"/>
112
- <input type="hidden" name="custom_type" value=""/>
113
- <div class="post-type-options">
114
- <table class="form-table" style="max-width:none;">
115
-
116
- <?php include( 'options/_main_options_template.php' ); ?>
117
-
118
- <tr>
119
- <td align="center" width="33%">
120
- <label><?php _e('Page Template', 'pmxi_plugin') ?></label> <br>
121
- <select name="page_template" id="page_template">
122
- <option value='default'><?php _e('Default', 'pmxi_plugin') ?></option>
123
- <?php page_template_dropdown($post['page_template']); ?>
124
- </select>
125
- </td>
126
- <td align="center" width="33%">
127
- <label><?php _e('Parent Page', 'pmxi_plugin') ?></label> <br>
128
- <?php wp_dropdown_pages(array('post_type' => 'page', 'selected' => $post['parent'], 'name' => 'parent', 'show_option_none' => __('(no parent)', 'pmxi_plugin'), 'sort_column'=> 'menu_order, post_title',)) ?>
129
- </td>
130
- <td align="center" width="33%">
131
- <label><?php _e('Order', 'pmxi_plugin') ?></label> <br>
132
- <input type="text" class="" name="order" value="<?php echo esc_attr($post['order']) ?>" />
133
- </td>
134
- </tr>
135
- <?php
136
- $post_type = 'post';
137
- $entry = 'page';
138
- include( 'options/_taxonomies_template.php' );
139
- include( 'options/_featured_template.php' );
140
- include( 'options/_reimport_template.php' );
141
- ?>
142
- </table>
143
- </div>
144
-
145
- <?php include( 'options/_buttons_template.php' ); ?>
146
-
147
- </form>
148
- </div>
149
-
150
- <!-- WooCommerce Add-On -->
151
- <?php
152
- if (class_exists('PMWI_Plugin')):
153
- ?>
154
- <div id="tabs-woo-product">
155
- <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
156
- <input type="hidden" name="custom_type" value="product"/>
157
- <input type="hidden" name="type" value="post"/>
158
- <div class="post-type-options">
159
- <table class="form-table" style="max-width:none;">
160
- <?php
161
-
162
- $post_type = $entry = 'product';
163
-
164
- include( 'options/_main_options_template.php' );
165
-
166
- $woo_controller = new PMWI_Admin_Import();
167
- $woo_controller->index();
168
-
169
- include( 'options/_taxonomies_template.php' );
170
- include( 'options/_custom_fields_template.php' );
171
- include( 'options/_featured_template.php' );
172
- include( 'options/_author_template.php' );
173
- include( 'options/_reimport_template.php' );
174
- include( 'options/_scheduling_template.php' );
175
-
176
- ?>
177
- </table>
178
- </div>
179
-
180
- <?php include( 'options/_buttons_template.php' ); ?>
181
-
182
- </form>
183
- </div>
184
- <?php
185
- endif;
186
- ?>
187
  </div>
188
- </td>
189
- <?php if ($this->isWizard or $this->isTemplateEdit): ?>
190
- <td class="right options">
191
- <?php $this->tag() ?>
192
- </td>
193
- <?php endif ?>
194
  </tr>
195
  </table>
29
  }
30
  }
31
  ?>
 
32
  <input type="hidden" id="selected_post_type" value="<?php echo (!empty($post['custom_type'])) ? $post['custom_type'] : '';?>">
33
  <input type="hidden" id="selected_type" value="<?php echo (!empty($post['type'])) ? $post['type'] : '';?>">
34
  <h2>
48
 
49
  <table class="layout">
50
  <tr>
51
+ <td class="left" style="width:100%;">
52
  <?php $templates = new PMXI_Template_List() ?>
53
  <form class="load_options options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
54
  <div class="load-template">
62
  </select>
63
  </div>
64
  </form>
65
+ <h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
66
+ <a class="nav-tab nav-tab-active" rel="posts" href="javascript:void(0);">Posts</a>
67
+ <a class="nav-tab" rel="pages" href="javascript:void(0);">Pages</a>
68
+ <?php
69
+ if (class_exists('PMWI_Plugin')):
70
+ ?>
71
+ <a class="nav-tab" rel="product" href="javascript:void(0);">WooCommerce Products</a>
72
+ <?php
73
+ endif;
74
+ ?>
75
+ </h2>
76
+ <div id="pmxi_tabs">
77
+ <div class="left">
78
+
79
+ <!-- Post Options -->
80
+
81
+ <div id="posts" class="pmxi_tab"> <!-- Basic -->
82
+ <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
83
+ <input type="hidden" name="type" value="post"/>
84
+ <input type="hidden" name="custom_type" value=""/>
85
+ <div class="post-type-options">
86
+ <table class="form-table" style="max-width:none;">
87
+ <?php
88
+ $post_type = 'post';
89
+ $entry = 'post';
90
+ include( 'options/_main_options_template.php' );
91
+ include( 'options/_taxonomies_template.php' );
92
+ include( 'options/_categories_template.php' );
93
+ include( 'options/_custom_fields_template.php' );
94
+ include( 'options/_featured_template.php' );
95
+ include( 'options/_author_template.php' );
96
+ include( 'options/_reimport_template.php' );
97
+ include( 'options/_settings_template.php' );
98
+ ?>
99
+ </table>
100
+ </div>
101
+
102
+ <?php include( 'options/_buttons_template.php' ); ?>
103
+
104
+ </form>
105
+ </div>
106
+
107
+ <!-- Page Options -->
108
+
109
+ <div id="pages" class="pmxi_tab">
110
+ <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
111
+ <input type="hidden" name="type" value="page"/>
112
+ <input type="hidden" name="custom_type" value=""/>
113
+ <div class="post-type-options">
114
+ <table class="form-table" style="max-width:none;">
115
+
116
+ <?php include( 'options/_main_options_template.php' ); ?>
117
+
118
+ <tr>
119
+ <td align="center" width="33%">
120
+ <label><?php _e('Page Template', 'pmxi_plugin') ?></label> <br>
121
+ <select name="page_template" id="page_template">
122
+ <option value='default'><?php _e('Default', 'pmxi_plugin') ?></option>
123
+ <?php page_template_dropdown($post['page_template']); ?>
124
+ </select>
125
+ </td>
126
+ <td align="center" width="33%">
127
+ <label><?php _e('Parent Page', 'pmxi_plugin') ?></label> <br>
128
+ <?php wp_dropdown_pages(array('post_type' => 'page', 'selected' => $post['parent'], 'name' => 'parent', 'show_option_none' => __('(no parent)', 'pmxi_plugin'), 'sort_column'=> 'menu_order, post_title',)) ?>
129
+ </td>
130
+ <td align="center" width="33%">
131
+ <label><?php _e('Order', 'pmxi_plugin') ?></label> <br>
132
+ <input type="text" class="" name="order" value="<?php echo esc_attr($post['order']) ?>" />
133
+ </td>
134
+ </tr>
135
+ <?php
136
+ $post_type = 'post';
137
+ $entry = 'page';
138
+ include( 'options/_custom_fields_template.php' );
139
+ include( 'options/_taxonomies_template.php' );
140
+ include( 'options/_featured_template.php' );
141
+ include( 'options/_author_template.php' );
142
+ include( 'options/_reimport_template.php' );
143
+ include( 'options/_settings_template.php' );
144
+ ?>
145
+ </table>
146
+ </div>
147
+
148
+ <?php include( 'options/_buttons_template.php' ); ?>
149
+
150
+ </form>
151
+ </div>
152
+
153
  <!-- WooCommerce Add-On -->
154
  <?php
155
  if (class_exists('PMWI_Plugin')):
156
  ?>
157
+ <div id="product" class="pmxi_tab">
158
+ <form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
159
+ <input type="hidden" name="custom_type" value="product"/>
160
+ <input type="hidden" name="type" value="post"/>
161
+ <div class="post-type-options">
162
+ <table class="form-table" style="max-width:none;">
163
+ <?php
164
+
165
+ $post_type = $entry = 'product';
166
+
167
+ include( 'options/_main_options_template.php' );
168
+
169
+ $woo_controller = new PMWI_Admin_Import();
170
+ $woo_controller->index();
171
+
172
+ include( 'options/_taxonomies_template.php' );
173
+ include( 'options/_custom_fields_template.php' );
174
+ include( 'options/_featured_template.php' );
175
+ include( 'options/_author_template.php' );
176
+ include( 'options/_reimport_template.php' );
177
+ include( 'options/_settings_template.php' );
178
+
179
+ ?>
180
+ </table>
181
+ </div>
182
+
183
+ <?php include( 'options/_buttons_template.php' ); ?>
184
+
185
+ </form>
186
+ </div>
187
  <?php
188
  endif;
189
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  </div>
191
+ <?php if ($this->isWizard or $this->isTemplateEdit): ?>
192
+ <div class="right options">
193
+ <?php $this->tag() ?>
194
+ </div>
195
+ <?php endif ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  </div>
197
+ </td>
 
 
 
 
 
198
  </tr>
199
  </table>
views/admin/import/options/_author_template.php CHANGED
@@ -1,20 +1,32 @@
 
 
 
 
 
 
 
 
 
 
1
  <tr>
2
  <td colspan="3">
3
  <h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
4
  <div>
5
- <input type="text" name="author" value="<?php echo esc_attr($post['author']) ?>" /> <a href="#help" class="help" title="<?php _e('Value that contains user ID, login, slug or email.', 'pmxi_plugin') ?>">?</a>
6
  </div>
7
  </td>
8
  </tr>
9
  <tr>
10
  <td colspan="3">
11
- <h3><?php _e('Post Excerpt', 'pmxi_plugin') ?></h3>
 
12
  <div>
13
  <input type="text" name="post_excerpt" style="width:100%;" value="<?php echo esc_attr($post['post_excerpt']) ?>" />
14
  </div>
 
15
  <h3><?php _e('Post Slug', 'pmxi_plugin') ?></h3>
16
  <div>
17
  <input type="text" name="post_slug" style="width:100%;" value="<?php echo esc_attr($post['post_slug']) ?>" />
18
- </div> <br><br>
19
  </td>
20
  </tr>
1
+ <tr>
2
+ <td colspan="3">
3
+ <h3 style="float:left;"><?php _e('Download & Import Attachments', 'pmxi_plugin') ?></h3>
4
+ <span class="separated_by" style="position:relative; top:15px; margin-right:0px;"><?php _e('Separated by','pmxi_plugin');?></span>
5
+ <div>
6
+ <input type="text" name="attachments" style="width:93%;" value="<?php echo esc_attr($post['attachments']) ?>" />
7
+ <input type="text" class="small" name="atch_delim" value="<?php echo esc_attr($post['atch_delim']) ?>" style="width:5%; text-align:center; float:right;"/>
8
+ </div>
9
+ </td>
10
+ </tr>
11
  <tr>
12
  <td colspan="3">
13
  <h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
14
  <div>
15
+ <input type="text" name="author" value="<?php echo esc_attr($post['author']) ?>"/> <a href="#help" class="help" title="<?php _e('Value that contains user ID, login, slug or email.', 'pmxi_plugin') ?>">?</a>
16
  </div>
17
  </td>
18
  </tr>
19
  <tr>
20
  <td colspan="3">
21
+ <?php if ($entry != 'page'):?>
22
+ <h3><?php (class_exists('PMWI_Plugin') and $entry == 'product') ? _e('WooCommerce Short Description', 'pmxi_plugin') : _e('Post Excerpt', 'pmxi_plugin'); ?></h3>
23
  <div>
24
  <input type="text" name="post_excerpt" style="width:100%;" value="<?php echo esc_attr($post['post_excerpt']) ?>" />
25
  </div>
26
+ <?php endif; ?>
27
  <h3><?php _e('Post Slug', 'pmxi_plugin') ?></h3>
28
  <div>
29
  <input type="text" name="post_slug" style="width:100%;" value="<?php echo esc_attr($post['post_slug']) ?>" />
30
+ </div>
31
  </td>
32
  </tr>
views/admin/import/options/_buttons_template.php CHANGED
@@ -1,49 +1,3 @@
1
- <br>
2
- <div class="input">
3
- <label for="save_import_as"><?php _e('Friendly Name','pmxi_plugin');?></label> <input type="text" name="friendly_name" title="<?php _e('Save friendly name...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:11px; background:#fff !important;" value="<?php echo esc_attr($post['friendly_name']) ?>" />
4
- </div>
5
- <br>
6
- <?php if (PMXI_Plugin::$session->data['pmxi_import']['large_file'] or (!empty($import) and $import->large_import == 'Yes')):?>
7
- <div class="input">
8
- <label for="records_per_request"><?php _e('Records Per Iteration', 'pmxi_plugin');?></label> <input type="text" name="records_per_request" style="vertical-align:middle; font-size:11px; background:#fff !important; width: 40px;" value="<?php echo esc_attr($post['records_per_request']) ?>" />
9
- <a href="#help" class="help" title="<?php _e('Your feed was detected as a &quot;large&quot; file. The import process will be executed via AJAX requests. To make import process faster you can increase the number of records imported per iteration. Higher numbers put more strain on your server but make the import process take less time. 10 is a very safe number. To speed up the process, try 100 or more, especially if your import settings are simple and you are not downloading images.', 'pmxi_plugin') ?>">?</a>
10
- </div>
11
- <div class="input">
12
- <input type="hidden" name="create_chunks" value="0" />
13
- <input type="checkbox" id="create_chunks_<?php echo $entry; ?>" name="create_chunks" value="1" <?php echo $post['create_chunks'] ? 'checked="checked"': '' ?>/>
14
- <label for="create_chunks_<?php echo $entry; ?>"><?php _e('create chunks', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Check this to split up the file into pieces before import. Will speed up the import of large files.', 'pmxi_plugin') ?>">?</a></label>
15
- </div>
16
- <br>
17
- <?php endif; ?>
18
- <div class="input">
19
- <input type="hidden" name="is_import_specified" value="0" />
20
- <input type="checkbox" id="is_import_specified_<?php echo $entry; ?>" class="switcher" name="is_import_specified" value="1" <?php echo $post['is_import_specified'] ? 'checked="checked"': '' ?>/>
21
- <label for="is_import_specified_<?php echo $entry; ?>"><?php _e('Import only specified records', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter records or record ranges separated by commas, e.g. <b>1,5,7-10</b> would import the first, the fifth, and the seventh to tenth.', 'pmxi_plugin') ?>">?</a></label>
22
- <span class="switcher-target-is_import_specified_<?php echo $entry; ?>" style="vertical-align:middle">
23
- <div class="input" style="display:inline;">
24
- <input type="text" name="import_specified" value="<?php echo esc_attr($post['import_specified']) ?>" style="width:50%;"/>
25
- </div>
26
- </span>
27
- </div>
28
- <p>
29
- <div class="input">
30
- <input type="checkbox" id="save_template_as_<?php echo $entry; ?>" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as_<?php echo $entry; ?>"><?php _e('Save template as:','pmxi_plugin');?></label> &nbsp;<input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
31
- </div>
32
- </p>
33
- <?php if (in_array($source_type, array('ftp', 'file'))): ?>
34
- <div class="input">
35
- <input type="hidden" name="is_delete_source" value="0" />
36
- <input type="checkbox" id="is_delete_source_<?php echo $entry; ?>" name="is_delete_source" value="1" <?php echo $post['is_delete_source'] ? 'checked="checked"': '' ?>/>
37
- <label for="is_delete_source_<?php echo $entry; ?>"><?php _e('Delete source XML file after importing', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting takes effect only when script has access rights to perform the action, e.g. file is not deleted when pulled via HTTP or delete permission is not granted to the user that script is executed under.', 'pmxi_plugin') ?>">?</a></label>
38
- </div>
39
- <?php endif; ?>
40
- <?php if (class_exists('PMLC_Plugin')): // option is only valid when `WP Wizard Cloak` pluign is enabled ?>
41
- <div class="input">
42
- <input type="hidden" name="is_cloak" value="0" />
43
- <input type="checkbox" id="is_cloak_<?php echo $entry; ?>" name="is_cloak" value="1" <?php echo $post['is_cloak'] ? 'checked="checked"': '' ?>/>
44
- <label for="is_cloak_<?php echo $entry; ?>"><?php _e('Auto-Cloak Links', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php printf(__('Automatically process all links present in body of created post or page with <b>%s</b> plugin', 'pmxi_plugin'), PMLC_Plugin::getInstance()->getName()) ?>">?</a></label>
45
- </div> <br>
46
- <?php endif; ?>
47
  <p class="submit-buttons">
48
  <?php wp_nonce_field('options', '_wpnonce_options') ?>
49
  <input type="hidden" name="is_submitted" value="1" />
@@ -54,13 +8,13 @@
54
 
55
  <?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
56
  <input type="hidden" class="save_only" value="0" name="save_only"/>
57
- <span style="font-size:16px;">or</span> <input type="submit" name="btn_save_only" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save Only', 'pmxi_plugin') ?>" />
58
  <?php endif ?>
59
 
60
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Finish', 'pmxi_plugin') ?>" />
61
 
62
  <?php else: ?>
63
  <a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
64
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save', 'pmxi_plugin') ?>" />
65
  <?php endif ?>
66
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <p class="submit-buttons">
2
  <?php wp_nonce_field('options', '_wpnonce_options') ?>
3
  <input type="hidden" name="is_submitted" value="1" />
8
 
9
  <?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
10
  <input type="hidden" class="save_only" value="0" name="save_only"/>
11
+ <input type="submit" name="btn_save_only" class="button button-primary button-hero large_button" value="<?php _e('Save Only', 'pmxi_plugin') ?>" />
12
  <?php endif ?>
13
 
14
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e('Finish', 'pmxi_plugin') ?>" />
15
 
16
  <?php else: ?>
17
  <a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
18
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e('Save', 'pmxi_plugin') ?>" />
19
  <?php endif ?>
20
  </p>
views/admin/import/options/_categories_template.php CHANGED
@@ -16,8 +16,8 @@
16
  ?>
17
  <li id="item_<?php echo $i; ?>">
18
  <div class="drag-element">
19
- <input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
20
- <input type="text" class="widefat" value="<?php echo (is_object($cat)) ? esc_attr($cat->xpath) : esc_attr($cat); ?>" />
21
  </div>
22
  <?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
23
  <?php if (is_object($cat)) echo reverse_taxonomies_html($categories, $cat->item_id, $i); ?>
@@ -27,28 +27,29 @@
27
  }; else: ?>
28
  <li id="item_1">
29
  <div class="drag-element">
30
- <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
31
- <input type="text" class="widefat" value="" />
32
  </div>
33
  </li>
34
  <?php endif;?>
35
  <?php else: ?>
36
  <li id="item_1">
37
  <div class="drag-element">
38
- <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
39
- <input type="text" class="widefat" value="" />
40
  </div>
41
  </li>
42
  <?php endif; ?>
43
  </ol>
44
- <?php if ($post_type == "post"):?><a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more', 'pmxi_plugin');?></a><?php endif; ?> <br><br>
45
  <input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
46
  <div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?"><?php _e('Remove only current category or current category with subcategories?', 'pmxi_plugin');?></div>
47
  <div class="delim">
48
  <label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
49
- <input type="text" class="small" name="categories_delim" value="<?php echo esc_attr($post['categories_delim']) ?>" />
50
  <label for="categories_auto_nested"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
51
- <input type="checkbox" id="categories_auto_nested" name="categories_auto_nested" <?php if ($post['categories_auto_nested']):?>checked="checked"<?php endif; ?> />
 
52
  <a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>&gt;</code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
53
  </div>
54
  </fieldset>
16
  ?>
17
  <li id="item_<?php echo $i; ?>">
18
  <div class="drag-element">
19
+ <input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
20
+ <input type="text" class="widefat" value="<?php echo (is_object($cat)) ? esc_attr($cat->xpath) : esc_attr($cat); ?>"/>
21
  </div>
22
  <?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
23
  <?php if (is_object($cat)) echo reverse_taxonomies_html($categories, $cat->item_id, $i); ?>
27
  }; else: ?>
28
  <li id="item_1">
29
  <div class="drag-element">
30
+ <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
31
+ <input type="text" class="widefat" value=""/>
32
  </div>
33
  </li>
34
  <?php endif;?>
35
  <?php else: ?>
36
  <li id="item_1">
37
  <div class="drag-element">
38
+ <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
39
+ <input type="text" class="widefat" value=""/>
40
  </div>
41
  </li>
42
  <?php endif; ?>
43
  </ol>
44
+ <a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more', 'pmxi_plugin');?></a> <br><br>
45
  <input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
46
  <div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?"><?php _e('Remove only current category or current category with subcategories?', 'pmxi_plugin');?></div>
47
  <div class="delim">
48
  <label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
49
+ <input type="text" class="small" name="categories_delim" value="<?php echo ( ! empty($post['categories_delim']) ) ? str_replace("&amp;","&", htmlentities(htmlentities($post['categories_delim']))) : ',' ; ?>" />
50
  <label for="categories_auto_nested"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
51
+ <input type="hidden" name="categories_auto_nested" value="0"/>
52
+ <input type="checkbox" id="categories_auto_nested" name="categories_auto_nested" <?php if ($post['categories_auto_nested']):?>checked="checked"<?php endif; ?>/>
53
  <a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>&gt;</code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
54
  </div>
55
  </fieldset>
views/admin/import/options/_custom_fields_template.php CHANGED
@@ -1,5 +1,5 @@
1
  <tr>
2
- <td colspan="3" style="border-bottom:1px solid #ccc;">
3
  <fieldset class="optionsset" style="text-align:center;">
4
  <legend>Custom Fields</legend>
5
 
1
  <tr>
2
+ <td colspan="3" style="padding-top:20px;">
3
  <fieldset class="optionsset" style="text-align:center;">
4
  <legend>Custom Fields</legend>
5
 
views/admin/import/options/_featured_template.php CHANGED
@@ -1,57 +1,72 @@
1
  <tr>
2
- <td colspan="3">
3
- <h3>
4
- <?php _e('Download & Import Images To The Post Media Gallery', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Specify URLs or XPath Template Tags to download and import images to the post media gallery. The first image will be set as the Featured Image. Example: <pre>{image[1]},{image[2]},{image[3]}</pre> Separate your URLs or XPath Template Tags with the comma. <i>Separated by</i> character will use if xPath value contains multiple URLs, for example: <br> \'http://test.com/first.jpg | http://test.com/second.png\'.', 'pmxi_plugin') ?>">?</a>
5
- <span class="separated_by"><?php _e('Separated by','pmxi_plugin');?></span>
6
- </h3>
7
- <div>
8
- <input type="text" name="featured_image" style="width:92%;" value="<?php echo ($post_type == "product") ? esc_attr($post['featured_image']) : ""; ?>" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
9
- <input type="text" class="small" name="featured_delim" maxlength="1" value="<?php echo esc_attr($post['featured_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
10
- </div>
11
- <div class="input">
12
- <input type="hidden" name="create_draft" value="no" />
13
- <input type="checkbox" id="create_draft_<?php echo $entry; ?>" name="create_draft" value="yes" <?php echo ($post_type == "product" and "yes" == $post['create_draft']) ? 'checked="checked"' : '' ?> <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
14
- <label for="create_draft_<?php echo $entry; ?>"><?php _e('<small>If no images are downloaded successfully, create entry as Draft.</small>', 'pmxi_plugin') ?></label>
15
- </div>
16
- <div class="input">
17
- <input type="radio" id="use_filename_<?php echo $entry; ?>" name="images_name" value="filename" <?php echo ($post['images_name'] == "filename") ? 'checked="checked"' : '' ?> <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
18
- <label for="use_filename_<?php echo $entry; ?>"><?php _e('<small>The image filenames should be generated based on URLs.</small>', 'pmxi_plugin') ?></label> <br>
19
-
20
- <input type="radio" id="use_autoname_<?php echo $entry; ?>" name="images_name" value="auto" <?php echo ($post['images_name'] == "auto") ? 'checked="checked"' : '' ?> <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
21
- <label for="use_autoname_<?php echo $entry; ?>"><?php _e('<small>The image filenames should be generated based on timestamp.</small>', 'pmxi_plugin') ?></label> <br>
22
- </div>
23
- <div class="input">
24
- <input type="hidden" name="auto_rename_images" value="0" />
25
- <input type="checkbox" id="auto_rename_images_<?php echo $entry; ?>" name="auto_rename_images" value="1" <?php echo $post['auto_rename_images'] ? 'checked="checked"' : '' ?> class="switcher" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
26
- <label for="auto_rename_images_<?php echo $entry; ?>"><?php _e('<small>The image filenames should be generated based on provided suffix.</small>', 'pmxi_plugin') ?></label>
27
- <a href="#help" class="help" title="<?php _e('Example <product_title>Acme Product</product>. Image filenames: acme_product-1.(ext), acme_product-2.(ext), acme_product-3.(ext), etc.', 'pmxi_plugin') ?>">?</a>
28
- </div>
29
- <div class="switcher-target-auto_rename_images_<?php echo $entry; ?>" style="padding-left:17px;">
30
  <div class="input">
31
- <?php _e('<small>Images suffix</small>', 'pmxi_plugin') ?>
32
- <input type="text" name="auto_rename_images_suffix" value="<?php echo esc_attr($post['auto_rename_images_suffix']) ?>" />
 
 
 
 
 
 
 
33
  </div>
34
- </div>
35
- <?php if ($post_type != "product"):?>
36
- <center>
37
-
38
- <hr />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- <b>Please upgrade to the professional edition of WP All Import to download and import images to the post media gallery.</b>
41
 
42
- <p style='font-size: 1.1em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=featured-images&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
43
 
44
- </center>
45
- <?php endif; ?>
46
 
47
- <h3>
48
- <?php _e('Download & Import Attachments', 'pmxi_plugin') ?>
49
- <span class="separated_by">Separated by</span>
50
- </h3>
51
- <div>
52
- <input type="text" name="attachments" style="width:92%;" value="<?php echo esc_attr($post['attachments']) ?>" />
53
- <input type="text" class="small" name="atch_delim" maxlength="1" value="<?php echo esc_attr($post['atch_delim']) ?>" style="width:5%; text-align:center;" />
54
- </div>
55
- <br>
56
  </td>
57
  </tr>
1
  <tr>
2
+ <td colspan="3" style="padding-top:20px;">
3
+ <fieldset class="optionsset">
4
+ <legend><?php _e('Featured Image & Media Gallery', 'pmxi_plugin') ?></legend>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  <div class="input">
6
+ <p style="margin-bottom:5px;"><?php _e('<b>Image URLs</b> (one per line)', 'pmxi_plugin');?></p>
7
+ <textarea name="featured_image" class="newline" style="width:100%;margin-bottom:5px;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>><?php echo esc_attr($post['featured_image']) ?></textarea>
8
+ <label for="featured_delim_<?php echo $entry;?>"><?php _e('Place one image URL per line, or separate URLs with a ', 'pmxi_plugin');?></label>
9
+ <input type="text" class="small" id="featured_delim_<?php echo $entry;?>" name="featured_delim" value="<?php echo esc_attr($post['featured_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
10
+ <span style="float:right;">
11
+ <input type="hidden" name="create_draft" value="no" />
12
+ <input type="checkbox" id="create_draft_<?php echo $entry; ?>" name="create_draft" value="yes" <?php echo 'yes' == $post['create_draft'] ? 'checked="checked"' : '' ?> class="fix_checkbox" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
13
+ <label for="create_draft_<?php echo $entry; ?>"><?php _e('If no images are downloaded successfully, create entry as Draft.', 'pmxi_plugin') ?></label>
14
+ </span>
15
  </div>
16
+ <div class="input" style="margin:3px 0px;">
17
+ <input type="hidden" name="download_images" value="0" />
18
+ <input type="checkbox" id="download_images_<?php echo $entry; ?>" name="download_images" value="1" <?php echo $post['download_images'] ? 'checked="checked"' : '' ?> class="switcher fix_checkbox" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
19
+ <label for="download_images_<?php echo $entry;?>"><?php _e('Download images','pmxi_plugin');?> </label>
20
+ <a href="#help" class="help" title="<?php _e('If this option enabled, then plugin will download images into the Uploads folder. If this option disabled, then plugin will search files in Uploads <strong>/wp-content/uploads/'.date("Y/m").'</strong> folder.', 'pmxi_plugin') ?>">?</a>
21
+ </div>
22
+ <div class="input switcher-target-download_images_<?php echo $entry; ?>" style="margin:3px 0px;">
23
+ <input type="hidden" name="auto_rename_images" value="0" />
24
+ <input type="checkbox" id="auto_rename_images_<?php echo $entry; ?>" name="auto_rename_images" value="1" <?php echo $post['auto_rename_images'] ? 'checked="checked"' : '' ?> class="switcher fix_checkbox" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
25
+ <label for="auto_rename_images_<?php echo $entry;?>"><?php _e('Instead of using original image file name, set file name(s) to','pmxi_plugin');?> </label>
26
+ <input type="text" id="auto_rename_images_suffix_<?php echo $entry;?>" class="switcher-target-auto_rename_images_<?php echo $entry; ?>" name="auto_rename_images_suffix" value="<?php echo esc_attr($post['auto_rename_images_suffix']) ?>" /> <a href="#help" class="help" title="<?php _e('Instead of using original image file name, set file name(s) suffix', 'pmxi_plugin') ?>">?</a>
27
+ </div>
28
+ <div class="input">
29
+ <input type="hidden" name="set_image_meta_data" value="0" />
30
+ <input type="checkbox" id="set_image_meta_data_<?php echo $entry; ?>" name="set_image_meta_data" value="1" <?php echo $post['set_image_meta_data'] ? 'checked="checked"' : '' ?> class="switcher fix_checkbox"/>
31
+ <label for="set_image_meta_data_<?php echo $entry;?>"><?php _e('Set Image Meta Data (alt text, caption, description, title)','pmxi_plugin');?></label>
32
+ </div>
33
+ <div class="switcher-target-set_image_meta_data_<?php echo $entry; ?>" style="padding-left:17px;">
34
+ <div class="input">
35
+ <p style="margin-bottom:5px;"><?php _e('Title', 'pmxi_plugin');?> <a href="#help" class="help" title="<?php _e('Image Title', 'pmxi_plugin') ?>">?</a></p>
36
+ <textarea name="image_meta_title" class="newline" style="width:100%; margin-bottom:5px;" placeholder="<?php _e('Default will be image filename. The first title will be associated with the first image URL, the second title will be associated with second image URL, etc.','pmxi_plugin');?>" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>><?php echo esc_attr($post['image_meta_title']) ?></textarea>
37
+ <label for="image_meta_title_delim_<?php echo $entry;?>"><?php _e('Separated by', 'pmxi_plugin');?></label>
38
+ <input type="text" class="small" id="image_meta_title_delim_<?php echo $entry;?>" name="image_meta_title_delim" value="<?php echo esc_attr($post['image_meta_title_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/> <span>(<?php _e('or newline','pmxi_plugin');?>)</span>
39
+ </div>
40
+ <div class="input">
41
+ <p style="margin-bottom:5px;"><?php _e('Caption', 'pmxi_plugin');?> <a href="#help" class="help" title="<?php _e('Image Capltion', 'pmxi_plugin') ?>">?</a></p>
42
+ <textarea name="image_meta_caption" class="newline" style="width:100%; margin-bottom:5px;" placeholder="The first caption will be associated with the first image URL, the second caption will be associated with the second image URL, etc." <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>><?php echo esc_attr($post['image_meta_caption']) ?></textarea>
43
+ <label for="image_meta_caption_delim_<?php echo $entry;?>"><?php _e('Separated by', 'pmxi_plugin');?></label>
44
+ <input type="text" class="small" id="image_meta_caption_delim_<?php echo $entry;?>" name="image_meta_caption_delim" value="<?php echo esc_attr($post['image_meta_caption_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/> <span>(<?php _e('or newline','pmxi_plugin');?>)</span>
45
+ </div>
46
+ <div class="input">
47
+ <p style="margin-bottom:5px;"><?php _e('Alt text', 'pmxi_plugin');?> <a href="#help" class="help" title="<?php _e('Image Alt Text', 'pmxi_plugin') ?>">?</a></p>
48
+ <textarea name="image_meta_alt" class="newline" style="width:100%; margin-bottom:5px;" placeholder="The first alt text will be associated with the first image URL, the second alt text will be associted with the second image URL, etc." <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>><?php echo esc_attr($post['image_meta_alt']) ?></textarea>
49
+ <label for="image_meta_alt_delim_<?php echo $entry;?>"><?php _e('Separated by', 'pmxi_plugin');?></label>
50
+ <input type="text" class="small" id="image_meta_alt_delim_<?php echo $entry;?>" name="image_meta_alt_delim" value="<?php echo esc_attr($post['image_meta_alt_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/> <span>(<?php _e('or newline','pmxi_plugin');?>)</span>
51
+ </div>
52
+ <div class="input">
53
+ <p style="margin-bottom:5px;"><?php _e('Description', 'pmxi_plugin');?> <a href="#help" class="help" title="<?php _e('Image Description', 'pmxi_plugin') ?>">?</a></p>
54
+ <textarea name="image_meta_description" class="newline" style="width:100%; margin-bottom:5px;" placeholder="The first description will be associated with the first URL, the second descrition will be associated with the second URL, etc." <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>><?php echo esc_attr($post['image_meta_description']) ?></textarea>
55
+ <label for="image_meta_description_delim_<?php echo $entry;?>"><?php _e('Separated by', 'pmxi_plugin');?></label>
56
+ <input type="text" class="small" id="image_meta_description_delim_<?php echo $entry;?>" name="image_meta_description_delim" value="<?php echo esc_attr($post['image_meta_description_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/> <span>(<?php _e('or newline','pmxi_plugin');?>)</span>
57
+ </div>
58
+ </div>
59
+ <?php if ($post_type != "product"):?>
60
+ <center>
61
 
62
+ <hr />
63
 
64
+ <b>Please upgrade to the professional edition of WP All Import to download and import images to the post media gallery.</b>
65
 
66
+ <p style='font-size: 1.1em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=featured-images&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
 
67
 
68
+ </center>
69
+ <?php endif; ?>
70
+ </fieldset>
 
 
 
 
 
 
71
  </td>
72
  </tr>
views/admin/import/options/_main_options_template.php CHANGED
@@ -1,17 +1,33 @@
1
  <tr>
2
- <td colspan="3" style="border-bottom:1px solid #ccc;">
3
- <div class="col2" style="margin-bottom:20px;">
4
- <h3><?php _e('Post Status', 'pmxi_plugin') ?></h3>
 
 
 
 
 
 
5
  <div>
6
  <div class="input">
7
- <input type="radio" id="status_publish_<?php echo $entry; ?>" name="status" value="publish" <?php echo 'publish' == $post['status'] ? 'checked="checked"' : '' ?> />
8
  <label for="status_publish_<?php echo $entry; ?>"><?php _e('Published', 'pmxi_plugin') ?></label>
9
  </div>
10
  <div class="input">
11
- <input type="radio" id="status_draft_<?php echo $entry; ?>" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?> />
12
  <label for="status_draft_<?php echo $entry; ?>"><?php _e('Draft', 'pmxi_plugin') ?></label>
13
  </div>
14
- <br>
 
 
 
 
 
 
 
 
 
 
15
  <div class="input">
16
  <input type="hidden" name="comment_status" value="closed" />
17
  <input type="checkbox" id="comment_status_<?php echo $entry; ?>" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?> />
@@ -22,10 +38,34 @@
22
  <input type="checkbox" id="ping_status_<?php echo $entry; ?>" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?> />
23
  <label for="ping_status_<?php echo $entry; ?>"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
24
  </div>
25
- </div>
26
- </div>
27
- <div class="col2">
28
- <h3><?php _e('Post Dates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Use any format supported by the PHP <b>strtotime</b> function. That means pretty much any human-readable date will work.', 'pmxi_plugin') ?>">?</a></h3>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  <div class="input">
30
  <input type="radio" id="date_type_specific_<?php echo $entry; ?>" class="switcher" name="date_type" value="specific" <?php echo 'random' != $post['date_type'] ? 'checked="checked"' : '' ?> />
31
  <label for="date_type_specific_<?php echo $entry; ?>">
@@ -45,7 +85,7 @@
45
  <?php _e('and', 'pmxi_plugin') ?>
46
  <input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>" />
47
  </span>
48
- </div>
49
  </div>
50
  </td>
51
  </tr>
1
  <tr>
2
+ <td style="border-bottom:1px solid #ccc;" colspan="3">
3
+
4
+ <input type="hidden" name="encoding" value="<?php echo ($this->isWizard) ? PMXI_Plugin::$session->data['pmxi_import']['encoding'] : $post['encoding']; ?>"/>
5
+ <input type="hidden" name="delimiter" value="<?php echo ($this->isWizard) ? PMXI_Plugin::$session->data['pmxi_import']['is_csv'] : $post['delimiter']; ?>"/>
6
+
7
+ <?php $is_support_post_format = ( current_theme_supports( 'post-formats' ) && post_type_supports( $post_type, 'post-formats' ) ) ? true : false; ?>
8
+
9
+ <div class="<?php echo ($is_support_post_format) ? 'col3' : 'col2';?>" style="margin-bottom:20px;">
10
+ <h3><?php _e('Post Status', 'pmxi_plugin') ?></h3>
11
  <div>
12
  <div class="input">
13
+ <input type="radio" id="status_publish_<?php echo $entry; ?>" name="status" value="publish" <?php echo 'publish' == $post['status'] ? 'checked="checked"' : '' ?> class="switcher"/>
14
  <label for="status_publish_<?php echo $entry; ?>"><?php _e('Published', 'pmxi_plugin') ?></label>
15
  </div>
16
  <div class="input">
17
+ <input type="radio" id="status_draft_<?php echo $entry; ?>" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?> class="switcher"/>
18
  <label for="status_draft_<?php echo $entry; ?>"><?php _e('Draft', 'pmxi_plugin') ?></label>
19
  </div>
20
+ <div class="input fleft" style="position:relative;width:220px; margin-bottom:15px;">
21
+ <input type="radio" id="status_xpath_<?php echo $entry; ?>" class="switcher" name="status" value="xpath" <?php echo 'xpath' == $post['status'] ? 'checked="checked"': '' ?>/>
22
+ <label for="status_xpath_<?php echo $entry; ?>"><?php _e('Set with XPath', 'pmxi_plugin' )?></label> <br>
23
+ <div class="switcher-target-status_xpath_<?php echo $entry; ?> set_xpath">
24
+ <div class="input">
25
+ &nbsp;<input type="text" class="smaller-text" name="status_xpath" style="width:150px; float:left;" value="<?php echo esc_attr($post['status_xpath']) ?>"/>
26
+ <a href="#help" class="help" title="<?php _e('The value of presented XPath should be one of the following: (\'publish\', \'draft\', \'trash\').', 'pmxi_plugin') ?>" style="position:relative; top:2px;">?</a>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ <div class="clear"></div>
31
  <div class="input">
32
  <input type="hidden" name="comment_status" value="closed" />
33
  <input type="checkbox" id="comment_status_<?php echo $entry; ?>" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?> />
38
  <input type="checkbox" id="ping_status_<?php echo $entry; ?>" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?> />
39
  <label for="ping_status_<?php echo $entry; ?>"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
40
  </div>
41
+ </div>
42
+ </div>
43
+ <?php if ($is_support_post_format):?>
44
+ <div class="col3">
45
+ <h3><?php _e('Post Format', 'pmxi_plugin') ?></h3>
46
+ <div>
47
+ <div class="input">
48
+ <input type="radio" id="post_format_<?php echo "standart_" . $entry; ?>" name="post_format" value="0" <?php echo (empty($post['post_format'])) ? 'checked="checked"' : '' ?> />
49
+ <label for="post_format_<?php echo "standart_" . $entry; ?>"><?php _e( "Standart", 'pmxi_plugin') ?></label>
50
+ </div>
51
+ <?php
52
+ $post_formats = get_terms( 'post_format' , array('hide_empty' => false));
53
+ if ( ! empty($post_formats) ){
54
+ foreach ($post_formats as $post_format) {
55
+ ?>
56
+ <div class="input">
57
+ <input type="radio" id="post_format_<?php echo $post_format->slug . "_" . $entry; ?>" name="post_format" value="<?php echo $post_format->name; ?>" <?php echo $post_format->name == $post['post_format'] ? 'checked="checked"' : '' ?> />
58
+ <label for="post_format_<?php echo $post_format->slug . "_" . $entry; ?>"><?php _e( $post_format->name, 'pmxi_plugin') ?></label>
59
+ </div>
60
+ <?php
61
+ }
62
+ }
63
+ ?>
64
+ </div>
65
+ </div>
66
+ <?php endif; ?>
67
+ <div class="<?php echo ($is_support_post_format) ? 'col3' : 'col2';?>" <?php if ($is_support_post_format):?>style="border-right:none; padding-right:0px;"<?php endif; ?>>
68
+ <h3><?php _e('Post Dates', 'pmxi_plugin') ?><a href="#help" class="help" title="<?php _e('Use any format supported by the PHP <b>strtotime</b> function. That means pretty much any human-readable date will work.', 'pmxi_plugin') ?>">?</a></h3>
69
  <div class="input">
70
  <input type="radio" id="date_type_specific_<?php echo $entry; ?>" class="switcher" name="date_type" value="specific" <?php echo 'random' != $post['date_type'] ? 'checked="checked"' : '' ?> />
71
  <label for="date_type_specific_<?php echo $entry; ?>">
85
  <?php _e('and', 'pmxi_plugin') ?>
86
  <input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>" />
87
  </span>
88
+ </div>
89
  </div>
90
  </td>
91
  </tr>
views/admin/import/options/_reimport_template.php CHANGED
@@ -1,32 +1,32 @@
1
  <tr>
2
- <td colspan="3">
3
  <fieldset class="optionsset">
4
- <legend><?php _e('Record Matching','pmxi_plugin');?></legend>
5
  <div class="input" style="margin-bottom:15px;">
6
- <input type="radio" id="auto_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="auto" <?php echo 'manual' != $post['duplicate_matching'] ? 'checked="checked"': '' ?> />
7
  <label for="auto_matching_<?php echo $entry; ?>"><?php _e('Automatic Record Matching', 'pmxi_plugin' )?></label><br>
8
  <div class="switcher-target-auto_matching_<?php echo $entry; ?>" style="padding-left:17px;">
9
  <div class="input">
10
  <label><?php _e("Unique key"); ?></label>
11
- <input type="text" class="smaller-text" name="unique_key" style="width:300px;" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?> />
12
  <a href="#help" class="help" title="<?php _e('Specify something that is unique for all records. If posts are being updated and not just created during a brand new import, the problem is that the value of the unique key is not unique.', 'pmxi_plugin') ?>">?</a>
13
  </div>
14
  </div>
15
- <input type="radio" id="manual_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="manual" <?php echo 'manual' == $post['duplicate_matching'] ? 'checked="checked"': '' ?> />
16
  <label for="manual_matching_<?php echo $entry; ?>"><?php _e('Manual Record Matching', 'pmxi_plugin' )?></label>
17
  <a href="#help" class="help" title="<?php _e('This allows you to match records by something other than Unique Key.', 'pmxi_plugin') ?>">?</a>
18
  <div class="switcher-target-manual_matching_<?php echo $entry; ?>" style="padding-left:17px;">
19
  <div class="input">
20
  <span style="vertical-align:middle"><?php _e('Match records based on...', 'pmxi_plugin') ?></span><br>
21
- <input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
22
  <label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
23
- <input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
24
  <label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
25
- <input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
26
  <label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
27
  <span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle; padding-left:17px;">
28
  <?php _e('Name', 'pmxi_plugin') ?>
29
- <input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>" /><br>
30
  <?php _e('Value', 'pmxi_plugin') ?>
31
  <input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>" />
32
  </span>
@@ -41,9 +41,9 @@
41
  </div>
42
  <div class="input">
43
  <input type="hidden" name="is_delete_missing" value="0" />
44
- <input type="checkbox" id="is_delete_missing_<?php echo $entry; ?>" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> class="switcher" />
45
  <label for="is_delete_missing_<?php echo $entry; ?>"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
46
- <a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from previous import operation which are not found among newly impoprted set.', 'pmxi_plugin') ?>">?</a>
47
  </div>
48
  <div class="switcher-target-is_delete_missing_<?php echo $entry; ?>" style="padding-left:17px;">
49
  <div class="input">
@@ -144,6 +144,12 @@
144
  <input type="checkbox" id="keep_custom_fields_<?php echo $entry; ?>" name="keep_custom_fields" value="1" <?php echo $post['keep_custom_fields'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed"/>
145
  <label for="keep_custom_fields_<?php echo $entry; ?>"><?php _e('Keep custom fields', 'pmxi_plugin') ?></label>
146
  <a href="#help" class="help" title="<?php _e('If Keep Custom Fields box is checked, it will keep all Custom Fields, and add any new Custom Fields specified in Custom Fields section, as long as they do not overwrite existing fields. If \'Only keep this Custom Fields\' is specified, it will only keep the specified fields.', 'pmxi_plugin') ?>">?</a>
 
 
 
 
 
 
147
  </div>
148
  <div class="switcher-target-keep_custom_fields_<?php echo $entry; ?>" style="padding-left:17px;">
149
  <div class="input">
@@ -152,7 +158,7 @@
152
  </div>
153
  </div>
154
  </div>
155
- </div>
156
  </fieldset>
157
  </td>
158
  </tr>
1
  <tr>
2
+ <td colspan="3" style="padding-top:20px;">
3
  <fieldset class="optionsset">
4
+ <legend><?php _e('Record Matching','pmxi_plugin');?></legend>
5
  <div class="input" style="margin-bottom:15px;">
6
+ <input type="radio" id="auto_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="auto" <?php echo 'manual' != $post['duplicate_matching'] ? 'checked="checked"': '' ?>/>
7
  <label for="auto_matching_<?php echo $entry; ?>"><?php _e('Automatic Record Matching', 'pmxi_plugin' )?></label><br>
8
  <div class="switcher-target-auto_matching_<?php echo $entry; ?>" style="padding-left:17px;">
9
  <div class="input">
10
  <label><?php _e("Unique key"); ?></label>
11
+ <input type="text" class="smaller-text" name="unique_key" style="width:300px;" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?>/>
12
  <a href="#help" class="help" title="<?php _e('Specify something that is unique for all records. If posts are being updated and not just created during a brand new import, the problem is that the value of the unique key is not unique.', 'pmxi_plugin') ?>">?</a>
13
  </div>
14
  </div>
15
+ <input type="radio" id="manual_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="manual" <?php echo 'manual' == $post['duplicate_matching'] ? 'checked="checked"': '' ?>/>
16
  <label for="manual_matching_<?php echo $entry; ?>"><?php _e('Manual Record Matching', 'pmxi_plugin' )?></label>
17
  <a href="#help" class="help" title="<?php _e('This allows you to match records by something other than Unique Key.', 'pmxi_plugin') ?>">?</a>
18
  <div class="switcher-target-manual_matching_<?php echo $entry; ?>" style="padding-left:17px;">
19
  <div class="input">
20
  <span style="vertical-align:middle"><?php _e('Match records based on...', 'pmxi_plugin') ?></span><br>
21
+ <input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
22
  <label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
23
+ <input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
24
  <label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
25
+ <input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>/>
26
  <label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
27
  <span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle; padding-left:17px;">
28
  <?php _e('Name', 'pmxi_plugin') ?>
29
+ <input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>" />
30
  <?php _e('Value', 'pmxi_plugin') ?>
31
  <input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>" />
32
  </span>
41
  </div>
42
  <div class="input">
43
  <input type="hidden" name="is_delete_missing" value="0" />
44
+ <input type="checkbox" id="is_delete_missing_<?php echo $entry; ?>" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> class="switcher"/>
45
  <label for="is_delete_missing_<?php echo $entry; ?>"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
46
+ <a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from the previous import operation which are not found among newly imported set.', 'pmxi_plugin') ?>">?</a>
47
  </div>
48
  <div class="switcher-target-is_delete_missing_<?php echo $entry; ?>" style="padding-left:17px;">
49
  <div class="input">
144
  <input type="checkbox" id="keep_custom_fields_<?php echo $entry; ?>" name="keep_custom_fields" value="1" <?php echo $post['keep_custom_fields'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed"/>
145
  <label for="keep_custom_fields_<?php echo $entry; ?>"><?php _e('Keep custom fields', 'pmxi_plugin') ?></label>
146
  <a href="#help" class="help" title="<?php _e('If Keep Custom Fields box is checked, it will keep all Custom Fields, and add any new Custom Fields specified in Custom Fields section, as long as they do not overwrite existing fields. If \'Only keep this Custom Fields\' is specified, it will only keep the specified fields.', 'pmxi_plugin') ?>">?</a>
147
+ <div class="keep_except" style="padding-left:17px; <?php if (!$post['keep_custom_fields'] ):?>display:none;<?php endif;?>" >
148
+ <div class="input">
149
+ <label for="keep_custom_fields_except"><?php _e('Keep all Custom Fields, except for the fields specified for update <small>(separate field names with commas)</small>', 'pmxi_plugin') ?></label>
150
+ <input type="text" id="keep_custom_fields_except" name="keep_custom_fields_except" style="width:100%;" value="<?php echo esc_attr($post['keep_custom_fields_except']) ?>" />
151
+ </div>
152
+ </div>
153
  </div>
154
  <div class="switcher-target-keep_custom_fields_<?php echo $entry; ?>" style="padding-left:17px;">
155
  <div class="input">
158
  </div>
159
  </div>
160
  </div>
161
+ </div>
162
  </fieldset>
163
  </td>
164
  </tr>
views/admin/import/options/_settings_template.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <td colspan="3" style="padding-top:20px;">
3
+ <fieldset class="optionsset">
4
+ <legend><?php _e('Import Settings','pmxi_plugin');?></legend>
5
+ <p>
6
+ <div class="input">
7
+ <label for="save_import_as"><?php _e('Friendly Name','pmxi_plugin');?></label> <input type="text" name="friendly_name" title="<?php _e('Save friendly name...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:11px; background:#fff !important;" value="<?php echo esc_attr($post['friendly_name']) ?>" />
8
+ </div>
9
+ </p>
10
+ <?php if ( ! empty(PMXI_Plugin::$session->data['pmxi_import']['large_file']) or (!empty($import) and $import->large_import == 'Yes')):?>
11
+ <p>
12
+ <div class="input">
13
+ <label for="records_per_request"><?php _e('Records Per Iteration', 'pmxi_plugin');?></label> <input type="text" name="records_per_request" style="vertical-align:middle; font-size:11px; background:#fff !important; width: 40px;" value="<?php echo esc_attr($post['records_per_request']) ?>" />
14
+ <a href="#help" class="help" title="<?php _e('Your feed was detected as a &quot;large&quot; file. The import process will be executed via AJAX requests. To make import process faster you can increase the number of records imported per iteration. Higher numbers put more strain on your server but make the import process take less time. 10 is a very safe number. To speed up the process, try 100 or more, especially if your import settings are simple and you are not downloading images.', 'pmxi_plugin') ?>">?</a>
15
+ </div>
16
+ </p>
17
+ <!--p>
18
+ <div class="input">
19
+ <input type="hidden" name="create_chunks" value="0" />
20
+ <input type="checkbox" id="create_chunks_<?php echo $entry; ?>" name="create_chunks" value="1" class="fix_checkbox" <?php echo $post['create_chunks'] ? 'checked="checked"': '' ?>/>
21
+ <label for="create_chunks_<?php echo $entry; ?>"><?php _e('create chunks', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Check this to split up the file into pieces before import. Will speed up the import of large files.', 'pmxi_plugin') ?>">?</a></label>
22
+ </div>
23
+ </p-->
24
+ <?php endif; ?>
25
+ <div class="input">
26
+ <input type="hidden" name="is_import_specified" value="0" />
27
+ <input type="checkbox" id="is_import_specified_<?php echo $entry; ?>" class="switcher fix_checkbox" name="is_import_specified" value="1" <?php echo $post['is_import_specified'] ? 'checked="checked"': '' ?>/>
28
+ <label for="is_import_specified_<?php echo $entry; ?>"><?php _e('Import only specified records', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter records or record ranges separated by commas, e.g. <b>1,5,7-10</b> would import the first, the fifth, and the seventh to tenth.', 'pmxi_plugin') ?>">?</a></label>
29
+ <span class="switcher-target-is_import_specified_<?php echo $entry; ?>" style="vertical-align:middle">
30
+ <div class="input" style="display:inline;">
31
+ <input type="text" name="import_specified" value="<?php echo esc_attr($post['import_specified']) ?>" style="width:50%;"/>
32
+ </div>
33
+ </span>
34
+ </div>
35
+ <p>
36
+ <div class="input">
37
+ <input type="checkbox" id="save_template_as_<?php echo $entry; ?>" name="save_template_as" class="fix_checkbox" value="1" <?php echo ( ! empty($post['save_template_as'])) ? 'checked="checked"' : '' ?>/> <label for="save_template_as_<?php echo $entry; ?>"><?php _e('Save template as:','pmxi_plugin');?></label> &nbsp;<input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo (!empty($post['name'])) ? esc_attr($post['name']) : ''; ?>" />
38
+ </div>
39
+ </p>
40
+ <?php if (in_array($source_type, array('ftp', 'file'))): ?>
41
+ <p>
42
+ <div class="input">
43
+ <input type="hidden" name="is_delete_source" value="0" />
44
+ <input type="checkbox" id="is_delete_source_<?php echo $entry; ?>" class="fix_checkbox" name="is_delete_source" value="1" <?php echo $post['is_delete_source'] ? 'checked="checked"': '' ?>/>
45
+ <label for="is_delete_source_<?php echo $entry; ?>"><?php _e('Delete source XML file after importing', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting takes effect only when script has access rights to perform the action, e.g. file is not deleted when pulled via HTTP or delete permission is not granted to the user that script is executed under.', 'pmxi_plugin') ?>">?</a></label>
46
+ </div>
47
+ </p>
48
+ <?php endif; ?>
49
+ <?php if (class_exists('PMLC_Plugin')): // option is only valid when `WP Wizard Cloak` pluign is enabled ?>
50
+ <p>
51
+ <div class="input">
52
+ <input type="hidden" name="is_cloak" value="0" />
53
+ <input type="checkbox" id="is_cloak_<?php echo $entry; ?>" class="fix_checkbox" name="is_cloak" value="1" <?php echo $post['is_cloak'] ? 'checked="checked"': '' ?>/>
54
+ <label for="is_cloak_<?php echo $entry; ?>"><?php _e('Auto-Cloak Links', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php printf(__('Automatically process all links present in body of created post or page with <b>%s</b> plugin', 'pmxi_plugin'), PMLC_Plugin::getInstance()->getName()) ?>">?</a></label>
55
+ </div>
56
+ </p>
57
+ <?php endif; ?>
58
+ </fieldset>
59
+ </td>
60
+ </tr>
views/admin/import/options/_taxonomies_template.php CHANGED
@@ -1,12 +1,15 @@
1
  <?php
2
- $post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array($post_type), 'object'), array_flip(array('category', 'post_tag', 'post_format', 'product_type')));
 
 
 
3
  if ( ! empty($post_taxonomies)): ?>
4
  <tr>
5
- <td colspan="3">
6
  <fieldset class="optionsset">
7
- <legend>Custom Taxonomies</legend>
8
- <?php foreach ($post_taxonomies as $ctx): ?>
9
- <table>
10
  <tr>
11
  <td>
12
  <div class="post_taxonomy">
@@ -24,8 +27,8 @@
24
  ?>
25
  <li id="item_<?php echo $i; ?>">
26
  <div class="drag-element">
27
- <input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
28
- <input type="text" class="widefat" value="<?php echo esc_attr($cat->xpath); ?>" />
29
  </div>
30
  <?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
31
  <?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, $i); ?>
@@ -35,16 +38,16 @@
35
  }; else:?>
36
  <li id="item_1">
37
  <div class="drag-element">
38
- <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
39
- <input type="text" class="widefat" value="" />
40
  </div>
41
  </li>
42
  <?php endif;
43
  else: ?>
44
  <li id="item_1">
45
  <div class="drag-element">
46
- <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
47
- <input type="text" class="widefat" value="" />
48
  </div>
49
  </li>
50
  <?php endif;?>
@@ -52,18 +55,18 @@
52
  <input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
53
  <div class="delim">
54
  <label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
55
- <input type="text" class="small tax_delim" value="<?php echo (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->delim) ? $taxonomies_hierarchy[0]->delim : ',' ?>" />
56
  <label for="nested_<?php echo $ctx->name;?>"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
57
- <input id="nested_<?php echo $ctx->name;?>" type="checkbox" class="taxonomy_auto_nested" <?php if (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->auto_nested):?>checked="checked"<?php endif; ?> />
58
  <a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>&gt;</code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
59
- <!--a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more','pmxi_plugin');?></a-->
60
  </div>
61
  </div>
62
  </div>
63
  </td>
64
  </tr>
65
  </table>
66
- <?php endforeach; ?>
67
  </fieldset>
68
  </td>
69
  </tr>
1
  <?php
2
+
3
+ $exclude_taxonomies = (class_exists('PMWI_Plugin')) ? array('category', 'post_tag', 'post_format', 'product_type') : array('category', 'post_format', 'post_tag');
4
+
5
+ $post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array($post_type), 'object'), array_flip($exclude_taxonomies));
6
  if ( ! empty($post_taxonomies)): ?>
7
  <tr>
8
+ <td colspan="3" style="padding-bottom:20px;">
9
  <fieldset class="optionsset">
10
+ <legend><?php _e('Custom Taxonomies','pmxi_plugin');?></legend>
11
+ <?php foreach ($post_taxonomies as $ctx): if ("" == $ctx->labels->name) continue;?>
12
+ <table style="width:100%;">
13
  <tr>
14
  <td>
15
  <div class="post_taxonomy">
27
  ?>
28
  <li id="item_<?php echo $i; ?>">
29
  <div class="drag-element">
30
+ <input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
31
+ <input type="text" class="widefat" value="<?php echo esc_attr($cat->xpath); ?>"/>
32
  </div>
33
  <?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
34
  <?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, $i); ?>
38
  }; else:?>
39
  <li id="item_1">
40
  <div class="drag-element">
41
+ <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
42
+ <input type="text" class="widefat" value=""/>
43
  </div>
44
  </li>
45
  <?php endif;
46
  else: ?>
47
  <li id="item_1">
48
  <div class="drag-element">
49
+ <input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
50
+ <input type="text" class="widefat" value=""/>
51
  </div>
52
  </li>
53
  <?php endif;?>
55
  <input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
56
  <div class="delim">
57
  <label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
58
+ <input type="text" class="small tax_delim" value="<?php echo (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->delim) ? str_replace("&amp;","&", htmlentities(htmlentities($taxonomies_hierarchy[0]->delim))) : ',' ?>" />
59
  <label for="nested_<?php echo $ctx->name;?>"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
60
+ <input id="nested_<?php echo $ctx->name;?>" type="checkbox" class="taxonomy_auto_nested" <?php if (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->auto_nested):?>checked="checked"<?php endif; ?>/>
61
  <a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>&gt;</code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
62
+ <a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more','pmxi_plugin');?></a>
63
  </div>
64
  </div>
65
  </div>
66
  </td>
67
  </tr>
68
  </table>
69
+ <?php endforeach; ?>
70
  </fieldset>
71
  </td>
72
  </tr>
views/admin/import/preview.php CHANGED
@@ -1,12 +1,12 @@
1
- <div id="post-preview">
2
- <?php if ($this->errors->get_error_codes()): ?>
3
- <?php $this->error() ?>
4
- <?php endif ?>
5
-
6
- <?php if (isset($title)): ?>
7
- <h2 class="title"><?php echo $title ?></h2>
8
- <?php endif ?>
9
- <?php if (isset($content)): ?>
10
- <div class="content"><?php echo apply_filters('the_content', $content) ?></div>
11
- <?php endif ?>
12
  </div>
1
+ <div id="post-preview">
2
+ <?php if ($this->errors->get_error_codes()): ?>
3
+ <?php $this->error() ?>
4
+ <?php endif ?>
5
+
6
+ <?php if (isset($title)): ?>
7
+ <h2 class="title"><?php echo $title ?></h2>
8
+ <?php endif ?>
9
+ <?php if (isset($content)): ?>
10
+ <div class="content"><?php echo apply_filters('the_content', $content) ?></div>
11
+ <?php endif ?>
12
  </div>
views/admin/import/tag.php CHANGED
@@ -1,21 +1,44 @@
1
- <?php if (!empty($elements->length)):?>
2
- <div class="tag">
3
- <input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
4
- <div class="title">
5
- <?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $elements->length : PMXI_Plugin::$session->data['pmxi_import']['count']); ?>
6
- <div class="navigation">
7
- <?php if ($tagno > 1): ?><a href="#prev">&lang;&lang;</a><?php else: ?><span>&lang;&lang;</span><?php endif ?>
8
- <?php if ($tagno < $elements->length or (PMXI_Plugin::$session->data['pmxi_import']['large_file'] and $tagno < PMXI_Plugin::$session->data['pmxi_import']['count'])): ?><a href="#next">&rang;&rang;</a><?php else: ?><span>&rang;&rang;</span><?php endif ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </div>
10
  </div>
11
- <div class="clear"></div>
12
- <div class="xml resetable"> <?php if (!empty($elements->length)) $this->render_xml_element(( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $elements->item($tagno - 1) : $elements->item(0), true); ?></div>
13
- <p class="xpath_help">
14
- <?php _e('Operate on elements using your own PHP functions, use FOREACH loops, and more.<br />Read the <a href="http://www.wpallimport.com/portal/" target="_blank">documentation</a> to learn how.', 'pmxi_plugin') ?>
15
- </p>
16
- </div>
17
- <?php else: ?>
18
- <div class="error inline below-h2" style="padding:10px; margin-top:45px;">
19
- <?php printf(__('History file not found.', 'pmxi_plugin')); ?>
20
- </div>
21
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
1
+ <div class="tag">
2
+ <div id="set_encoding">
3
+ <a href="javascript:void(0);" class="set_encoding"><?php _e('Set Character Encoding', 'pmxi_plugin');?></a>
4
+ <div id="select_encoding">
5
+ <label for="import_encoding"><?php _e('Current Character Encoding', 'pmxi_plugin');?></label>
6
+ <select id="import_encoding" name="import_encoding">
7
+ <?php $encoding_detected = false; foreach (PMXI_Plugin::$encodings as $key => $enc) :
8
+ ?>
9
+ <option value="<?php echo $enc; ?>" <?php if (PMXI_Plugin::$session->data['pmxi_import']['encoding'] == $enc): $encoding_detected = true; ?>selected="selected"<?php endif;?>><?php echo $enc; ?></option>
10
+ <?php
11
+ endforeach;
12
+ ?>
13
+ <?php if ( ! $encoding_detected ): ?>
14
+ <option value="<?php echo PMXI_Plugin::$session->data['pmxi_import']['encoding'];?>"><?php echo PMXI_Plugin::$session->data['pmxi_import']['encoding'];?></option>
15
+ <?php endif;?>
16
+ <option value="new"><?php _e('Enter new...', 'pmxi_plugin');?></option>
17
+ </select>
18
+ </div>
19
+ <div id="add_encoding">
20
+ <input id="new_encoding" value=""/>
21
+ <a href="javascript:void(0);" id="add_new_encoding"><?php _e('Add', 'pmxi_plugin');?></a>
22
+ <a href="javascript:void(0);" id="cancel_new_encoding"><?php _e('Cancel', 'pmxi_plugin');?></a>
23
  </div>
24
  </div>
25
+ <?php if (!empty($elements->length)):?>
26
+ <input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
27
+ <div class="title">
28
+ <?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, ( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $elements->length : PMXI_Plugin::$session->data['pmxi_import']['count']); ?>
29
+ <div class="navigation">
30
+ <?php if ($tagno > 1): ?><a href="#prev">&lang;&lang;</a><?php else: ?><span>&lang;&lang;</span><?php endif ?>
31
+ <?php if ($tagno < $elements->length or (PMXI_Plugin::$session->data['pmxi_import']['large_file'] and $tagno < PMXI_Plugin::$session->data['pmxi_import']['count'])): ?><a href="#next">&rang;&rang;</a><?php else: ?><span>&rang;&rang;</span><?php endif ?>
32
+ </div>
33
+ </div>
34
+ <div class="clear"></div>
35
+ <div class="xml resetable"> <?php if (!empty($elements->length)) $this->render_xml_element(( ! PMXI_Plugin::$session->data['pmxi_import']['large_file']) ? $elements->item($tagno - 1) : $elements->item(0), true); ?></div>
36
+ <p class="xpath_help">
37
+ <?php _e('Operate on elements using your own PHP functions, use FOREACH loops, and more.<br />Read the <a href="http://www.wpallimport.com/portal/" target="_blank">documentation</a> to learn how.', 'pmxi_plugin') ?>
38
+ </p>
39
+ <?php else: ?>
40
+ <div class="error inline below-h2" style="padding:10px; margin-top:45px;">
41
+ <?php printf(__('History file not found. Probably you are using wrong encoding.', 'pmxi_plugin')); ?>
42
+ </div>
43
+ <?php endif; ?>
44
+ </div>
views/admin/import/template.php CHANGED
@@ -16,18 +16,23 @@
16
  <table class="layout">
17
  <tr>
18
  <td class="left">
19
- <h3><?php _e('Post Title','pmxi_plugin');?></h3>
20
- <div style="width:100%">
21
- <input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" />
 
 
22
  </div>
23
 
24
- <h3>
25
  <?php _e('Post Content','pmxi_plugin');?>
26
  </h3>
27
- <div id="poststuff">
28
  <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
29
 
30
- <?php the_editor($post['content']) ?>
 
 
 
31
  <table id="post-status-info" cellspacing="0">
32
  <tbody>
33
  <tr>
@@ -40,30 +45,36 @@
40
  </table>
41
  </div>
42
  </div>
43
- <p>
44
- <?php $legacy_handling = PMXI_Plugin::getInstance()->getOption('legacy_special_character_handling'); ?>
45
- <span class="header-option">
46
- <input type="hidden" name="is_keep_linebreaks" value="0" />
47
- <input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
48
- <label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label> <br>
49
- <input type="hidden" name="is_leave_html" value="0" />
50
- <input type="checkbox" id="is_leave_html" name="is_leave_html" value="1" <?php echo $post['is_leave_html'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;" class="switcher"/>
51
- <label for="is_leave_html"><?php _e('Decode HTML entities with <b>'.(($legacy_handling) ? 'htmlspecialchars_decode' : 'html_entity_decode').'</b>', 'pmxi_plugin') ?></label><a class="help" href="#help" original-title="If HTML code is showing up in your posts, use this option. You can also use <br /><br /><i>[html_entity_decode({my/xpath})]</i><br /><br /> or <br /><br /><i>[htmlentities({my/xpath})]</i><br /><br /> to decode or encode HTML in your file.">?</a>
52
- <div class="switcher-target-is_leave_html" style="padding-left:17px;">
53
- <input type="hidden" name="fix_characters" value="0" />
54
- <input type="checkbox" id="fix_characters" name="fix_characters" value="1" <?php echo $post['fix_characters'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
55
- <label for="fix_characters"><?php _e('Auto-fix broken special characters', 'pmxi_plugin') ?></label>
56
- </div>
57
- </span>
58
- </p>
59
- <hr>
60
- <p style="clear:both;">
61
- <?php wp_nonce_field('template', '_wpnonce_template'); ?>
62
- <input type="hidden" name="is_submitted" value="1" />
63
- <div class="input">
64
- <input type="checkbox" id="save_template_as" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as"><?php _e('Save template as:','pmxi_plugin');?></label> &nbsp;<input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
65
- </div>
66
- </p>
 
 
 
 
 
 
67
 
68
  <?php $templates = new PMXI_Template_List() ?>
69
  <div class="load-template">
@@ -75,22 +86,24 @@
75
  <?php endforeach ?>
76
  </select>
77
  </div>
78
-
79
- <p>
80
- <span class="submit-buttons" style="float:right;">
81
- <?php if ($this->isWizard):?>
82
- <a href="<?php echo add_query_arg('action', 'element', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
83
- <?php else: ?>
84
- <a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
85
- <?php endif; ?>
86
- <a href="#preview" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button preview" title="<?php _e('Preview Post', 'pmxi_plugin') ?>"><?php _e('Preview', 'pmxi_plugin') ?></a>
87
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e( ($this->isWizard) ? 'Next' : 'Update', 'pmxi_plugin') ?>" />
88
- </span>
89
- </p>
90
  </td>
91
  <?php if ($this->isWizard or $this->isTemplateEdit): ?>
92
  <td class="right template-sidebar">
 
93
  <?php $this->tag() ?>
 
94
  </td>
95
  <?php endif ?>
96
  </tr>
16
  <table class="layout">
17
  <tr>
18
  <td class="left">
19
+
20
+ <div id="titlediv">
21
+ <div id="titlewrap">
22
+ <input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" placeholder="Enter title here"/>
23
+ </div>
24
  </div>
25
 
26
+ <h3 style="margin-bottom:0px;">
27
  <?php _e('Post Content','pmxi_plugin');?>
28
  </h3>
29
+ <div id="poststuff" style="margin-top:-25px;">
30
  <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
31
 
32
+ <?php wp_editor($post['content'], 'content', array(
33
+ 'dfw' => true,
34
+ 'editor_height' => 360));
35
+ ?>
36
  <table id="post-status-info" cellspacing="0">
37
  <tbody>
38
  <tr>
45
  </table>
46
  </div>
47
  </div>
48
+ <div class="input">
49
+ <p style="margin-bottom:0px;">
50
+ <span class="header-option">
51
+ <input type="hidden" name="is_keep_linebreaks" value="0" />
52
+ <input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> />
53
+ <label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label>
54
+ </span>
55
+ </p>
56
+ </div>
57
+ <div class="input">
58
+ <p style="margin-bottom:0px; margin-top:2px;">
59
+ <span class="header-option">
60
+ <input type="hidden" name="is_leave_html" value="0" />
61
+ <input type="checkbox" id="is_leave_html" name="is_leave_html" value="1" <?php echo $post['is_leave_html'] ? 'checked="checked"' : '' ?> style="position:relative;"/>
62
+ <label for="is_leave_html"><?php _e('Decode HTML entities with <b>html_entity_decode</b>', 'pmxi_plugin') ?></label>
63
+ <a class="help" href="#help" original-title="If HTML code is showing up in your posts, use this option. You can also use <br /><br /><i>[html_entity_decode({my/xpath})]</i><br /><br /> or <br /><br /><i>[htmlentities({my/xpath})]</i><br /><br /> to decode or encode HTML in your file.">?</a>
64
+ </span>
65
+ </p>
66
+ </div>
67
+
68
+ <?php wp_nonce_field('template', '_wpnonce_template'); ?>
69
+ <input type="hidden" name="is_submitted" value="1" />
70
+
71
+ <div class="input">
72
+ <p style="margin-top:0px;">
73
+ <input type="checkbox" id="save_template_as" name="save_template_as" value="1" <?php echo ( ! empty($post['save_template_as'])) ? 'checked="checked"' : '' ?> />
74
+ <label for="save_template_as"><?php _e('Save template as:','pmxi_plugin');?></label> &nbsp;
75
+ <input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
76
+ </p>
77
+ </div>
78
 
79
  <?php $templates = new PMXI_Template_List() ?>
80
  <div class="load-template">
86
  <?php endforeach ?>
87
  </select>
88
  </div>
89
+
90
+ <span class="submit-buttons" style="float:right; position:relative; top: -60px;">
91
+ <?php if ($this->isWizard):?>
92
+ <a href="<?php echo add_query_arg('action', 'element', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
93
+ <?php else: ?>
94
+ <a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
95
+ <?php endif; ?>
96
+ <!--a href="#preview" class="button button-primary button-hero large_button preview" title="<?php _e('Preview Post', 'pmxi_plugin') ?>"><?php _e('Preview', 'pmxi_plugin') ?></a-->
97
+ <input type="button" class="button button-primary button-hero large_button preview" value="<?php _e('Preview', 'pmxi_plugin') ?>" />
98
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e( ($this->isWizard) ? 'Next' : 'Update', 'pmxi_plugin') ?>" />
99
+ </span>
100
+
101
  </td>
102
  <?php if ($this->isWizard or $this->isTemplateEdit): ?>
103
  <td class="right template-sidebar">
104
+ <div style="position:relative;">
105
  <?php $this->tag() ?>
106
+ </div>
107
  </td>
108
  <?php endif ?>
109
  </tr>
views/admin/manage/bulk.php CHANGED
@@ -1,18 +1,18 @@
1
- <h2>Bulk Delete Imports</h2>
2
-
3
- <form method="post">
4
- <input type="hidden" name="action" value="bulk" />
5
- <input type="hidden" name="bulk-action" value="<?php echo esc_attr($action) ?>" />
6
- <?php foreach ($ids as $id): ?>
7
- <input type="hidden" name="items[]" value="<?php echo esc_attr($id) ?>" />
8
- <?php endforeach ?>
9
-
10
- <p><?php printf(__('Are you sure you want to delete <strong>%s</strong> selected %s?', 'pmxi_plugin'), $items->count(), _n('import', 'imports', $items->count(), 'pmxi_plugin')) ?></p>
11
- <p><input type="checkbox" id="is_delete_posts" name="is_delete_posts" /> <label for="is_delete_posts">Delete associated posts as well</label></p>
12
-
13
- <p class="submit">
14
- <?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
15
- <input type="hidden" name="is_confirmed" value="1" />
16
- <input type="submit" class="button-primary" value="Delete" />
17
- </p>
18
  </form>
1
+ <h2>Bulk Delete Imports</h2>
2
+
3
+ <form method="post">
4
+ <input type="hidden" name="action" value="bulk" />
5
+ <input type="hidden" name="bulk-action" value="<?php echo esc_attr($action) ?>" />
6
+ <?php foreach ($ids as $id): ?>
7
+ <input type="hidden" name="items[]" value="<?php echo esc_attr($id) ?>" />
8
+ <?php endforeach ?>
9
+
10
+ <p><?php printf(__('Are you sure you want to delete <strong>%s</strong> selected %s?', 'pmxi_plugin'), $items->count(), _n('import', 'imports', $items->count(), 'pmxi_plugin')) ?></p>
11
+ <p><input type="checkbox" id="is_delete_posts" name="is_delete_posts" /> <label for="is_delete_posts">Delete associated posts as well</label></p>
12
+
13
+ <p class="submit">
14
+ <?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
15
+ <input type="hidden" name="is_confirmed" value="1" />
16
+ <input type="submit" class="button-primary" value="Delete" />
17
+ </p>
18
  </form>
views/admin/manage/delete.php CHANGED
@@ -1,14 +1,14 @@
1
- <h2><?php _e('Delete Import', 'pmxi_plugin') ?></h2>
2
-
3
- <form method="post">
4
- <p><?php printf(__('Are you sure you want to delete <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
5
- <div class="input">
6
- <input type="checkbox" id="is_delete_posts" name="is_delete_posts" /> <label for="is_delete_posts">Delete associated posts as well</label>
7
- </div>
8
- <p class="submit">
9
- <?php wp_nonce_field('delete-import', '_wpnonce_delete-import') ?>
10
- <input type="hidden" name="is_confirmed" value="1" />
11
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="Delete" />
12
- </p>
13
-
14
  </form>
1
+ <h2><?php _e('Delete Import', 'pmxi_plugin') ?></h2>
2
+
3
+ <form method="post">
4
+ <p><?php printf(__('Are you sure you want to delete <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
5
+ <div class="input">
6
+ <input type="checkbox" id="is_delete_posts" name="is_delete_posts" /> <label for="is_delete_posts">Delete associated posts as well</label>
7
+ </div>
8
+ <p class="submit">
9
+ <?php wp_nonce_field('delete-import', '_wpnonce_delete-import') ?>
10
+ <input type="hidden" name="is_confirmed" value="1" />
11
+ <input type="submit" class="button-primary" value="Delete" />
12
+ </p>
13
+
14
  </form>
views/admin/manage/index.php CHANGED
@@ -1,7 +1,7 @@
1
  <h2>
2
  <?php _e('Manage Imports', 'pmxi_plugin') ?>
3
  &nbsp;
4
- <a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" style="font-size:15px; padding:10px 20px; text-decoration:none;"><?php echo esc_html_x('New Import', 'pmxi_plugin'); ?></a>
5
  </h2>
6
 
7
  <?php
@@ -170,11 +170,11 @@ $columns = array(
170
 
171
  <span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'edit'), $this->baseUrl)) ?>"><?php _e('Edit Template', 'pmxi_plugin') ?></a></span> |
172
  <span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'options'), $this->baseUrl)) ?>"><?php _e('Edit Options', 'pmxi_plugin') ?></a></span> |
173
- <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update'), $this->baseUrl)) ?>"><?php _e('Update', 'pmxi_plugin') ?></a></span> |
174
- <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import', 'id' => $item['id']), admin_url('admin.php'))) ?>"><?php _e('Use New File', 'pmxi_plugin') ?></a></span> |
175
  <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'log'), $this->baseUrl)) ?>"><?php _e('Download Log', 'pmxi_plugin') ?></a></span> |
176
  <span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
177
- <?php if ( "Yes" == $item['large_import'] and $item['imported'] != $item['count']):?>
178
  | <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update', 'type' => 'continue'), $this->baseUrl)) ?>"><?php _e('Continue import', 'pmxi_plugin') ?></a></span>
179
  <?php endif; ?>
180
  </div>
@@ -241,9 +241,6 @@ $columns = array(
241
  }
242
  ?>
243
 
244
-
245
-
246
- <p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=manage&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Find out more about the professional edition of WP All Import.</a></p>
247
-
248
 
249
  </form>
1
  <h2>
2
  <?php _e('Manage Imports', 'pmxi_plugin') ?>
3
  &nbsp;
4
+ <a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="add-new-h2"><?php echo esc_html_x('New Import', 'pmxi_plugin'); ?></a>
5
  </h2>
6
 
7
  <?php
170
 
171
  <span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'edit'), $this->baseUrl)) ?>"><?php _e('Edit Template', 'pmxi_plugin') ?></a></span> |
172
  <span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'options'), $this->baseUrl)) ?>"><?php _e('Edit Options', 'pmxi_plugin') ?></a></span> |
173
+ <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update'), $this->baseUrl)) ?>"><?php _e('Re-Run Import', 'pmxi_plugin') ?></a></span> |
174
+ <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import', 'id' => $item['id']), admin_url('admin.php'))) ?>"><?php _e('Re-Run With New File', 'pmxi_plugin') ?></a></span> |
175
  <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'log'), $this->baseUrl)) ?>"><?php _e('Download Log', 'pmxi_plugin') ?></a></span> |
176
  <span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
177
+ <?php if ( "Yes" == $item['large_import'] and (($item['imported'] + $item['skipped']) != $item['count'] and ! $item['options']['is_import_specified']) ):?>
178
  | <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update', 'type' => 'continue'), $this->baseUrl)) ?>"><?php _e('Continue import', 'pmxi_plugin') ?></a></span>
179
  <?php endif; ?>
180
  </div>
241
  }
242
  ?>
243
 
244
+ <p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=manage&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Find out more about the professional edition of WP All Import.</a></p>
 
 
 
245
 
246
  </form>
views/admin/manage/update.php CHANGED
@@ -1,23 +1,23 @@
1
- <h2><?php _e('Update Import', 'pmxi_plugin') ?></h2>
2
-
3
- <?php if ($this->errors->get_error_codes()): ?>
4
- <?php $this->error() ?>
5
- <?php endif ?>
6
-
7
- <?php if ($item->path): ?>
8
- <form method="post">
9
- <p><?php printf(__('Are you sure you want to update <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
10
- <p><?php printf(__('Source path is <strong>%s</strong>', 'pmxi_plugin'), $item->path) ?></p>
11
-
12
- <p class="submit">
13
- <?php wp_nonce_field('update-import', '_wpnonce_update-import') ?>
14
- <input type="hidden" name="is_confirmed" value="1" />
15
- <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only ajax-update" value="Create Posts" />
16
- </p>
17
-
18
- </form>
19
- <?php else: ?>
20
- <div class="error">
21
- <p><?php _e('Update feature is not available for this import since it has no external path linked.') ?></p>
22
- </div>
23
  <?php endif ?>
1
+ <h2><?php _e('Update Import', 'pmxi_plugin') ?></h2>
2
+
3
+ <?php if ($this->errors->get_error_codes()): ?>
4
+ <?php $this->error() ?>
5
+ <?php endif ?>
6
+
7
+ <?php if ($item->path): ?>
8
+ <form method="post">
9
+ <p><?php printf(__('Are you sure you want to update <strong>%s</strong> import?', 'pmxi_plugin'), $item->name) ?></p>
10
+ <p><?php printf(__('Source path is <strong>%s</strong>', 'pmxi_plugin'), $item->path) ?></p>
11
+
12
+ <p class="submit">
13
+ <?php wp_nonce_field('update-import', '_wpnonce_update-import') ?>
14
+ <input type="hidden" name="is_confirmed" value="1" />
15
+ <input type="submit" class="button-primary ajax-update" value="Create Posts" />
16
+ </p>
17
+
18
+ </form>
19
+ <?php else: ?>
20
+ <div class="error">
21
+ <p><?php _e('Update feature is not available for this import since it has no external path linked.') ?></p>
22
+ </div>
23
  <?php endif ?>
views/admin/settings/index.php CHANGED
@@ -1,30 +1,36 @@
1
- <form class="settings" method="post" action="<?php echo $this->baseUrl ?>">
2
 
3
  <h2><?php _e('WP All Import Settings', 'pmxi_plugin') ?></h2>
4
  <hr />
5
  <?php if ($this->errors->get_error_codes()): ?>
6
  <?php $this->error() ?>
7
  <?php endif ?>
8
-
9
  <h3><?php _e('Saved Templates', 'pmxi_plugin') ?></h3>
10
  <?php $templates = new PMXI_Template_List(); $templates->getBy()->convertRecords() ?>
11
  <?php if ($templates->total()): ?>
12
  <table>
13
  <?php foreach ($templates as $t): ?>
14
  <tr>
15
- <td><input id="template-<?php echo $t->id ?>" type="checkbox" name="templates[]" value="<?php echo $t->id ?>" /></td>
16
- <td><label for="template-<?php echo $t->id ?>"><?php echo $t->name ?></label></td>
 
17
  </tr>
18
  <?php endforeach ?>
19
  </table>
20
  <p class="submit-buttons">
21
- <?php wp_nonce_field('delete-templates', '_wpnonce_delete-templates') ?>
22
- <input type="hidden" name="is_templates_submitted" value="1" />
23
- <input type="submit" class="button-primary" value="<?php _e('Delete Selected', 'pmxi_plugin') ?>" />
24
- </p>
25
  <?php else: ?>
26
  <em><?php _e('There are no templates saved', 'pmxi_plugin') ?></em>
27
  <?php endif ?>
 
 
 
 
 
28
  </form>
29
  <br />
30
 
@@ -40,34 +46,42 @@
40
 
41
  <h3><?php _e('Recurring & Scheduled Imports', 'pmxi_plugin') ?></h3>
42
 
 
43
 
44
- <hr />
45
-
46
- <h3>Please upgrade to the professional edition of WP All Import to perform recurring and scheduled imports.</h3>
47
 
48
- <p>WP All Import can periodically check your XML/CSV for updates on the schedule you define, and overwrite your existing import with new data. New posts will be made for new entries in the XML/CSV. Entries that haven't changed will be left alone. WP All Import can even delete "expired" posts (if their data is no longer in the updated XML/CSV).</p>
49
 
50
- <p>You can configure recurring imports from within WP All Import, or by setting up a cron job in your web hosting control panel.</p>
51
 
52
- <p>WP All Import can perform recurring imports with a file online at an http:// URL, or a file on an FTP server.</p>
53
 
54
- <p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=recurring&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
55
-
56
- <hr />
57
 
 
58
 
59
  <h3><?php _e('Import Settings', 'pmxi_plugin') ?></h3>
60
  <div><?php printf(__('Chunk maximum size %s (Kb)', 'pmxi_plugin'), '<input type="text" name="chunk_size" value="' . esc_attr($post['chunk_size']) . '"/>') ?></div>
61
  <p>
62
  <input type="hidden" name="legacy_special_character_handling" value="0"/>
63
- <?php printf(__('<label for="legacy_special_character_handling">Use legacy special character handling</label> %s', 'pmxi_plugin'), '<input type="checkbox" name="legacy_special_character_handling" id="legacy_special_character_handling" value="1" style="position:relative; top:-2px;" '. (($post['legacy_special_character_handling']) ? 'checked="checked"' : '') .'/>') ?>
64
- <a href="#help" class="help" title="<?php _e('By default wpallimport uses htmlspecialchars() to encode html tags in csv feeds. If this option is enabled that wpallimport will use htmlentities() function.', 'pmxi_plugin') ?>">?</a>
 
 
 
 
 
65
  </p>
66
  <p>
67
  <input type="hidden" name="pingbacks" value="0"/>
68
- <?php printf(__('Enable WP_IMPORTING %s', 'pmxi_plugin'), '<input type="checkbox" name="pingbacks" value="1" style="position:relative; top:-2px;" '. (($post['pingbacks']) ? 'checked="checked"' : '') .'/>') ?>
69
  <a href="#help" class="help" title="<?php _e('Avoid triggering pingback.', 'pmxi_plugin') ?>">?</a>
70
  </p>
 
 
 
 
 
71
  <p class="submit-buttons">
72
  <?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
73
  <input type="hidden" name="is_settings_submitted" value="1" />
1
+ <form class="settings" method="post" action="<?php echo $this->baseUrl ?>" enctype="multipart/form-data">
2
 
3
  <h2><?php _e('WP All Import Settings', 'pmxi_plugin') ?></h2>
4
  <hr />
5
  <?php if ($this->errors->get_error_codes()): ?>
6
  <?php $this->error() ?>
7
  <?php endif ?>
8
+
9
  <h3><?php _e('Saved Templates', 'pmxi_plugin') ?></h3>
10
  <?php $templates = new PMXI_Template_List(); $templates->getBy()->convertRecords() ?>
11
  <?php if ($templates->total()): ?>
12
  <table>
13
  <?php foreach ($templates as $t): ?>
14
  <tr>
15
+ <td>
16
+ <label class="selectit" for="template-<?php echo $t->id ?>"><input id="template-<?php echo $t->id ?>" type="checkbox" name="templates[]" value="<?php echo $t->id ?>" /> <?php echo $t->name ?></label>
17
+ </td>
18
  </tr>
19
  <?php endforeach ?>
20
  </table>
21
  <p class="submit-buttons">
22
+ <?php wp_nonce_field('delete-templates', '_wpnonce_delete-templates') ?>
23
+ <input type="submit" class="button-primary" name="delete_templates" value="<?php _e('Delete Selected', 'pmxi_plugin') ?>" />
24
+ <input type="submit" class="button-primary" name="export_templates" value="<?php _e('Export Selected', 'pmxi_plugin') ?>" />
25
+ </p>
26
  <?php else: ?>
27
  <em><?php _e('There are no templates saved', 'pmxi_plugin') ?></em>
28
  <?php endif ?>
29
+ <p>
30
+ <input type="hidden" name="is_templates_submitted" value="1" />
31
+ <input type="file" name="template_file"/>
32
+ <input type="submit" class="button-primary" name="import_templates" value="<?php _e('Import Templates', 'pmxi_plugin') ?>" />
33
+ </p>
34
  </form>
35
  <br />
36
 
46
 
47
  <h3><?php _e('Recurring & Scheduled Imports', 'pmxi_plugin') ?></h3>
48
 
49
+ <hr />
50
 
51
+ <h3>Please upgrade to the professional edition of WP All Import to perform recurring and scheduled imports.</h3>
 
 
52
 
53
+ <p>WP All Import can periodically check your XML/CSV for updates on the schedule you define, and overwrite your existing import with new data. New posts will be made for new entries in the XML/CSV. Entries that haven't changed will be left alone. WP All Import can even delete "expired" posts (if their data is no longer in the updated XML/CSV).</p>
54
 
55
+ <p>You can configure recurring imports from within WP All Import, or by setting up a cron job in your web hosting control panel.</p>
56
 
57
+ <p>WP All Import can perform recurring imports with a file online at an http:// URL, or a file on an FTP server.</p>
58
 
59
+ <p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=recurring&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
 
 
60
 
61
+ <hr />
62
 
63
  <h3><?php _e('Import Settings', 'pmxi_plugin') ?></h3>
64
  <div><?php printf(__('Chunk maximum size %s (Kb)', 'pmxi_plugin'), '<input type="text" name="chunk_size" value="' . esc_attr($post['chunk_size']) . '"/>') ?></div>
65
  <p>
66
  <input type="hidden" name="legacy_special_character_handling" value="0"/>
67
+ <?php printf(__('%s <label for="legacy_special_character_handling">My CSV files contain HTML code</label>', 'pmxi_plugin'), '<input type="checkbox" name="legacy_special_character_handling" id="legacy_special_character_handling" value="1" style="position:relative; top:-2px;" '. (($post['legacy_special_character_handling']) ? 'checked="checked"' : '') .'/>') ?>
68
+ <a href="#help" class="help" title="<?php _e('By default wpallimport do not encode html tags in csv feeds. If this option is enabled that wpallimport will use htmlspecialchars() function.', 'pmxi_plugin') ?>">?</a>
69
+ </p>
70
+ <p>
71
+ <input type="hidden" name="case_sensitive" value="0"/>
72
+ <?php printf(__('%s <label for="case_sensitive">Enable case-sensitivity mode</label>', 'pmxi_plugin'), '<input type="checkbox" name="case_sensitive" id="case_sensitive" value="1" style="position:relative; top:-2px;" '. (($post['case_sensitive']) ? 'checked="checked"' : '') .'/>') ?>
73
+ <a href="#help" class="help" title="<?php _e('', 'pmxi_plugin') ?>">?</a>
74
  </p>
75
  <p>
76
  <input type="hidden" name="pingbacks" value="0"/>
77
+ <?php printf(__('%s <label for="pingbacks">Enable WP_IMPORTING</label>', 'pmxi_plugin'), '<input type="checkbox" name="pingbacks" id="pingbacks" value="1" style="position:relative; top:-2px;" '. (($post['pingbacks']) ? 'checked="checked"' : '') .'/>') ?>
78
  <a href="#help" class="help" title="<?php _e('Avoid triggering pingback.', 'pmxi_plugin') ?>">?</a>
79
  </p>
80
+ <p>
81
+ <?php printf(__('%s <label for="session_mode_default">Session Mode (default)</label>', 'pmxi_plugin'), '<input type="radio" name="session_mode" id="session_mode_default" value="default" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'default') ? 'checked="checked"' : '') .'/>') ?> <br>
82
+ <?php printf(__('%s <label for="session_mode_files">Session Mode (files)</label>', 'pmxi_plugin'), '<input type="radio" name="session_mode" id="session_mode_files" value="files" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'files') ? 'checked="checked"' : '') .'/>') ?> <br>
83
+ <?php printf(__('%s <label for="session_mode_database">Session Mode (database)</label>', 'pmxi_plugin'), '<input type="radio" name="session_mode" id="session_mode_database" value="database" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'database') ? 'checked="checked"' : '') .'/>') ?>
84
+ </p>
85
  <p class="submit-buttons">
86
  <?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
87
  <input type="hidden" name="is_settings_submitted" value="1" />
views/controller/error.php CHANGED
@@ -1,3 +1,3 @@
1
- <?php foreach ($errors as $msg): ?>
2
- <div class="error"><p><?php echo $msg ?></p></div>
3
  <?php endforeach ?>
1
+ <?php foreach ($errors as $msg): ?>
2
+ <div class="error"><p><?php echo $msg ?></p></div>
3
  <?php endforeach ?>