cli
16 hours ago
fields
16 hours ago
widgets
16 hours ago
Pods.php
16 hours ago
PodsAPI.php
16 hours ago
PodsAdmin.php
16 hours ago
PodsArray.php
16 hours ago
PodsComponent.php
16 hours ago
PodsComponents.php
16 hours ago
PodsData.php
16 hours ago
PodsField.php
16 hours ago
PodsForm.php
16 hours ago
PodsI18n.php
16 hours ago
PodsInit.php
16 hours ago
PodsMeta.php
16 hours ago
PodsMigrate.php
16 hours ago
PodsRESTFields.php
16 hours ago
PodsRESTHandlers.php
16 hours ago
PodsTermSplitting.php
16 hours ago
PodsUI.php
16 hours ago
PodsView.php
16 hours ago
PodsMigrate.php
1376 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 | $column_value = ( isset( $row[ $ckey ] ) ? $row[ $ckey ] : '' ); |
| 277 | |
| 278 | if ( 'NULL' === $column_value ) { |
| 279 | // Maybe set the value as null. |
| 280 | $column_value = null; |
| 281 | } elseif ( |
| 282 | 0 === strpos( $column_value, '\\=' ) |
| 283 | || 0 === strpos( $column_value, '\\+' ) |
| 284 | || 0 === strpos( $column_value, '\\-' ) |
| 285 | || 0 === strpos( $column_value, '\\@' ) |
| 286 | ) { |
| 287 | // Maybe remove the first backslash. |
| 288 | $column_value = substr( $column_value, 1 ); |
| 289 | } |
| 290 | |
| 291 | $data['items'][ $key ][ $column ] = $column_value; |
| 292 | } |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | $this->parsed = $data; |
| 297 | |
| 298 | return $this->parsed; |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Handle str_getcsv for cases where it's not set |
| 303 | * |
| 304 | * @param $line |
| 305 | * @param string $delimiter |
| 306 | * @param string $enclosure |
| 307 | * @param string $escape |
| 308 | * |
| 309 | * @return array|mixed |
| 310 | */ |
| 311 | public function str_getcsv( $line, $delimiter = ',', $enclosure = '"', $escape = '\\' ) { |
| 312 | |
| 313 | $line = str_replace( "\r\n", "\n", $line ); |
| 314 | $line = str_replace( "\r", "\n", $line ); |
| 315 | |
| 316 | if ( '\n' !== $delimiter && function_exists( 'str_getcsv' ) ) { |
| 317 | return str_getcsv( $line, $delimiter, $enclosure, $escape ); |
| 318 | } |
| 319 | |
| 320 | $delimiter = str_replace( '/', '\/', $delimiter ); |
| 321 | $enclosure = preg_quote( $enclosure, '/' ); |
| 322 | |
| 323 | $split = "/{$delimiter}(?=(?:[^{$enclosure}]*{$enclosure}[^{$enclosure}]*{$enclosure})*(?![^{$enclosure}]*{$enclosure}))/"; |
| 324 | |
| 325 | $data = preg_split( $split, trim( $line ), - 1, PREG_SPLIT_NO_EMPTY ); |
| 326 | |
| 327 | if ( '\n' !== $delimiter ) { |
| 328 | $data = preg_replace( "/^{$enclosure}(.*){$enclosure}$/s", '$1', $data ); |
| 329 | } |
| 330 | |
| 331 | return $data; |
| 332 | } |
| 333 | |
| 334 | /** |
| 335 | * @param array $data Array of data |
| 336 | * |
| 337 | * @return bool |
| 338 | */ |
| 339 | public function parse_xml( $data = null ) { |
| 340 | |
| 341 | if ( ! empty( $data ) ) { |
| 342 | $this->input = $data; |
| 343 | } |
| 344 | |
| 345 | $xml = new SimpleXMLElement( $this->input ); |
| 346 | |
| 347 | if ( ! isset( $xml->items ) ) { |
| 348 | return false; |
| 349 | } |
| 350 | |
| 351 | $data = array( |
| 352 | 'columns' => array(), |
| 353 | 'items' => array(), |
| 354 | ); |
| 355 | |
| 356 | /** |
| 357 | * @var $child SimpleXMLElement |
| 358 | * @var $item_child SimpleXMLElement |
| 359 | * @var $data_child SimpleXMLElement |
| 360 | */ |
| 361 | |
| 362 | if ( isset( $xml->columns ) ) { |
| 363 | foreach ( $xml->columns->children() as $child ) { |
| 364 | $sub = $child->getName(); |
| 365 | |
| 366 | if ( empty( $sub ) || 'column' !== $sub ) { |
| 367 | continue; |
| 368 | } |
| 369 | |
| 370 | if ( isset( $child->name ) ) { |
| 371 | if ( is_array( $child->name ) ) { |
| 372 | $column = $child->name[0]; |
| 373 | } else { |
| 374 | $column = $child->name; |
| 375 | } |
| 376 | |
| 377 | $data['columns'][] = $column; |
| 378 | } |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | foreach ( $xml->items->children() as $child ) { |
| 383 | $sub = $child->getName(); |
| 384 | |
| 385 | if ( empty( $sub ) || 'item' !== $sub ) { |
| 386 | continue; |
| 387 | } |
| 388 | |
| 389 | $item = array(); |
| 390 | |
| 391 | $attributes = $child->attributes(); |
| 392 | |
| 393 | if ( ! empty( $attributes ) ) { |
| 394 | foreach ( $attributes as $column => $value ) { |
| 395 | if ( ! in_array( $column, $data['columns'], true ) ) { |
| 396 | $data['columns'][] = $column; |
| 397 | } |
| 398 | |
| 399 | $item[ $column ] = $value; |
| 400 | } |
| 401 | } |
| 402 | |
| 403 | $item_child = $child->children(); |
| 404 | |
| 405 | if ( ! empty( $item_child ) ) { |
| 406 | foreach ( $item_child->children() as $data_child ) { |
| 407 | $column = $data_child->getName(); |
| 408 | |
| 409 | if ( ! in_array( $column, $data['columns'], true ) ) { |
| 410 | $data['columns'][] = $column; |
| 411 | } |
| 412 | |
| 413 | $item[ $column ] = $item_child->$column; |
| 414 | } |
| 415 | } |
| 416 | |
| 417 | if ( ! empty( $item ) ) { |
| 418 | $data['items'][] = $item; |
| 419 | } |
| 420 | }//end foreach |
| 421 | |
| 422 | $this->parsed = $data; |
| 423 | |
| 424 | return $this->parsed; |
| 425 | } |
| 426 | |
| 427 | /** |
| 428 | * @param array $data Array of data |
| 429 | * |
| 430 | * @return mixed |
| 431 | * |
| 432 | * @todo For much much later |
| 433 | */ |
| 434 | public function parse_sql( $data = null ) { |
| 435 | |
| 436 | if ( ! empty( $data ) ) { |
| 437 | $this->input = $data; |
| 438 | } |
| 439 | |
| 440 | $this->parsed = $data; |
| 441 | |
| 442 | return $this->parsed; |
| 443 | } |
| 444 | |
| 445 | /** |
| 446 | * Exporting / Building Code |
| 447 | * |
| 448 | * @param array $data Array of data |
| 449 | * @param string $type Export Type (php, json, sv, xml) |
| 450 | * @param string $delimiter Delimiter for export type 'sv' |
| 451 | * |
| 452 | * @return mixed |
| 453 | */ |
| 454 | public function export( $data = null, $type = null, $delimiter = null ) { |
| 455 | |
| 456 | if ( ! empty( $data ) ) { |
| 457 | $this->set_data( $data ); |
| 458 | } |
| 459 | |
| 460 | if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) { |
| 461 | $this->type = $type; |
| 462 | } |
| 463 | |
| 464 | if ( ! empty( $delimiter ) ) { |
| 465 | $this->delimiter = $delimiter; |
| 466 | } |
| 467 | |
| 468 | if ( method_exists( $this, "build_{$this->type}" ) ) { |
| 469 | call_user_func( array( $this, 'build_' . $this->type ) ); |
| 470 | } |
| 471 | |
| 472 | return $this->built; |
| 473 | } |
| 474 | |
| 475 | /** |
| 476 | * @param array $data Array of data |
| 477 | */ |
| 478 | public function export_pod_items( $data = null ) { |
| 479 | |
| 480 | if ( ! empty( $data ) ) { |
| 481 | $this->set_data( $data ); |
| 482 | } |
| 483 | } |
| 484 | |
| 485 | /** |
| 486 | * @param array $data Array of data |
| 487 | * @param string $type Export Type (php, json, sv, xml) |
| 488 | * |
| 489 | * @return null |
| 490 | */ |
| 491 | public function build( $data = null, $type = null ) { |
| 492 | |
| 493 | if ( ! empty( $data ) ) { |
| 494 | $this->set_data( $data ); |
| 495 | } |
| 496 | |
| 497 | if ( ! empty( $type ) && in_array( $type, $this->types, true ) ) { |
| 498 | $this->type = $type; |
| 499 | } |
| 500 | |
| 501 | if ( method_exists( $this, "build_{$this->type}" ) ) { |
| 502 | call_user_func( array( $this, 'build_' . $this->type ) ); |
| 503 | } |
| 504 | |
| 505 | return $this->data; |
| 506 | } |
| 507 | |
| 508 | /** |
| 509 | * @param array $data Array of data |
| 510 | * |
| 511 | * @return bool |
| 512 | */ |
| 513 | public function build_json( $data = null ) { |
| 514 | |
| 515 | if ( ! empty( $data ) ) { |
| 516 | $this->set_data( $data ); |
| 517 | } |
| 518 | |
| 519 | if ( empty( $this->data ) || ! is_array( $this->data ) ) { |
| 520 | return false; |
| 521 | } |
| 522 | |
| 523 | // Only export to a basic object if building for a single item. |
| 524 | if ( ! empty( $this->data['single'] ) ) { |
| 525 | $data = $this->data['items']; |
| 526 | } else { |
| 527 | $data = array( |
| 528 | 'items' => array( |
| 529 | 'count' => count( $this->data['items'] ), |
| 530 | 'item' => array(), |
| 531 | ), |
| 532 | ); |
| 533 | |
| 534 | foreach ( $this->data['items'] as $item ) { |
| 535 | $row = array(); |
| 536 | |
| 537 | foreach ( $this->data['columns'] as $column => $label ) { |
| 538 | if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) { |
| 539 | $column = $label; |
| 540 | } |
| 541 | |
| 542 | $value = ''; |
| 543 | |
| 544 | if ( is_object( $item ) ) { |
| 545 | if ( ! isset( $item->$column ) ) { |
| 546 | $item->$column = ''; |
| 547 | } |
| 548 | |
| 549 | $value = $item->$column; |
| 550 | } elseif ( is_array( $item ) ) { |
| 551 | if ( ! isset( $item[ $column ] ) ) { |
| 552 | $item[ $column ] = ''; |
| 553 | } |
| 554 | |
| 555 | $value = $item[ $column ]; |
| 556 | } |
| 557 | |
| 558 | $row[ $column ] = $value; |
| 559 | }//end foreach |
| 560 | |
| 561 | $data['items']['item'][] = $row; |
| 562 | }//end foreach |
| 563 | } |
| 564 | |
| 565 | $this->built = @json_encode( $data ); |
| 566 | |
| 567 | return $this->built; |
| 568 | } |
| 569 | |
| 570 | /** |
| 571 | * @param array $data Array of data |
| 572 | * @param string $delimiter Delimiter for export type 'sv' |
| 573 | * |
| 574 | * @return bool |
| 575 | */ |
| 576 | public function build_sv( $data = null, $delimiter = null ) { |
| 577 | |
| 578 | if ( ! empty( $data ) ) { |
| 579 | $this->set_data( $data ); |
| 580 | } |
| 581 | |
| 582 | if ( ! empty( $delimiter ) ) { |
| 583 | $this->delimiter = $delimiter; |
| 584 | } |
| 585 | |
| 586 | if ( empty( $this->data ) || ! is_array( $this->data ) ) { |
| 587 | return false; |
| 588 | } |
| 589 | |
| 590 | $head = ''; |
| 591 | $lines = ''; |
| 592 | |
| 593 | foreach ( $this->data['columns'] as $column => $label ) { |
| 594 | $head .= '"' . $label . '"' . $this->delimiter; |
| 595 | } |
| 596 | |
| 597 | $head = substr( $head, 0, - 1 ); |
| 598 | |
| 599 | $items = $this->get_items(); |
| 600 | |
| 601 | foreach ( $items as $item ) { |
| 602 | $line = ''; |
| 603 | |
| 604 | foreach ( $this->data['columns'] as $column => $label ) { |
| 605 | if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) { |
| 606 | $column = $label; |
| 607 | } |
| 608 | |
| 609 | $value = ''; |
| 610 | |
| 611 | if ( is_object( $item ) ) { |
| 612 | if ( ! isset( $item->$column ) ) { |
| 613 | $item->$column = ''; |
| 614 | } |
| 615 | |
| 616 | $value = $item->$column; |
| 617 | } elseif ( is_array( $item ) ) { |
| 618 | if ( ! isset( $item[ $column ] ) ) { |
| 619 | $item[ $column ] = ''; |
| 620 | } |
| 621 | |
| 622 | $value = $item[ $column ]; |
| 623 | } |
| 624 | |
| 625 | if ( is_array( $value ) || is_object( $value ) ) { |
| 626 | $value = pods_serial_comma( |
| 627 | $value, array( |
| 628 | 'field' => $column, |
| 629 | 'fields' => pods_var_raw( $column, $this->data['fields'] ), |
| 630 | 'and' => '', |
| 631 | ) |
| 632 | ); |
| 633 | } |
| 634 | |
| 635 | $value = str_replace( array( '"', "\r\n", "\r", "\n" ), array( '\\"', "\n", "\n", '\n' ), $value ); |
| 636 | |
| 637 | // Maybe escape the first character to prevent formulas from getting used when opening the file with a spreadsheet app. |
| 638 | if ( |
| 639 | 0 === strpos( $value, '=' ) |
| 640 | || 0 === strpos( $value, '+' ) |
| 641 | || 0 === strpos( $value, '-' ) |
| 642 | || 0 === strpos( $value, '@' ) |
| 643 | ) { |
| 644 | $value = '\\' . $value; |
| 645 | } |
| 646 | |
| 647 | $line .= '"' . $value . '"' . $this->delimiter; |
| 648 | }//end foreach |
| 649 | |
| 650 | $lines .= substr( $line, 0, - 1 ) . "\n"; |
| 651 | }//end foreach |
| 652 | |
| 653 | if ( ! empty( $lines ) ) { |
| 654 | $lines = "\n" . substr( $lines, 0, - 1 ); |
| 655 | } |
| 656 | |
| 657 | $this->built = $head . $lines; |
| 658 | |
| 659 | return $this->built; |
| 660 | } |
| 661 | |
| 662 | /** |
| 663 | * @param array $data Array of data |
| 664 | * |
| 665 | * @return bool |
| 666 | */ |
| 667 | public function build_xml( $data = null ) { |
| 668 | |
| 669 | if ( ! empty( $data ) ) { |
| 670 | $this->set_data( $data ); |
| 671 | } |
| 672 | |
| 673 | if ( empty( $this->data ) || ! is_array( $this->data ) ) { |
| 674 | return false; |
| 675 | } |
| 676 | |
| 677 | $items = $this->get_items(); |
| 678 | |
| 679 | $head = '<' . '?' . 'xml version="1.0" encoding="utf-8" ' . '?' . '>' . "\r\n<items count=\"" . count( $items ) . "\">\r\n"; |
| 680 | $lines = ''; |
| 681 | |
| 682 | foreach ( $items as $item ) { |
| 683 | $line = "\t<item>\r\n"; |
| 684 | |
| 685 | foreach ( $this->data['columns'] as $column => $label ) { |
| 686 | if ( is_numeric( $column ) && ( ( is_object( $item ) && ! isset( $item->$column ) ) || ( is_array( $item ) && ! isset( $item[ $column ] ) ) ) ) { |
| 687 | $column = $label; |
| 688 | } |
| 689 | |
| 690 | $line .= $this->build_xml_level( $item, $column ); |
| 691 | } |
| 692 | |
| 693 | $line .= "\t</item>\r\n"; |
| 694 | $lines .= $line; |
| 695 | } |
| 696 | |
| 697 | $foot = '</items>'; |
| 698 | |
| 699 | $this->built = $head . $lines . $foot; |
| 700 | |
| 701 | return $this->built; |
| 702 | } |
| 703 | |
| 704 | /** |
| 705 | * @param array|object $item |
| 706 | * @param string $column |
| 707 | * @param int $level |
| 708 | * @param string $column_name |
| 709 | * |
| 710 | * @return string |
| 711 | */ |
| 712 | public function build_xml_level( $item, $column, $level = 2, $column_name = '' ) { |
| 713 | |
| 714 | $column = pods_clean_name( $column, false, false ); |
| 715 | |
| 716 | $line = ''; |
| 717 | |
| 718 | $value = ''; |
| 719 | |
| 720 | if ( is_object( $item ) ) { |
| 721 | if ( ! isset( $item->$column ) ) { |
| 722 | $item->$column = ''; |
| 723 | } |
| 724 | |
| 725 | $value = $item->$column; |
| 726 | } elseif ( is_array( $item ) ) { |
| 727 | if ( ! isset( $item[ $column ] ) ) { |
| 728 | $item[ $column ] = ''; |
| 729 | } |
| 730 | |
| 731 | $value = $item[ $column ]; |
| 732 | } |
| 733 | |
| 734 | if ( ! empty( $column_name ) ) { |
| 735 | $column = $column_name; |
| 736 | } |
| 737 | |
| 738 | $tabs = str_repeat( "\t", $level ); |
| 739 | |
| 740 | $line .= $tabs . "<{$column}>"; |
| 741 | |
| 742 | if ( is_array( $value ) || is_object( $value ) ) { |
| 743 | if ( is_object( $value ) ) { |
| 744 | $value = get_object_vars( $value ); |
| 745 | } |
| 746 | |
| 747 | foreach ( $value as $k => $v ) { |
| 748 | if ( is_int( $k ) ) { |
| 749 | $line .= $this->build_xml_level( $value, $k, $level + 1, 'value' ); |
| 750 | } else { |
| 751 | $line .= $this->build_xml_level( $value, $k, $level + 1 ); |
| 752 | } |
| 753 | } |
| 754 | } elseif ( false !== strpos( $value, '<' ) ) { |
| 755 | $value = str_replace( array( '<![CDATA[', ']]>' ), array( '<![CDATA[', ']]>' ), $value ); |
| 756 | |
| 757 | $line .= '<![CDATA[' . $value . ']]>'; |
| 758 | } else { |
| 759 | $line .= str_replace( '&', '&', $value ); |
| 760 | } |
| 761 | |
| 762 | $line .= "</{$column}>\r\n"; |
| 763 | |
| 764 | return $line; |
| 765 | } |
| 766 | |
| 767 | /** |
| 768 | * @param array $data Array of data |
| 769 | * |
| 770 | * @return mixed |
| 771 | */ |
| 772 | public function build_sql( $data = null ) { |
| 773 | |
| 774 | if ( ! empty( $data ) ) { |
| 775 | $this->set_data( $data ); |
| 776 | } |
| 777 | |
| 778 | $this->built = $data; |
| 779 | |
| 780 | return $this->built; |
| 781 | } |
| 782 | |
| 783 | /** |
| 784 | * Save export to a file. |
| 785 | * |
| 786 | * @param array $params Additional options for saving. |
| 787 | * |
| 788 | * @return string The URL of the saved file, a path if not attached. |
| 789 | */ |
| 790 | public function save( $params = array() ) { |
| 791 | |
| 792 | $defaults = array( |
| 793 | 'file' => null, |
| 794 | 'path' => null, |
| 795 | 'attach' => false, |
| 796 | ); |
| 797 | |
| 798 | $params = array_merge( $defaults, $params ); |
| 799 | |
| 800 | $extension = 'txt'; |
| 801 | |
| 802 | if ( ! empty( $params['file'] ) ) { |
| 803 | $export_file = $params['file']; |
| 804 | |
| 805 | if ( false !== strpos( $export_file, '.' ) ) { |
| 806 | $extension = explode( '.', $export_file ); |
| 807 | $extension = end( $extension ); |
| 808 | } |
| 809 | } else { |
| 810 | if ( 'sv' === $this->type ) { |
| 811 | if ( ',' === $this->delimiter ) { |
| 812 | $extension = 'csv'; |
| 813 | } elseif ( "\t" === $this->delimiter ) { |
| 814 | $extension = 'tsv'; |
| 815 | } |
| 816 | } else { |
| 817 | $extension = $this->type; |
| 818 | } |
| 819 | |
| 820 | $export_file = sprintf( |
| 821 | 'pods_export_%s.%s', |
| 822 | wp_create_nonce( date_i18n( 'm-d-Y_h-i-sa' ) ), |
| 823 | $extension |
| 824 | ); |
| 825 | } |
| 826 | |
| 827 | if ( ! empty( $params['path'] ) ) { |
| 828 | $new_file = sprintf( |
| 829 | '%s/%s', |
| 830 | untrailingslashit( $params['path'] ), |
| 831 | $export_file |
| 832 | ); |
| 833 | |
| 834 | $filename = $export_file; |
| 835 | } else { |
| 836 | $uploads = wp_upload_dir( current_time( 'mysql' ) ); |
| 837 | |
| 838 | if ( ! $uploads || false !== $uploads['error'] ) { |
| 839 | return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true ); |
| 840 | } |
| 841 | |
| 842 | // Generate unique file name |
| 843 | $filename = wp_unique_filename( $uploads['path'], $export_file ); |
| 844 | |
| 845 | // move the file to the uploads dir |
| 846 | $new_file = $uploads['path'] . '/' . $filename; |
| 847 | } |
| 848 | |
| 849 | file_put_contents( $new_file, $this->built ); |
| 850 | |
| 851 | // Set correct file permissions |
| 852 | $stat = stat( dirname( $new_file ) ); |
| 853 | $perms = $stat['mode'] & 0000666; |
| 854 | @chmod( $new_file, $perms ); |
| 855 | |
| 856 | // Only attach if we want to and don't have a custom path. |
| 857 | if ( $params['attach'] && empty( $params['path'] ) ) { |
| 858 | // Get the file type |
| 859 | $wp_filetype = wp_check_filetype( $filename, $this->mimes ); |
| 860 | |
| 861 | // construct the attachment array |
| 862 | $attachment = array( |
| 863 | 'post_mime_type' => 'text/' . $extension, |
| 864 | 'guid' => $uploads['url'] . '/' . $filename, |
| 865 | 'post_parent' => null, |
| 866 | 'post_title' => 'Pods Export (' . $export_file . ')', |
| 867 | 'post_content' => '', |
| 868 | 'post_status' => 'private' |
| 869 | ); |
| 870 | |
| 871 | if ( $wp_filetype['type'] ) { |
| 872 | $attachment['post_mime_type'] = $wp_filetype['type']; |
| 873 | } |
| 874 | |
| 875 | // insert attachment |
| 876 | $attachment_id = wp_insert_attachment( $attachment, $new_file ); |
| 877 | |
| 878 | // error! |
| 879 | if ( is_wp_error( $attachment_id ) ) { |
| 880 | return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true ); |
| 881 | } |
| 882 | |
| 883 | $url = $attachment['guid']; |
| 884 | } else { |
| 885 | $url = $new_file; |
| 886 | } |
| 887 | |
| 888 | return $url; |
| 889 | |
| 890 | } |
| 891 | |
| 892 | /* |
| 893 | The real enchilada! |
| 894 | |
| 895 | EXAMPLES |
| 896 | //// minimal import (if your fields match on both your pods and tables) |
| 897 | $import = array('my_pod' => array('table' => 'my_table')); // if your table name doesn't match the pod name |
| 898 | $import = array('my_pod'); // if your table name matches your pod name |
| 899 | |
| 900 | //// advanced import |
| 901 | $import = array(); |
| 902 | $import['my_pod'] = array(); |
| 903 | $import['my_pod']['fields']['this_field'] = 'field_name_in_table'; // if the field name doesn't match on table and pod |
| 904 | $import['my_pod']['fields'][] = 'that_field'; // if the field name matches on table and pod |
| 905 | $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)] |
| 906 | $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 |
| 907 | $import[] = 'my_other_pod'; // if your table name matches your pod name |
| 908 | $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 |
| 909 | $import['another_pod'] = array('reset' => true); // you can choose to reset all data in a pod before importing |
| 910 | |
| 911 | //// run import |
| 912 | pods_import_it($import); |
| 913 | */ |
| 914 | /** |
| 915 | * @param $import |
| 916 | * @param bool $output |
| 917 | */ |
| 918 | public function heres_the_beef( $import, $output = true ) { |
| 919 | |
| 920 | global $wpdb; |
| 921 | |
| 922 | $api = pods_api(); |
| 923 | |
| 924 | for ( $i = 0; $i < 40000; $i ++ ) { |
| 925 | echo " \t"; |
| 926 | // extra spaces |
| 927 | } |
| 928 | |
| 929 | $default_data = array( |
| 930 | 'pod' => null, |
| 931 | 'table' => null, |
| 932 | 'reset' => null, |
| 933 | 'update_on' => null, |
| 934 | 'where' => null, |
| 935 | 'fields' => array(), |
| 936 | 'row_filter' => null, |
| 937 | 'pre_save' => null, |
| 938 | 'post_save' => null, |
| 939 | 'sql' => null, |
| 940 | 'sort' => null, |
| 941 | 'limit' => null, |
| 942 | 'page' => null, |
| 943 | 'output' => null, |
| 944 | 'page_var' => 'ipg', |
| 945 | 'bypass_helpers' => false, |
| 946 | ); |
| 947 | |
| 948 | $default_field_data = array( |
| 949 | 'field' => null, |
| 950 | 'filter' => null, |
| 951 | ); |
| 952 | |
| 953 | if ( ! is_array( $import ) ) { |
| 954 | $import = array( $import ); |
| 955 | } elseif ( empty( $import ) ) { |
| 956 | die( '<h1 style="color:red;font-weight:bold;">ERROR: No imports configured</h1>' ); |
| 957 | } |
| 958 | |
| 959 | $import_counter = 0; |
| 960 | $total_imports = count( $import ); |
| 961 | $paginated = false; |
| 962 | $avg_time = - 1; |
| 963 | $total_time = 0; |
| 964 | $counter = 0; |
| 965 | $avg_unit = 100; |
| 966 | $avg_counter = 0; |
| 967 | |
| 968 | foreach ( $import as $datatype => $data ) { |
| 969 | $import_counter ++; |
| 970 | |
| 971 | flush(); |
| 972 | @ob_end_flush(); |
| 973 | usleep( 50000 ); |
| 974 | |
| 975 | if ( ! is_array( $data ) ) { |
| 976 | $datatype = $data; |
| 977 | $data = array( 'table' => $data ); |
| 978 | } |
| 979 | |
| 980 | if ( isset( $data[0] ) ) { |
| 981 | $data = array( 'table' => $data[0] ); |
| 982 | } |
| 983 | |
| 984 | $data = array_merge( $default_data, $data ); |
| 985 | |
| 986 | if ( null === $data['pod'] ) { |
| 987 | $data['pod'] = array( 'name' => $datatype ); |
| 988 | } |
| 989 | |
| 990 | if ( false !== $output ) { |
| 991 | 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"; |
| 992 | } |
| 993 | |
| 994 | if ( 2 > count( $data['pod'] ) ) { |
| 995 | $data['pod'] = $api->load_pod( array( 'name' => $data['pod']['name'] ) ); |
| 996 | } |
| 997 | |
| 998 | if ( empty( $data['pod']['fields'] ) ) { |
| 999 | continue; |
| 1000 | } |
| 1001 | |
| 1002 | if ( null === $data['table'] ) { |
| 1003 | $data['table'] = $data['pod']['name']; |
| 1004 | } |
| 1005 | |
| 1006 | if ( $data['reset'] === true ) { |
| 1007 | if ( false !== $output ) { |
| 1008 | 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"; |
| 1009 | } |
| 1010 | |
| 1011 | $api->reset_pod( |
| 1012 | array( |
| 1013 | 'id' => $data['pod']['id'], |
| 1014 | 'name' => $data['pod']['name'], |
| 1015 | ) |
| 1016 | ); |
| 1017 | } |
| 1018 | |
| 1019 | if ( null === $data['sort'] && null !== $data['update_on'] && isset( $data['fields'][ $data['update_on'] ] ) ) { |
| 1020 | if ( isset( $data['fields'][ $data['update_on'] ]['field'] ) ) { |
| 1021 | $data['sort'] = $data['fields'][ $data['update_on'] ]['field']; |
| 1022 | } else { |
| 1023 | $data['sort'] = $data['update_on']; |
| 1024 | } |
| 1025 | } |
| 1026 | |
| 1027 | $page = 1; |
| 1028 | |
| 1029 | if ( false !== $data['page_var'] && isset( $_GET[ $data['page_var'] ] ) ) { |
| 1030 | $page = absval( $_GET[ $data['page_var'] ] ); |
| 1031 | } |
| 1032 | |
| 1033 | if ( null === $data['sql'] ) { |
| 1034 | $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']}" : '' ); |
| 1035 | } |
| 1036 | |
| 1037 | if ( false !== $output ) { |
| 1038 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Getting Results: ' . $data['pod']['name'] . "\n"; |
| 1039 | } |
| 1040 | |
| 1041 | if ( false !== $output ) { |
| 1042 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Using Query: <small><code>' . $data['sql'] . "</code></small>\n"; |
| 1043 | } |
| 1044 | |
| 1045 | $result = $wpdb->get_results( $data['sql'], ARRAY_A ); |
| 1046 | |
| 1047 | if ( false !== $output ) { |
| 1048 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Results Found: ' . count( $result ) . "\n"; |
| 1049 | } |
| 1050 | |
| 1051 | $avg_time = - 1; |
| 1052 | $total_time = 0; |
| 1053 | $counter = 0; |
| 1054 | $avg_unit = 100; |
| 1055 | $avg_counter = 0; |
| 1056 | $result_count = count( $result ); |
| 1057 | $paginated = false; |
| 1058 | |
| 1059 | if ( false !== $data['page_var'] && $result_count === $data['limit'] ) { |
| 1060 | $paginated = "<input type=\"button\" onclick=\"document.location=\'" . pods_ui_var_update( array( $data['page_var'] => $page + 1 ), false, false ) . "\';\" value=\" Continue Import » \" />"; |
| 1061 | } |
| 1062 | |
| 1063 | if ( $result_count < $avg_unit && 5 < $result_count ) { |
| 1064 | $avg_unit = number_format( $result_count / 5, 0, '', '' ); |
| 1065 | } elseif ( 2000 < $result_count && 10 < count( $data['pod']['fields'] ) ) { |
| 1066 | $avg_unit = 40; |
| 1067 | } |
| 1068 | |
| 1069 | $data['count'] = $result_count; |
| 1070 | timer_start(); |
| 1071 | |
| 1072 | if ( false !== $output && 1 === $import_counter ) { |
| 1073 | 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"; |
| 1074 | } |
| 1075 | |
| 1076 | foreach ( $result as $k => $row ) { |
| 1077 | flush(); |
| 1078 | @ob_end_flush(); |
| 1079 | usleep( 50000 ); |
| 1080 | |
| 1081 | if ( false !== $output ) { |
| 1082 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Processing Row #' . ( $k + 1 ) . "\n"; |
| 1083 | } |
| 1084 | |
| 1085 | if ( null !== $data['row_filter'] && function_exists( $data['row_filter'] ) ) { |
| 1086 | if ( false !== $output ) { |
| 1087 | 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"; |
| 1088 | } |
| 1089 | |
| 1090 | $row = $data['row_filter']( $row, $data ); |
| 1091 | } |
| 1092 | |
| 1093 | if ( ! is_array( $row ) ) { |
| 1094 | continue; |
| 1095 | } |
| 1096 | |
| 1097 | $params = array( |
| 1098 | 'datatype' => $data['pod']['name'], |
| 1099 | 'columns' => array(), |
| 1100 | 'bypass_helpers' => $data['bypass_helpers'], |
| 1101 | ); |
| 1102 | |
| 1103 | foreach ( $data['pod']['fields'] as $fk => $field_info ) { |
| 1104 | $field = $field_info['name']; |
| 1105 | |
| 1106 | if ( ! empty( $data['fields'] ) && ! isset( $data['fields'][ $field ] ) && ! in_array( $field, $data['fields'], true ) ) { |
| 1107 | continue; |
| 1108 | } |
| 1109 | |
| 1110 | if ( isset( $data['fields'][ $field ] ) ) { |
| 1111 | if ( is_array( $data['fields'][ $field ] ) ) { |
| 1112 | $field_data = $data['fields'][ $field ]; |
| 1113 | } else { |
| 1114 | $field_data = array( 'field' => $data['fields'][ $field ] ); |
| 1115 | } |
| 1116 | } else { |
| 1117 | $field_data = array(); |
| 1118 | } |
| 1119 | |
| 1120 | if ( ! is_array( $field_data ) ) { |
| 1121 | $field = $field_data; |
| 1122 | $field_data = array(); |
| 1123 | } |
| 1124 | |
| 1125 | $field_data = pods_config_merge_data( $default_field_data, $field_data ); |
| 1126 | |
| 1127 | if ( null === $field_data['field'] ) { |
| 1128 | $field_data['field'] = $field; |
| 1129 | } |
| 1130 | |
| 1131 | $data['fields'][ $field ] = $field_data; |
| 1132 | $value = ''; |
| 1133 | |
| 1134 | if ( isset( $row[ $field_data['field'] ] ) ) { |
| 1135 | $value = $row[ $field_data['field'] ]; |
| 1136 | } |
| 1137 | |
| 1138 | if ( null !== $field_data['filter'] ) { |
| 1139 | if ( function_exists( $field_data['filter'] ) ) { |
| 1140 | if ( false !== $output ) { |
| 1141 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Filtering <strong>' . $field_data['filter'] . '</strong> on Field: ' . $field . "\n"; |
| 1142 | } |
| 1143 | |
| 1144 | $value = $field_data['filter']( $value, $row, $data ); |
| 1145 | } else { |
| 1146 | $value = ''; |
| 1147 | } |
| 1148 | } |
| 1149 | |
| 1150 | if ( 1 === $field_info['required'] && ( ! is_string( $value ) || strlen( $value ) < 1 ) ) { |
| 1151 | die( '<h1 style="color:red;font-weight:bold;">ERROR: Field Required for <strong>' . $field . '</strong></h1>' ); |
| 1152 | } |
| 1153 | |
| 1154 | $params['columns'][ $field ] = $value; |
| 1155 | |
| 1156 | unset( $value, $field_data, $field_info, $fk ); |
| 1157 | }//end foreach |
| 1158 | |
| 1159 | if ( empty( $params['columns'] ) ) { |
| 1160 | continue; |
| 1161 | } |
| 1162 | |
| 1163 | $params['columns'] = pods_sanitize( $params['columns'] ); |
| 1164 | |
| 1165 | if ( null !== $data['update_on'] && isset( $params['columns'][ $data['update_on'] ] ) ) { |
| 1166 | if ( false !== $output ) { |
| 1167 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - Checking for Existing Item\n"; |
| 1168 | } |
| 1169 | |
| 1170 | $check = new Pod( $data['pod']['name'] ); |
| 1171 | $check->findRecords( |
| 1172 | array( |
| 1173 | 'orderby' => 't.id', |
| 1174 | 'limit' => 1, |
| 1175 | 'where' => "t.{$data['update_on']} = '{$params['columns'][$data['update_on']]}'", |
| 1176 | 'search' => false, |
| 1177 | 'page' => 1, |
| 1178 | ) |
| 1179 | ); |
| 1180 | |
| 1181 | if ( 0 < $check->getTotalRows() ) { |
| 1182 | $check->fetchRecord(); |
| 1183 | |
| 1184 | $params['tbl_row_id'] = $check->get_field( 'id' ); |
| 1185 | $params['pod_id'] = $check->get_pod_id(); |
| 1186 | |
| 1187 | if ( false !== $output ) { |
| 1188 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - Found Existing Item w/ ID: ' . $params['tbl_row_id'] . "\n"; |
| 1189 | } |
| 1190 | |
| 1191 | unset( $check ); |
| 1192 | } |
| 1193 | |
| 1194 | if ( ! isset( $params['tbl_row_id'] ) && false !== $output ) { |
| 1195 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . "</em> - Existing item not found - Creating New\n"; |
| 1196 | } |
| 1197 | }//end if |
| 1198 | |
| 1199 | if ( null !== $data['pre_save'] && function_exists( $data['pre_save'] ) ) { |
| 1200 | if ( false !== $output ) { |
| 1201 | 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"; |
| 1202 | } |
| 1203 | |
| 1204 | $params = $data['pre_save']( $params, $row, $data ); |
| 1205 | } |
| 1206 | |
| 1207 | $id = $api->save_pod_item( $params ); |
| 1208 | |
| 1209 | if ( false !== $output ) { |
| 1210 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - <strong>Saved Row #' . ( $k + 1 ) . ' w/ ID: ' . $id . "</strong>\n"; |
| 1211 | } |
| 1212 | |
| 1213 | $params['tbl_row_id'] = $id; |
| 1214 | |
| 1215 | if ( null !== $data['post_save'] && function_exists( $data['post_save'] ) ) { |
| 1216 | if ( false !== $output ) { |
| 1217 | 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"; |
| 1218 | } |
| 1219 | |
| 1220 | $data['post_save']( $params, $row, $data ); |
| 1221 | } |
| 1222 | |
| 1223 | unset( $params, $result[ $k ], $row ); |
| 1224 | |
| 1225 | wp_cache_flush(); |
| 1226 | $wpdb->queries = array(); |
| 1227 | |
| 1228 | $avg_counter ++; |
| 1229 | $counter ++; |
| 1230 | |
| 1231 | if ( $avg_counter === $avg_unit && false !== $output ) { |
| 1232 | $avg_counter = 0; |
| 1233 | $avg_time = timer_stop( 0, 10 ); |
| 1234 | $total_time += $avg_time; |
| 1235 | $rows_left = $result_count - $counter; |
| 1236 | $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60; |
| 1237 | $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count ); |
| 1238 | |
| 1239 | 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"; |
| 1240 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . ' - <em>' . $data['pod']['name'] . '</em> - <strong>Updated Status:</strong> ' . $percent_complete . "% Complete</strong>\n"; |
| 1241 | } |
| 1242 | }//end foreach |
| 1243 | |
| 1244 | if ( false !== $output ) { |
| 1245 | $avg_counter = 0; |
| 1246 | $avg_time = timer_stop( 0, 10 ); |
| 1247 | $total_time += $avg_time; |
| 1248 | $rows_left = $result_count - $counter; |
| 1249 | $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60; |
| 1250 | $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count ); |
| 1251 | |
| 1252 | 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"; |
| 1253 | 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"; |
| 1254 | } |
| 1255 | |
| 1256 | unset( $result, $import[ $datatype ], $datatype, $data ); |
| 1257 | |
| 1258 | wp_cache_flush(); |
| 1259 | $wpdb->queries = array(); |
| 1260 | }//end foreach |
| 1261 | |
| 1262 | if ( false !== $output ) { |
| 1263 | $avg_counter = 0; |
| 1264 | $avg_time = timer_stop( 0, 10 ); |
| 1265 | $total_time += $avg_time; |
| 1266 | $rows_left = $result_count - $counter; |
| 1267 | |
| 1268 | 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"; |
| 1269 | echo '<br />' . date( 'Y-m-d h:i:sa' ) . " - <strong style='color:green;'>Import Complete</strong>\n"; |
| 1270 | } |
| 1271 | } |
| 1272 | |
| 1273 | /** |
| 1274 | * Export data to a file. |
| 1275 | * |
| 1276 | * @param string $file File to export to. |
| 1277 | * @param array $data Data to export. |
| 1278 | * @param bool $single Whether this is a single item export. |
| 1279 | * |
| 1280 | * @return mixed |
| 1281 | */ |
| 1282 | public static function export_data_to_file( $file, $data, $single = false ) { |
| 1283 | |
| 1284 | $path = ABSPATH; |
| 1285 | |
| 1286 | // Detect path if it is set in the file param. |
| 1287 | if ( false !== strpos( $file, '/' ) ) { |
| 1288 | $path = dirname( $file ); |
| 1289 | $file = basename( $file ); |
| 1290 | } |
| 1291 | |
| 1292 | $format = 'json'; |
| 1293 | |
| 1294 | // Detect the export format. |
| 1295 | if ( false !== strpos( $file, '.' ) ) { |
| 1296 | $format = explode( '.', $file ); |
| 1297 | $format = end( $format ); |
| 1298 | } |
| 1299 | |
| 1300 | $migrate_data = array( |
| 1301 | 'items' => $data, |
| 1302 | 'single' => $single, |
| 1303 | ); |
| 1304 | |
| 1305 | // Try to guess the column labels based on the supplied data. |
| 1306 | $first_item = null; |
| 1307 | |
| 1308 | if ( $single ) { |
| 1309 | $first_item = $data; |
| 1310 | } elseif ( is_array( $data ) ) { |
| 1311 | $first_item = reset( $data ); |
| 1312 | } |
| 1313 | |
| 1314 | if ( is_array( $first_item ) ) { |
| 1315 | $fields = array_keys( $first_item ); |
| 1316 | $migrate_data['columns'] = array_combine( $fields, $fields ); |
| 1317 | } |
| 1318 | |
| 1319 | $migrate = new self( $format, null, $migrate_data ); |
| 1320 | |
| 1321 | // Handle processing the data into the format needed. |
| 1322 | $migrate->export(); |
| 1323 | |
| 1324 | $save_params = array( |
| 1325 | 'path' => $path, |
| 1326 | 'file' => $file, |
| 1327 | 'attach' => true, |
| 1328 | ); |
| 1329 | |
| 1330 | return $migrate->save( $save_params ); |
| 1331 | |
| 1332 | } |
| 1333 | |
| 1334 | /** |
| 1335 | * Get data from a file. |
| 1336 | * |
| 1337 | * @param string $file File to get data from. |
| 1338 | * @param bool $single Whether this is a single item. |
| 1339 | * |
| 1340 | * @return mixed |
| 1341 | */ |
| 1342 | public static function get_data_from_file( $file, $single = false ) { |
| 1343 | |
| 1344 | $path = ABSPATH; |
| 1345 | |
| 1346 | // Detect path if it is set in the file param. |
| 1347 | if ( false !== strpos( $file, DIRECTORY_SEPARATOR ) ) { |
| 1348 | $path = dirname( $file ); |
| 1349 | $file = basename( $file ); |
| 1350 | } |
| 1351 | |
| 1352 | $format = 'json'; |
| 1353 | |
| 1354 | // Detect the export format. |
| 1355 | if ( false !== strpos( $file, '.' ) ) { |
| 1356 | $format = explode( '.', $file ); |
| 1357 | $format = end( $format ); |
| 1358 | } |
| 1359 | |
| 1360 | $migrate_data = array( |
| 1361 | 'single' => $single, |
| 1362 | ); |
| 1363 | |
| 1364 | $migrate = new self( $format, null, $migrate_data ); |
| 1365 | |
| 1366 | $raw_data = file_get_contents( $path . DIRECTORY_SEPARATOR . $file ); |
| 1367 | |
| 1368 | // Handle processing the raw data from the format needed. |
| 1369 | $data = $migrate->parse( $raw_data ); |
| 1370 | |
| 1371 | return $data; |
| 1372 | |
| 1373 | } |
| 1374 | |
| 1375 | } |
| 1376 |