PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/marketpress/marketpress-includes/marketpress-importers.php

https://github.com/bfay/maniacal-kitten
PHP | 500 lines | 350 code | 93 blank | 57 comment | 70 complexity | 67e61da0020f79be22c925f3bf40b897 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-3.0, LGPL-2.1
  1. <?php
  2. /*
  3. MarketPress Importers
  4. */
  5. /*
  6. * Parent class to extend
  7. */
  8. class MarketPress_Importer {
  9. var $importer_name = '';
  10. var $results;
  11. function MarketPress_Importer() {
  12. $this->__construct();
  13. }
  14. function __construct() {
  15. global $mp;
  16. $priority = isset($_POST['mp_import-'.sanitize_title($this->importer_name)]) ? 1 : 10;
  17. add_action( 'marketpress_add_importer', array(&$this, '_html'), $priority );
  18. $this->on_creation();
  19. }
  20. function _html() {
  21. global $mp;
  22. if (isset($_POST['mp_import-'.sanitize_title($this->importer_name)])) {
  23. $this->process();
  24. remove_all_actions('marketpress_add_importer', 10);
  25. }
  26. ?>
  27. <div class="postbox">
  28. <h3 class='hndle'><span><?php printf(__('Import From %s', 'mp'), $this->importer_name); ?></span></h3>
  29. <div class="inside">
  30. <?php $this->display(); ?>
  31. </div>
  32. </div>
  33. <?php
  34. }
  35. /* Public methods */
  36. function import_button($label = '') {
  37. $label = !empty($label) ? $label : __('Import Now &raquo;', 'mp');
  38. ?>
  39. <p class="submit">
  40. <input class="button-primary" type="submit" name="mp_import-<?php echo sanitize_title($this->importer_name); ?>" value="<?php echo $label; ?>" />
  41. </p>
  42. <?php
  43. }
  44. function on_creation() {
  45. }
  46. function display() {
  47. }
  48. function process() {
  49. }
  50. }
  51. /* ------------------------------------------------------------------ */
  52. /* ----------------------- Begin Importers -------------------------- */
  53. /* ------------------------------------------------------------------ */
  54. /*
  55. * WP e-Commerce Plugin Importer
  56. */
  57. class WP_eCommerceImporter extends MarketPress_Importer {
  58. var $importer_name = 'WP e-Commerce';
  59. function display() {
  60. global $wpdb;
  61. if ($this->results) {
  62. ?>
  63. <p><?php printf( __('Successfully imported %s products from WP e-Commerce. The old products were not deleted, so running the importer again will just create copies of the products in MarketPress.', 'mp'), number_format_i18n($this->results) ); ?></p>
  64. <?php if ( class_exists('WP_eCommerce') ) { ?>
  65. <p><?php printf( __('You should <a href="%s">deactivate the WP e-Commerce plugin now</a>. Have fun!', 'mp'), wp_nonce_url(admin_url('plugins.php?action=deactivate&plugin=wp-e-commerce%2Fwp-shopping-cart.php'), 'deactivate-plugin_wp-e-commerce/wp-shopping-cart.php') ); ?></p>
  66. <?php
  67. }
  68. } else {
  69. $num_products = $wpdb->get_var("SELECT count(*) FROM $wpdb->posts WHERE post_type = 'wpsc-product'");
  70. if ($num_products) {
  71. ?>
  72. <span class="description"><?php _e('This will allow you to import your products and most of their attributes from the WP e-Commerce plugin.', 'mp'); ?></span>
  73. <p><?php printf( __('It appears that you have %s products from WP e-Commerce. Click below to begin your import!', 'mp'), number_format_i18n($num_products) ); ?></p>
  74. <?php
  75. if ( class_exists('WP_eCommerce') ) {
  76. $this->import_button();
  77. } else {
  78. ?>
  79. <p><?php _e('Please activate the WP e-Commerce plugin to import these products.', 'mp'); ?></p>
  80. <?php
  81. }
  82. } else { //no products
  83. ?>
  84. <p><?php printf( __('It appears you have no products from WP e-Commerce to import. Check that the plugin is updated to the latest version (the importer only works with >3.8).', 'mp'), wp_nonce_url(admin_url('plugins.php?action=deactivate&plugin=wp-e-commerce%2Fwp-shopping-cart.php'), 'deactivate-plugin_wp-e-commerce/wp-shopping-cart.php') ); ?></p>
  85. <?php
  86. }
  87. }
  88. }
  89. function process() {
  90. global $wpdb;
  91. set_time_limit(90); //this can take a while
  92. $this->results = 0;
  93. $products = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_type = 'wpsc-product'", ARRAY_A);
  94. foreach ($products as $product) {
  95. //import product
  96. $old_id = $product['ID'];
  97. unset($product['ID']); //clear id so it inserts as new
  98. $product['post_type'] = 'product';
  99. $product['comment_status'] = 'closed';
  100. $product['comment_count'] = 0;
  101. //add tags
  102. $tags = wp_get_object_terms($old_id, 'product_tag');
  103. if (is_array($tags) && count($tags)) {
  104. $product_tags = array();
  105. foreach ($tags as $tag) {
  106. $product_tags[] = $tag->name;
  107. }
  108. $product_tags = join(", ", $product_tags);
  109. $product['tax_input']['product_tag'] = $product_tags;
  110. }
  111. $new_id = wp_insert_post($product); //create the post
  112. //insert categories
  113. $cats = wp_get_object_terms($old_id, 'wpsc_product_category');
  114. if (is_array($cats) && count($cats)) {
  115. $product_cats = array();
  116. foreach ($cats as $cat) {
  117. $product_cats[] = $cat->name;
  118. }
  119. wp_set_object_terms($new_id, $product_cats, 'product_category');
  120. }
  121. //add product meta
  122. $meta = get_post_custom($old_id);
  123. $meta_data = unserialize($meta['_wpsc_product_metadata'][0]);
  124. update_post_meta($new_id, 'mp_sku', $meta['_wpsc_sku']); //add sku
  125. update_post_meta($new_id, 'mp_price', $meta['_wpsc_price']); //add price
  126. //add sale price only if set and different than reg price
  127. if (isset($meta['_wpsc_special_price'][0]) && $meta['_wpsc_special_price'][0] && $meta['_wpsc_special_price'][0] != $meta['_wpsc_price'][0]) {
  128. update_post_meta($new_id, 'mp_is_sale', 1);
  129. update_post_meta($new_id, 'mp_sale_price', $meta['_wpsc_special_price']);
  130. }
  131. //add stock count
  132. if (isset($meta['_wpsc_stock'][0]) && $meta['_wpsc_stock'][0]) {
  133. update_post_meta($new_id, 'mp_track_inventory', 1);
  134. update_post_meta($new_id, 'mp_inventory', $meta['_wpsc_stock']);
  135. }
  136. //add external link
  137. if (!empty($meta_data['external_link']))
  138. update_post_meta($new_id, 'mp_product_link', esc_url_raw($meta_data['external_link']));
  139. //add shipping info
  140. $shipping = array();
  141. if (!empty($meta_data['shipping']['local']))
  142. $shipping['extra_cost'] = round( (float)preg_replace('/[^0-9.]/', '', $meta_data['shipping']['local']), 2 );
  143. if (!empty($meta_data['weight']))
  144. $shipping['weight'] = round( (float)preg_replace('/[^0-9.]/', '', $meta_data['weight']), 2 );
  145. update_post_meta($new_id, 'mp_shipping', $shipping);
  146. //add thumbnail
  147. if (isset($meta['_thumbnail_id'][0])) { //if featured image is set
  148. update_post_meta($new_id, '_thumbnail_id', $meta['_thumbnail_id'][0]);
  149. } else { //grab first attachment as there is no featured image
  150. $images =& get_children( "post_type=attachment&post_mime_type=image&post_parent=$old_id" );
  151. $thumbnail_id = false;
  152. foreach ( (array) $images as $attachment_id => $attachment ) {
  153. $thumbnail_id = $attachment_id;
  154. break; //only grab the first attachment
  155. }
  156. if ($thumbnail_id)
  157. update_post_meta($new_id, '_thumbnail_id', $thumbnail_id);
  158. }
  159. //get first downloadable product url
  160. $args = array(
  161. 'post_type' => 'wpsc-product-file',
  162. 'post_parent' => $old_id,
  163. 'numberposts' => 1,
  164. 'post_status' => 'any'
  165. );
  166. $attached_files = (array)get_posts($args);
  167. if (count($attached_files))
  168. update_post_meta($new_id, 'mp_file', esc_url_raw($attached_files[0]->guid));
  169. //inc count
  170. $this->results++;
  171. }
  172. }
  173. }
  174. //only load if the plugin is active and installed
  175. $mp_wpecommerce = new WP_eCommerceImporter();
  176. /*
  177. * CSV Importer
  178. */
  179. class CsvImporter extends MarketPress_Importer {
  180. var $importer_name = 'CSV';
  181. function display() {
  182. global $mp;
  183. $file_path = $this->file_path();
  184. //delete file
  185. if (isset($_GET['csv_del']) && file_exists($file_path)) {
  186. @unlink($file_path);
  187. echo '<div class="updated fade"><p>'.__('Import file successfully deleted.', 'mp').'</p></div>';
  188. }
  189. //if uploaded file
  190. if ( isset($_FILES['csv_file']['name']) && current_user_can('upload_files') ) {
  191. //make sure directory exists
  192. wp_mkdir_p( $this->file_path(true) );
  193. //check extension
  194. if ( preg_match( '!\.(csv)$!i', strtolower($_FILES['csv_file']['name']) ) ) {
  195. //attempt to move uploaded file
  196. if (!move_uploaded_file($_FILES['csv_file']['tmp_name'], $file_path)) {
  197. @unlink($_FILES['csv_file']['tmp_name']);
  198. echo '<div class="error"><p>'.__('There was a problem uploading your file. Please check permissions or use FTP.', 'mp').'</p></div>';
  199. } else {
  200. //check for required fields
  201. $headers = $this->get_csv_headers();
  202. if ( !in_array('title', $headers) || !in_array('price', $headers) ) {
  203. @unlink($file_path);
  204. echo '<div class="error"><p>'.__('The CSV file must contain at a minimum the "title" and "price" columns. Please fix and upload again.', 'mp').'</p></div>';
  205. }
  206. }
  207. } else {
  208. @unlink($_FILES['csv_file']['tmp_name']);
  209. echo '<div class="error"><p>'.__('Invalid file format. Please upload your import file ending in ".csv".', 'mp').'</p></div>';
  210. }
  211. }
  212. if ($this->results) {
  213. @unlink($file_path);
  214. ?>
  215. <p><?php printf( __('Successfully imported %s products from your CSV file. Products were created in draft status, so you will need to review them then publish (bulk or one-by-one). Importing the CSV file again will just create copies of the products in MarketPress.', 'mp'), number_format_i18n($this->results) ); ?></p>
  216. <p><a class="button" href="<?php echo admin_url('edit.php?post_status=draft&post_type=product'); ?>"><?php _e('Review Now &raquo;', 'mp'); ?></a></p>
  217. <?php
  218. } else {
  219. //if file has been uploaded
  220. if ( file_exists($file_path) ) {
  221. $total = count($this->get_csv_array());
  222. ?>
  223. <h4><?php echo sprintf(__('A CSV import file was detected with %d products to process.', 'mp'), $total); ?> <a class="button" href="<?php echo admin_url('edit.php?post_type=product&page=marketpress&tab=importers&csv_del=1'); ?>" title="<?php _e("Delete the current CSV import file", 'mp'); ?>"><?php _e("Re-upload", 'mp'); ?></a></h4>
  224. <p><?php _e('Please be patient while products are being imported. Ready?', 'mp') ?></p>
  225. <?php
  226. $this->import_button();
  227. } else { //file does not exist, show upload form
  228. $dirs = wp_upload_dir();
  229. ?>
  230. <span class="description"><?php _e('This will allow you to import products and most of their attributes from a CSV file.', 'mp'); ?></span>
  231. <p><span class="description"><?php _e('Your CSV file must be comma (,) delimited and fields with commas or quotes in them must be surrounded by parenthesis (") as per the CSV standard. Columns in the CSV file can be in any order, provided that they have the correct headings from the example file. "title" and "price" are the only required columns, all others can be left blank.', 'mp'); ?></span></p>
  232. <p><span class="description"><?php printf(__('To import featured images, it is preferable to upload them via FTP to a directory in your WP uploads folder: %s. Image paths should be relative to the uploads folder, like "/myimport/myimage.png". You may also include full external image urls and the importer will download them. This is not a preferable though because it can be too slow for a large import, and you may need to split your CSV file into multple imports to avoid timeouts. A spreadsheet program like Excel or Numbers can be used to easily manipulate your import file, and their save as CSV option will create a correctly formatted file.', 'mp'), $dirs['basedir']); ?></span></p>
  233. <p><?php _e('Please select and upload your CSV file below.', 'mp'); ?>
  234. <a href="<?php echo $mp->plugin_url; ?>sample-marketpress-import.csv" target="_blank"><?php _e('Use this example file &raquo;', 'mp'); ?></a>
  235. </p>
  236. <p>
  237. <input name="csv_file" id="csv_file" size="20" type="file" />
  238. <input class="button-secondary" name="Submit" value="<?php _e('Upload &raquo;', 'mp') ?>" type="submit"><br />
  239. <small><?php echo __('Maximum file size: ', 'mp') . ini_get('upload_max_filesize'); ?></small>
  240. </p>
  241. <?php
  242. } //end file exists
  243. }
  244. }
  245. function process() {
  246. global $wpdb;
  247. set_time_limit(120); //this can take a while
  248. $this->results = 0;
  249. $products = $this->get_csv_array();
  250. $dirs = wp_upload_dir();
  251. foreach ($products as $row) {
  252. $product = array();
  253. if (empty($row['title']) || empty($row['price']))
  254. continue;
  255. //import product
  256. $product['post_title'] = $row['title'];
  257. $product['post_content'] = $row['description'];
  258. $product['post_status'] = 'draft';
  259. $product['post_type'] = 'product';
  260. $product['comment_status'] = 'closed';
  261. $product['comment_count'] = 0;
  262. //add tags
  263. if (!empty($row['tags']))
  264. $product['tax_input']['product_tag'] = trim($row['tags']);
  265. $new_id = wp_insert_post($product); //create the post
  266. //insert categories
  267. if (!empty($row['categories'])) {
  268. $product_cats = explode(',', trim($row['categories']));
  269. $product_cats = array_map('trim', $product_cats);
  270. wp_set_object_terms($new_id, $product_cats, 'product_category');
  271. }
  272. //add product meta
  273. update_post_meta($new_id, 'mp_sku', array( preg_replace("/[^a-zA-Z0-9_-]/", "", trim(@$row['sku'])) ) ); //add sku
  274. update_post_meta($new_id, 'mp_price', array( round( (float)preg_replace('/[^0-9.]/', '', $row['price']), 2 ) ) ); //add price
  275. update_post_meta($new_id, 'mp_var_name', array('') ); //add blank var name
  276. //add sale price only if set
  277. if (!empty($row['sale_price'])) {
  278. update_post_meta($new_id, 'mp_is_sale', 1);
  279. update_post_meta($new_id, 'mp_sale_price', array( round( (float)preg_replace('/[^0-9.]/', '', $row['sale_price']), 2 ) ) );
  280. update_post_meta($new_id, 'mp_price_sort', round( (float)preg_replace('/[^0-9.]/', '', $row['sale_price']), 2 ));
  281. } else {
  282. update_post_meta($new_id, 'mp_is_sale', 0);
  283. update_post_meta($new_id, 'mp_price_sort', round( (float)preg_replace('/[^0-9.]/', '', $row['price']), 2 ));
  284. }
  285. //add stock count if set
  286. if (!empty($row['stock'])) {
  287. update_post_meta($new_id, 'mp_track_inventory', 1);
  288. update_post_meta($new_id, 'mp_inventory', array( intval($row['stock']) ));
  289. } else {
  290. update_post_meta($new_id, 'mp_track_inventory', 0);
  291. }
  292. //add external link
  293. if (!empty($row['external_link']))
  294. update_post_meta($new_id, 'mp_product_link', esc_url_raw($row['external_link']));
  295. //add shipping info
  296. $shipping = array();
  297. if (!empty($row['extra_shipping']))
  298. $shipping['extra_cost'] = round( (float)preg_replace('/[^0-9.]/', '', $row['extra_shipping']), 2 );
  299. if (!empty($row['weight']))
  300. $shipping['weight'] = round( (float)preg_replace('/[^0-9.]/', '', $row['weight']), 2 );
  301. update_post_meta($new_id, 'mp_shipping', $shipping);
  302. //download
  303. if (!empty($row['download_url']))
  304. update_post_meta($new_id, 'mp_file', esc_url_raw($row['download_url']));
  305. //download
  306. if (isset($row['sales_count']))
  307. update_post_meta($new_id, 'mp_sales_count', intval($row['sales_count']));
  308. //add featured images
  309. if (isset($row['image']) && !empty($row['image'])) {
  310. // Determine if this file is in our server
  311. $local = false;
  312. $img_location = str_replace($dirs['baseurl'], $dirs['basedir'], $row['image']);
  313. if ( file_exists($img_location) ) {
  314. $local = true;
  315. } else if ( file_exists($dirs['basedir'] . '/' . ltrim($row['image'], '/')) ) {
  316. $local = true;
  317. $img_location = $dirs['basedir'] . '/' . ltrim($row['image'], '/');
  318. }
  319. if ( $local ) { //just resize without downloading as it's on our server
  320. preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $img_location, $matches );
  321. $file_array = array();
  322. $file_array['name'] = basename($matches[0]);
  323. $file_array['tmp_name'] = $img_location;
  324. // do the validation and storage stuff
  325. $id = media_handle_sideload( $file_array, $new_id, $row['title'] );
  326. // If error storing permanently, unlink
  327. if ( !is_wp_error($id) ) {
  328. // add featured image to post
  329. add_post_meta($new_id, '_thumbnail_id', $id);
  330. }
  331. } else { //download the image and attach
  332. require_once(ABSPATH . '/wp-admin/includes/file.php');
  333. $img_html = media_sideload_image( $row['image'], $new_id, $row['title'] );
  334. if ( !is_wp_error($img_html) ) {
  335. //figure out the id
  336. $args = array(
  337. 'numberposts' => 1,
  338. 'order'=> 'DESC',
  339. 'post_mime_type' => 'image',
  340. 'post_parent' => $new_id,
  341. 'post_type' => 'attachment'
  342. );
  343. $get_children_array = get_children($args, ARRAY_A); //returns Array ( [$image_ID]...
  344. $rekeyed_array = array_values($get_children_array);
  345. $child_image = $rekeyed_array[0];
  346. // add featured image to post
  347. add_post_meta($new_id, '_thumbnail_id', $child_image['ID']);
  348. }
  349. }
  350. }
  351. //inc count
  352. $this->results++;
  353. }
  354. }
  355. function get_csv_headers() {
  356. $file_path = $this->file_path();
  357. @ini_set('auto_detect_line_endings', true); //so it doesn't choke on mac CR line endings
  358. $fh = @fopen($file_path, 'r');
  359. if ($fh) {
  360. $temp_fields = fgetcsv($fh, 5120); // 5KB
  361. if (is_array($temp_fields))
  362. $headers = array_map('strtolower', $temp_fields);
  363. fclose($fh);
  364. return $headers;
  365. } else {
  366. return false;
  367. }
  368. }
  369. function get_csv_array() {
  370. $file_path = $this->file_path();
  371. $i = 0;
  372. @ini_set('auto_detect_line_endings', true); //so it doesn't choke on mac CR line endings
  373. $fh = @fopen($file_path, 'r');
  374. if ($fh) {
  375. while (!feof($fh)) {
  376. //parse csv line
  377. $temp_fields = fgetcsv($fh, 5120); // 5KB
  378. if (is_array($temp_fields)) {
  379. if (!isset($titles))
  380. $titles = array_map('strtolower', $temp_fields);
  381. //switch keys out for titles
  382. $new_fields = array();
  383. foreach ($temp_fields as $key => $value) {
  384. $new_fields[$titles[$key]] = $value;
  385. }
  386. $fields[] = $new_fields;
  387. }
  388. }
  389. fclose($fh);
  390. //remove header row
  391. array_shift($fields);
  392. return $fields;
  393. } else {
  394. return false;
  395. }
  396. }
  397. function file_path($dir = false) {
  398. $target_path = wp_upload_dir();
  399. if ($dir)
  400. return trailingslashit($target_path['basedir']);
  401. else
  402. return trailingslashit($target_path['basedir']) . 'marketpress-import.csv';
  403. }
  404. }
  405. //only load if the plugin is active and installed
  406. $mp_csv = new CsvImporter();
  407. ?>