PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/PodsMigrate.php

https://github.com/ElmsPark/pods
PHP | 925 lines | 560 code | 218 blank | 147 comment | 169 complexity | 8b1e2887ae1c4fb1fc380c79eb792a53 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. * @package Pods
  4. */
  5. class PodsMigrate {
  6. /**
  7. * @var null|string
  8. */
  9. var $type = 'php';
  10. /**
  11. * @var array
  12. */
  13. var $types = array( 'php', 'json', 'sv', 'xml' );
  14. /**
  15. * @var array
  16. */
  17. var $mimes = array(
  18. 'json' => 'application/json',
  19. 'csv' => 'text/csv',
  20. 'tsv' => 'text/tsv',
  21. 'xml' => 'text/xml',
  22. );
  23. /**
  24. * @var null|string
  25. */
  26. var $delimiter = ',';
  27. /**
  28. * @var null
  29. */
  30. var $data;
  31. /**
  32. * @var
  33. */
  34. var $parsed;
  35. /**
  36. * @var
  37. */
  38. var $built;
  39. /**
  40. * Migrate Data to and from Pods
  41. *
  42. * @param string $type Export Type (php, json, sv, xml)
  43. * @param string $delimiter Delimiter for export type 'sv'
  44. * @param array $data Array of data
  45. *
  46. * @license http://www.gnu.org/licenses/gpl-2.0.html
  47. * @since 2.0.0
  48. */
  49. function __construct ( $type = null, $delimiter = null, $data = null ) {
  50. if ( !empty( $type ) && in_array( $type, $this->types ) )
  51. $this->type = $type;
  52. if ( !empty( $delimiter ) )
  53. $this->delimiter = $delimiter;
  54. if ( !empty( $data ) )
  55. $this->data = $data;
  56. }
  57. /**
  58. * Importing / Parsing / Validating Code
  59. *
  60. * @param array $data Array of data
  61. * @param string $type Export Type (php, json, sv, xml)
  62. * @param string $delimiter Delimiter for export type 'sv'
  63. */
  64. function import ( $data = null, $type = null, $delimiter = null ) {
  65. if ( !empty( $data ) )
  66. $this->data = $data;
  67. if ( !empty( $type ) && in_array( $type, $this->types ) )
  68. $this->type = $type;
  69. if ( !empty( $delimiter ) )
  70. $this->delimiter = $delimiter;
  71. if ( method_exists( $this, "parse_{$this->type}" ) )
  72. call_user_func( array( $this, 'parse_' . $this->type ) );
  73. return $this->import_pod_items();
  74. }
  75. /**
  76. * @param array $data Array of data
  77. * @param string $type Export Type (php, json, sv, xml)
  78. */
  79. public function import_pod_items ( $data = null, $type = null ) {
  80. if ( !empty( $data ) )
  81. $this->data = $data;
  82. if ( !empty( $type ) && in_array( $type, $this->types ) )
  83. $this->type = $type;
  84. }
  85. /**
  86. * @param array $data Array of data
  87. * @param string $type Export Type (php, json, sv, xml)
  88. *
  89. * @return null
  90. */
  91. public function parse ( $data = null, $type = null ) {
  92. if ( !empty( $data ) )
  93. $this->data = $data;
  94. if ( !empty( $type ) && in_array( $type, $this->types ) )
  95. $this->type = $type;
  96. if ( method_exists( $this, "parse_{$this->type}" ) )
  97. call_user_func( array( $this, 'parse_' . $this->type ) );
  98. return $this->data;
  99. }
  100. /**
  101. * @param array $data Array of data
  102. *
  103. * @return bool
  104. */
  105. public function parse_json ( $data = null ) {
  106. if ( !empty( $data ) )
  107. $this->data = $data;
  108. $items = @json_decode( $this->data, true );
  109. if ( !is_array( $items ) )
  110. return false;
  111. $data = array( 'columns' => array(), 'items' => array() );
  112. foreach ( $items as $key => $item ) {
  113. if ( !is_array( $item ) )
  114. continue;
  115. foreach ( $item as $column => $value ) {
  116. if ( !in_array( $column, $data[ 'columns' ] ) )
  117. $data[ 'columns' ][] = $column;
  118. }
  119. $data[ 'items' ][ $key ] = $item;
  120. }
  121. $this->parsed = $data;
  122. return $this->parsed;
  123. }
  124. /**
  125. * @param array $data Array of data
  126. * @param string $delimiter Delimiter for export type 'sv'
  127. *
  128. * @return bool
  129. */
  130. public function parse_sv ( $data = null, $delimiter = null ) {
  131. if ( !empty( $data ) )
  132. $this->data = $data;
  133. if ( !empty( $delimiter ) )
  134. $this->delimiter = $delimiter;
  135. $rows = @str_getcsv( $this->data, "\n" );
  136. if ( empty( $rows ) || 2 > count( $rows ) )
  137. return false;
  138. $data = array( 'columns' => array(), 'items' => array() );
  139. foreach ( $rows as $key => $row ) {
  140. if ( 0 == $key )
  141. $data[ 'columns' ] = @str_getcsv( $row, $this->delimiter );
  142. else {
  143. $row = @str_getcsv( $row, $this->delimiter );
  144. $data[ 'items' ][ $key ] = array();
  145. foreach ( $data[ 'columns' ] as $ckey => $column ) {
  146. $data[ 'items' ][ $key ][ $column ] = ( isset( $row[ $ckey ] ) ? $row[ $ckey ] : '' );
  147. }
  148. }
  149. }
  150. $this->parsed = $data;
  151. return $this->parsed;
  152. }
  153. /**
  154. * @param array $data Array of data
  155. *
  156. * @return bool
  157. */
  158. public function parse_xml ( $data = null ) {
  159. if ( !empty( $data ) )
  160. $this->data = $data;
  161. $xml = new SimpleXMLElement( $this->data );
  162. if ( !isset( $xml->items ) )
  163. return false;
  164. $data = array( 'columns' => array(), 'items' => array() );
  165. if ( isset( $xml->columns ) ) {
  166. foreach ( $xml->columns->children() as $child ) {
  167. $sub = $child->getName();
  168. if ( empty( $sub ) || 'column' != $sub )
  169. continue;
  170. $column = false;
  171. if ( isset( $child->name ) ) {
  172. if ( is_array( $child->name ) )
  173. $column = $child->name[ 0 ];
  174. else
  175. $column = $child->name;
  176. $data[ 'columns' ][] = $column;
  177. }
  178. }
  179. }
  180. foreach ( $xml->items->children() as $child ) {
  181. $sub = $child->getName();
  182. if ( empty( $sub ) || 'item' != $sub )
  183. continue;
  184. $item = array();
  185. $attributes = $child->attributes();
  186. if ( !empty( $attributes ) ) {
  187. foreach ( $attributes as $column => $value ) {
  188. if ( !in_array( $column, $data[ 'columns' ] ) )
  189. $data[ 'columns' ][] = $column;
  190. $item[ $column ] = $value;
  191. }
  192. }
  193. $item_child = $child->children();
  194. if ( !empty( $item_child ) ) {
  195. foreach ( $item_child->children() as $data_child ) {
  196. $column = $data_child->getName();
  197. if ( !in_array( $column, $data[ 'columns' ] ) )
  198. $data[ 'columns' ][] = $column;
  199. $item[ $column ] = $item_child->$column;
  200. }
  201. }
  202. if ( !empty( $item ) )
  203. $data[ 'items' ][] = $item;
  204. }
  205. $this->parsed = $data;
  206. return $this->parsed;
  207. }
  208. /**
  209. * @param array $data Array of data
  210. *
  211. * @return mixed
  212. *
  213. * @todo For much much later
  214. */
  215. public function parse_sql ( $data = null ) {
  216. if ( !empty( $data ) )
  217. $this->data = $data;
  218. $this->parsed = $data;
  219. return $this->parsed;
  220. }
  221. /**
  222. * Exporting / Building Code
  223. *
  224. * @param array $data Array of data
  225. * @param string $type Export Type (php, json, sv, xml)
  226. * @param string $delimiter Delimiter for export type 'sv'
  227. */
  228. public function export ( $data = null, $type = null, $delimiter = null ) {
  229. if ( !empty( $data ) )
  230. $this->data = $data;
  231. if ( !empty( $type ) && in_array( $type, $this->types ) )
  232. $this->type = $type;
  233. if ( !empty( $delimiter ) )
  234. $this->delimiter = $delimiter;
  235. if ( method_exists( $this, "build_{$this->type}" ) )
  236. call_user_func( array( $this, 'build_' . $this->type ) );
  237. return $this->built;
  238. }
  239. /**
  240. * @param array $data Array of data
  241. */
  242. public function export_pod_items ( $data = null ) {
  243. if ( !empty( $data ) )
  244. $this->data = $data;
  245. }
  246. /**
  247. * @param array $data Array of data
  248. * @param string $type Export Type (php, json, sv, xml)
  249. *
  250. * @return null
  251. */
  252. public function build ( $data = null, $type = null ) {
  253. if ( !empty( $data ) )
  254. $this->data = $data;
  255. if ( !empty( $type ) && in_array( $type, $this->types ) )
  256. $this->type = $type;
  257. if ( method_exists( $this, "build_{$this->type}" ) )
  258. call_user_func( array( $this, 'build_' . $this->type ) );
  259. return $this->data;
  260. }
  261. /**
  262. * @param array $data Array of data
  263. *
  264. * @return bool
  265. */
  266. public function build_json ( $data = null ) {
  267. if ( !empty( $data ) )
  268. $this->data = $data;
  269. if ( empty( $this->data ) || !is_array( $this->data ) )
  270. return false;
  271. $data = array(
  272. 'items' => array(
  273. 'count' => count( $this->data[ 'items' ] ),
  274. 'item' => array()
  275. )
  276. );
  277. foreach ( $this->data[ 'items' ] as $item ) {
  278. $row = array();
  279. foreach ( $this->data[ 'columns' ] as $column => $label ) {
  280. if ( is_numeric( $column ) && ( ( is_object( $item ) && !isset( $item->$column ) ) || ( is_array( $item ) && !isset( $item[ $column ] ) ) ) )
  281. $column = $label;
  282. $value = '';
  283. if ( is_object( $item ) ) {
  284. if ( !isset( $item->$column ) )
  285. $item->$column = '';
  286. $value = $item->$column;
  287. }
  288. elseif ( is_array( $item ) ) {
  289. if ( !isset( $item[ $column ] ) )
  290. $item[ $column ] = '';
  291. $value = $item[ $column ];
  292. }
  293. $row[ $column ] = $value;
  294. }
  295. $data[ 'items' ][ 'item' ][] = $row;
  296. }
  297. $this->built = @json_encode( $data );
  298. return $this->built;
  299. }
  300. /**
  301. * @param array $data Array of data
  302. * @param string $delimiter Delimiter for export type 'sv'
  303. *
  304. * @return bool
  305. */
  306. public function build_sv ( $data = null, $delimiter = null ) {
  307. if ( !empty( $data ) )
  308. $this->data = $data;
  309. if ( !empty( $delimiter ) )
  310. $this->delimiter = $delimiter;
  311. if ( empty( $this->data ) || !is_array( $this->data ) )
  312. return false;
  313. $head = $lines = '';
  314. foreach ( $this->data[ 'columns' ] as $column => $label ) {
  315. $head .= '"' . $label . '"' . $this->delimiter;
  316. }
  317. $head = substr( $head, 0, -1 );
  318. foreach ( $this->data[ 'items' ] as $item ) {
  319. $line = '';
  320. foreach ( $this->data[ 'columns' ] as $column => $label ) {
  321. if ( is_numeric( $column ) && ( ( is_object( $item ) && !isset( $item->$column ) ) || ( is_array( $item ) && !isset( $item[ $column ] ) ) ) )
  322. $column = $label;
  323. $value = '';
  324. if ( is_object( $item ) ) {
  325. if ( !isset( $item->$column ) )
  326. $item->$column = '';
  327. $value = $item->$column;
  328. }
  329. elseif ( is_array( $item ) ) {
  330. if ( !isset( $item[ $column ] ) )
  331. $item[ $column ] = '';
  332. $value = $item[ $column ];
  333. }
  334. $value = str_replace( array( '"', "\r\n", "\r", "\n" ), array( '\\"', "\n", "\n", '\n' ), $value );
  335. $line .= '"' . $value . '"' . $this->delimiter;
  336. }
  337. $lines .= substr( $line, 0, -1 ) . "\n";
  338. }
  339. if ( !empty( $lines ) )
  340. $lines = "\n" . substr( $lines, 0, -1 );
  341. $this->built = $head . $lines;
  342. return $this->built;
  343. }
  344. /**
  345. * @param array $data Array of data
  346. *
  347. * @return bool
  348. */
  349. public function build_xml ( $data = null ) {
  350. if ( !empty( $data ) )
  351. $this->data = $data;
  352. if ( empty( $this->data ) || !is_array( $this->data ) )
  353. return false;
  354. $head = '<' . '?' . 'xml version="1.0" encoding="utf-8" ' . '?' . '>' . "\r\n<items count=\"" . count( $this->data[ 'items' ] ) . "\">\r\n";
  355. $lines = '';
  356. foreach ( $this->data[ 'items' ] as $item ) {
  357. $line = "\t<item>\r\n";
  358. foreach ( $this->data[ 'columns' ] as $column => $label ) {
  359. if ( is_numeric( $column ) && ( ( is_object( $item ) && !isset( $item->$column ) ) || ( is_array( $item ) && !isset( $item[ $column ] ) ) ) )
  360. $column = $label;
  361. $value = '';
  362. if ( is_object( $item ) ) {
  363. if ( !isset( $item->$column ) )
  364. $item->$column = '';
  365. $value = $item->$column;
  366. }
  367. elseif ( is_array( $item ) ) {
  368. if ( !isset( $item[ $column ] ) )
  369. $item[ $column ] = '';
  370. $value = $item[ $column ];
  371. }
  372. $line .= "\t\t<{$column}>";
  373. if ( false !== strpos( $value, '<' ) ) {
  374. $value = str_replace( array( '<![CDATA[', ']]>' ), array( '&lt;![CDATA[', ']]&gt;' ), $value );
  375. $line .= "<![CDATA[" . $value . "]]>";
  376. }
  377. else
  378. $line .= $value;
  379. $line .= "</{$column}>\r\n";
  380. }
  381. $line .= "\t</item>\r\n";
  382. $lines .= $line;
  383. }
  384. $foot = '</items>';
  385. $this->built = $head . $lines . $foot;
  386. return $this->built;
  387. }
  388. /**
  389. * @param array $data Array of data
  390. *
  391. * @return mixed
  392. */
  393. public function build_sql ( $data = null ) {
  394. if ( !empty( $data ) )
  395. $this->data = $data;
  396. $this->built = $data;
  397. return $this->built;
  398. }
  399. /**
  400. * Save export to a file
  401. */
  402. public function save() {
  403. $extension = 'txt';
  404. if ( 'sv' == $this->type ) {
  405. if ( ',' == $this->delimiter )
  406. $extension = 'csv';
  407. elseif ( "\t" == $this->delimiter )
  408. $extension = 'tsv';
  409. }
  410. else
  411. $extension = $this->type;
  412. $export_file = 'pods_export_' . wp_create_nonce( date_i18n( 'm-d-Y_h-i-sa' ) ) . '.' . $extension;
  413. if ( !( ( $uploads = wp_upload_dir( current_time( 'mysql' ) ) ) && false === $uploads[ 'error' ] ) )
  414. return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true );
  415. // Generate unique file name
  416. $filename = wp_unique_filename( $uploads[ 'path' ], $export_file );
  417. // move the file to the uploads dir
  418. $new_file = $uploads[ 'path' ] . '/' . $filename;
  419. file_put_contents( $new_file, $this->built );
  420. // Set correct file permissions
  421. $stat = stat( dirname( $new_file ) );
  422. $perms = $stat[ 'mode' ] & 0000666;
  423. @chmod( $new_file, $perms );
  424. // Get the file type
  425. $wp_filetype = wp_check_filetype( $filename, $this->mimes );
  426. // construct the attachment array
  427. $attachment = array(
  428. 'post_mime_type' => ( !$wp_filetype[ 'type' ] ? 'text/' . $extension : $wp_filetype[ 'type' ] ),
  429. 'guid' => $uploads[ 'url' ] . '/' . $filename,
  430. 'post_parent' => null,
  431. 'post_title' => '',
  432. 'post_content' => '',
  433. );
  434. // insert attachment
  435. $attachment_id = wp_insert_attachment( $attachment, $new_file );
  436. // error!
  437. if ( is_wp_error( $attachment_id ) )
  438. return pods_error( __( 'There was an issue saving the export file in your uploads folder.', 'pods' ), true );
  439. return $attachment[ 'guid' ];
  440. }
  441. /*
  442. * The real enchilada!
  443. */
  444. /* EXAMPLES
  445. //// minimal import (if your fields match on both your pods and tables)
  446. $import = array('my_pod' => array('table' => 'my_table')); // if your table name doesn't match the pod name
  447. $import = array('my_pod'); // if your table name matches your pod name
  448. //// advanced import
  449. $import = array();
  450. $import['my_pod'] = array();
  451. $import['my_pod']['fields']['this_field'] = 'field_name_in_table'; // if the field name doesn't match on table and pod
  452. $import['my_pod']['fields'][] = 'that_field'; // if the field name matches on table and pod
  453. $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)]
  454. $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
  455. $import[] = 'my_other_pod'; // if your table name matches your pod name
  456. $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
  457. $import['another_pod'] = array('reset' => true); // you can choose to reset all data in a pod before importing
  458. //// run import
  459. pods_import_it($import);
  460. */
  461. /**
  462. * @param $import
  463. * @param bool $output
  464. */
  465. public function heres_the_beef ( $import, $output = true ) {
  466. global $wpdb;
  467. $api = pods_api();
  468. for ( $i = 0; $i < 40000; $i++ ) {
  469. echo " \t"; // extra spaces
  470. }
  471. $default_data = array(
  472. 'pod' => null,
  473. 'table' => null,
  474. 'reset' => null,
  475. 'update_on' => null,
  476. 'where' => null,
  477. 'fields' => array(),
  478. 'row_filter' => null,
  479. 'pre_save' => null,
  480. 'post_save' => null,
  481. 'sql' => null,
  482. 'sort' => null,
  483. 'limit' => null,
  484. 'page' => null,
  485. 'output' => null,
  486. 'page_var' => 'ipg',
  487. 'bypass_helpers' => false
  488. );
  489. $default_field_data = array( 'field' => null, 'filter' => null );
  490. if ( !is_array( $import ) )
  491. $import = array( $import );
  492. elseif ( empty( $import ) )
  493. die( '<h1 style="color:red;font-weight:bold;">ERROR: No imports configured</h1>' );
  494. $import_counter = 0;
  495. $total_imports = count( $import );
  496. $paginated = false;
  497. $avg_time = -1;
  498. $total_time = 0;
  499. $counter = 0;
  500. $avg_unit = 100;
  501. $avg_counter = 0;
  502. foreach ( $import as $datatype => $data ) {
  503. $import_counter++;
  504. flush();
  505. @ob_end_flush();
  506. usleep( 50000 );
  507. if ( !is_array( $data ) ) {
  508. $datatype = $data;
  509. $data = array( 'table' => $data );
  510. }
  511. if ( isset( $data[ 0 ] ) )
  512. $data = array( 'table' => $data[ 0 ] );
  513. $data = array_merge( $default_data, $data );
  514. if ( null === $data[ 'pod' ] )
  515. $data[ 'pod' ] = array( 'name' => $datatype );
  516. if ( false !== $output )
  517. 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";
  518. if ( 2 > count( $data[ 'pod' ] ) )
  519. $data[ 'pod' ] = $api->load_pod( array( 'name' => $data[ 'pod' ][ 'name' ] ) );
  520. if ( empty( $data[ 'pod' ][ 'fields' ] ) )
  521. continue;
  522. if ( null === $data[ 'table' ] )
  523. $data[ 'table' ] = $data[ 'pod' ][ 'name' ];
  524. if ( $data[ 'reset' ] === true ) {
  525. if ( false !== $output )
  526. 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";
  527. $api->reset_pod( array( 'id' => $data[ 'pod' ][ 'id' ], 'name' => $data[ 'pod' ][ 'name' ] ) );
  528. }
  529. if ( null === $data[ 'sort' ] && null !== $data[ 'update_on' ] && isset( $data[ 'fields' ][ $data[ 'update_on' ] ] ) ) {
  530. if ( isset( $data[ 'fields' ][ $data[ 'update_on' ] ][ 'field' ] ) )
  531. $data[ 'sort' ] = $data[ 'fields' ][ $data[ 'update_on' ] ][ 'field' ];
  532. else
  533. $data[ 'sort' ] = $data[ 'update_on' ];
  534. }
  535. $page = 1;
  536. if ( false !== $data[ 'page_var' ] && isset( $_GET[ $data[ 'page_var' ] ] ) )
  537. $page = absval( $_GET[ $data[ 'page_var' ] ] );
  538. if ( null === $data[ 'sql' ] )
  539. $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']}" : '' );
  540. if ( false !== $output )
  541. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Getting Results: " . $data[ 'pod' ][ 'name' ] . "\n";
  542. if ( false !== $output )
  543. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Using Query: <small><code>" . $data[ 'sql' ] . "</code></small>\n";
  544. $result = $wpdb->get_results( $data[ 'sql' ], ARRAY_A );
  545. if ( false !== $output )
  546. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Results Found: " . count( $result ) . "\n";
  547. $avg_time = -1;
  548. $total_time = 0;
  549. $counter = 0;
  550. $avg_unit = 100;
  551. $avg_counter = 0;
  552. $result_count = count( $result );
  553. $paginated = false;
  554. if ( false !== $data[ 'page_var' ] && $result_count == $data[ 'limit' ] )
  555. $paginated = "<input type=\"button\" onclick=\"document.location=\'" . pods_ui_var_update( array( $data[ 'page_var' ] => $page + 1 ), false, false ) . "\';\" value=\" Continue Import &raquo; \" />";
  556. if ( $result_count < $avg_unit && 5 < $result_count )
  557. $avg_unit = number_format( $result_count / 5, 0, '', '' );
  558. elseif ( 2000 < $result_count && 10 < count( $data[ 'pod' ][ 'fields' ] ) )
  559. $avg_unit = 40;
  560. $data[ 'count' ] = $result_count;
  561. timer_start();
  562. if ( false !== $output && 1 == $import_counter )
  563. 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";
  564. foreach ( $result as $k => $row ) {
  565. flush();
  566. @ob_end_flush();
  567. usleep( 50000 );
  568. if ( false !== $output )
  569. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Processing Row #" . ( $k + 1 ) . "\n";
  570. if ( null !== $data[ 'row_filter' ] && function_exists( $data[ 'row_filter' ] ) ) {
  571. if ( false !== $output )
  572. 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";
  573. $row = $data[ 'row_filter' ]( $row, $data );
  574. }
  575. if ( !is_array( $row ) )
  576. continue;
  577. $params = array(
  578. 'datatype' => $data[ 'pod' ][ 'name' ],
  579. 'columns' => array(),
  580. 'bypass_helpers' => $data[ 'bypass_helpers' ]
  581. );
  582. foreach ( $data[ 'pod' ][ 'fields' ] as $fk => $field_info ) {
  583. $field = $field_info[ 'name' ];
  584. if ( !empty( $data[ 'fields' ] ) && !isset( $data[ 'fields' ][ $field ] ) && !in_array( $field, $data[ 'fields' ] ) )
  585. continue;
  586. if ( isset( $data[ 'fields' ][ $field ] ) ) {
  587. if ( is_array( $data[ 'fields' ][ $field ] ) )
  588. $field_data = $data[ 'fields' ][ $field ];
  589. else
  590. $field_data = array( 'field' => $data[ 'fields' ][ $field ] );
  591. }
  592. else
  593. $field_data = array();
  594. if ( !is_array( $field_data ) ) {
  595. $field = $field_data;
  596. $field_data = array();
  597. }
  598. $field_data = array_merge( $default_field_data, $field_data );
  599. if ( null === $field_data[ 'field' ] )
  600. $field_data[ 'field' ] = $field;
  601. $data[ 'fields' ][ $field ] = $field_data;
  602. $value = '';
  603. if ( isset( $row[ $field_data[ 'field' ] ] ) )
  604. $value = $row[ $field_data[ 'field' ] ];
  605. if ( null !== $field_data[ 'filter' ] ) {
  606. if ( function_exists( $field_data[ 'filter' ] ) ) {
  607. if ( false !== $output )
  608. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Filtering <strong>" . $field_data[ 'filter' ] . "</strong> on Field: " . $field . "\n";
  609. $value = $field_data[ 'filter' ]( $value, $row, $data );
  610. }
  611. else
  612. $value = '';
  613. }
  614. if ( 1 > strlen( $value ) && 1 == $field_info[ 'required' ] )
  615. die( '<h1 style="color:red;font-weight:bold;">ERROR: Field Required for <strong>' . $field . '</strong></h1>' );
  616. $params[ 'columns' ][ $field ] = $value;
  617. unset( $value );
  618. unset( $field_data );
  619. unset( $field_info );
  620. unset( $fk );
  621. }
  622. if ( empty( $params[ 'columns' ] ) )
  623. continue;
  624. $params[ 'columns' ] = pods_sanitize( $params[ 'columns' ] );
  625. if ( null !== $data[ 'update_on' ] && isset( $params[ 'columns' ][ $data[ 'update_on' ] ] ) ) {
  626. if ( false !== $output )
  627. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Checking for Existing Item\n";
  628. $check = new Pod( $data[ 'pod' ][ 'name' ] );
  629. $check->findRecords( array(
  630. 'orderby' => 't.id',
  631. 'limit' => 1,
  632. 'where' => "t.{$data['update_on']} = '{$params['columns'][$data['update_on']]}'",
  633. 'search' => false,
  634. 'page' => 1
  635. ) );
  636. if ( 0 < $check->getTotalRows() ) {
  637. $check->fetchRecord();
  638. $params[ 'tbl_row_id' ] = $check->get_field( 'id' );
  639. $params[ 'pod_id' ] = $check->get_pod_id();
  640. if ( false !== $output )
  641. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Found Existing Item w/ ID: " . $params[ 'tbl_row_id' ] . "\n";
  642. unset( $check );
  643. }
  644. if ( !isset( $params[ 'tbl_row_id' ] ) && false !== $output )
  645. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - Existing item not found - Creating New\n";
  646. }
  647. if ( null !== $data[ 'pre_save' ] && function_exists( $data[ 'pre_save' ] ) ) {
  648. if ( false !== $output )
  649. 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";
  650. $params = $data[ 'pre_save' ]( $params, $row, $data );
  651. }
  652. $id = $api->save_pod_item( $params );
  653. if ( false !== $output )
  654. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - <strong>Saved Row #" . ( $k + 1 ) . " w/ ID: " . $id . "</strong>\n";
  655. $params[ 'tbl_row_id' ] = $id;
  656. if ( null !== $data[ 'post_save' ] && function_exists( $data[ 'post_save' ] ) ) {
  657. if ( false !== $output )
  658. 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";
  659. $data[ 'post_save' ]( $params, $row, $data );
  660. }
  661. unset( $params );
  662. unset( $result[ $k ] );
  663. unset( $row );
  664. wp_cache_flush();
  665. $wpdb->queries = array();
  666. $avg_counter++;
  667. $counter++;
  668. if ( $avg_counter == $avg_unit && false !== $output ) {
  669. $avg_counter = 0;
  670. $avg_time = timer_stop( 0, 10 );
  671. $total_time += $avg_time;
  672. $rows_left = $result_count - $counter;
  673. $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60;
  674. $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count );
  675. 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";
  676. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <em>" . $data[ 'pod' ][ 'name' ] . "</em> - <strong>Updated Status:</strong> " . $percent_complete . "% Complete</strong>\n";
  677. }
  678. }
  679. if ( false !== $output ) {
  680. $avg_counter = 0;
  681. $avg_time = timer_stop( 0, 10 );
  682. $total_time += $avg_time;
  683. $rows_left = $result_count - $counter;
  684. $estimated_time_left = ( ( $total_time / $counter ) * $rows_left ) / 60;
  685. $percent_complete = 100 - ( ( $rows_left * 100 ) / $result_count );
  686. 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";
  687. 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";
  688. }
  689. unset( $result );
  690. unset( $import[ $datatype ] );
  691. unset( $datatype );
  692. unset( $data );
  693. wp_cache_flush();
  694. $wpdb->queries = array();
  695. }
  696. if ( false !== $output ) {
  697. $avg_counter = 0;
  698. $avg_time = timer_stop( 0, 10 );
  699. $total_time += $avg_time;
  700. $rows_left = $result_count - $counter;
  701. 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";
  702. echo "<br />" . date( 'Y-m-d h:i:sa' ) . " - <strong style='color:green;'>Import Complete</strong>\n";
  703. }
  704. }
  705. }