PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.7.31.4
Pods – Custom Content Types and Fields v2.7.31.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / classes / PodsMigrate.php
pods / classes Last commit date
cli 2 days ago fields 2 days ago widgets 2 days ago Pods.php 2 days ago PodsAPI.php 2 days ago PodsAdmin.php 2 days ago PodsArray.php 2 days ago PodsComponent.php 2 days ago PodsComponents.php 2 days ago PodsData.php 2 days ago PodsField.php 2 days ago PodsForm.php 2 days ago PodsI18n.php 2 days ago PodsInit.php 2 days ago PodsMeta.php 2 days ago PodsMigrate.php 2 days ago PodsRESTFields.php 2 days ago PodsRESTHandlers.php 2 days ago PodsTermSplitting.php 2 days ago PodsUI.php 2 days ago PodsView.php 2 days ago
PodsMigrate.php
1355 lines
1 <?php
2
3 /**
4 * @package Pods
5 */
6 class PodsMigrate {
7
8 /**
9 * @var null|string
10 */
11 public $type = 'php';
12
13 /**
14 * @var array
15 */
16 public $types = array( 'php', 'json', 'sv', 'xml' );
17
18 /**
19 * @var array
20 */
21 public $mimes = array(
22 'json' => 'application/json',
23 'csv' => 'text/csv',
24 'tsv' => 'text/tsv',
25 'xml' => 'text/xml',
26 );
27
28 /**
29 * @var null|string
30 */
31 public $delimiter = ',';
32
33 /**
34 * @var null
35 */
36 public $data = array(
37 'items' => array(),
38 'columns' => array(),
39 'fields' => array(),
40 'single' => false,
41 );
42
43 /**
44 * @var null
45 */
46 public $input;
47
48 /**
49 * @var
50 */
51 public $parsed;
52
53 /**
54 * @var
55 */
56 public $built;
57
58 /**
59 * Migrate Data to and from Pods
60 *
61 * @param string $type Export Type (php, json, sv, xml)
62 * @param string $delimiter Delimiter for export type 'sv'
63 * @param array $data Array of data settings
64 *
65 * @return \PodsMigrate
66 *
67 * @license http://www.gnu.org/licenses/gpl-2.0.html
68 * @since 2.0.0
69 */
70 public function __construct( $type = null, $delimiter = null, $data = null ) {
71
72 if ( ! empty( $type ) ) {
73 if ( 'csv' === $type ) {
74 $type = 'sv';
75
76 if ( null === $delimiter ) {
77 $delimiter = ',';
78 }
79 } elseif ( 'tsv' === $type ) {
80 $type = 'sv';
81
82 if ( null === $delimiter ) {
83 $delimiter = "\t";
84 }
85 }
86
87 if ( in_array( $type, $this->types, true ) ) {
88 $this->type = $type;
89 }
90 }
91
92 if ( ! empty( $delimiter ) ) {
93 $this->delimiter = $delimiter;
94 }
95
96 if ( ! empty( $data ) ) {
97 $this->set_data( $data );
98 }
99 }
100
101 /**
102 * @param $data
103 */
104 public function set_data( $data ) {
105
106 $defaults = array(
107 'items' => array(),
108 'columns' => array(),
109 'fields' => array(),
110 );
111
112 $this->data = array_merge( $defaults, (array) $data );
113 }
114
115 /**
116 * Get items.
117 *
118 * @since 2.7.17
119 *
120 * @return array List of data items.
121 */
122 private function get_items() {
123
124 return empty( $this->data['single'] ) ?
125 $this->data['items'] :
126 array( $this->data['items'] );
127
128 }
129
130 /**
131 * Importing / Parsing / Validating Code
132 *
133 * @param array $data Array of data
134 * @param string $type Export Type (php, json, sv, xml)
135 * @param string $delimiter Delimiter for export type 'sv'
136 *
137 * @return bool
138 */
139 public function import( $data = null, $type = null, $delimiter = null ) {
140
141 $this->parse( $data, $type, $delimiter );
142
143 return $this->import_pod_items();
144
145 }
146
147 /**
148 * @param array $data Array of data
149 * @param string $type Export Type (php, json, sv, xml)
150 *
151 * @return bool
152 */
153 public function import_pod_items( $data = null, $type = null ) {
154
155 if ( ! empty( $data ) ) {
156 $this->input = $data;
157 }
158
159 if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) {
160 $this->type = $type;
161 }
162
163 return false;
164 }
165
166 /**
167 * @param array $data Array of data
168 * @param string $type Parse Type (php, json, sv, xml)
169 * @param string $delimiter Delimiter for export type 'sv'
170 *
171 * @return null
172 */
173 public function parse( $data = null, $type = null, $delimiter = null ) {
174
175 if ( ! empty( $data ) ) {
176 $this->input = $data;
177 }
178
179 if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) {
180 $this->type = $type;
181 }
182
183 if ( !empty( $delimiter ) )
184 $this->delimiter = $delimiter;
185
186 if ( method_exists( $this, "parse_{$this->type}" ) ) {
187 return call_user_func( array( $this, 'parse_' . $this->type ) );
188 }
189
190 return $this->parsed;
191 }
192
193 /**
194 * @param array $data Array of data
195 *
196 * @return bool
197 */
198 public function parse_json( $data = null ) {
199
200 if ( ! empty( $data ) ) {
201 $this->input = $data;
202 }
203
204 $items = @json_decode( $this->input, true );
205
206 if ( ! is_array( $items ) ) {
207 return false;
208 }
209
210 // Only export to a basic object if building for a single item.
211 if ( ! empty( $this->data['single'] ) ) {
212 $data = $items;
213 } else {
214 $data = array(
215 'columns' => array(),
216 'items' => array(),
217 'fields' => array(),
218 );
219
220 foreach ( $items as $key => $item ) {
221 if ( ! is_array( $item ) ) {
222 continue;
223 }
224
225 foreach ( $item as $column => $value ) {
226 if ( ! in_array( $column, $data['columns'], true ) ) {
227 $data['columns'][] = $column;
228 }
229 }
230
231 $data['items'][ $key ] = $item;
232 }
233 }
234
235 $this->parsed = $data;
236
237 return $this->parsed;
238 }
239
240 /**
241 * @param array $data Array of data
242 * @param string $delimiter Delimiter for export type 'sv'
243 *
244 * @return bool
245 */
246 public function parse_sv( $data = null, $delimiter = null ) {
247
248 if ( ! empty( $data ) ) {
249 $this->input = $data;
250 }
251
252 if ( ! empty( $delimiter ) ) {
253 $this->delimiter = $delimiter;
254 }
255
256 $rows = $this->str_getcsv( $this->input, '\n' );
257
258 if ( empty( $rows ) || 2 > count( $rows ) ) {
259 return false;
260 }
261
262 $data = array(
263 'columns' => array(),
264 'items' => array(),
265 );
266
267 foreach ( $rows as $key => $row ) {
268 if ( 0 === $key ) {
269 $data['columns'] = $this->str_getcsv( $row, $this->delimiter );
270 } else {
271 $row = $this->str_getcsv( $row, $this->delimiter );
272
273 $data['items'][ $key ] = array();
274
275 foreach ( $data['columns'] as $ckey => $column ) {
276 $data['items'][ $key ][ $column ] = ( isset( $row[ $ckey ] ) ? $row[ $ckey ] : '' );
277
278 if ( 'NULL' === $data['items'][ $key ][ $column ] ) {
279 $data['items'][ $key ][ $column ] = null;
280 }
281 }
282 }
283 }
284
285 $this->parsed = $data;
286
287 return $this->parsed;
288 }
289
290 /**
291 * Handle str_getcsv for cases where it's not set
292 *
293 * @param $line
294 * @param string $delimiter
295 * @param string $enclosure
296 * @param string $escape
297 *
298 * @return array|mixed
299 */
300 public function str_getcsv( $line, $delimiter = ',', $enclosure = '"', $escape = '\\' ) {
301
302 $line = str_replace( "\r\n", "\n", $line );
303 $line = str_replace( "\r", "\n", $line );
304
305 if ( '\n' !== $delimiter && function_exists( 'str_getcsv' ) ) {
306 return str_getcsv( $line, $delimiter, $enclosure, $escape );
307 }
308
309 $delimiter = str_replace( '/', '\/', $delimiter );
310 $enclosure = preg_quote( $enclosure, '/' );
311
312 $split = "/{$delimiter}(?=(?:[^{$enclosure}]*{$enclosure}[^{$enclosure}]*{$enclosure})*(?![^{$enclosure}]*{$enclosure}))/";
313
314 $data = preg_split( $split, trim( $line ), - 1, PREG_SPLIT_NO_EMPTY );
315
316 if ( '\n' !== $delimiter ) {
317 $data = preg_replace( "/^{$enclosure}(.*){$enclosure}$/s", '$1', $data );
318 }
319
320 return $data;
321 }
322
323 /**
324 * @param array $data Array of data
325 *
326 * @return bool
327 */
328 public function parse_xml( $data = null ) {
329
330 if ( ! empty( $data ) ) {
331 $this->input = $data;
332 }
333
334 $xml = new SimpleXMLElement( $this->input );
335
336 if ( ! isset( $xml->items ) ) {
337 return false;
338 }
339
340 $data = array(
341 'columns' => array(),
342 'items' => array(),
343 );
344
345 /**
346 * @var $child SimpleXMLElement
347 * @var $item_child SimpleXMLElement
348 * @var $data_child SimpleXMLElement
349 */
350
351 if ( isset( $xml->columns ) ) {
352 foreach ( $xml->columns->children() as $child ) {
353 $sub = $child->getName();
354
355 if ( empty( $sub ) || 'column' !== $sub ) {
356 continue;
357 }
358
359 if ( isset( $child->name ) ) {
360 if ( is_array( $child->name ) ) {
361 $column = $child->name[0];
362 } else {
363 $column = $child->name;
364 }
365
366 $data['columns'][] = $column;
367 }
368 }
369 }
370
371 foreach ( $xml->items->children() as $child ) {
372 $sub = $child->getName();
373
374 if ( empty( $sub ) || 'item' !== $sub ) {
375 continue;
376 }
377
378 $item = array();
379
380 $attributes = $child->attributes();
381
382 if ( ! empty( $attributes ) ) {
383 foreach ( $attributes as $column => $value ) {
384 if ( ! in_array( $column, $data['columns'], true ) ) {
385 $data['columns'][] = $column;
386 }
387
388 $item[ $column ] = $value;
389 }
390 }
391
392 $item_child = $child->children();
393
394 if ( ! empty( $item_child ) ) {
395 foreach ( $item_child->children() as $data_child ) {
396 $column = $data_child->getName();
397
398 if ( ! in_array( $column, $data['columns'], true ) ) {
399 $data['columns'][] = $column;
400 }
401
402 $item[ $column ] = $item_child->$column;
403 }
404 }
405
406 if ( ! empty( $item ) ) {
407 $data['items'][] = $item;
408 }
409 }//end foreach
410
411 $this->parsed = $data;
412
413 return $this->parsed;
414 }
415
416 /**
417 * @param array $data Array of data
418 *
419 * @return mixed
420 *
421 * @todo For much much later
422 */
423 public function parse_sql( $data = null ) {
424
425 if ( ! empty( $data ) ) {
426 $this->input = $data;
427 }
428
429 $this->parsed = $data;
430
431 return $this->parsed;
432 }
433
434 /**
435 * Exporting / Building Code
436 *
437 * @param array $data Array of data
438 * @param string $type Export Type (php, json, sv, xml)
439 * @param string $delimiter Delimiter for export type 'sv'
440 *
441 * @return mixed
442 */
443 public function export( $data = null, $type = null, $delimiter = null ) {
444
445 if ( ! empty( $data ) ) {
446 $this->set_data( $data );
447 }
448
449 if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) {
450 $this->type = $type;
451 }
452
453 if ( ! empty( $delimiter ) ) {
454 $this->delimiter = $delimiter;
455 }
456
457 if ( method_exists( $this, "build_{$this->type}" ) ) {
458 call_user_func( array( $this, 'build_' . $this->type ) );
459 }
460
461 return $this->built;
462 }
463
464 /**
465 * @param array $data Array of data
466 */
467 public function export_pod_items( $data = null ) {
468
469 if ( ! empty( $data ) ) {
470 $this->set_data( $data );
471 }
472 }
473
474 /**
475 * @param array $data Array of data
476 * @param string $type Export Type (php, json, sv, xml)
477 *
478 * @return null
479 */
480 public function build( $data = null, $type = null ) {
481
482 if ( ! empty( $data ) ) {
483 $this->set_data( $data );
484 }
485
486 if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) {
487 $this->type = $type;
488 }
489
490 if ( method_exists( $this, "build_{$this->type}" ) ) {
491 call_user_func( array( $this, 'build_' . $this->type ) );
492 }
493
494 return $this->data;
495 }
496
497 /**
498 * @param array $data Array of data
499 *
500 * @return bool
501 */
502 public function build_json( $data = null ) {
503
504 if ( ! empty( $data ) ) {
505 $this->set_data( $data );
506 }
507
508 if ( empty( $this->data ) || ! is_array( $this->data ) ) {
509 return false;
510 }
511
512 // Only export to a basic object if building for a single item.
513 if ( ! empty( $this->data['single'] ) ) {
514 $data = $this->data['items'];
515 } else {
516 $data = array(
517 'items' => array(
518 'count' => count( $this->data['items'] ),
519 'item' => array(),
520 ),
521 );
522
523 foreach ( $this->data['items'] as $item ) {
524 $row = array();
525
526 foreach ( $this->data['columns'] as $column => $label ) {
527 if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) {
528 $column = $label;
529 }
530
531 $value = '';
532
533 if ( is_object( $item ) ) {
534 if ( ! isset( $item->$column ) ) {
535 $item->$column = '';
536 }
537
538 $value = $item->$column;
539 } elseif ( is_array( $item ) ) {
540 if ( ! isset( $item[ $column ] ) ) {
541 $item[ $column ] = '';
542 }
543
544 $value = $item[ $column ];
545 }
546
547 $row[ $column ] = $value;
548 }//end foreach
549
550 $data['items']['item'][] = $row;
551 }//end foreach
552 }
553
554 $this->built = @json_encode( $data );
555
556 return $this->built;
557 }
558
559 /**
560 * @param array $data Array of data
561 * @param string $delimiter Delimiter for export type 'sv'
562 *
563 * @return bool
564 */
565 public function build_sv( $data = null, $delimiter = null ) {
566
567 if ( ! empty( $data ) ) {
568 $this->set_data( $data );
569 }
570
571 if ( ! empty( $delimiter ) ) {
572 $this->delimiter = $delimiter;
573 }
574
575 if ( empty( $this->data ) || ! is_array( $this->data ) ) {
576 return false;
577 }
578
579 $head = '';
580 $lines = '';
581
582 foreach ( $this->data['columns'] as $column => $label ) {
583 $head .= '"' . $label . '"' . $this->delimiter;
584 }
585
586 $head = substr( $head, 0, - 1 );
587
588 $items = $this->get_items();
589
590 foreach ( $items as $item ) {
591 $line = '';
592
593 foreach ( $this->data['columns'] as $column => $label ) {
594 if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) {
595 $column = $label;
596 }
597
598 $value = '';
599
600 if ( is_object( $item ) ) {
601 if ( ! isset( $item->$column ) ) {
602 $item->$column = '';
603 }
604
605 $value = $item->$column;
606 } elseif ( is_array( $item ) ) {
607 if ( ! isset( $item[ $column ] ) ) {
608 $item[ $column ] = '';
609 }
610
611 $value = $item[ $column ];
612 }
613
614 if ( is_array( $value ) || is_object( $value ) ) {
615 $value = pods_serial_comma(
616 $value, array(
617 'field' => $column,
618 'fields' => pods_var_raw( $column, $this->data['fields'] ),
619 'and' => '',
620 )
621 );
622 }
623
624 $value = str_replace( array( '"', "\r\n", "\r", "\n" ), array( '\\"', "\n", "\n", '\n' ), $value );
625
626 $line .= '"' . $value . '"' . $this->delimiter;
627 }//end foreach
628
629 $lines .= substr( $line, 0, - 1 ) . "\n";
630 }//end foreach
631
632 if ( ! empty( $lines ) ) {
633 $lines = "\n" . substr( $lines, 0, - 1 );
634 }
635
636 $this->built = $head . $lines;
637
638 return $this->built;
639 }
640
641 /**
642 * @param array $data Array of data
643 *
644 * @return bool
645 */
646 public function build_xml( $data = null ) {
647
648 if ( ! empty( $data ) ) {
649 $this->set_data( $data );
650 }
651
652 if ( empty( $this->data ) || ! is_array( $this->data ) ) {
653 return false;
654 }
655
656 $items = $this->get_items();
657
658 $head = '<' . '?' . 'xml version="1.0" encoding="utf-8" ' . '?' . '>' . "\r\n<items count=\"" . count( $items ) . "\">\r\n";
659 $lines = '';
660
661 foreach ( $items as $item ) {
662 $line = "\t<item>\r\n";
663
664 foreach ( $this->data['columns'] as $column => $label ) {
665 if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) {
666 $column = $label;
667 }
668
669 $line .= $this->build_xml_level( $item, $column );
670 }
671
672 $line .= "\t</item>\r\n";
673 $lines .= $line;
674 }
675
676 $foot = '</items>';
677
678 $this->built = $head . $lines . $foot;
679
680 return $this->built;
681 }
682
683 /**
684 * @param array|object $item
685 * @param string $column
686 * @param int $level
687 * @param string $column_name
688 *
689 * @return string
690 */
691 public function build_xml_level( $item, $column, $level = 2, $column_name = '' ) {
692
693 $column = pods_clean_name( $column, false, false );
694
695 $line = '';
696
697 $value = '';
698
699 if ( is_object( $item ) ) {
700 if ( ! isset( $item->$column ) ) {
701 $item->$column = '';
702 }
703
704 $value = $item->$column;
705 } elseif ( is_array( $item ) ) {
706 if ( ! isset( $item[ $column ] ) ) {
707 $item[ $column ] = '';
708 }
709
710 $value = $item[ $column ];
711 }
712
713 if ( ! empty( $column_name ) ) {
714 $column = $column_name;
715 }
716
717 $tabs = str_repeat( "\t", $level );
718
719 $line .= $tabs . "<{$column}>";
720
721 if ( is_array( $value ) || is_object( $value ) ) {
722 if ( is_object( $value ) ) {
723 $value = get_object_vars( $value );
724 }
725
726 foreach ( $value as $k => $v ) {
727 if ( is_int( $k ) ) {
728 $line .= $this->build_xml_level( $value, $k, $level + 1, 'value' );
729 } else {
730 $line .= $this->build_xml_level( $value, $k, $level + 1 );
731 }
732 }
733 } elseif ( false !== strpos( $value, '<' ) ) {
734 $value = str_replace( array( '<![CDATA[', ']]>' ), array( '&lt;![CDATA[', ']]&gt;' ), $value );
735
736 $line .= '<![CDATA[' . $value . ']]>';
737 } else {
738 $line .= str_replace( '&', '&amp;', $value );
739 }
740
741 $line .= "</{$column}>\r\n";
742
743 return $line;
744 }
745
746 /**
747 * @param array $data Array of data
748 *
749 * @return mixed
750 */
751 public function build_sql( $data = null ) {
752
753 if ( ! empty( $data ) ) {
754 $this->set_data( $data );
755 }
756
757 $this->built = $data;
758
759 return $this->built;
760 }
761
762 /**
763 * Save export to a file.
764 *
765 * @param array $params Additional options for saving.
766 *
767 * @return string The URL of the saved file, a path if not attached.
768 */
769 public function save( $params = array() ) {
770
771 $defaults = array(
772 'file' => null,
773 'path' => null,
774 'attach' => false,
775 );
776
777 $params = array_merge( $defaults, $params );
778
779 $extension = 'txt';
780
781 if ( ! empty( $params['file'] ) ) {
782 $export_file = $params['file'];
783
784 if ( false !== strpos( $export_file, '.' ) ) {
785 $extension = explode( '.', $export_file );
786 $extension = end( $extension );
787 }
788 } else {
789 if ( 'sv' === $this->type ) {
790 if ( ',' === $this->delimiter ) {
791 $extension = 'csv';
792 } elseif ( "\t" === $this->delimiter ) {
793 $extension = 'tsv';
794 }
795 } else {
796 $extension = $this->type;
797 }
798
799 $export_file = sprintf(
800 'pods_export_%s.%s',
801 wp_create_nonce( date_i18n( 'm-d-Y_h-i-sa' ) ),
802 $extension
803 );
804 }
805
806 if ( ! empty( $params['path'] ) ) {
807 $new_file = sprintf(
808 '%s/%s',
809 untrailingslashit( $params['path'] ),
810 $export_file
811 );
812
813 $filename = $export_file;
814 } else {
815 $uploads = wp_upload_dir( current_time( 'mysql' ) );
816
817 if ( ! $uploads || false !== $uploads['error'] ) {
818 return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true );
819 }
820
821 // Generate unique file name
822 $filename = wp_unique_filename( $uploads['path'], $export_file );
823
824 // move the file to the uploads dir
825 $new_file = $uploads['path'] . '/' . $filename;
826 }
827
828 file_put_contents( $new_file, $this->built );
829
830 // Set correct file permissions
831 $stat = stat( dirname( $new_file ) );
832 $perms = $stat['mode'] & 0000666;
833 @chmod( $new_file, $perms );
834
835 // Only attach if we want to and don't have a custom path.
836 if ( $params['attach'] && empty( $params['path'] ) ) {
837 // Get the file type
838 $wp_filetype = wp_check_filetype( $filename, $this->mimes );
839
840 // construct the attachment array
841 $attachment = array(
842 'post_mime_type' => 'text/' . $extension,
843 'guid' => $uploads['url'] . '/' . $filename,
844 'post_parent' => null,
845 'post_title' => 'Pods Export (' . $export_file . ')',
846 'post_content' => '',
847 'post_status' => 'private'
848 );
849
850 if ( $wp_filetype['type'] ) {
851 $attachment['post_mime_type'] = $wp_filetype['type'];
852 }
853
854 // insert attachment
855 $attachment_id = wp_insert_attachment( $attachment, $new_file );
856
857 // error!
858 if ( is_wp_error( $attachment_id ) ) {
859 return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true );
860 }
861
862 $url = $attachment['guid'];
863 } else {
864 $url = $new_file;
865 }
866
867 return $url;
868
869 }
870
871 /*
872 The real enchilada!
873
874 EXAMPLES
875 //// minimal import (if your fields match on both your pods and tables)
876 $import = array('my_pod' => array('table' => 'my_table')); // if your table name doesn't match the pod name
877 $import = array('my_pod'); // if your table name matches your pod name
878
879 //// advanced import
880 $import = array();
881 $import['my_pod'] = array();
882 $import['my_pod']['fields']['this_field'] = 'field_name_in_table'; // if the field name doesn't match on table and pod
883 $import['my_pod']['fields'][] = 'that_field'; // if the field name matches on table and pod
884 $import['my_pod']['fields']['this_other_field'] = array('filter' => 'wpautop'); // if you want the value to be different than is provided, set a filter function to use [filter uses = filter_name($value,$rowdata)]
885 $import['my_pod']['fields']['another_field'] = array('field' => 'the_real_field_in_table','filter' => 'my_custom_function'); // if you want the value to be filtered, and the field name doesn't match on the table and pod
886 $import[] = 'my_other_pod'; // if your table name matches your pod name
887 $import['another_pod'] = array('update_on' => 'main_field'); // you can update a pod item if the value of this field is the same on both tables
888 $import['another_pod'] = array('reset' => true); // you can choose to reset all data in a pod before importing
889
890 //// run import
891 pods_import_it($import);
892 */
893 /**
894 * @param $import
895 * @param bool $output
896 */
897 public function heres_the_beef( $import, $output = true ) {
898
899 global $wpdb;
900
901 $api = pods_api();
902
903 for ( $i = 0; $i < 40000; $i ++ ) {
904 echo " \t";
905 // extra spaces
906 }
907
908 $default_data = array(
909 'pod' => null,
910 'table' => null,
911 'reset' => null,
912 'update_on' => null,
913 'where' => null,
914 'fields' => array(),
915 'row_filter' => null,
916 'pre_save' => null,
917 'post_save' => null,
918 'sql' => null,
919 'sort' => null,
920 'limit' => null,
921 'page' => null,
922 'output' => null,
923 'page_var' => 'ipg',
924 'bypass_helpers' => false,
925 );
926
927 $default_field_data = array(
928 'field' => null,
929 'filter' => null,
930 );
931
932 if ( ! is_array( $import ) ) {
933 $import = array( $import );
934 } elseif ( empty( $import ) ) {
935 die( '<h1 style="color:red;font-weight:bold;">ERROR: No imports configured</h1>' );
936 }
937
938 $import_counter = 0;
939 $total_imports = count( $import );
940 $paginated = false;
941 $avg_time = - 1;
942 $total_time = 0;
943 $counter = 0;
944 $avg_unit = 100;
945 $avg_counter = 0;
946
947 foreach ( $import as $datatype => $data ) {
948 $import_counter ++;
949
950 flush();
951 @ob_end_flush();
952 usleep( 50000 );
953
954 if ( ! is_array( $data ) ) {
955 $datatype = $data;
956 $data = array( 'table' => $data );
957 }
958
959 if ( isset( $data[0] ) ) {
960 $data = array( 'table' => $data[0] );
961 }
962
963 $data = array_merge( $default_data, $data );
964
965 if ( null === $data['pod'] ) {
966 $data['pod'] = array( 'name' => $datatype );
967 }
968
969 if ( false !== $output ) {
970 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - <em>' . $data['pod']['name'] . '</em> - <strong>Loading Pod: ' . $data['pod']['name'] . "</strong>\n";
971 }
972
973 if ( 2 > count( $data['pod'] ) ) {
974 $data['pod'] = $api->load_pod( array( 'name' => $data['pod']['name'] ) );
975 }
976
977 if ( empty( $data['pod']['fields'] ) ) {
978 continue;
979 }
980
981 if ( null === $data['table'] ) {
982 $data['table'] = $data['pod']['name'];
983 }
984
985 if ( $data['reset'] === true ) {
986 if ( false !== $output ) {
987 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - <strong style='color:blue;'>Resetting Pod: " . $data['pod']['name'] . "</strong>\n";
988 }
989
990 $api->reset_pod(
991 array(
992 'id' => $data['pod']['id'],
993 'name' => $data['pod']['name'],
994 )
995 );
996 }
997
998 if ( null === $data['sort'] && null !== $data['update_on'] && isset( $data['fields'][ $data['update_on'] ] ) ) {
999 if ( isset( $data['fields'][ $data['update_on'] ]['field'] ) ) {
1000 $data['sort'] = $data['fields'][ $data['update_on'] ]['field'];
1001 } else {
1002 $data['sort'] = $data['update_on'];
1003 }
1004 }
1005
1006 $page = 1;
1007
1008 if ( false !== $data['page_var'] && isset( $_GET[ $data['page_var'] ] ) ) {
1009 $page = absval( $_GET[ $data['page_var'] ] );
1010 }
1011
1012 if ( null === $data['sql'] ) {
1013 $data['sql'] = "SELECT * FROM {$data['table']}" . ( null !== $data['where'] ? " WHERE {$data['where']}" : '' ) . ( null !== $data['sort'] ? " ORDER BY {$data['sort']}" : '' ) . ( null !== $data['limit'] ? ' LIMIT ' . ( 1 < $page ? ( ( $page - 1 ) * $data['limit'] ) . ',' : '' ) . "{$data['limit']}" : '' );
1014 }
1015
1016 if ( false !== $output ) {
1017 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Getting Results: ' . $data['pod']['name'] . "\n";
1018 }
1019
1020 if ( false !== $output ) {
1021 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Using Query: <small><code>' . $data['sql'] . "</code></small>\n";
1022 }
1023
1024 $result = $wpdb->get_results( $data['sql'], ARRAY_A );
1025
1026 if ( false !== $output ) {
1027 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Results Found: ' . count( $result ) . "\n";
1028 }
1029
1030 $avg_time = - 1;
1031 $total_time = 0;
1032 $counter = 0;
1033 $avg_unit = 100;
1034 $avg_counter = 0;
1035 $result_count = count( $result );
1036 $paginated = false;
1037
1038 if ( false !== $data['page_var'] && $result_count === $data['limit'] ) {
1039 $paginated = "<input type=\"button\" onclick=\"document.location=\'" . pods_ui_var_update( array( $data['page_var'] => $page + 1 ), false, false ) . "\';\" value=\" Continue Import &raquo; \" />";
1040 }
1041
1042 if ( $result_count < $avg_unit && 5 < $result_count ) {
1043 $avg_unit = number_format( $result_count / 5, 0, '', '' );
1044 } elseif ( 2000 < $result_count && 10 < count( $data['pod']['fields'] ) ) {
1045 $avg_unit = 40;
1046 }
1047
1048 $data['count'] = $result_count;
1049 timer_start();
1050
1051 if ( false !== $output && 1 === $import_counter ) {
1052 echo "<div style='width:50%;background-color:navy;padding:10px 10px 30px 10px;color:#FFF;position:absolute;top:10px;left:25%;text-align:center;'><p id='progress_status' align='center'>" . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Running Importer..</p><br /><small>This will automatically update every ' . $avg_unit . " rows</small></div>\n";
1053 }
1054
1055 foreach ( $result as $k => $row ) {
1056 flush();
1057 @ob_end_flush();
1058 usleep( 50000 );
1059
1060 if ( false !== $output ) {
1061 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Processing Row #' . ( $k + 1 ) . "\n";
1062 }
1063
1064 if ( null !== $data['row_filter'] && function_exists( $data['row_filter'] ) ) {
1065 if ( false !== $output ) {
1066 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Filtering <strong>' . $data['row_filter'] . '</strong> on Row #' . ( $k + 1 ) . "\n";
1067 }
1068
1069 $row = $data['row_filter']( $row, $data );
1070 }
1071
1072 if ( ! is_array( $row ) ) {
1073 continue;
1074 }
1075
1076 $params = array(
1077 'datatype' => $data['pod']['name'],
1078 'columns' => array(),
1079 'bypass_helpers' => $data['bypass_helpers'],
1080 );
1081
1082 foreach ( $data['pod']['fields'] as $fk => $field_info ) {
1083 $field = $field_info['name'];
1084
1085 if ( ! empty( $data['fields'] ) && ! isset( $data['fields'][ $field ] ) && ! in_array( $field, $data['fields'], true ) ) {
1086 continue;
1087 }
1088
1089 if ( isset( $data['fields'][ $field ] ) ) {
1090 if ( is_array( $data['fields'][ $field ] ) ) {
1091 $field_data = $data['fields'][ $field ];
1092 } else {
1093 $field_data = array( 'field' => $data['fields'][ $field ] );
1094 }
1095 } else {
1096 $field_data = array();
1097 }
1098
1099 if ( ! is_array( $field_data ) ) {
1100 $field = $field_data;
1101 $field_data = array();
1102 }
1103
1104 $field_data = array_merge( $default_field_data, $field_data );
1105
1106 if ( null === $field_data['field'] ) {
1107 $field_data['field'] = $field;
1108 }
1109
1110 $data['fields'][ $field ] = $field_data;
1111 $value = '';
1112
1113 if ( isset( $row[ $field_data['field'] ] ) ) {
1114 $value = $row[ $field_data['field'] ];
1115 }
1116
1117 if ( null !== $field_data['filter'] ) {
1118 if ( function_exists( $field_data['filter'] ) ) {
1119 if ( false !== $output ) {
1120 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Filtering <strong>' . $field_data['filter'] . '</strong> on Field: ' . $field . "\n";
1121 }
1122
1123 $value = $field_data['filter']( $value, $row, $data );
1124 } else {
1125 $value = '';
1126 }
1127 }
1128
1129 if ( 1 > strlen( $value ) && 1 === $field_info['required'] ) {
1130 die( '<h1 style="color:red;font-weight:bold;">ERROR: Field Required for <strong>' . $field . '</strong></h1>' );
1131 }
1132
1133 $params['columns'][ $field ] = $value;
1134
1135 unset( $value, $field_data, $field_info, $fk );
1136 }//end foreach
1137
1138 if ( empty( $params['columns'] ) ) {
1139 continue;
1140 }
1141
1142 $params['columns'] = pods_sanitize( $params['columns'] );
1143
1144 if ( null !== $data['update_on'] && isset( $params['columns'][ $data['update_on'] ] ) ) {
1145 if ( false !== $output ) {
1146 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - Checking for Existing Item\n";
1147 }
1148
1149 $check = new Pod( $data['pod']['name'] );
1150 $check->findRecords(
1151 array(
1152 'orderby' => 't.id',
1153 'limit' => 1,
1154 'where' => "t.{$data['update_on']} = '{$params['columns'][$data['update_on']]}'",
1155 'search' => false,
1156 'page' => 1,
1157 )
1158 );
1159
1160 if ( 0 < $check->getTotalRows() ) {
1161 $check->fetchRecord();
1162
1163 $params['tbl_row_id'] = $check->get_field( 'id' );
1164 $params['pod_id'] = $check->get_pod_id();
1165
1166 if ( false !== $output ) {
1167 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Found Existing Item w/ ID: ' . $params['tbl_row_id'] . "\n";
1168 }
1169
1170 unset( $check );
1171 }
1172
1173 if ( ! isset( $params['tbl_row_id'] ) && false !== $output ) {
1174 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - Existing item not found - Creating New\n";
1175 }
1176 }//end if
1177
1178 if ( null !== $data['pre_save'] && function_exists( $data['pre_save'] ) ) {
1179 if ( false !== $output ) {
1180 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Running Pre Save <strong>' . $data['pre_save'] . '</strong> on ' . $data['pod']['name'] . "\n";
1181 }
1182
1183 $params = $data['pre_save']( $params, $row, $data );
1184 }
1185
1186 $id = $api->save_pod_item( $params );
1187
1188 if ( false !== $output ) {
1189 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - <strong>Saved Row #' . ( $k + 1 ) . ' w/ ID: ' . $id . "</strong>\n";
1190 }
1191
1192 $params['tbl_row_id'] = $id;
1193
1194 if ( null !== $data['post_save'] && function_exists( $data['post_save'] ) ) {
1195 if ( false !== $output ) {
1196 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Running Post Save <strong>' . $data['post_save'] . '</strong> on ' . $data['pod']['name'] . "\n";
1197 }
1198
1199 $data['post_save']( $params, $row, $data );
1200 }
1201
1202 unset( $params, $result[ $k ], $row );
1203
1204 wp_cache_flush();
1205 $wpdb->queries = array();
1206
1207 $avg_counter ++;
1208 $counter ++;
1209
1210 if ( $avg_counter === $avg_unit && false !== $output ) {
1211 $avg_counter = 0;
1212 $avg_time = timer_stop( 0, 10 );
1213 $total_time += $avg_time;
1214 $rows_left = $result_count - $counter;
1215 $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60;
1216 $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count );
1217
1218 echo "<script type='text/javascript'>document.getElementById('progress_status').innerHTML = '" . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em><br /><strong>' . $percent_complete . '% Complete</strong><br /><strong>Estimated Time Left:</strong> ' . $estimated_time_left . ' minute(s) or ' . ( $estimated_time_left / 60 ) . ' hours(s)<br /><strong>Time Spent:</strong> ' . ( $total_time / 60 ) . ' minute(s)<br /><strong>Rows Done:</strong> ' . ( $result_count - $rows_left ) . '/' . $result_count . '<br /><strong>Rows Left:</strong> ' . $rows_left . "';</script>\n";
1219 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - <strong>Updated Status:</strong> ' . $percent_complete . "% Complete</strong>\n";
1220 }
1221 }//end foreach
1222
1223 if ( false !== $output ) {
1224 $avg_counter = 0;
1225 $avg_time = timer_stop( 0, 10 );
1226 $total_time += $avg_time;
1227 $rows_left = $result_count - $counter;
1228 $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60;
1229 $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count );
1230
1231 echo "<script type='text/javascript'>document.getElementById('progress_status').innerHTML = '" . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em><br /><strong style=\'color:green;\'>100% Complete</strong><br /><br /><strong>Time Spent:</strong> " . ( $total_time / 60 ) . ' minute(s)<br /><strong>Rows Imported:</strong> ' . $result_count . ( false !== $paginated ? '<br /><br />' . $paginated : '' ) . "';</script>\n";
1232 echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - <strong style='color:green;'>Done Importing: " . $data['pod']['name'] . "</strong>\n";
1233 }
1234
1235 unset( $result, $import[ $datatype ], $datatype, $data );
1236
1237 wp_cache_flush();
1238 $wpdb->queries = array();
1239 }//end foreach
1240
1241 if ( false !== $output ) {
1242 $avg_counter = 0;
1243 $avg_time = timer_stop( 0, 10 );
1244 $total_time += $avg_time;
1245 $rows_left = $result_count - $counter;
1246
1247 echo "<script type='text/javascript'>document.getElementById('progress_status').innerHTML = '" . date( 'Y-m-d h:i:sa' ) . " - <strong style=\'color:green;\'>Import Complete</strong><br /><br /><strong>Time Spent:</strong> " . ( $total_time / 60 ) . ' minute(s)<br /><strong>Rows Imported:</strong> ' . $result_count . ( false !== $paginated ? '<br /><br />' . $paginated : '' ) . "';</script>\n";
1248 echo '<br />' . date( 'Y-m-d h:i:sa' ) . " - <strong style='color:green;'>Import Complete</strong>\n";
1249 }
1250 }
1251
1252 /**
1253 * Export data to a file.
1254 *
1255 * @param string $file File to export to.
1256 * @param array $data Data to export.
1257 * @param bool $single Whether this is a single item export.
1258 *
1259 * @return mixed
1260 */
1261 public static function export_data_to_file( $file, $data, $single = false ) {
1262
1263 $path = ABSPATH;
1264
1265 // Detect path if it is set in the file param.
1266 if ( false !== strpos( $file, '/' ) ) {
1267 $path = dirname( $file );
1268 $file = basename( $file );
1269 }
1270
1271 $format = 'json';
1272
1273 // Detect the export format.
1274 if ( false !== strpos( $file, '.' ) ) {
1275 $format = explode( '.', $file );
1276 $format = end( $format );
1277 }
1278
1279 $migrate_data = array(
1280 'items' => $data,
1281 'single' => $single,
1282 );
1283
1284 // Try to guess the column labels based on the supplied data.
1285 $first_item = null;
1286
1287 if ( $single ) {
1288 $first_item = $data;
1289 } elseif ( is_array( $data ) ) {
1290 $first_item = reset( $data );
1291 }
1292
1293 if ( is_array( $first_item ) ) {
1294 $fields = array_keys( $first_item );
1295 $migrate_data['columns'] = array_combine( $fields, $fields );
1296 }
1297
1298 $migrate = new self( $format, null, $migrate_data );
1299
1300 // Handle processing the data into the format needed.
1301 $migrate->export();
1302
1303 $save_params = array(
1304 'path' => $path,
1305 'file' => $file,
1306 'attach' => true,
1307 );
1308
1309 return $migrate->save( $save_params );
1310
1311 }
1312
1313 /**
1314 * Get data from a file.
1315 *
1316 * @param string $file File to get data from.
1317 * @param bool $single Whether this is a single item.
1318 *
1319 * @return mixed
1320 */
1321 public static function get_data_from_file( $file, $single = false ) {
1322
1323 $path = ABSPATH;
1324
1325 // Detect path if it is set in the file param.
1326 if ( false !== strpos( $file, DIRECTORY_SEPARATOR ) ) {
1327 $path = dirname( $file );
1328 $file = basename( $file );
1329 }
1330
1331 $format = 'json';
1332
1333 // Detect the export format.
1334 if ( false !== strpos( $file, '.' ) ) {
1335 $format = explode( '.', $file );
1336 $format = end( $format );
1337 }
1338
1339 $migrate_data = array(
1340 'single' => $single,
1341 );
1342
1343 $migrate = new self( $format, null, $migrate_data );
1344
1345 $raw_data = file_get_contents( $path . DIRECTORY_SEPARATOR . $file );
1346
1347 // Handle processing the raw data from the format needed.
1348 $data = $migrate->parse( $raw_data );
1349
1350 return $data;
1351
1352 }
1353
1354 }
1355