Advertisement
Guest User

Marketplace.php

a guest
Jun 27th, 2012
765
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 306.48 KB | None | 0 0
  1. <?php
  2. /*
  3. Plugin Name: MarketPress
  4. Version: 2.5.9
  5. Plugin URI: http://premium.wpmudev.org/project/e-commerce
  6. Description: The complete WordPress ecommerce plugin - works perfectly with BuddyPress and Multisite too to create a social marketplace, where you can take a percentage! Activate the plugin, adjust your settings then add some products to your store.
  7. Author: Aaron Edwards (Incsub)
  8. Author URI: http://uglyrobot.com
  9. Text Domain: mp
  10. WDP ID: 144
  11.  
  12. Copyright 2009-2012 Incsub (http://incsub.com)
  13.  
  14. This program is free software; you can redistribute it and/or modify
  15. it under the terms of the GNU General Public License (Version 2 - GPLv2) as published by
  16. the Free Software Foundation.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program; if not, write to the Free Software
  25. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27.  
  28. class MarketPress {
  29.  
  30. var $version = '2.5.9';
  31. var $location;
  32. var $plugin_dir = '';
  33. var $plugin_url = '';
  34. var $product_template;
  35. var $product_taxonomy_template;
  36. var $product_list_template;
  37. var $store_template;
  38. var $checkout_template;
  39. var $orderstatus_template;
  40. var $language = '';
  41. var $checkout_error = false;
  42. var $cart_cache = false;
  43. var $is_shop_page = false;
  44. var $global_cart = false;
  45. var $skip_shipping_notice = false;
  46.  
  47. function MarketPress() {
  48. $this->__construct();
  49. }
  50.  
  51. function __construct() {
  52. //setup our variables
  53. $this->init_vars();
  54.  
  55. //install plugin
  56. register_activation_hook( __FILE__, array($this, 'install') );
  57.  
  58. //load template functions
  59. require_once( $this->plugin_dir . 'template-functions.php' );
  60.  
  61. //load shortcodes
  62. include_once( $this->plugin_dir . 'marketpress-shortcodes.php' );
  63.  
  64. //load stats
  65. include_once( $this->plugin_dir . 'marketpress-stats.php' );
  66.  
  67. //load sitewide features if WPMU
  68. if (is_multisite()) {
  69. include_once( $this->plugin_dir . 'marketpress-ms.php' );
  70. $network_settings = get_site_option( 'mp_network_settings' );
  71. if ( $network_settings['global_cart'] )
  72. $this->global_cart = true;
  73. }
  74.  
  75. $settings = get_option('mp_settings');
  76.  
  77. //localize the plugin
  78. add_action( 'plugins_loaded', array(&$this, 'localization'), 9 );
  79.  
  80. //load APIs and plugins
  81. add_action( 'plugins_loaded', array(&$this, 'load_plugins') );
  82.  
  83. //load importers
  84. add_action( 'plugins_loaded', array(&$this, 'load_importers') );
  85.  
  86. //custom post type
  87. add_action( 'init', array(&$this, 'register_custom_posts'), 0 ); //super high priority
  88. add_filter( 'request', array(&$this, 'handle_edit_screen_filter') );
  89.  
  90. //edit products page
  91. add_filter( 'manage_product_posts_columns', array(&$this, 'edit_products_columns') );
  92. add_action( 'manage_posts_custom_column', array(&$this, 'edit_products_custom_columns') );
  93. add_action( 'restrict_manage_posts', array(&$this, 'edit_products_filter') );
  94.  
  95. //manage orders page
  96. add_filter( 'manage_product_page_marketpress-orders_columns', array(&$this, 'manage_orders_columns') );
  97. add_action( 'manage_posts_custom_column', array(&$this, 'manage_orders_custom_columns') );
  98.  
  99. //Plug admin pages
  100. add_action( 'admin_menu', array(&$this, 'add_menu_items') );
  101. add_action( 'admin_print_styles', array(&$this, 'admin_css') );
  102. add_action( 'admin_print_scripts', array(&$this, 'admin_script_post') );
  103. add_action( 'admin_notices', array(&$this, 'admin_nopermalink_warning') );
  104. add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'plugin_action_link'), 10, 2);
  105. add_action( 'wp_ajax_mp-hide-help', array(&$this, 'hide_help') );
  106.  
  107. //Meta boxes
  108. add_action( 'add_meta_boxes_product', array(&$this, 'meta_boxes') );
  109. add_action( 'wp_insert_post', array(&$this, 'save_product_meta'), 10, 2 );
  110. add_filter( 'enter_title_here', array(&$this, 'filter_title') );
  111.  
  112. //Templates and Rewrites
  113. add_action( 'wp', array(&$this, 'load_store_templates') );
  114. add_action( 'template_redirect', array(&$this, 'load_store_theme') );
  115. add_action( 'pre_get_posts', array(&$this, 'remove_canonical') );
  116. add_filter( 'rewrite_rules_array', array(&$this, 'add_rewrite_rules') );
  117. add_filter( 'query_vars', array(&$this, 'add_queryvars') );
  118. add_action( 'option_rewrite_rules', array(&$this, 'check_rewrite_rules') );
  119. if ( !defined('MP_HIDE_MENUS') ) { //allows you to hide MP menus
  120. add_filter( 'wp_list_pages', array(&$this, 'filter_list_pages'), 10, 2 );
  121. add_filter( 'wp_nav_menu_objects', array(&$this, 'filter_nav_menu'), 10, 2 );
  122. }
  123.  
  124. //Payment gateway returns
  125. add_action( 'pre_get_posts', array(&$this, 'handle_gateway_returns'), 1 );
  126.  
  127. //Store cart handling
  128. add_action( 'template_redirect', array(&$this, 'store_script') ); //only on front pages
  129. /* use both actions so logged in and not logged in users can send this AJAX request */
  130. add_action( 'wp_ajax_nopriv_mp-update-cart', array(&$this, 'update_cart') );
  131. add_action( 'wp_ajax_mp-update-cart', array(&$this, 'update_cart') );
  132. add_action( 'wp_ajax_mp-province-field', 'mp_province_field' ); //province field callback for shipping form
  133. add_action( 'wp_ajax_nopriv_mp-province-field', 'mp_province_field' );
  134. add_action( 'wp_ajax_mp-orders-export', array(&$this, 'export_orders_csv') );
  135. add_action( 'wp_logout', array(&$this, 'logout_clear_session') ); //see http://premium.wpmudev.org/forums/topic/security-issue-with-marketpress
  136.  
  137. //Relies on post thumbnails for products
  138. add_action( 'after_setup_theme', array(&$this, 'post_thumbnails'), 9999 );
  139.  
  140. //Add widgets
  141. if (!$settings['disable_cart'])
  142. add_action( 'widgets_init', create_function('', 'return register_widget("MarketPress_Shopping_Cart");') );
  143.  
  144. add_action( 'widgets_init', create_function('', 'return register_widget("MarketPress_Product_List");') );
  145. add_action( 'widgets_init', create_function('', 'return register_widget("MarketPress_Categories_Widget");') );
  146. add_action( 'widgets_init', create_function('', 'return register_widget("MarketPress_Tag_Cloud_Widget");') );
  147.  
  148. // Edit profile
  149. add_action( 'profile_update', array(&$this, 'user_profile_update') );
  150. add_action( 'edit_user_profile', array(&$this, 'user_profile_fields') );
  151. add_action( 'show_user_profile', array(&$this, 'user_profile_fields') );
  152.  
  153. //update install script if necessary
  154. if (get_option('mp_version') != $this->version) {
  155. $this->install();
  156. }
  157. }
  158.  
  159. function install() {
  160. $old_settings = get_option('mp_settings');
  161. $old_version = get_option('mp_version');
  162.  
  163. //our default settings
  164. $default_settings = array (
  165. 'base_country' => 'US',
  166. 'tax' => array (
  167. 'rate' => 0,
  168. 'tax_shipping' => 1,
  169. 'tax_inclusive' => 0
  170. ),
  171. 'currency' => 'USD',
  172. 'curr_symbol_position' => 1,
  173. 'curr_decimal' => 1,
  174. 'disable_cart' => 0,
  175. 'hide_popup' => 0,
  176. 'inventory_threshhold' => 3,
  177. 'max_downloads' => 5,
  178. 'force_login' => 0,
  179. 'ga_ecommerce' => 'none',
  180. 'special_instructions' => 0,
  181. 'store_theme' => 'icons',
  182. 'show_img' => 1,
  183. 'product_img_height' => 150,
  184. 'product_img_width' => 150,
  185. 'list_img_height' => 150,
  186. 'list_img_width' => 150,
  187. 'show_excerpt' => 1,
  188. 'per_page' => 20,
  189. 'order_by' => 'title',
  190. /* Translators: change default slugs here */
  191. 'slugs' => array (
  192. 'store' => __('store', 'mp'),
  193. 'products' => __('products', 'mp'),
  194. 'cart' => __('shopping-cart', 'mp'),
  195. 'orderstatus' => __('order-status', 'mp'),
  196. 'category' => __('category', 'mp'),
  197. 'tag' => __('tag', 'mp')
  198. ),
  199. 'product_button_type' => 'addcart',
  200. 'show_quantity' => 1,
  201. 'product_img_size' => 'medium',
  202. 'show_lightbox' => 1,
  203. 'list_view' => 'list',
  204. 'list_button_type' => 'addcart',
  205. 'show_thumbnail' => 1,
  206. 'list_img_size' => 'thumbnail',
  207. 'paginate' => 1,
  208. 'order' => 'DESC',
  209. 'shipping' => array (
  210. 'allowed_countries' => array ('CA', 'US'),
  211. 'method' => 'flat-rate',
  212. 'system' => 'english'
  213. ),
  214. 'gateways' => array (
  215. 'paypal-express' => array (
  216. 'locale' => 'US',
  217. 'currency' => 'USD',
  218. 'mode' => 'sandbox'
  219. ),
  220. 'paypal-chained' => array (
  221. 'currency' => 'USD',
  222. 'mode' => 'sandbox'
  223. )
  224. ),
  225. 'msg' => array (
  226. 'product_list' => '',
  227. 'order_status' => __('<p>If you have any questions about your order please do not hesitate to contact us.</p>', 'mp'),
  228. 'cart' => '',
  229. 'shipping' => __('<p>Please enter your shipping information in the form below to proceed with your order.</p>', 'mp'),
  230. 'checkout' => '',
  231. 'confirm_checkout' => __('<p>You are almost done! Please do a final review of your order to make sure everything is correct then click the "Confirm Payment" button.</p>', 'mp'),
  232. 'success' => __('<p>Thank you for your order! We appreciate your business, and please come back often to check out our new products.</p>', 'mp')
  233. ),
  234. 'store_email' => get_option("admin_email"),
  235. 'email' => array (
  236. 'new_order_subject' => __('Your Order Confirmation (ORDERID)', 'mp'),
  237. 'new_order_txt' => __("Thank you for your order CUSTOMERNAME!
  238.  
  239. Your order has been received, and any items to be shipped will be processed as soon as possible. Please refer to your Order ID (ORDERID) whenever contacting us.
  240. Here is a confirmation of your order details:
  241.  
  242. Order Information:
  243. ORDERINFO
  244.  
  245. Shipping Information:
  246. SHIPPINGINFO
  247.  
  248. Payment Information:
  249. PAYMENTINFO
  250.  
  251. ORDERNOTES
  252.  
  253. You can track the latest status of your order here: TRACKINGURL
  254.  
  255. Thanks again!", 'mp'),
  256. 'shipped_order_subject' => __('Your Order Has Been Shipped! (ORDERID)', 'mp'),
  257. 'shipped_order_txt' => __("Dear CUSTOMERNAME,
  258.  
  259. Your order has been shipped! Depending on the shipping method and your location it should be arriving shortly. Please refer to your Order ID (ORDERID) whenever contacting us.
  260. Here is a confirmation of your order details:
  261.  
  262. Order Information:
  263. ORDERINFO
  264.  
  265. Shipping Information:
  266. SHIPPINGINFO
  267.  
  268. Payment Information:
  269. PAYMENTINFO
  270.  
  271. ORDERNOTES
  272.  
  273. You can track the latest status of your order here: TRACKINGURL
  274.  
  275. Thanks again!", 'mp')
  276. )
  277. );
  278.  
  279. //filter default settings
  280. $default_settings = apply_filters( 'mp_default_settings', $default_settings );
  281. $settings = wp_parse_args( (array)$old_settings, $default_settings );
  282. update_option( 'mp_settings', $settings );
  283.  
  284. //2.1.4 update
  285. if ( version_compare($old_version, '2.1.4', '<') )
  286. $this->update_214();
  287.  
  288. //only run these on first install
  289. if ( empty($old_settings) ) {
  290.  
  291. //define settings that don't need to autoload for efficiency
  292. add_option( 'mp_coupons', '', '', 'no' );
  293. add_option( 'mp_store_page', '', '', 'no' );
  294.  
  295. //create store page
  296. add_action( 'admin_init', array(&$this, 'create_store_page') );
  297.  
  298. //add cart widget to first sidebar
  299. add_action( 'widgets_init', array(&$this, 'add_default_widget'), 11 );
  300. }
  301.  
  302. //add action to flush rewrite rules after we've added them for the first time
  303. add_action( 'init', array(&$this, 'flush_rewrite'), 999 );
  304.  
  305. update_option( 'mp_version', $this->version );
  306. }
  307.  
  308. //run on 2.1.4 update to fix price sorts
  309. function update_214() {
  310. global $wpdb;
  311.  
  312. $posts = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product'");
  313.  
  314. foreach ($posts as $post_id) {
  315. $meta = get_post_custom($post_id);
  316. //unserialize
  317. foreach ($meta as $key => $val) {
  318. $meta[$key] = maybe_unserialize($val[0]);
  319. if (!is_array($meta[$key]) && $key != "mp_is_sale" && $key != "mp_track_inventory" && $key != "mp_product_link" && $key != "mp_file" && $key != "mp_price_sort")
  320. $meta[$key] = array($meta[$key]);
  321. }
  322.  
  323. //fix price sort field if missing
  324. if ( empty($meta["mp_price_sort"]) && is_array($meta["mp_price"]) ) {
  325. if ( $meta["mp_is_sale"] && $meta["mp_sale_price"][0] )
  326. $sort_price = $meta["mp_sale_price"][0];
  327. else
  328. $sort_price = $meta["mp_price"][0];
  329. update_post_meta($post_id, 'mp_price_sort', $sort_price);
  330. }
  331. }
  332. }
  333.  
  334. function localization() {
  335. // Load up the localization file if we're using WordPress in a different language
  336. // Place it in this plugin's "languages" folder and name it "mp-[value in wp-config].mo"
  337. if ($this->location == 'mu-plugins')
  338. load_muplugin_textdomain( 'mp', '/marketpress-includes/languages/' );
  339. else if ($this->location == 'subfolder-plugins')
  340. load_plugin_textdomain( 'mp', false, '/marketpress/marketpress-includes/languages/' );
  341. else if ($this->location == 'plugins')
  342. load_plugin_textdomain( 'mp', false, '/marketpress-includes/languages/' );
  343.  
  344. //setup language code for jquery datepicker translation
  345. $temp_locales = explode('_', get_locale());
  346. $this->language = ($temp_locales[0]) ? $temp_locales[0] : 'en';
  347. }
  348.  
  349. function init_vars() {
  350. //setup proper directories
  351. if (defined('WP_PLUGIN_URL') && defined('WP_PLUGIN_DIR') && file_exists(WP_PLUGIN_DIR . '/marketpress/' . basename(__FILE__))) {
  352. $this->location = 'subfolder-plugins';
  353. $this->plugin_dir = WP_PLUGIN_DIR . '/marketpress/marketpress-includes/';
  354. $this->plugin_url = plugins_url( '/marketpress-includes/', __FILE__ );
  355. } else if (defined('WP_PLUGIN_URL') && defined('WP_PLUGIN_DIR') && file_exists(WP_PLUGIN_DIR . '/' . basename(__FILE__))) {
  356. $this->location = 'plugins';
  357. $this->plugin_dir = WP_PLUGIN_DIR . '/marketpress-includes/';
  358. $this->plugin_url = plugins_url( '/marketpress-includes/', __FILE__ );
  359. } else if (is_multisite() && defined('WPMU_PLUGIN_URL') && defined('WPMU_PLUGIN_DIR') && file_exists(WPMU_PLUGIN_DIR . '/' . basename(__FILE__))) {
  360. $this->location = 'mu-plugins';
  361. $this->plugin_dir = WPMU_PLUGIN_DIR . '/marketpress-includes/';
  362. $this->plugin_url = WPMU_PLUGIN_URL . '/marketpress-includes/';
  363. } else {
  364. wp_die(__('There was an issue determining where MarketPress is installed. Please reinstall.', 'mp'));
  365. }
  366.  
  367. //load data structures
  368. require_once( $this->plugin_dir . 'marketpress-data.php' );
  369.  
  370. }
  371.  
  372. /* Only load code that needs BuddyPress to run once BP is loaded and initialized. */
  373. function load_bp_features() {
  374. include_once( $this->plugin_dir . 'marketpress-bp.php' );
  375. }
  376.  
  377. function load_importers() {
  378. include_once( $this->plugin_dir . 'marketpress-importers.php' );
  379. }
  380.  
  381. function load_plugins() {
  382. $settings = get_option('mp_settings');
  383.  
  384. if (is_network_admin() || !$settings['disable_cart']) {
  385. //load shipping plugin API
  386. require_once( $this->plugin_dir . 'marketpress-shipping.php' );
  387. $this->load_shipping_plugins();
  388.  
  389. //load gateway plugin API
  390. require_once( $this->plugin_dir . 'marketpress-gateways.php' );
  391. $this->load_gateway_plugins();
  392. }
  393. }
  394.  
  395. function load_shipping_plugins() {
  396.  
  397. //save settings from screen. Put here to be before plugin is loaded
  398. if (isset($_POST['shipping_settings'])) {
  399. $settings = get_option('mp_settings');
  400. //allow plugins to verify settings before saving
  401. $settings = array_merge($settings, apply_filters('mp_shipping_settings_filter', $_POST['mp']));
  402. update_option('mp_settings', $settings);
  403. }
  404.  
  405. //get shipping plugins dir
  406. $dir = $this->plugin_dir . 'plugins-shipping/';
  407.  
  408. //search the dir for files
  409. $shipping_plugins = array();
  410. if ( !is_dir( $dir ) )
  411. return;
  412. if ( ! $dh = opendir( $dir ) )
  413. return;
  414. while ( ( $plugin = readdir( $dh ) ) !== false ) {
  415. if ( substr( $plugin, -4 ) == '.php' )
  416. $shipping_plugins[] = $dir . $plugin;
  417. }
  418. closedir( $dh );
  419. sort( $shipping_plugins );
  420.  
  421. //include them suppressing errors
  422. foreach ($shipping_plugins as $file)
  423. @include_once( $file );
  424.  
  425. //allow plugins from an external location to register themselves
  426. do_action('mp_load_shipping_plugins');
  427.  
  428. //load chosen plugin class
  429. global $mp_shipping_plugins, $mp_shipping_active_plugins;
  430. $settings = get_option('mp_settings');
  431.  
  432. if ($settings['shipping']['method'] == 'calculated') {
  433. //load just the calculated ones
  434. foreach ((array)$mp_shipping_plugins as $code => $plugin) {
  435. if ($plugin[2]) {
  436. if ( isset($settings['shipping']['calc_methods'][$code]) && class_exists($plugin[0]) && !$plugin[3] )
  437. $mp_shipping_active_plugins[$code] = new $plugin[0];
  438. }
  439. }
  440. } else {
  441. //load only and all calculated ones
  442. $class = $mp_shipping_plugins[$settings['shipping']['method']][0];
  443. if (class_exists($class))
  444. $mp_shipping_active_plugins[$settings['shipping']['method']] = new $class;
  445. }
  446. }
  447.  
  448. function load_gateway_plugins() {
  449.  
  450. //save settings from screen. Put here to be before plugin is loaded
  451. if (isset($_POST['gateway_settings'])) {
  452. $settings = get_option('mp_settings');
  453.  
  454. //see if there are checkboxes checked
  455. if ( isset( $_POST['mp'] ) ) {
  456.  
  457. //clear allowed array as it will be refilled
  458. unset( $settings['gateways']['allowed'] );
  459.  
  460. //allow plugins to verify settings before saving
  461. $settings = array_merge($settings, apply_filters('mp_gateway_settings_filter', $_POST['mp']));
  462. } else {
  463. //blank array if no checkboxes
  464. $settings['gateways']['allowed'] = array();
  465. }
  466.  
  467. update_option('mp_settings', $settings);
  468. }
  469.  
  470. //get gateway plugins dir
  471. $dir = $this->plugin_dir . 'plugins-gateway/';
  472.  
  473. //search the dir for files
  474. $gateway_plugins = array();
  475. if ( !is_dir( $dir ) )
  476. return;
  477. if ( ! $dh = opendir( $dir ) )
  478. return;
  479. while ( ( $plugin = readdir( $dh ) ) !== false ) {
  480. if ( substr( $plugin, -4 ) == '.php' )
  481. $gateway_plugins[] = $dir . '/' . $plugin;
  482. }
  483. closedir( $dh );
  484. sort( $gateway_plugins );
  485.  
  486. //include them suppressing errors
  487. foreach ($gateway_plugins as $file)
  488. include( $file );
  489.  
  490. //allow plugins from an external location to register themselves
  491. do_action('mp_load_gateway_plugins');
  492.  
  493. //load chosen plugin classes
  494. global $mp_gateway_plugins, $mp_gateway_active_plugins;
  495. $settings = get_option('mp_settings');
  496. $network_settings = get_site_option( 'mp_network_settings' );
  497.  
  498. foreach ((array)$mp_gateway_plugins as $code => $plugin) {
  499. $class = $plugin[0];
  500. //if global cart is enabled force it
  501. if ( $this->global_cart ) {
  502. if ( $code == $network_settings['global_gateway'] && class_exists($class) ) {
  503. $mp_gateway_active_plugins[] = new $class;
  504. break;
  505. }
  506. } else {
  507. if ( in_array($code, (array)$settings['gateways']['allowed']) && class_exists($class) && !$plugin[3] )
  508. $mp_gateway_active_plugins[] = new $class;
  509. }
  510. }
  511. }
  512.  
  513. function handle_gateway_returns($wp_query) {
  514. //listen for gateway IPN returns and tie them in to proper gateway plugin
  515. if(!empty($wp_query->query_vars['paymentgateway'])) {
  516. do_action( 'mp_handle_payment_return_' . $wp_query->query_vars['paymentgateway'] );
  517. // exit();
  518. }
  519.  
  520. //stop canonical problems with virtual pages
  521. $page = get_query_var('pagename');
  522. if ($page == 'cart' || $page == 'orderstatus' || $page == 'product_list') {
  523. remove_action('template_redirect', 'redirect_canonical');
  524. }
  525. }
  526.  
  527. function remove_canonical($wp_query) {
  528. //stop canonical problems with virtual pages redirecting
  529. $page = get_query_var('pagename');
  530. if ($page == 'cart' || $page == 'orderstatus' || $page == 'product_list') {
  531. remove_action('template_redirect', 'redirect_canonical');
  532. }
  533. }
  534.  
  535. function admin_nopermalink_warning() {
  536. //warns admins if permalinks are not enabled on the blog
  537. if ( current_user_can('manage_options') && !get_option('permalink_structure') )
  538. echo '<div class="error"><p>'.__('You must enable Pretty Permalinks</a> to use MarketPress - <a href="options-permalink.php">Enable now &raquo;</a>', 'mp').'</p></div>';
  539. }
  540.  
  541. function plugin_action_link($links, $file) {
  542. // the anchor tag and href to the URL we want. For a "Settings" link, this needs to be the url of your settings page
  543. $settings_link = '<a href="' . admin_url('edit.php?post_type=product&page=marketpress') . '">' . __('Settings', 'mp') . '</a>';
  544. // add the link to the list
  545. array_unshift($links, $settings_link);
  546. return $links;
  547. }
  548.  
  549. function add_menu_items() {
  550. $settings = get_option('mp_settings');
  551.  
  552. //only process the manage orders page for editors and above and if orders hasn't been disabled
  553. if (current_user_can('edit_others_posts') && !$settings['disable_cart']) {
  554. $num_posts = wp_count_posts('mp_order'); //get pending order count
  555. $count = $num_posts->order_received + $num_posts->order_paid;
  556. if ( $count > 0 )
  557. $count_output = '&nbsp;<span class="update-plugins"><span class="updates-count count-' . $count . '">' . $count . '</span></span>';
  558. else
  559. $count_output = '';
  560. $orders_page = add_submenu_page('edit.php?post_type=product', __('Manage Orders', 'mp'), __('Manage Orders', 'mp') . $count_output, 'edit_others_posts', 'marketpress-orders', array(&$this, 'orders_page'));
  561. }
  562.  
  563. $page = add_submenu_page('edit.php?post_type=product', __('Store Settings', 'mp'), __('Store Settings', 'mp'), 'manage_options', 'marketpress', array(&$this, 'admin_page'));
  564. add_action( 'admin_print_scripts-' . $page, array(&$this, 'admin_script_settings') );
  565. add_action( 'admin_print_styles-' . $page, array(&$this, 'admin_css_settings') );
  566. add_contextual_help($page, '<iframe src="http://premium.wpmudev.org/wdp-un.php?action=help&id=144" width="100%" height="600px"></iframe>');
  567. }
  568.  
  569. function admin_css() {
  570. wp_enqueue_style( 'mp-admin-css', $this->plugin_url . 'css/marketpress.css', false, $this->version);
  571. }
  572.  
  573. //enqeue js on custom post edit screen
  574. function admin_script_post() {
  575. global $current_screen;
  576. if ($current_screen->id == 'product')
  577. wp_enqueue_script( 'mp-post', $this->plugin_url . 'js/post-screen.js', array('jquery'), $this->version);
  578. }
  579.  
  580. //enqeue css on product settings screen
  581. function admin_css_settings() {
  582. wp_enqueue_style( 'jquery-datepicker-css', $this->plugin_url . 'datepicker/css/ui-lightness/datepicker.css', false, $this->version);
  583. wp_enqueue_style( 'jquery-colorpicker-css', $this->plugin_url . 'colorpicker/css/colorpicker.css', false, $this->version);
  584. }
  585.  
  586. //enqeue js on product settings screen
  587. function admin_script_settings() {
  588. wp_enqueue_script( 'jquery-colorpicker', $this->plugin_url . 'colorpicker/js/colorpicker.js', array('jquery'), $this->version);
  589. wp_enqueue_script( 'jquery-datepicker', $this->plugin_url . 'datepicker/js/datepicker.min.js', array('jquery', 'jquery-ui-core'), $this->version);
  590.  
  591. //only load languages for datepicker if not english (or it will show Chinese!)
  592. if ($this->language != 'en')
  593. wp_enqueue_script( 'jquery-datepicker-i18n', $this->plugin_url . 'datepicker/js/datepicker-i18n.min.js', array('jquery', 'jquery-ui-core', 'jquery-datepicker'), $this->version);
  594.  
  595. $settings = get_option('mp_settings');
  596. if (intval($settings['hide_popup']) < 3) {
  597. wp_enqueue_script( 'mp-need-help', $this->plugin_url . 'js/need-help.js', array('jquery'), $this->version);
  598. $settings['hide_popup'] = intval($settings['hide_popup']) + 1;
  599. update_option('mp_settings', $settings);
  600. }
  601. }
  602.  
  603. //ties into the ajax request to disable help popup if clicked
  604. function hide_help() {
  605. $settings = get_option('mp_settings');
  606. $settings['hide_popup'] = 3;
  607. update_option('mp_settings', $settings);
  608. }
  609.  
  610. //ajax cart handling for store frontend
  611. function store_script() {
  612. //disable ajax cart if incompatible by domain mapping plugin settings
  613. if (is_multisite() && class_exists('domain_map') && 'original' == get_site_option('map_admindomain'))
  614. return;
  615.  
  616. //setup ajax cart javascript
  617. wp_enqueue_script( 'mp-ajax-js', $this->plugin_url . 'js/ajax-cart.js', array('jquery'), $this->version );
  618.  
  619. // declare the variables we need to access in js
  620. wp_localize_script( 'mp-ajax-js', 'MP_Ajax', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'emptyCartMsg' => __('Are you sure you want to remove all items from your cart?', 'mp'), 'successMsg' => __('Item(s) Added!', 'mp'), 'imgUrl' => $this->plugin_url.'images/loading.gif', 'addingMsg' => __('Adding to your cart...', 'mp'), 'outMsg' => __('In Your Cart', 'mp') ) );
  621. }
  622.  
  623. //loads the jquery lightbox plugin
  624. function enqueue_lightbox() {
  625.  
  626. $settings = get_option('mp_settings');
  627. if (!$settings['show_lightbox'])
  628. return;
  629.  
  630. wp_enqueue_style( 'jquery-lightbox', $this->plugin_url . 'lightbox/style/lumebox.css', false, $this->version );
  631. wp_enqueue_script( 'jquery-lightbox', $this->plugin_url . 'lightbox/js/jquery.lumebox.min.js', array('jquery'), $this->version, true );
  632.  
  633. // declare the variables we need to access in js
  634. $js_vars = array( 'graphicsDir' => $this->plugin_url . 'lightbox/style/' );
  635. wp_localize_script( 'jquery-lightbox', 'lumeboxOptions', $js_vars );
  636. }
  637.  
  638. //if cart widget is not in a sidebar, add it to the top of the first sidebar. Only runs at initial install
  639. function add_default_widget() {
  640. if (!is_active_widget(false, false, 'mp_cart_widget')) {
  641. $sidebars_widgets = wp_get_sidebars_widgets();
  642. if ( is_array($sidebars_widgets) ) {
  643. foreach ( $sidebars_widgets as $sidebar => $widgets ) {
  644. if ( 'wp_inactive_widgets' == $sidebar )
  645. continue;
  646.  
  647. if ( is_array($widgets) ) {
  648. array_unshift($widgets, 'mp_cart_widget-1');
  649. $sidebars_widgets[$sidebar] = $widgets;
  650. wp_set_sidebars_widgets( $sidebars_widgets );
  651. $settings = array();
  652. $settings[1] = array( 'title' => __('Shopping Cart', 'mp'), 'custom_text' => '', 'show_thumbnail' => 1, 'size' => 25 );
  653. $settings['_multiwidget'] = 1;
  654. update_option( 'widget_mp_cart_widget', $settings );
  655. return true;
  656. }
  657. }
  658. }
  659. }
  660. }
  661.  
  662. //creates the store page on install and updates
  663. function create_store_page($old_slug = false) {
  664. global $wpdb, $user_ID;
  665. $settings = get_option('mp_settings');
  666.  
  667. //remove old page if updating
  668. if ($old_slug && $old_slug != $settings['slugs']['store']) {
  669. $old_post_id = $wpdb->get_var("SELECT ID FROM " . $wpdb->posts . " WHERE post_name = '$old_slug' AND post_type = 'page'");
  670. $old_post = get_post($old_post_id);
  671.  
  672. $old_post->post_name = $settings['slugs']['store'];
  673. wp_update_post($old_post);
  674. }
  675.  
  676. //insert new page if not existing
  677. $page_count = $wpdb->get_var("SELECT COUNT(*) FROM " . $wpdb->posts . " WHERE post_name = '" . $settings['slugs']['store'] . "' AND post_type = 'page'");
  678. if ( !$page_count ) {
  679.  
  680. //default page content
  681. $content = '<p>' . __('Welcome to our online store! Feel free to browse around:', 'mp') . '</p>';
  682. $content .= '[mp_store_navigation]';
  683. $content .= '<p>' . __('Check out our most popular products:', 'mp') . '</p>';
  684. $content .= '[mp_popular_products]';
  685. $content .= '<p>' . __('Browse by category:', 'mp') . '</p>';
  686. $content .= '[mp_list_categories]';
  687. $content .= '<p>' . __('Browse by tag:', 'mp') . '</p>';
  688. $content .= '[mp_tag_cloud]';
  689.  
  690. $id = wp_insert_post( array('post_title' => __('Store', 'mp'), 'post_name' => $settings['slugs']['store'], 'post_status' => 'publish', 'post_type' => 'page', 'post_content' => $content ) );
  691. update_option('mp_store_page', $id);
  692. }
  693. }
  694.  
  695. function register_custom_posts() {
  696. ob_start();
  697.  
  698. $settings = get_option('mp_settings');
  699.  
  700. // Register custom taxonomy
  701. register_taxonomy( 'product_category', 'product', apply_filters( 'mp_register_product_category', array("hierarchical" => true, 'label' => __('Product Categories', 'mp'), 'singular_label' => __('Product Category', 'mp'), 'rewrite' => array('slug' => $settings['slugs']['store'] . '/' . $settings['slugs']['products'] . '/' . $settings['slugs']['category'])) ) );
  702. register_taxonomy( 'product_tag', 'product', apply_filters( 'mp_register_product_tag', array("hierarchical" => false, 'label' => __('Product Tags', 'mp'), 'singular_label' => __('Product Tag', 'mp'), 'rewrite' => array('slug' => $settings['slugs']['store'] . '/' . $settings['slugs']['products'] . '/' . $settings['slugs']['tag'])) ) );
  703.  
  704. // Register custom product post type
  705. $supports = array( 'title', 'editor', 'author', 'excerpt', 'revisions', 'thumbnail' );
  706. $args = array (
  707. 'labels' => array('name' => __('Products', 'mp'),
  708. 'singular_name' => __('Product', 'mp'),
  709. 'add_new' => __('Create New', 'mp'),
  710. 'add_new_item' => __('Create New Product', 'mp'),
  711. 'edit_item' => __('Edit Products', 'mp'),
  712. 'edit' => __('Edit', 'mp'),
  713. 'new_item' => __('New Product', 'mp'),
  714. 'view_item' => __('View Product', 'mp'),
  715. 'search_items' => __('Search Products', 'mp'),
  716. 'not_found' => __('No Products Found', 'mp'),
  717. 'not_found_in_trash' => __('No Products found in Trash', 'mp'),
  718. 'view' => __('View Product', 'mp')
  719. ),
  720. 'description' => __('Products for your MarketPress store.', 'mp'),
  721. 'menu_icon' => $this->plugin_url . 'images/marketpress-icon.png',
  722. 'public' => true,
  723. 'show_ui' => true,
  724. 'publicly_queryable' => true,
  725. 'capability_type' => 'page',
  726. 'hierarchical' => false,
  727. 'rewrite' => array('slug' => $settings['slugs']['store'] . '/' . $settings['slugs']['products'], 'with_front' => false), // Permalinks format
  728. 'query_var' => true,
  729. 'supports' => $supports
  730. );
  731. register_post_type( 'product' , apply_filters( 'mp_register_post_type', $args ) );
  732.  
  733. //register the orders post type
  734. register_post_type( 'mp_order', array(
  735. 'labels' => array('name' => __('Orders', 'mp'),
  736. 'singular_name' => __('Order', 'mp'),
  737. 'edit' => __('Edit', 'mp'),
  738. 'view_item' => __('View Order', 'mp'),
  739. 'search_items' => __('Search Orders', 'mp'),
  740. 'not_found' => __('No Orders Found', 'mp')
  741. ),
  742. 'description' => __('Orders from your MarketPress store.', 'mp'),
  743. 'public' => false,
  744. 'show_ui' => false,
  745. 'capability_type' => apply_filters( 'mp_orders_capability', 'page' ),
  746. 'hierarchical' => false,
  747. 'rewrite' => false,
  748. 'query_var' => false,
  749. 'supports' => array()
  750. ) );
  751.  
  752. //register custom post statuses for our orders
  753. register_post_status( 'order_received', array(
  754. 'label' => __('Received', 'mp'),
  755. 'label_count' => array( __('Received <span class="count">(%s)</span>', 'mp'), __('Received <span class="count">(%s)</span>', 'mp') ),
  756. 'post_type' => 'mp_order',
  757. 'public' => false
  758. ) );
  759. register_post_status( 'order_paid', array(
  760. 'label' => __('Paid', 'mp'),
  761. 'label_count' => array( __('Paid <span class="count">(%s)</span>', 'mp'), __('Paid <span class="count">(%s)</span>', 'mp') ),
  762. 'post_type' => 'mp_order',
  763. 'public' => false
  764. ) );
  765. register_post_status( 'order_shipped', array(
  766. 'label' => __('Shipped', 'mp'),
  767. 'label_count' => array( __('Shipped <span class="count">(%s)</span>', 'mp'), __('Shipped <span class="count">(%s)</span>', 'mp') ),
  768. 'post_type' => 'mp_order',
  769. 'public' => false
  770. ) );
  771. register_post_status( 'order_closed', array(
  772. 'label' => __('Closed', 'mp'),
  773. 'label_count' => array( __('Closed <span class="count">(%s)</span>', 'mp'), __('Closed <span class="count">(%s)</span>', 'mp') ),
  774. 'post_type' => 'mp_order',
  775. 'public' => false
  776. ) );
  777. }
  778.  
  779. //necessary to mod array directly rather than with add_theme_support() to play nice with other themes. See http://www.wptavern.com/forum/plugins-hacks/1751-need-help-enabling-post-thumbnails-custom-post-type.html
  780. function post_thumbnails() {
  781. global $_wp_theme_features;
  782.  
  783. if( !isset( $_wp_theme_features['post-thumbnails'] ) )
  784. $_wp_theme_features['post-thumbnails'] = array( array( 'product' ) );
  785. else if ( is_array( $_wp_theme_features['post-thumbnails'] ) )
  786. $_wp_theme_features['post-thumbnails'][0][] = 'product';
  787. }
  788.  
  789. // This function clears the rewrite rules and forces them to be regenerated
  790. function flush_rewrite() {
  791. global $wp_rewrite;
  792. $wp_rewrite->flush_rules();
  793. }
  794.  
  795. function add_rewrite_rules($rules){
  796. $settings = get_option('mp_settings');
  797.  
  798. $new_rules = array();
  799.  
  800. //product list
  801. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['products'] . '/?$'] = 'index.php?pagename=product_list';
  802. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['products'] . '/page/?([0-9]{1,})/?$'] = 'index.php?pagename=product_list&paged=$matches[1]';
  803.  
  804. //checkout page
  805. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['cart'] . '/?$'] = 'index.php?pagename=cart';
  806. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['cart'] . '/([^/]+)/?$'] = 'index.php?pagename=cart&checkoutstep=$matches[1]';
  807.  
  808. //order status page
  809. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['orderstatus'] . '/?$'] = 'index.php?pagename=orderstatus';
  810. $new_rules[$settings['slugs']['store'] . '/' . $settings['slugs']['orderstatus'] . '/([^/]+)/?$'] = 'index.php?pagename=orderstatus&order_id=$matches[1]';
  811.  
  812. //ipn handling for payment gateways
  813. $new_rules[$settings['slugs']['store'] . '/payment-return/(.+)'] = 'index.php?paymentgateway=$matches[1]';
  814.  
  815. return array_merge($new_rules, $rules);
  816. }
  817.  
  818. //unfortunately some plugins flush rewrites before the init hook so they kill custom post type rewrites. This function verifies they are in the final array and flushes if not
  819. function check_rewrite_rules($value) {
  820. $settings = get_option('mp_settings');
  821.  
  822. //prevent an infinite loop by only
  823. if ( ! post_type_exists( 'product' ) )
  824. return $value;
  825.  
  826. if ( is_array($value) && !in_array('index.php?product=$matches[1]&paged=$matches[2]', $value) ) {
  827. $this->flush_rewrite();
  828. } else {
  829. return $value;
  830. }
  831. }
  832.  
  833. function add_queryvars($vars) {
  834. // This function add the checkout queryvars to the list that WordPress is looking for.
  835. if(!in_array('checkoutstep', $vars))
  836. $vars[] = 'checkoutstep';
  837.  
  838. if(!in_array('order_id', $vars))
  839. $vars[] = 'order_id';
  840.  
  841. if(!in_array('paymentgateway', $vars))
  842. $vars[] = 'paymentgateway';
  843.  
  844. return $vars;
  845. }
  846.  
  847. function start_session() {
  848. //start the sessions for cart handling
  849. if (session_id() == "")
  850. session_start();
  851. }
  852.  
  853. function logout_clear_session() {
  854. $this->start_session();
  855.  
  856. //clear personal info
  857. unset($_SESSION['mp_shipping_info']);
  858. unset($_SESSION['mp_billing_info']);
  859.  
  860. //remove coupon code
  861. if (is_multisite()) {
  862. global $blog_id;
  863. unset($_SESSION['mp_cart_coupon_' . $blog_id]);
  864. } else {
  865. unset($_SESSION['mp_cart_coupon']);
  866. }
  867. }
  868.  
  869. //scans post type at template_redirect to apply custom themeing to products
  870. function load_store_templates() {
  871. global $wp_query, $mp_wpmu, $mp_gateway_active_plugins;
  872. $settings = get_option('mp_settings');
  873.  
  874. //load proper theme for single product page display
  875. if ($wp_query->is_single && $wp_query->query_vars['post_type'] == 'product') {
  876.  
  877. //check for custom theme templates
  878. $product_name = get_query_var('product');
  879. $product_id = (int) $wp_query->get_queried_object_id();
  880.  
  881. //serve download if it exists
  882. $this->serve_download($product_id);
  883.  
  884. $templates = array();
  885. if ( $product_name )
  886. $templates[] = "mp_product-$product_name.php";
  887. if ( $product_id )
  888. $templates[] = "mp_product-$product_id.php";
  889. $templates[] = "mp_product.php";
  890.  
  891. //if custom template exists load it
  892. if ($this->product_template = locate_template($templates)) {
  893. add_filter( 'template_include', array(&$this, 'custom_product_template') );
  894. } else {
  895. //otherwise load the page template and use our own theme
  896. $wp_query->is_single = null;
  897. $wp_query->is_page = 1;
  898. add_filter( 'the_content', array(&$this, 'product_theme'), 99 );
  899.  
  900. //genesis fixes
  901. remove_action( 'genesis_post_content', 'genesis_do_post_image' );
  902. remove_action( 'genesis_post_content', 'genesis_do_post_content' );
  903. add_action('genesis_post_content', 'the_content');
  904. }
  905.  
  906. $this->is_shop_page = true;
  907.  
  908. //enqueue lightbox on single product page
  909. $this->enqueue_lightbox();
  910.  
  911. }
  912.  
  913. //load proper theme for main store page
  914. if ($wp_query->query_vars['pagename'] == $settings['slugs']['store']) {
  915.  
  916. //check for custom theme template
  917. $templates = array("mp_store.php");
  918.  
  919. //if custom template exists load it
  920. if ($this->store_template = locate_template($templates)) {
  921. add_filter( 'template_include', array(&$this, 'custom_store_template') );
  922. } else {
  923. //otherwise load the page template and use our own theme
  924. add_filter( 'the_content', array(&$this, 'store_theme'), 99 );
  925. }
  926.  
  927. $this->is_shop_page = true;
  928. }
  929.  
  930. //load proper theme for checkout page
  931. if ($wp_query->query_vars['pagename'] == 'cart') {
  932.  
  933. //init session for store pages
  934. $this->start_session();
  935.  
  936. //process cart updates
  937. $this->update_cart();
  938.  
  939. //if global cart is on forward to main site checkout
  940. if ( $this->global_cart && is_object($mp_wpmu) && !$mp_wpmu->is_main_site() ) {
  941. wp_redirect( mp_cart_link(false, true) );
  942. exit;
  943. }
  944.  
  945. // Redirect to https if forced to use SSL by a payment gateway
  946. if (get_query_var('checkoutstep')) {
  947. foreach ((array)$mp_gateway_active_plugins as $plugin) {
  948. if ($plugin->force_ssl) {
  949. if ( !is_ssl() ) {
  950. wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
  951. exit();
  952. }
  953. }
  954. }
  955. }
  956.  
  957. //force login if required
  958. if (!is_user_logged_in() && $settings['force_login'] && get_query_var('checkoutstep')) {
  959. wp_redirect( wp_login_url( mp_checkout_step_url( get_query_var('checkoutstep') ) ) );
  960. exit();
  961. }
  962.  
  963. //setup shopping cart javascript
  964. wp_enqueue_script( 'mp-store-js', $this->plugin_url . 'js/store.js', array('jquery'), $this->version );
  965.  
  966. //check for custom theme template
  967. $templates = array("mp_cart.php");
  968.  
  969. //if custom template exists load it
  970. if ($this->checkout_template = locate_template($templates)) {
  971. add_filter( 'template_include', array(&$this, 'custom_checkout_template') );
  972. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  973. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  974. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  975. } else {
  976. //otherwise load the page template and use our own theme
  977. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  978. add_filter( 'the_title', array(&$this, 'page_title_output'), 99 );
  979. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  980. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  981. add_filter( 'the_content', array(&$this, 'checkout_theme'), 99 );
  982. }
  983.  
  984. $wp_query->is_page = 1;
  985. $wp_query->is_singular = 1;
  986. $wp_query->is_404 = null;
  987. $wp_query->post_count = 1;
  988.  
  989. $this->is_shop_page = true;
  990. }
  991.  
  992. //load proper theme for order status page
  993. if ($wp_query->query_vars['pagename'] == 'orderstatus') {
  994.  
  995. //check for custom theme template
  996. $templates = array("mp_orderstatus.php");
  997.  
  998. //if custom template exists load it
  999. if ($this->orderstatus_template = locate_template($templates)) {
  1000. add_filter( 'template_include', array(&$this, 'custom_orderstatus_template') );
  1001. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1002. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1003. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1004. } else {
  1005. //otherwise load the page template and use our own theme
  1006. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1007. add_filter( 'the_title', array(&$this, 'page_title_output'), 99 );
  1008. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1009. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1010. add_filter( 'the_content', array(&$this, 'orderstatus_theme'), 99 );
  1011. }
  1012.  
  1013. $wp_query->is_page = 1;
  1014. $wp_query->is_singular = 1;
  1015. $wp_query->is_404 = false;
  1016. $wp_query->post_count = 1;
  1017.  
  1018. $this->is_shop_page = true;
  1019. }
  1020.  
  1021. //load proper theme for product listings
  1022. if ($wp_query->query_vars['pagename'] == 'product_list') {
  1023.  
  1024. //check for custom theme template
  1025. $templates = array("mp_productlist.php");
  1026.  
  1027. //if custom template exists load it
  1028. if ($this->product_list_template = locate_template($templates)) {
  1029.  
  1030. //call a custom query posts for this listing
  1031. //setup pagination
  1032. if ($settings['paginate']) {
  1033. //figure out perpage
  1034. $paginate_query = '&posts_per_page='.$settings['per_page'];
  1035.  
  1036. //figure out page
  1037. if ($wp_query->query_vars['paged'])
  1038. $paginate_query .= '&paged='.intval($wp_query->query_vars['paged']);
  1039. } else {
  1040. $paginate_query = '&nopaging=true';
  1041. }
  1042.  
  1043. //get order by
  1044. if ($settings['order_by'] == 'price')
  1045. $order_by_query = '&meta_key=mp_price&orderby=mp_price';
  1046. else if ($settings['order_by'] == 'sales')
  1047. $order_by_query = '&meta_key=mp_sales_count&orderby=mp_sales_count';
  1048. else
  1049. $order_by_query = '&orderby='.$settings['order_by'];
  1050.  
  1051. //get order direction
  1052. $order_query = '&order='.$settings['order'];
  1053.  
  1054. //The Query
  1055. query_posts('post_type=product' . $paginate_query . $order_by_query . $order_query);
  1056.  
  1057. add_filter( 'template_include', array(&$this, 'custom_product_list_template') );
  1058. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1059. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1060. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1061. } else {
  1062. //otherwise load the page template and use our own theme
  1063. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1064. add_filter( 'the_title', array(&$this, 'page_title_output'), 99 );
  1065. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1066. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1067. add_filter( 'the_content', array(&$this, 'product_list_theme'), 99 );
  1068. add_filter( 'the_excerpt', array(&$this, 'product_list_theme'), 99 );
  1069.  
  1070. //genesis fixes
  1071. remove_action( 'genesis_post_content', 'genesis_do_post_image' );
  1072. remove_action( 'genesis_post_content', 'genesis_do_post_content' );
  1073. add_action('genesis_post_content', 'the_content');
  1074. }
  1075.  
  1076. $wp_query->is_page = 1;
  1077. //$wp_query->is_singular = 1;
  1078. $wp_query->is_404 = null;
  1079. $wp_query->post_count = 1;
  1080.  
  1081. $this->is_shop_page = true;
  1082. }
  1083.  
  1084. //load proper theme for product category or tag listings
  1085. if ($wp_query->query_vars['taxonomy'] == 'product_category' || $wp_query->query_vars['taxonomy'] == 'product_tag') {
  1086. $templates = array();
  1087.  
  1088. if ($wp_query->query_vars['taxonomy'] == 'product_category') {
  1089.  
  1090. $cat_name = get_query_var('product_category');
  1091. $cat_id = absint( $wp_query->get_queried_object_id() );
  1092. if ( $cat_name )
  1093. $templates[] = "mp_category-$cat_name.php";
  1094. if ( $cat_id )
  1095. $templates[] = "mp_category-$cat_id.php";
  1096. $templates[] = "mp_category.php";
  1097.  
  1098. } else if ($wp_query->query_vars['taxonomy'] == 'product_tag') {
  1099.  
  1100. $tag_name = get_query_var('product_tag');
  1101. $tag_id = absint( $wp_query->get_queried_object_id() );
  1102. if ( $tag_name )
  1103. $templates[] = "mp_tag-$tag_name.php";
  1104. if ( $tag_id )
  1105. $templates[] = "mp_tag-$tag_id.php";
  1106. $templates[] = "mp_tag.php";
  1107.  
  1108. }
  1109.  
  1110. //defaults
  1111. $templates[] = "mp_taxonomy.php";
  1112. $templates[] = "mp_productlist.php";
  1113.  
  1114. //override if id is passed, mainly for product category dropdown widget
  1115. if ( is_numeric( get_query_var($wp_query->query_vars['taxonomy']) ) ) {
  1116. $term = get_term( get_query_var($wp_query->query_vars['taxonomy']), $wp_query->query_vars['taxonomy'] );
  1117. $wp_query->query_vars[$wp_query->query_vars['taxonomy']] = $term->slug;
  1118. $wp_query->query_vars['term'] = $term->slug;
  1119. }
  1120.  
  1121. //if custom template exists load it
  1122. if ($this->product_taxonomy_template = locate_template($templates)) {
  1123.  
  1124. //call a custom query posts for this listing
  1125. $taxonomy_query = '&' . $wp_query->query_vars['taxonomy'] . '=' . get_query_var($wp_query->query_vars['taxonomy']);
  1126.  
  1127. //setup pagination
  1128. if ($settings['paginate']) {
  1129. //figure out perpage
  1130. $paginate_query = '&posts_per_page='.$settings['per_page'];
  1131.  
  1132. //figure out page
  1133. if ($wp_query->query_vars['paged'])
  1134. $paginate_query .= '&paged='.intval($wp_query->query_vars['paged']);
  1135. } else {
  1136. $paginate_query = '&nopaging=true';
  1137. }
  1138.  
  1139. //get order by
  1140. if ($settings['order_by'] == 'price')
  1141. $order_by_query = '&meta_key=mp_price&orderby=mp_price';
  1142. else if ($settings['order_by'] == 'sales')
  1143. $order_by_query = '&meta_key=mp_sales_count&orderby=mp_sales_count';
  1144. else
  1145. $order_by_query = '&orderby='.$settings['order_by'];
  1146.  
  1147. //get order direction
  1148. $order_query = '&order='.$settings['order'];
  1149.  
  1150. //The Query
  1151. query_posts('post_type=product' . $taxonomy_query . $paginate_query . $order_by_query . $order_query);
  1152.  
  1153. add_filter( 'template_include', array(&$this, 'custom_product_taxonomy_template'));
  1154. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1155. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1156. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1157. } else {
  1158. //otherwise load the page template and use our own list theme. We don't use theme's taxonomy as not enough control
  1159. $wp_query->is_page = 1;
  1160. //$wp_query->is_singular = 1;
  1161. $wp_query->is_404 = null;
  1162. $wp_query->post_count = 1;
  1163. add_filter( 'single_post_title', array(&$this, 'page_title_output'), 99 );
  1164. add_filter( 'bp_page_title', array(&$this, 'page_title_output'), 99 );
  1165. add_filter( 'wp_title', array(&$this, 'wp_title_output'), 19, 3 );
  1166. add_filter( 'the_title', array(&$this, 'page_title_output'), 99, 2 );
  1167. add_filter( 'the_content', array(&$this, 'product_taxonomy_list_theme'), 99 );
  1168. add_filter( 'the_excerpt', array(&$this, 'product_taxonomy_list_theme'), 99 );
  1169.  
  1170. //genesis fixes
  1171. remove_action( 'genesis_post_content', 'genesis_do_post_image' );
  1172. remove_action( 'genesis_post_content', 'genesis_do_post_content' );
  1173. add_action('genesis_post_content', 'the_content');
  1174. }
  1175.  
  1176. $this->is_shop_page = true;
  1177. }
  1178.  
  1179. //load shop specific items
  1180. if ($this->is_shop_page) {
  1181. //fixes a nasty bug in BP theme's functions.php file which always loads the activity stream if not a normal page
  1182. remove_all_filters('page_template');
  1183.  
  1184. //prevents 404 for virtual pages
  1185. status_header( 200 );
  1186. }
  1187. }
  1188.  
  1189. //loads the selected theme css files
  1190. function load_store_theme() {
  1191. $settings = get_option('mp_settings');
  1192.  
  1193. if ( $settings['store_theme'] == 'none' || current_theme_supports('mp_style') ) {
  1194. return;
  1195. } else if (file_exists($this->plugin_dir . 'themes/' . $settings['store_theme'] . '.css')) {
  1196. wp_enqueue_style( 'mp-store-theme', $this->plugin_url . 'themes/' . $settings['store_theme'] . '.css', false, $this->version );
  1197. } else if (file_exists(WP_CONTENT_DIR . '/marketpress-styles/' . $settings['store_theme'] . '.css')) {
  1198. wp_enqueue_style( 'mp-store-theme', WP_CONTENT_URL . '/marketpress-styles/' . $settings['store_theme'] . '.css', false, $this->version );
  1199. }
  1200.  
  1201. }
  1202.  
  1203. //list store themes in dropdown
  1204. function store_themes_select() {
  1205. $settings = get_option('mp_settings');
  1206.  
  1207. //get theme dir
  1208. $theme_dir = $this->plugin_dir . 'themes/';
  1209.  
  1210. //scan directory for theme css files
  1211. $theme_list = array();
  1212. if ($handle = @opendir($theme_dir)) {
  1213. while (false !== ($file = readdir($handle))) {
  1214. if (($pos = strrpos($file, '.css')) !== false) {
  1215. $value = substr($file, 0, $pos);
  1216. if (is_readable("$theme_dir/$file")) {
  1217. $theme_data = get_file_data( "$theme_dir/$file", array('name' => 'MarketPress Style') );
  1218. if (is_array($theme_data))
  1219. $theme_list[$value] = $theme_data['name'];
  1220. }
  1221. }
  1222. }
  1223.  
  1224. @closedir($handle);
  1225. }
  1226.  
  1227. //scan wp-content/marketpress-styles/ directory for theme css files
  1228. $theme_dir = WP_CONTENT_DIR . '/marketpress-styles/';
  1229. if ($handle = @opendir($theme_dir)) {
  1230. while (false !== ($file = readdir($handle))) {
  1231. if (($pos = strrpos($file, '.css')) !== false) {
  1232. $value = substr($file, 0, $pos);
  1233. if (is_readable("$theme_dir/$file")) {
  1234. $theme_data = get_file_data( "$theme_dir/$file", array('name' => 'MarketPress Style') );
  1235. if (is_array($theme_data))
  1236. $theme_list[$value] = $theme_data['name'];
  1237. }
  1238. }
  1239. }
  1240.  
  1241. @closedir($handle);
  1242. }
  1243.  
  1244. //sort the themes
  1245. asort($theme_list);
  1246.  
  1247. //check network permissions
  1248. if (is_multisite()) {
  1249. $allowed_list = array();
  1250. $network_settings = get_site_option( 'mp_network_settings' );
  1251.  
  1252. foreach ($theme_list as $value => $name) {
  1253. if ($network_settings['allowed_themes'][$value] == 'full')
  1254. $allowed_list[$value] = $name;
  1255. else if ($network_settings['allowed_themes'][$value] == 'supporter' && function_exists('is_pro_site') && is_pro_site(false, $network_settings['themes_pro_level'][$value]))
  1256. $allowed_list[$value] = $name;
  1257. else if (is_super_admin()) //super admins can access all installed themes
  1258. $allowed_list[$value] = $name;
  1259. }
  1260. $theme_list = $allowed_list;
  1261. }
  1262.  
  1263. echo '<select name="mp[store_theme]">';
  1264. foreach ($theme_list as $value => $name) {
  1265. ?><option value="<?php echo $value ?>"<?php selected($settings['store_theme'], $value) ?>><?php echo $name ?></option><?php
  1266. }
  1267. ?>
  1268. <option value="none"<?php selected($settings['store_theme'], 'none') ?>><?php _e('None - Custom theme template', 'mp') ?></option>
  1269. </select>
  1270. <?php
  1271. }
  1272.  
  1273. //filter the custom single product template
  1274. function custom_product_template($template) {
  1275. return $this->product_template;
  1276. }
  1277.  
  1278. //filter the custom store template
  1279. function custom_store_template($template) {
  1280. return $this->store_template;
  1281. }
  1282.  
  1283. //filter the custom checkout template
  1284. function custom_checkout_template($template) {
  1285. return $this->checkout_template;
  1286. }
  1287.  
  1288. //filter the custom orderstatus template
  1289. function custom_orderstatus_template($template) {
  1290. return $this->orderstatus_template;
  1291. }
  1292.  
  1293. //filter the custom product taxonomy template
  1294. function custom_product_taxonomy_template($template) {
  1295. return $this->product_taxonomy_template;
  1296. }
  1297.  
  1298. //filter the custom product list template
  1299. function custom_product_list_template($template) {
  1300. return $this->product_list_template;
  1301. }
  1302.  
  1303. //adds our links to theme nav menus using wp_list_pages()
  1304. function filter_list_pages($list, $args) {
  1305.  
  1306. if ($args['depth'] == 1)
  1307. return $list;
  1308.  
  1309. $settings = get_option('mp_settings');
  1310.  
  1311. $temp_break = strpos($list, mp_store_link(false, true) . '"');
  1312.  
  1313. //if we can't find the page for some reason skip
  1314. if ($temp_break === false)
  1315. return $list;
  1316.  
  1317. $break = strpos($list, '</a>', $temp_break) + 4;
  1318.  
  1319. $nav = substr($list, 0, $break);
  1320.  
  1321. if ( !$settings['disable_cart'] ) {
  1322. $nav .= '<ul class="children"><li class="page_item'. ((get_query_var('pagename') == 'product_list') ? ' current_page_item' : '') . '"><a href="' . mp_products_link(false, true) . '" title="' . __('Products', 'mp') . '">' . __('Products', 'mp') . '</a></li>';
  1323. $nav .= '<li class="page_item'. ((get_query_var('pagename') == 'cart') ? ' current_page_item' : '') . '"><a href="' . mp_cart_link(false, true) . '" title="' . __('Shopping Cart', 'mp') . '">' . __('Shopping Cart', 'mp') . '</a></li>';
  1324. $nav .= '<li class="page_item'. ((get_query_var('pagename') == 'orderstatus') ? ' current_page_item' : '') . '"><a href="' . mp_orderstatus_link(false, true) . '" title="' . __('Order Status', 'mp') . '">' . __('Order Status', 'mp') . '</a></li>
  1325. </ul>
  1326. ';
  1327. } else {
  1328. $nav .= '
  1329. <ul>
  1330. <li class="page_item'. ((get_query_var('pagename') == 'product_list') ? ' current_page_item' : '') . '"><a href="' . mp_products_link(false, true) . '" title="' . __('Products', 'mp') . '">' . __('Products', 'mp') . '</a></li>
  1331. </ul>
  1332. ';
  1333. }
  1334. $nav .= substr($list, $break);
  1335.  
  1336. return $nav;
  1337. }
  1338.  
  1339. //adds our links to custom theme nav menus using wp_nav_menu()
  1340. function filter_nav_menu($list, $args = array()) {
  1341. $settings = get_option('mp_settings');
  1342.  
  1343. if ($args->depth == 1)
  1344. return $list;
  1345.  
  1346. //find store page
  1347. $store_url = mp_store_link(false, true);
  1348. $store_page = get_option('mp_store_page');
  1349. foreach($list as $menu_item) {
  1350. if ($menu_item->object_id == $store_page || $menu_item->url == $store_url) {
  1351. $store_object = $menu_item;
  1352. break;
  1353. }
  1354. }
  1355.  
  1356. if ($store_object) {
  1357. $obj_products = clone $store_object;
  1358. $obj_products->title = __('Products', 'mp');
  1359. $obj_products->menu_item_parent = $store_object->ID;
  1360. $obj_products->ID = '99999999999';
  1361. $obj_products->db_id = '99999999999';
  1362. $obj_products->post_name = '99999999999';
  1363. $obj_products->url = mp_products_link(false, true);
  1364. $obj_products->current = (get_query_var('pagename') == 'product_list') ? true : false;
  1365. $obj_products->current_item_ancestor = (get_query_var('pagename') == 'product_list') ? true : false;
  1366. $list[] = $obj_products;
  1367.  
  1368. //if cart disabled return only the products menu item
  1369. if ($settings['disable_cart'])
  1370. return $list;
  1371.  
  1372. $obj_cart = clone $store_object;
  1373. $obj_cart->title = __('Shopping Cart', 'mp');
  1374. $obj_cart->menu_item_parent = $store_object->ID;
  1375. $obj_cart->ID = '99999999999';
  1376. $obj_cart->db_id = '99999999999';
  1377. $obj_cart->post_name = '99999999999';
  1378. $obj_cart->url = mp_cart_link(false, true);
  1379. $obj_cart->current = (get_query_var('pagename') == 'cart') ? true : false;
  1380. $obj_cart->current_item_ancestor = (get_query_var('pagename') == 'cart') ? true : false;
  1381. $list[] = $obj_cart;
  1382.  
  1383. $obj_order = clone $store_object;
  1384. $obj_order->title = __('Order Status', 'mp');
  1385. $obj_order->menu_item_parent = $store_object->ID;
  1386. $obj_order->ID = '99999999999';
  1387. $obj_order->db_id = '99999999999';
  1388. $obj_order->post_name = '99999999999';
  1389. $obj_order->url = mp_orderstatus_link(false, true);
  1390. $obj_order->current = (get_query_var('pagename') == 'orderstatus') ? true : false;
  1391. $obj_order->current_item_ancestor = (get_query_var('pagename') == 'orderstatus') ? true : false;
  1392. $list[] = $obj_order;
  1393. }
  1394.  
  1395. return $list;
  1396. }
  1397.  
  1398. function wp_title_output($title, $sep, $seplocation) {
  1399. // Determines position of the separator and direction of the breadcrumb
  1400. if ( 'right' == $seplocation )
  1401. return $this->page_title_output($title, true) . " $sep ";
  1402. else
  1403. return " $sep " . $this->page_title_output($title, true);
  1404. }
  1405.  
  1406. //filters the titles for our custom pages
  1407. function page_title_output($title, $id = false) {
  1408. global $wp_query;
  1409.  
  1410. //filter out nav titles
  1411. if (!empty($title) && $id === false)
  1412. return $title;
  1413.  
  1414. //taxonomy pages
  1415. if (($wp_query->query_vars['taxonomy'] == 'product_category' || $wp_query->query_vars['taxonomy'] == 'product_tag') && $wp_query->post->ID == $id) {
  1416. if ($wp_query->query_vars['taxonomy'] == 'product_category') {
  1417. $term = get_term_by('slug', get_query_var('product_category'), 'product_category');
  1418. return sprintf( __('Product Category: %s', 'mp'), $term->name );
  1419. } else if ($wp_query->query_vars['taxonomy'] == 'product_tag') {
  1420. $term = get_term_by('slug', get_query_var('product_tag'), 'product_tag');
  1421. return sprintf( __('Product Tag: %s', 'mp'), $term->name );
  1422. }
  1423. }
  1424.  
  1425. switch ($wp_query->query_vars['pagename']) {
  1426. case 'cart':
  1427. if ($wp_query->query_vars['checkoutstep'] == 'shipping')
  1428. return $this->download_only_cart($this->get_cart_contents()) ? __('Checkout Information', 'mp') : __('Shipping Information', 'mp');
  1429. else if ($wp_query->query_vars['checkoutstep'] == 'checkout')
  1430. return __('Payment Information', 'mp');
  1431. else if ($wp_query->query_vars['checkoutstep'] == 'confirm-checkout')
  1432. return __('Confirm Your Purchase', 'mp');
  1433. else if ($wp_query->query_vars['checkoutstep'] == 'confirmation')
  1434. return __('Order Confirmation', 'mp');
  1435. else
  1436. return __('Your Shopping Cart', 'mp');
  1437. break;
  1438.  
  1439. case 'orderstatus':
  1440. return __('Track Your Order', 'mp');
  1441. break;
  1442.  
  1443. case 'product_list':
  1444. return __('Products', 'mp');
  1445. break;
  1446.  
  1447. default:
  1448. return $title;
  1449. }
  1450. }
  1451.  
  1452. //this is the default theme added to single product listings
  1453. function product_theme($content) {
  1454. global $post;
  1455.  
  1456. //don't filter outside of the loop
  1457. if ( !in_the_loop() )
  1458. return $content;
  1459.  
  1460. $settings = get_option('mp_settings');
  1461.  
  1462. //add thumbnail
  1463. if ($settings['show_img']) {
  1464. $content = mp_product_image( false, 'single' ) . $content;
  1465. }
  1466.  
  1467. $content .= '<div class="mp_product_meta">';
  1468. $content .= mp_product_price(false);
  1469. $content .= mp_buy_button(false, 'single');
  1470. $content .= '</div>';
  1471.  
  1472. $content .= mp_category_list($post->ID, '<div class="mp_product_categories">' . __( 'Categorized in ', 'mp' ), ', ', '</div>');
  1473.  
  1474. //$content .= mp_tag_list($post->ID, '<div class="mp_product_tags">', ', ', '</div>');
  1475.  
  1476. return $content;
  1477. }
  1478.  
  1479. //this is the default theme added to the checkout page
  1480. function store_theme($content) {
  1481. //don't filter outside of the loop
  1482. if ( !in_the_loop() )
  1483. return $content;
  1484.  
  1485. return $content;
  1486. }
  1487.  
  1488. //this is the default theme added to the checkout page
  1489. function checkout_theme($content) {
  1490. global $wp_query;
  1491.  
  1492. //don't filter outside of the loop
  1493. if ( !in_the_loop() )
  1494. return $content;
  1495.  
  1496. $content = mp_show_cart('checkout', $wp_query->query_vars['checkoutstep'], false);
  1497.  
  1498. return $content;
  1499. }
  1500.  
  1501. //this is the default theme added to the order status page
  1502. function orderstatus_theme($content) {
  1503. //don't filter outside of the loop
  1504. if ( !in_the_loop() )
  1505. return $content;
  1506.  
  1507. mp_order_status();
  1508. return $content;
  1509. }
  1510.  
  1511. //this is the default theme added to product listings
  1512. function product_list_theme($content) {
  1513. //don't filter outside of the loop
  1514. if ( !in_the_loop() )
  1515. return $content;
  1516.  
  1517. $settings = get_option('mp_settings');
  1518. $content .= $settings['msg']['product_list'];
  1519. $content .= mp_list_products(false);
  1520. $content .= get_posts_nav_link();
  1521.  
  1522. return $content;
  1523. }
  1524.  
  1525. //this is the default theme added to product taxonomies
  1526. function product_taxonomy_list_theme($content) {
  1527. //don't filter outside of the loop
  1528. if ( !in_the_loop() )
  1529. return $content;
  1530.  
  1531. $settings = get_option('mp_settings');
  1532. $content = $settings['msg']['product_list'];
  1533. $content .= mp_list_products(false);
  1534. $content .= get_posts_nav_link();
  1535.  
  1536. return $content;
  1537. }
  1538.  
  1539. //adds the "filter by product category" to the edit products screen
  1540. function edit_products_filter() {
  1541. global $current_screen;
  1542.  
  1543. if ( $current_screen->id == 'edit-product' ) {
  1544. $dropdown_options = array('taxonomy' => 'product_category', 'show_option_all' => __('View all categories'), 'hide_empty' => 0, 'hierarchical' => 1,
  1545. 'show_count' => 0, 'orderby' => 'name', 'name' => 'product_category', 'selected' => $_GET['product_category']);
  1546. wp_dropdown_categories($dropdown_options);
  1547. }
  1548. }
  1549.  
  1550. //adjusts the query vars on the products/order management screens.
  1551. function handle_edit_screen_filter($request) {
  1552. global $current_screen;
  1553.  
  1554. if ( $current_screen->id == 'edit-product' ) {
  1555. //Switches the product_category ids to slugs as you can't query custom taxonomys with ids
  1556. $cat = get_term_by('id', $request['product_category'], 'product_category');
  1557. $request['product_category'] = $cat->slug;
  1558. } else if ( $current_screen->id == 'product_page_marketpress-orders' && !isset($_GET['post_status']) ) {
  1559. //set the post status when on "All" to everything but closed
  1560. $request['post_status'] = 'order_received,order_paid,order_shipped';
  1561. }
  1562.  
  1563. return $request;
  1564. }
  1565.  
  1566. //adds our custom column headers to edit products screen
  1567. function edit_products_columns($old_columns) {
  1568. global $post_status;
  1569.  
  1570. $columns['cb'] = '<input type="checkbox" />';
  1571. $columns['thumbnail'] = __('Thumbnail', 'mp');
  1572. $columns['title'] = __('Product Name', 'mp');
  1573. $columns['color'] = __('ColorVariations', 'mp');
  1574. $columns['variations'] = __('Variations', 'mp');
  1575. $columns['sku'] = __('SKU', 'mp');
  1576. $columns['pricing'] = __('Price', 'mp');
  1577. if (!$settings['disable_cart']) {
  1578. $columns['stock'] = __('Stock', 'mp');
  1579. $columns['sales'] = __('Sales', 'mp');
  1580. }
  1581. $columns['product_categories'] = __('Product Categories', 'mp');
  1582. $columns['product_tags'] = __('Product Tags', 'mp');
  1583.  
  1584.  
  1585. /*
  1586. if ( !in_array( $post_status, array('pending', 'draft', 'future') ) )
  1587. $columns['reviews'] = __('Reviews', 'mp');
  1588. //*/
  1589.  
  1590. return $columns;
  1591. }
  1592.  
  1593. //adds our custom column content
  1594. function edit_products_custom_columns($column) {
  1595. global $post;
  1596. $settings = get_option('mp_settings');
  1597. $meta = get_post_custom();
  1598. //unserialize
  1599. foreach ($meta as $key => $val) {
  1600. $meta[$key] = maybe_unserialize($val[0]);
  1601. if (!is_array($meta[$key]) && $key != "mp_is_sale" && $key != "mp_track_inventory" && $key != "mp_product_link")
  1602. $meta[$key] = array($meta[$key]);
  1603. }
  1604.  
  1605. switch ($column) {
  1606. case "thumbnail":
  1607. if (has_post_thumbnail()) {
  1608. echo '<a href="' . get_edit_post_link() . '" title="' . __('Edit &raquo;') . '">';
  1609. the_post_thumbnail(array(50,50), array('title' => ''));
  1610. echo '</a>';
  1611. }
  1612. break;
  1613.  
  1614. case "color":
  1615. if (is_array($meta["mp_var_name"]) && count($meta["mp_var_name"]) > 1) {
  1616. foreach ($meta["mp_var_name"] as $value) {
  1617. echo esc_attr($value) . '<br />';
  1618. }
  1619. } else {
  1620. _e('N/A', 'mp');
  1621. }
  1622. break;
  1623.  
  1624. case "variations":
  1625. if (is_array($meta["mp_var_name"]) && count($meta["mp_var_name"]) > 1) {
  1626. foreach ($meta["mp_var_name"] as $value) {
  1627. echo esc_attr($value) . '<br />';
  1628. }
  1629. } else {
  1630. _e('N/A', 'mp');
  1631. }
  1632. break;
  1633.  
  1634. case "sku":
  1635. if (is_array($meta["mp_var_name"])) {
  1636. foreach ((array)$meta["mp_sku"] as $value) {
  1637. echo esc_attr($value) . '<br />';
  1638. }
  1639. } else {
  1640. _e('N/A', 'mp');
  1641. }
  1642. break;
  1643.  
  1644. case "pricing":
  1645. if (is_array($meta["mp_price"])) {
  1646. foreach ($meta["mp_price"] as $key => $value) {
  1647. if ($meta["mp_is_sale"] && $meta["mp_sale_price"][$key]) {
  1648. echo '<del>'.$this->format_currency('', $value).'</del> ';
  1649. echo $this->format_currency('', $meta["mp_sale_price"][$key]) . '<br />';
  1650. } else {
  1651. echo $this->format_currency('', $value) . '<br />';
  1652. }
  1653. }
  1654. } else {
  1655. echo $this->format_currency('', 0);
  1656. }
  1657. break;
  1658.  
  1659. case "sales":
  1660. echo number_format_i18n(($meta["mp_sales_count"][0]) ? $meta["mp_sales_count"][0] : 0);
  1661. break;
  1662.  
  1663. case "stock":
  1664. if ($meta["mp_track_inventory"]) {
  1665. foreach ((array)$meta["mp_inventory"] as $value) {
  1666. $inventory = ($value) ? $value : 0;
  1667. if ($inventory == 0)
  1668. $class = 'mp-inv-out';
  1669. else if ($inventory <= $settings['inventory_threshhold'])
  1670. $class = 'mp-inv-warn';
  1671. else
  1672. $class = 'mp-inv-full';
  1673.  
  1674. echo '<span class="' . $class . '">' . number_format_i18n($inventory) . '</span><br />';
  1675. }
  1676. } else {
  1677. _e('N/A', 'mp');
  1678. }
  1679. break;
  1680.  
  1681. case "product_categories":
  1682. echo mp_category_list();
  1683. break;
  1684.  
  1685. case "product_tags":
  1686. echo mp_tag_list();
  1687. break;
  1688.  
  1689. case "reviews":
  1690. echo '<div class="post-com-count-wrapper">
  1691. <a href="edit-comments.php?p=913" title="0 pending" class="post-com-count"><span class="comment-count">0</span></a>
  1692. </div>';
  1693. break;
  1694. }
  1695. }
  1696.  
  1697. //adds our custom column headers
  1698. function manage_orders_columns($old_columns) {
  1699. global $post_status;
  1700.  
  1701. $columns['cb'] = '<input type="checkbox" />';
  1702. $columns['mp_orders_status'] = __('Status', 'mp');
  1703. $columns['mp_orders_id'] = __('Order ID', 'mp');
  1704. $columns['mp_orders_date'] = __('Order Date', 'mp');
  1705. $columns['mp_orders_name'] = __('From', 'mp');
  1706. $columns['mp_orders_items'] = __('Items', 'mp');
  1707. $columns['mp_orders_shipping'] = __('Shipping', 'mp');
  1708. $columns['mp_orders_tax'] = __('Tax', 'mp');
  1709. $columns['mp_orders_discount'] = __('Discount', 'mp');
  1710. $columns['mp_orders_total'] = __('Total', 'mp');
  1711.  
  1712. return $columns;
  1713. }
  1714.  
  1715. //adds our custom column content
  1716. function manage_orders_custom_columns($column) {
  1717. global $post;
  1718. $settings = get_option('mp_settings');
  1719. $meta = get_post_custom();
  1720. //unserialize
  1721. foreach ($meta as $key => $val)
  1722. $meta[$key] = array_map('maybe_unserialize', $val);
  1723.  
  1724. switch ($column) {
  1725.  
  1726. case "mp_orders_status":
  1727. if ($post->post_status == 'order_received')
  1728. $text = __('Received', 'mp');
  1729. else if ($post->post_status == 'order_paid')
  1730. $text = __('Paid', 'mp');
  1731. else if ($post->post_status == 'order_shipped')
  1732. $text = __('Shipped', 'mp');
  1733. else if ($post->post_status == 'order_closed')
  1734. $text = __('Closed', 'mp');
  1735.  
  1736. ?><a class="mp_order_status" href="edit.php?post_type=product&page=marketpress-orders&order_id=<?php echo $post->ID; ?>" title="<?php echo __('View Order Details', 'mp'); ?>"><?php echo $text ?></a><?php
  1737. break;
  1738.  
  1739. case "mp_orders_date":
  1740. $t_time = get_the_time(__('Y/m/d g:i:s A'));
  1741. $m_time = $post->post_date;
  1742. $time = get_post_time('G', true, $post);
  1743.  
  1744. $time_diff = time() - $time;
  1745.  
  1746. if ( $time_diff > 0 && $time_diff < 24*60*60 )
  1747. $h_time = sprintf( __('%s ago'), human_time_diff( $time ) );
  1748. else
  1749. $h_time = mysql2date(__('Y/m/d'), $m_time);
  1750. echo '<abbr title="' . $t_time . '">' . $h_time . '</abbr>';
  1751. break;
  1752.  
  1753. case "mp_orders_id":
  1754. $title = _draft_or_post_title();
  1755. ?>
  1756. <strong><a class="row-title" href="edit.php?post_type=product&page=marketpress-orders&order_id=<?php echo $post->ID; ?>" title="<?php echo esc_attr(sprintf(__('View &#8220;%s&#8221;', 'mp'), $title)); ?>"><?php echo $title ?></a></strong>
  1757. <?php
  1758. $actions = array();
  1759. if ($post->post_status == 'order_received') {
  1760. $actions['paid'] = "<a title='" . esc_attr(__('Mark as Paid', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=paid&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Paid', 'mp') . "</a>";
  1761. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  1762. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  1763. } else if ($post->post_status == 'order_paid') {
  1764. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  1765. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  1766. } else if ($post->post_status == 'order_shipped') {
  1767. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  1768. } else if ($post->post_status == 'order_closed') {
  1769. $actions['received'] = "<a title='" . esc_attr(__('Mark as Received', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=received&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Received', 'mp') . "</a>";
  1770. $actions['paid'] = "<a title='" . esc_attr(__('Mark as Paid', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=paid&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Paid', 'mp') . "</a>";
  1771. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $post->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  1772. }
  1773.  
  1774. $action_count = count($actions);
  1775. $i = 0;
  1776. echo '<div class="row-actions">';
  1777. foreach ( $actions as $action => $link ) {
  1778. ++$i;
  1779. ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
  1780. echo "<span class='$action'>$link$sep</span>";
  1781. }
  1782. echo '</div>';
  1783. break;
  1784.  
  1785. case "mp_orders_name":
  1786. echo esc_attr($meta["mp_shipping_info"][0]['name']) . ' (<a href="mailto:' . urlencode($meta["mp_shipping_info"][0]['name']) . ' &lt;' . esc_attr($meta["mp_shipping_info"][0]['email']) . '&gt;?subject=' . urlencode(sprintf(__('Regarding Your Order (%s)', 'mp'), $post->post_title)) . '">' . esc_attr($meta["mp_shipping_info"][0]['email']) . '</a>)';
  1787. break;
  1788.  
  1789. case "mp_orders_items":
  1790. echo number_format_i18n($meta["mp_order_items"][0]);
  1791. break;
  1792.  
  1793. case "mp_orders_shipping":
  1794. echo $this->format_currency('', $meta["mp_shipping_total"][0]);
  1795. break;
  1796.  
  1797. case "mp_orders_tax":
  1798. echo $this->format_currency('', $meta["mp_tax_total"][0]);
  1799. break;
  1800.  
  1801. case "mp_orders_discount":
  1802. if ($meta["mp_discount_info"][0])
  1803. echo $meta["mp_discount_info"][0]['discount'];
  1804. else
  1805. _e('N/A', 'mp');
  1806. break;
  1807.  
  1808. case "mp_orders_total":
  1809. echo $this->format_currency('', $meta["mp_order_total"][0]);
  1810. break;
  1811.  
  1812. }
  1813. }
  1814.  
  1815. //filters label in new product title field
  1816. function filter_title($post) {
  1817. global $post_type;
  1818.  
  1819. if ($post_type != 'product')
  1820. return $post;
  1821.  
  1822. return __( 'Enter Product title here', 'mp' );
  1823. }
  1824.  
  1825. //adds our custom meta boxes the the product edit screen
  1826. function meta_boxes() {
  1827. global $wp_meta_boxes;
  1828. $settings = get_option('mp_settings');
  1829.  
  1830. add_meta_box('mp-meta-details', __('Product Details', 'mp'), array(&$this, 'meta_details'), 'product', 'normal', 'high');
  1831.  
  1832. //only add these boxes if orders are enabled
  1833. if (!$settings['disable_cart']) {
  1834.  
  1835. //only display metabox if shipping plugin ties into it
  1836. if ( has_action('mp_shipping_metabox') )
  1837. add_meta_box('mp-meta-shipping', __('Shipping', 'mp'), array(&$this, 'meta_shipping'), 'product', 'normal', 'high');
  1838.  
  1839. //for product downloads
  1840. add_meta_box('mp-meta-download', __('Product Download', 'mp'), array(&$this, 'meta_download'), 'product', 'normal', 'high');
  1841. }
  1842.  
  1843. //all this junk is to reorder the metabox array to move the featured image box to the top right below submit box. User order will override
  1844. if ( isset( $wp_meta_boxes['product']['side']['low']['postimagediv'] ) ) {
  1845. $imagediv = $wp_meta_boxes['product']['side']['low']['postimagediv'];
  1846. unset( $wp_meta_boxes['product']['side']['low'] );
  1847. $submitdiv = $wp_meta_boxes['product']['side']['core']['submitdiv'];
  1848. unset( $wp_meta_boxes['product']['side']['core']['submitdiv'] );
  1849. $new_core['submitdiv'] = $submitdiv;
  1850. $new_core['postimagediv'] = $imagediv;
  1851. $wp_meta_boxes['product']['side']['core'] = array_merge( $new_core, $wp_meta_boxes['product']['side']['core']) ;
  1852. //filter title
  1853. $wp_meta_boxes['product']['side']['core']['postimagediv']['title'] = __('Product Image', 'mp');
  1854. }
  1855. }
  1856.  
  1857. //Save our post meta when a product is created or updated
  1858. function save_product_meta($post_id, $post = null) {
  1859. //skip quick edit
  1860. if ( defined('DOING_AJAX') )
  1861. return;
  1862.  
  1863. if ( $post->post_type == "product" && isset( $_POST['mp_product_meta'] ) ) {
  1864. $meta = get_post_custom($post_id);
  1865. foreach ($meta as $key => $val) {
  1866. $meta[$key] = maybe_unserialize($val[0]);
  1867. if (!is_array($meta[$key]) && $key != "mp_is_sale" && $key != "mp_track_inventory" && $key != "mp_product_link")
  1868. $meta[$key] = array($meta[$key]);
  1869. }
  1870.  
  1871. //price function
  1872. $func_curr = '$price = round(preg_replace("/[^0-9.]/", "", $price), 2);return ($price) ? $price : 0;';
  1873.  
  1874. //sku function
  1875. $func_sku = 'return preg_replace("/[^a-zA-Z0-9_-]/", "", $value);';
  1876.  
  1877. update_post_meta($post_id, 'mp_var_name', $_POST['mp_var_name']);
  1878. update_post_meta($post_id, 'mp_sku', array_map(create_function('$value', $func_sku), $_POST['mp_sku']));
  1879. update_post_meta($post_id, 'mp_price', array_map(create_function('$price', $func_curr), $_POST['mp_price']));
  1880. update_post_meta($post_id, 'mp_is_sale', isset($_POST['mp_is_sale']) ? 1 : 0);
  1881. update_post_meta($post_id, 'mp_sale_price', array_map(create_function('$price', $func_curr), $_POST['mp_sale_price']));
  1882. update_post_meta($post_id, 'mp_track_inventory', isset($_POST['mp_track_inventory']) ? 1 : 0);
  1883. update_post_meta($post_id, 'mp_inventory', array_map('intval', (array)$_POST['mp_inventory']));
  1884.  
  1885. //save true first variation price for sorting
  1886. if ( isset($_POST['mp_is_sale']) )
  1887. $sort_price = round($_POST['mp_sale_price'][0], 2);
  1888. else
  1889. $sort_price = round($_POST['mp_price'][0], 2);
  1890. update_post_meta($post_id, 'mp_price_sort', $sort_price);
  1891.  
  1892. //if changing delete flag so emails will be sent again
  1893. if ( $_POST['mp_inventory'] != $meta['mp_inventory'] )
  1894. delete_post_meta($product_id, 'mp_stock_email_sent');
  1895.  
  1896. update_post_meta( $post_id, 'mp_product_link', esc_url_raw($_POST['mp_product_link']) );
  1897.  
  1898. update_post_meta($post_id, 'mp_is_special_tax', isset($_POST['mp_is_special_tax']) ? 1 : 0);
  1899. $tax_rate = round(preg_replace("/[^0-9.]/", "", $_POST['mp_special_tax']), 3) * .01;
  1900. update_post_meta($post_id, 'mp_special_tax', $tax_rate);
  1901.  
  1902. //set sales count to zero if none set
  1903. $sale_count = ($meta["mp_sales_count"][0]) ? $meta["mp_sales_count"][0] : 0;
  1904. update_post_meta($post_id, 'mp_sales_count', $sale_count);
  1905.  
  1906. //for shipping plugins to save their meta values
  1907. $mp_shipping = maybe_unserialize($meta["mp_shipping"][0]);
  1908. if ( !is_array($mp_shipping) )
  1909. $mp_shipping = array();
  1910.  
  1911. update_post_meta( $post_id, 'mp_shipping', apply_filters('mp_save_shipping_meta', $mp_shipping) );
  1912.  
  1913. //download url
  1914. update_post_meta( $post_id, 'mp_file', esc_url_raw($_POST['mp_file']) );
  1915.  
  1916. //for any other plugin to hook into
  1917. do_action( 'mp_save_product_meta', $post_id, $meta );
  1918. }
  1919. }
  1920.  
  1921. //The Product Details meta box
  1922. function meta_details() {
  1923. global $post;
  1924. $settings = get_option('mp_settings');
  1925. $meta = get_post_custom($post->ID);
  1926. //unserialize
  1927. foreach ($meta as $key => $val) {
  1928. $meta[$key] = maybe_unserialize($val[0]);
  1929. if (!is_array($meta[$key]) && $key != "mp_is_sale" && $key != "mp_track_inventory" && $key != "mp_product_link" && $key != "mp_file" && $key != "mp_is_special_tax" && $key != "mp_special_tax")
  1930. $meta[$key] = array($meta[$key]);
  1931. }
  1932. ?>
  1933. <input type="hidden" name="mp_product_meta" value="1" />
  1934. <table class="widefat" id="mp_color_variations_table">
  1935. <thead>
  1936. <tr>
  1937. <th scope="col" class="mp_var_col"><?php _e('Color', 'mp') ?></th>
  1938. <th scope="col" class="mp_sku_col" title="<?php _e('Stock Keeping Unit - Your custom Product ID number', 'mp'); ?>"><?php _e('SKU', 'mp') ?></th>
  1939. <th scope="col" class="mp_price_col"><?php _e('Price', 'mp') ?></th>
  1940. <th scope="col" class="mp_sale_col"><label title="<?php _e('When checked these override the normal price.', 'mp'); ?>"><input type="checkbox" id="mp_is_sale" name="mp_is_sale" value="1"<?php checked($meta["mp_is_sale"], '1'); ?> /> <?php _e('Sale Price', 'mp') ?></label></th>
  1941. <th scope="col" class="mp_inv_col"><label title="<?php _e('When checked inventory tracking will be enabled.', 'mp'); ?>"><input type="checkbox" id="mp_track_inventory" name="mp_track_inventory" value="1"<?php checked($meta["mp_track_inventory"], '1'); ?> /> <?php _e('Inventory', 'mp') ?></label></th>
  1942. <th scope="col" class="mp_var_remove"></th>
  1943. </tr>
  1944. </thead>
  1945. <tbody>
  1946. <?php
  1947. if ($meta["mp_price"]) {
  1948. //if download enabled only show first variation
  1949. $meta["mp_price"] = (empty($meta["mp_file"]) && empty($meta["mp_product_link"])) ? $meta["mp_price"] : array($meta["mp_price"][0]);
  1950. $count = 1;
  1951. $last = count($meta["mp_price"]);
  1952. foreach ($meta["mp_price"] as $key => $price) {
  1953. ?>
  1954. <tr class="variation">
  1955. <td class="mp_var_col"><input type="text" name="mp_var_name[]" value="<?php echo esc_attr($meta["mp_var_name"][$key]); ?>" /></td>
  1956. <td class="mp_sku_col"><input type="text" name="mp_sku[]" value="<?php echo esc_attr($meta["mp_sku"][$key]); ?>" /></td>
  1957. <td class="mp_price_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_price[]" value="<?php echo isset($meta["mp_price"][$key]) ? $this->display_currency($meta["mp_price"][$key]) : '0.00'; ?>" /></td>
  1958. <td class="mp_sale_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_sale_price[]" value="<?php echo isset($meta["mp_sale_price"][$key]) ? $this->display_currency($meta["mp_sale_price"][$key]) : $this->display_currency($meta["mp_price"][$key]); ?>" disabled="disabled" /></td>
  1959. <td class="mp_inv_col"><input type="text" name="mp_inventory[]" value="<?php echo intval($meta["mp_inventory"][$key]); ?>" disabled="disabled" /></td>
  1960. <td class="mp_var_remove">
  1961. <?php if ($count == $last) { ?><a href="#mp_color_variations_table" title="<?php _e('Remove Variation', 'mp'); ?>">x</a><?php } ?>
  1962. </td>
  1963. </tr>
  1964. <?php
  1965. $count++;
  1966. }
  1967. } else {
  1968. ?>
  1969. <tr class="variation">
  1970. <td class="mp_var_col"><input type="text" name="mp_var_name[]" value="" /></td>
  1971. <td class="mp_sku_col"><input type="text" name="mp_sku[]" value="" /></td>
  1972. <td class="mp_price_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_price[]" value="0.00" /></td>
  1973. <td class="mp_sale_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_sale_price[]" value="0.00" disabled="disabled" /></td>
  1974. <td class="mp_inv_col"><input type="text" name="mp_inventory[]" value="0" disabled="disabled" /></td>
  1975. <td class="mp_var_remove"><a href="#mp_color_variations_table" title="<?php _e('Remove Variation', 'mp'); ?>">x</a></td>
  1976. </tr>
  1977. <?php
  1978. }
  1979. ?>
  1980. </tbody>
  1981. </table>
  1982. <input type="hidden" name="mp_product_meta" value="1" />
  1983. <table class="widefat" id="mp_product_variations_table">
  1984. <thead>
  1985. <tr>
  1986. <th scope="col" class="mp_var_col"><?php _e('Variation Name', 'mp') ?></th>
  1987. <th scope="col" class="mp_sku_col" title="<?php _e('Stock Keeping Unit - Your custom Product ID number', 'mp'); ?>"><?php _e('SKU', 'mp') ?></th>
  1988. <th scope="col" class="mp_price_col"><?php _e('Price', 'mp') ?></th>
  1989. <th scope="col" class="mp_sale_col"><label title="<?php _e('When checked these override the normal price.', 'mp'); ?>"><input type="checkbox" id="mp_is_sale" name="mp_is_sale" value="1"<?php checked($meta["mp_is_sale"], '1'); ?> /> <?php _e('Sale Price', 'mp') ?></label></th>
  1990. <th scope="col" class="mp_inv_col"><label title="<?php _e('When checked inventory tracking will be enabled.', 'mp'); ?>"><input type="checkbox" id="mp_track_inventory" name="mp_track_inventory" value="1"<?php checked($meta["mp_track_inventory"], '1'); ?> /> <?php _e('Inventory', 'mp') ?></label></th>
  1991. <th scope="col" class="mp_var_remove"></th>
  1992. </tr>
  1993. </thead>
  1994. <tbody>
  1995. <?php
  1996. if ($meta["mp_price"]) {
  1997. //if download enabled only show first variation
  1998. $meta["mp_price"] = (empty($meta["mp_file"]) && empty($meta["mp_product_link"])) ? $meta["mp_price"] : array($meta["mp_price"][0]);
  1999. $count = 1;
  2000. $last = count($meta["mp_price"]);
  2001. foreach ($meta["mp_price"] as $key => $price) {
  2002. ?>
  2003. <tr class="color">
  2004. <td class="mp_var_col"><input type="text" name="mp_var_name[]" value="<?php echo esc_attr($meta["mp_var_name"][$key]); ?>" /></td>
  2005. <td class="mp_sku_col"><input type="text" name="mp_sku[]" value="<?php echo esc_attr($meta["mp_sku"][$key]); ?>" /></td>
  2006. <td class="mp_price_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_price[]" value="<?php echo isset($meta["mp_price"][$key]) ? $this->display_currency($meta["mp_price"][$key]) : '0.00'; ?>" /></td>
  2007. <td class="mp_sale_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_sale_price[]" value="<?php echo isset($meta["mp_sale_price"][$key]) ? $this->display_currency($meta["mp_sale_price"][$key]) : $this->display_currency($meta["mp_price"][$key]); ?>" disabled="disabled" /></td>
  2008. <td class="mp_inv_col"><input type="text" name="mp_inventory[]" value="<?php echo intval($meta["mp_inventory"][$key]); ?>" disabled="disabled" /></td>
  2009. <td class="mp_var_remove">
  2010. <?php if ($count == $last) { ?><a href="#mp_product_variations_table" title="<?php _e('Remove Variation', 'mp'); ?>">x</a><?php } ?>
  2011. </td>
  2012. </tr>
  2013. <?php
  2014. $count++;
  2015. }
  2016. } else {
  2017. ?>
  2018. <tr class="color">
  2019. <td class="mp_var_col"><input type="text" name="mp_var_name[]" value="" /></td>
  2020. <td class="mp_sku_col"><input type="text" name="mp_sku[]" value="" /></td>
  2021. <td class="mp_price_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_price[]" value="0.00" /></td>
  2022. <td class="mp_sale_col"><?php echo $this->format_currency(); ?><input type="text" name="mp_sale_price[]" value="0.00" disabled="disabled" /></td>
  2023. <td class="mp_inv_col"><input type="text" name="mp_inventory[]" value="0" disabled="disabled" /></td>
  2024. <td class="mp_var_remove"><a href="#mp_product_variations_table" title="<?php _e('Remove Variation', 'mp'); ?>">x</a></td>
  2025. </tr>
  2026. <?php
  2027. }
  2028. ?>
  2029. </tbody>
  2030. </table>
  2031.  
  2032. <?php if (empty($meta["mp_file"]) && empty($meta["mp_product_link"])) { ?>
  2033. <div id="mp_add_vars"><a href="#mp_product_variations_table"><?php _e('Add Variation', 'mp'); ?></a></div>
  2034. <?php } else { ?>
  2035. <span class="description" id="mp_variation_message"><?php _e('Product variations are not allowed for Downloadable or Externally Linked products.', 'mp') ?></span>
  2036. <?php } ?>
  2037.  
  2038. <div id="mp_product_link_div">
  2039. <label title="<?php _e('Some examples are linking to a song/album in iTunes, or linking to a product on another site with your own affiliate link.', 'mp'); ?>"><?php _e('External Link', 'mp'); ?>:<br /><small><?php _e('When set this overrides the purchase button with a link to this URL.', 'mp'); ?></small><br />
  2040. <input type="text" style="width: 100%;" id="mp_product_link" name="mp_product_link" value="<?php echo esc_url($meta["mp_product_link"]); ?>" /></label>
  2041. </div>
  2042.  
  2043. <div id="mp_tax_rate_div">
  2044. <label title="<?php esc_attr_e('Depending on local tax laws, some items are tax-free or a have different sales tax rate. You can set that here.', 'mp'); ?>"><input type="checkbox" id="mp_is_special_tax" name="mp_is_special_tax" value="1" <?php checked($meta["mp_is_special_tax"]); ?>/> <?php _e('Special Tax Rate?', 'mp'); ?></label>
  2045. <label id="mp_special_tax"<?php echo ($meta["mp_is_special_tax"]) ? '' : ' style="display:none;"'; ?>><?php _e('Rate:', 'mp'); ?> <input type="text" size="2" name="mp_special_tax" value="<?php echo isset($meta["mp_special_tax"]) ? round($meta["mp_special_tax"] * 100, 3) : 0; ?>" />%</label>
  2046. </div>
  2047.  
  2048. <?php do_action( 'mp_details_metabox' ); ?>
  2049. <div class="clear"></div>
  2050. <?php
  2051. }
  2052.  
  2053. //The Shipping meta box
  2054. function meta_shipping() {
  2055. global $post;
  2056. $settings = get_option('mp_settings');
  2057. $meta = get_post_custom($post->ID);
  2058. $mp_shipping = maybe_unserialize($meta["mp_shipping"][0]);
  2059.  
  2060. //tie in for shipping plugins
  2061. do_action( 'mp_shipping_metabox', $mp_shipping, $settings );
  2062. }
  2063.  
  2064. //The Product Download meta box
  2065. function meta_download() {
  2066. global $post;
  2067. $settings = get_option('mp_settings');
  2068. $meta = get_post_custom($post->ID);
  2069. ?>
  2070. <label><?php _e('File URL', 'mp'); ?>:<br /><input type="text" size="50" id="mp_file" class="mp_file" name="mp_file" value="<?php echo esc_attr($meta["mp_file"][0]); ?>" /></label>
  2071. <input id="mp_upload_button" type="button" value="<?php _e('Upload File', 'mp'); ?>" /><br />
  2072. <?php
  2073. //display allowed filetypes if WPMU
  2074. if (is_multisite()) {
  2075. echo '<span class="description">Allowed Filetypes: '.implode(', ', explode(' ', get_site_option('upload_filetypes'))).'</span>';
  2076. if (is_super_admin()) {
  2077. echo '<p>Super Admin: You can change allowed filetypes for your network <a href="' . network_admin_url('settings.php#upload_filetypes') . '">here &raquo;</a></p>';
  2078. }
  2079. }
  2080.  
  2081. do_action( 'mp_download_metabox' );
  2082. }
  2083.  
  2084. //returns the calculated price adjusted for sales, formatted or not
  2085. function product_price($product_id, $variation = 0, $format = false) {
  2086.  
  2087. $meta = get_post_custom($product_id);
  2088. //unserialize
  2089. foreach ($meta as $key => $val) {
  2090. $meta[$key] = maybe_unserialize($val[0]);
  2091. if (!is_array($meta[$key]) && $key != "mp_is_sale" && $key != "mp_track_inventory" && $key != "mp_product_link")
  2092. $meta[$key] = array($meta[$key]);
  2093. }
  2094.  
  2095. if (is_array($meta["mp_price"])) {
  2096. if ($meta["mp_is_sale"]) {
  2097. $price = $meta["mp_sale_price"][$variation];
  2098. } else {
  2099. $price = $meta["mp_price"][$variation];
  2100. }
  2101. }
  2102.  
  2103. $price = ($price) ? $price : 0;
  2104. $price = $this->display_currency($price);
  2105.  
  2106. $price = apply_filters( 'mp_product_price', $price, $product_id );
  2107.  
  2108. if ($format)
  2109. return $this->format_currency('', $price);
  2110. else
  2111. return $price;
  2112. }
  2113.  
  2114. //returns the calculated price for shipping. Returns False if shipping address is not available
  2115. function shipping_price($format = false, $cart = false) {
  2116. global $mp_shipping_active_plugins;
  2117. $settings = get_option('mp_settings');
  2118.  
  2119. //grab cart for just this blog
  2120. if (!$cart)
  2121. $cart = $this->get_cart_contents();
  2122.  
  2123. //get total after any coupons
  2124. $totals = array();
  2125. foreach ($cart as $product_id => $variations) {
  2126. foreach ($variations as $variation => $data) {
  2127. $totals[] = $this->before_tax_price($data['price'], $product_id) * $data['quantity'];
  2128. }
  2129. }
  2130.  
  2131. $total = array_sum($totals);
  2132.  
  2133. $coupon_code = $this->get_coupon_code();
  2134. if ( $coupon = $this->coupon_value($coupon_code, $total) )
  2135. $total = $coupon['new_total'];
  2136.  
  2137. //get address
  2138. $meta = get_user_meta(get_current_user_id(), 'mp_shipping_info', true);
  2139. $address1 = isset($_SESSION['mp_shipping_info']['address1']) ? $_SESSION['mp_shipping_info']['address1'] : $meta['address1'];
  2140. $address2 = isset($_SESSION['mp_shipping_info']['address2']) ? $_SESSION['mp_shipping_info']['address2'] : $meta['address2'];
  2141. $city = isset($_SESSION['mp_shipping_info']['city']) ? $_SESSION['mp_shipping_info']['city'] : $meta['city'];
  2142. $state = isset($_SESSION['mp_shipping_info']['state']) ? $_SESSION['mp_shipping_info']['state'] : $meta['state'];
  2143. $zip = isset($_SESSION['mp_shipping_info']['zip']) ? $_SESSION['mp_shipping_info']['zip'] : $meta['zip'];
  2144. $country = isset($_SESSION['mp_shipping_info']['country']) ? $_SESSION['mp_shipping_info']['country'] : $meta['country'];
  2145. $selected_option = isset($_SESSION['mp_shipping_info']['shipping_sub_option']) ? $_SESSION['mp_shipping_info']['shipping_sub_option'] : null;
  2146.  
  2147. //check required fields
  2148. if ( empty($address1) || empty($city) || empty($zip) || empty($country) || !(is_array($cart) && count($cart)) )
  2149. return false;
  2150.  
  2151. //don't charge shipping if only digital products
  2152. if ( $this->download_only_cart($cart) ) {
  2153. $price = 0;
  2154. } else if ( $settings['shipping']['method'] == 'calculated' && isset($_SESSION['mp_shipping_info']['shipping_option']) && isset($mp_shipping_active_plugins[$_SESSION['mp_shipping_info']['shipping_option']]) ) {
  2155. //shipping plugins tie into this to calculate their shipping cost
  2156. $price = apply_filters( 'mp_calculate_shipping_'.$_SESSION['mp_shipping_info']['shipping_option'], 0, $total, $cart, $address1, $address2, $city, $state, $zip, $country, $selected_option );
  2157. } else {
  2158. //shipping plugins tie into this to calculate their shipping cost
  2159. $price = apply_filters( 'mp_calculate_shipping_'.$settings['shipping']['method'], 0, $total, $cart, $address1, $address2, $city, $state, $zip, $country, $selected_option );
  2160. }
  2161.  
  2162. //calculate extra shipping
  2163. $extras = array();
  2164. foreach ($cart as $product_id => $variations) {
  2165. $shipping_meta = get_post_meta($product_id, 'mp_shipping', true);
  2166. foreach ($variations as $variation => $data) {
  2167. if (!$data['download'])
  2168. $extras[] = $shipping_meta['extra_cost'] * $data['quantity'];
  2169. }
  2170. }
  2171. $extra = array_sum($extras);
  2172.  
  2173. //merge
  2174. $price = round($price + $extra, 2);
  2175.  
  2176. //boot if shipping plugin didn't return at least 0
  2177. if (empty($price))
  2178. return false;
  2179.  
  2180. if ($format)
  2181. return $this->format_currency('', $price);
  2182. else
  2183. return $price;
  2184. }
  2185.  
  2186. //returns the calculated price for taxes based on a bunch of foreign tax laws.
  2187. function tax_price($format = false, $cart = false) {
  2188. $settings = get_option('mp_settings');
  2189.  
  2190. //grab cart for just this blog
  2191. if (!$cart)
  2192. $cart = $this->get_cart_contents();
  2193.  
  2194. //get address
  2195. $meta = get_user_meta(get_current_user_id(), 'mp_shipping_info', true);
  2196.  
  2197. if (!isset($meta['state'])) {
  2198. $meta['state'] = '';
  2199. }
  2200. if (!isset($meta['country'])) {
  2201. $meta['country'] = '';
  2202. }
  2203.  
  2204. $state = isset($_SESSION['mp_shipping_info']['state']) ? $_SESSION['mp_shipping_info']['state'] : $meta['state'];
  2205. $country = isset($_SESSION['mp_shipping_info']['country']) ? $_SESSION['mp_shipping_info']['country'] : $meta['country'];
  2206.  
  2207. //if we've skipped the shipping page and no address is set, use base for tax calculation
  2208. if ($this->download_only_cart($cart) || $settings['tax']['tax_inclusive']) {
  2209. if (empty($country))
  2210. $country = $settings['base_country'];
  2211. if (empty($state))
  2212. $state = $settings['base_province'];
  2213. }
  2214.  
  2215. //TODO calculate all taxes per product before rounding
  2216.  
  2217. //get total after any coupons
  2218. $totals = array();
  2219. $special_totals = array();
  2220. foreach ($cart as $product_id => $variations) {
  2221. //check for special rate
  2222. $special = (bool)get_post_meta($product_id, 'mp_is_special_tax', true);
  2223. if ($special)
  2224. $special_rate = get_post_meta($product_id, 'mp_special_tax', true);
  2225. foreach ($variations as $variation => $data) {
  2226. if ($special)
  2227. $special_totals[] = ($this->before_tax_price($data['price'], $product_id) * $data['quantity']) * $special_rate;
  2228. else
  2229. $totals[] = $this->before_tax_price($data['price'], false) * $data['quantity'];
  2230. }
  2231. }
  2232.  
  2233. $total = array_sum($totals);
  2234. $special_total = array_sum($special_totals);
  2235.  
  2236. $coupon_code = $this->get_coupon_code();
  2237. if ( $coupon = $this->coupon_value($coupon_code, $total) )
  2238. $total = $coupon['new_total'];
  2239.  
  2240. //add in shipping?
  2241. if ( $settings['tax']['tax_shipping'] && ($shipping_price = $this->shipping_price()) )
  2242. $total += $shipping_price;
  2243.  
  2244. //check required fields
  2245. if ( empty($country) || !(is_array($cart) && count($cart)) || ($total + $special_total) <= 0 ) {
  2246. return false;
  2247. }
  2248.  
  2249. switch ($settings['base_country']) {
  2250. case 'US':
  2251. //USA taxes are only for orders delivered inside the state
  2252. if ($country == 'US' && $state == $settings['base_province'])
  2253. $price = round(($total * $settings['tax']['rate']) + $special_total, 2);
  2254. break;
  2255.  
  2256. case 'CA':
  2257. //Canada tax is for all orders in country, based on province shipped to. We're assuming the rate is a combination of GST/PST/etc.
  2258. if ( $country == 'CA' && array_key_exists($state, $this->canadian_provinces) ) {
  2259. if (isset($settings['tax']['canada_rate'][$state]))
  2260. $price = round(($total * $settings['tax']['canada_rate'][$state]) + $special_total, 2);
  2261. else //backwards compat with pre 2.2 if per province rates are not set
  2262. $price = round(($total * $settings['tax']['rate']) + $special_total, 2);
  2263. }
  2264. break;
  2265.  
  2266. case 'AU':
  2267. //Australia taxes orders in country
  2268. if ($country == 'AU')
  2269. $price = round(($total * $settings['tax']['rate']) + $special_total, 2);
  2270. break;
  2271.  
  2272. default:
  2273. //EU countries charge VAT within the EU
  2274. if ( in_array($settings['base_country'], $this->eu_countries) ) {
  2275. if (in_array($country, $this->eu_countries))
  2276. $price = round(($total * $settings['tax']['rate']) + $special_total, 2);
  2277. } else {
  2278. //all other countries use the tax outside preference
  2279. if ($settings['tax']['tax_outside'] || (!$settings['tax']['tax_outside'] && $country == $settings['base_country']))
  2280. $price = round(($total * $settings['tax']['rate']) + $special_total, 2);
  2281. }
  2282. break;
  2283. }
  2284. if (empty($price))
  2285. $price = 0;
  2286.  
  2287. $price = apply_filters( 'mp_tax_price', $price, $total, $cart, $country, $state );
  2288.  
  2289. if ($format)
  2290. return $this->format_currency('', $price);
  2291. else
  2292. return $price;
  2293. }
  2294.  
  2295. //returns the before tax price for a given amount based on a bunch of foreign tax laws.
  2296. function before_tax_price($tax_price, $product_id = false) {
  2297. $settings = get_option('mp_settings');
  2298.  
  2299. //if tax inclusve pricing is turned off just return given price
  2300. if (!$settings['tax']['tax_inclusive'])
  2301. return $tax_price;
  2302.  
  2303. if ($product_id && get_post_meta($product_id, 'mp_is_special_tax', true)) {
  2304. $rate = get_post_meta($product_id, 'mp_special_tax', true);
  2305. } else {
  2306. //figure out rate in case its based on a canadian base province
  2307. $rate = ('CA' == $settings['base_country']) ? $settings['tax']['canada_rate'][$settings['base_province']] : $settings['tax']['rate'];
  2308. }
  2309.  
  2310. return round($tax_price / ($rate + 1), 2);
  2311. }
  2312.  
  2313. //returns contents of shopping cart cookie
  2314. function get_cart_cookie($global = false) {
  2315. global $blog_id;
  2316. $blog_id = (is_multisite()) ? $blog_id : 1;
  2317.  
  2318. $cookie_id = 'mp_globalcart_' . COOKIEHASH;
  2319.  
  2320. if (isset($_COOKIE[$cookie_id])) {
  2321. $global_cart = unserialize($_COOKIE[$cookie_id]);
  2322. } else {
  2323. $global_cart = array($blog_id => array());
  2324. }
  2325.  
  2326. if ($global) {
  2327. return $global_cart;
  2328. } else {
  2329. if (isset($global_cart[$blog_id])) {
  2330. return $global_cart[$blog_id];
  2331. } else {
  2332. return array();
  2333. }
  2334. }
  2335. }
  2336.  
  2337. //saves global cart array to cookie
  2338. function set_global_cart_cookie($global_cart) {
  2339. $cookie_id = 'mp_globalcart_' . COOKIEHASH;
  2340.  
  2341. //set cookie
  2342. $expire = time() + 2592000; //1 month expire
  2343. setcookie($cookie_id, serialize($global_cart), $expire, COOKIEPATH, COOKIE_DOMAIN);
  2344.  
  2345. // Set the cookie variable as well, sometimes updating the cache doesn't work
  2346. $_COOKIE[$cookie_id] = serialize($global_cart);
  2347.  
  2348. //mark cache for updating
  2349. $this->cart_cache = false;
  2350. }
  2351.  
  2352. //saves cart array to cookie
  2353. function set_cart_cookie($cart) {
  2354. global $blog_id, $mp_gateway_active_plugins;
  2355. $blog_id = (is_multisite()) ? $blog_id : 1;
  2356.  
  2357. $global_cart = $this->get_cart_cookie(true);
  2358.  
  2359. if ($this->global_cart && count($global_cart = $this->get_cart_cookie(true)) >= $mp_gateway_active_plugins[0]->max_stores && !isset($global_cart[$blog_id])) {
  2360. $this->cart_checkout_error(sprintf(__("Sorry, currently it's not possible to checkout with items from more than %s stores.", 'mp'), $mp_gateway_active_plugins[0]->max_stores));
  2361. } else {
  2362. $global_cart[$blog_id] = $cart;
  2363. }
  2364.  
  2365. //update cache
  2366. $this->set_global_cart_cookie($global_cart);
  2367. }
  2368.  
  2369. //returns the full array of cart contents
  2370. function get_cart_contents($global = false) {
  2371. global $blog_id;
  2372. $blog_id = (is_multisite()) ? $blog_id : 1;
  2373. $current_blog_id = $blog_id;
  2374.  
  2375. //check cache
  2376. if ($this->cart_cache) {
  2377. if ($global) {
  2378. return $this->cart_cache;
  2379. } else {
  2380. if (isset($this->cart_cache[$blog_id])) {
  2381. return $this->cart_cache[$blog_id];
  2382. } else {
  2383. return array();
  2384. }
  2385. }
  2386. }
  2387.  
  2388. $global_cart = $this->get_cart_cookie(true);
  2389. if (!is_array($global_cart))
  2390. return array();
  2391.  
  2392. $full_cart = array();
  2393. foreach ($global_cart as $bid => $cart) {
  2394.  
  2395. if (is_multisite())
  2396. switch_to_blog($bid);
  2397.  
  2398. $full_cart[$bid] = array();
  2399. foreach ($cart as $product_id => $variations) {
  2400. $product = get_post($product_id);
  2401.  
  2402. if ( empty($product) ) {
  2403. continue;
  2404. }
  2405.  
  2406. $full_cart[$bid][$product_id] = array();
  2407. foreach ($variations as $variation => $quantity) {
  2408. //check stock
  2409. if (get_post_meta($product_id, 'mp_track_inventory', true)) {
  2410. $stock = maybe_unserialize(get_post_meta($product_id, 'mp_inventory', true));
  2411. if (!is_array($stock))
  2412. $stock[0] = $stock;
  2413. if ($stock[$variation] < $quantity) {
  2414. $this->cart_checkout_error( sprintf(__("Sorry, we don't have enough of %1$s in stock. Your cart quantity has been changed to %2$s.", 'mp'), $product->post_title, number_format_i18n($stock[$variation])) );
  2415. $quantity = $stock[$variation];
  2416. }
  2417. }
  2418.  
  2419. //check limit if tracking on or downloadable
  2420. if (get_post_meta($product_id, 'mp_track_limit', true) || $file = get_post_meta($product_id, 'mp_file', true)) {
  2421. $limit = empty($file) ? maybe_unserialize(get_post_meta($product_id, 'mp_limit', true)) : array($variation => 1);
  2422. if ($limit[$variation] && $limit[$variation] < $quantity) {
  2423. $this->cart_checkout_error( sprintf(__('Sorry, there is a per order limit of %1$s for "%2$s". Your cart quantity has been changed to %3$s.', 'mp'), number_format_i18n($limit[$variation]), $product->post_title, number_format_i18n($limit[$variation])) );
  2424. $quantity = $limit[$variation];
  2425. }
  2426. }
  2427.  
  2428. $skus = maybe_unserialize(get_post_meta($product_id, 'mp_sku', true));
  2429. if (!is_array($skus))
  2430. $skus[0] = $skus;
  2431. $var_names = maybe_unserialize(get_post_meta($product_id, 'mp_var_name', true));
  2432. if (is_array($var_names) && count($var_names) > 1)
  2433. $name = $product->post_title . ': ' . $var_names[$variation];
  2434. else
  2435. $name = $product->post_title;
  2436.  
  2437. //get if downloadable
  2438. if ( $download_url = get_post_meta($product_id, 'mp_file', true) )
  2439. $download = array('url' => $download_url, 'downloaded' => 0);
  2440. else
  2441. $download = false;
  2442.  
  2443. $full_cart[$bid][$product_id][$variation] = array('SKU' => $skus[$variation], 'name' => $name, 'url' => get_permalink($product_id), 'price' => $this->product_price($product_id, $variation), 'quantity' => $quantity, 'download' => $download);
  2444. }
  2445. }
  2446. }
  2447.  
  2448. if (is_multisite())
  2449. switch_to_blog($current_blog_id);
  2450.  
  2451. //save to cache
  2452. $this->cart_cache = $full_cart;
  2453.  
  2454. if ($global) {
  2455. return $full_cart;
  2456. } else {
  2457. if (isset($full_cart[$blog_id])) {
  2458. return $full_cart[$blog_id];
  2459. } else {
  2460. return array();
  2461. }
  2462. }
  2463. }
  2464.  
  2465. //receives a post and updates cookie variables for cart
  2466. function update_cart() {
  2467. global $blog_id, $mp_gateway_active_plugins;
  2468. $blog_id = (is_multisite()) ? $blog_id : 1;
  2469. $current_blog_id = $blog_id;
  2470. $settings = get_option('mp_settings');
  2471.  
  2472. $cart = $this->get_cart_cookie();
  2473.  
  2474. if (isset($_POST['empty_cart'])) { //empty cart contents
  2475.  
  2476. //clear all blog products only if global checkout enabled
  2477. if ($this->global_cart)
  2478. $this->set_global_cart_cookie(array());
  2479. else
  2480. $this->set_cart_cookie(array());
  2481.  
  2482. if (defined('DOING_AJAX') && DOING_AJAX) {
  2483. ?>
  2484. <div class="mp_cart_empty">
  2485. <?php _e('There are no items in your cart.', 'mp') ?>
  2486. </div>
  2487. <div id="mp_cart_actions_widget">
  2488. <a class="mp_store_link" href="<?php mp_products_link(true, true); ?>"><?php _e('Browse Products &raquo;', 'mp') ?></a>
  2489. </div>
  2490. <?php
  2491. exit;
  2492. }
  2493.  
  2494. } else if (isset($_POST['product_id'])) { //add a product to cart
  2495.  
  2496. //if not valid product_id return
  2497. $product_id = apply_filters('mp_product_id_add_to_cart', intval($_POST['product_id']));
  2498. $product = get_post($product_id);
  2499. if (!$product)
  2500. return false;
  2501.  
  2502. //get quantity
  2503. $quantity = (isset($_POST['quantity'])) ? intval(abs($_POST['quantity'])) : 1;
  2504.  
  2505. //get color
  2506. $variation = (isset($_POST['color'])) ? intval(abs($_POST['color'])) : 0;
  2507.  
  2508. //get variation
  2509. $variation = (isset($_POST['variation'])) ? intval(abs($_POST['variation'])) : 0;
  2510.  
  2511. //check max stores
  2512. if ($this->global_cart && count($global_cart = $this->get_cart_cookie(true)) >= $mp_gateway_active_plugins[0]->max_stores && !isset($global_cart[$blog_id])) {
  2513. if (defined('DOING_AJAX') && DOING_AJAX) {
  2514. echo 'error||' . sprintf(__("Sorry, currently it's not possible to checkout with items from more than %s stores.", 'mp'), $mp_gateway_active_plugins[0]->max_stores);
  2515. exit;
  2516. } else {
  2517. $this->cart_checkout_error(sprintf(__("Sorry, currently it's not possible to checkout with items from more than %s stores.", 'mp'), $mp_gateway_active_plugins[0]->max_stores));
  2518. return false;
  2519. }
  2520. }
  2521.  
  2522. //calculate new quantity
  2523. $new_quantity = $cart[$product_id][$variation] + $quantity;
  2524.  
  2525. //check stock
  2526. if (get_post_meta($product_id, 'mp_track_inventory', true)) {
  2527. $stock = maybe_unserialize(get_post_meta($product_id, 'mp_inventory', true));
  2528. if (!is_array($stock))
  2529. $stock[0] = $stock;
  2530. if ($stock[$variation] < $new_quantity) {
  2531. if (defined('DOING_AJAX') && DOING_AJAX) {
  2532. echo 'error||' . sprintf(__("Sorry, we don't have enough of this item in stock. (%s remaining)", 'mp'), number_format_i18n($stock[$variation]-$cart[$product_id][$variation]));
  2533. exit;
  2534. } else {
  2535. $this->cart_checkout_error( sprintf(__("Sorry, we don't have enough of this item in stock. (%s remaining)", 'mp'), number_format_i18n($stock[$variation]-$cart[$product_id][$variation])) );
  2536. return false;
  2537. }
  2538. }
  2539. //send ajax leftover stock
  2540. if (defined('DOING_AJAX') && DOING_AJAX) {
  2541. $return = array_sum($stock)-$new_quantity . '||';
  2542. }
  2543. } else {
  2544. //send ajax always stock if stock checking turned off
  2545. if (defined('DOING_AJAX') && DOING_AJAX) {
  2546. $return = 1 . '||';
  2547. }
  2548. }
  2549.  
  2550. //check limit if tracking on or downloadable
  2551. if (get_post_meta($product_id, 'mp_track_limit', true) || $file = get_post_meta($product_id, 'mp_file', true)) {
  2552. $limit = empty($file) ? maybe_unserialize(get_post_meta($product_id, 'mp_limit', true)) : array($variation => 1);
  2553. if ($limit[$variation] && $limit[$variation] < $new_quantity) {
  2554. if (defined('DOING_AJAX') && DOING_AJAX) {
  2555. echo 'error||' . sprintf(__('Sorry, there is a per order limit of %1$s for "%2$s".', 'mp'), number_format_i18n($limit[$variation]), $product->post_title);
  2556. exit;
  2557. } else {
  2558. $this->cart_checkout_error( sprintf(__('Sorry, there is a per order limit of %1$s for "%2$s".', 'mp'), number_format_i18n($limit[$variation]), $product->post_title) );
  2559. return false;
  2560. }
  2561. }
  2562. }
  2563.  
  2564. $cart[$product_id][$variation] = $new_quantity;
  2565.  
  2566. //save items to cookie
  2567. $this->set_cart_cookie($cart);
  2568.  
  2569. //if running via ajax return updated cart and die
  2570. if (defined('DOING_AJAX') && DOING_AJAX) {
  2571. $return .= mp_show_cart('widget', false, false);
  2572. echo $return;
  2573. exit;
  2574. }
  2575. } else if (isset($_POST['update_cart_submit'])) { //update cart contents
  2576. $global_cart = $this->get_cart_cookie(true);
  2577.  
  2578. //process quantity updates
  2579. if (is_array($_POST['quant'])) {
  2580. foreach ($_POST['quant'] as $pbid => $quant) {
  2581. list($bid, $product_id, $variation) = split(':', $pbid);
  2582.  
  2583. if (is_multisite())
  2584. switch_to_blog($bid);
  2585.  
  2586. $quant = intval(abs($quant));
  2587.  
  2588. if ($quant) {
  2589. //check stock
  2590. if (get_post_meta($product_id, 'mp_track_inventory', true)) {
  2591. $stock = maybe_unserialize(get_post_meta($product_id, 'mp_inventory', true));
  2592. if (!is_array($stock))
  2593. $stock[0] = $stock;
  2594. if ($stock[$variation] < $quant) {
  2595. $left = (($stock[$variation]-intval($global_cart[$bid][$product_id][$variation])) < 0) ? 0 : ($stock[$variation]-intval($global_cart[$bid][$product_id][$variation]));
  2596. $this->cart_checkout_error( sprintf(__('Sorry, there is not enough stock for "%s". (%s remaining)', 'mp'), get_the_title($product_id), number_format_i18n($left)) );
  2597. continue;
  2598. }
  2599. }
  2600. //check limit if tracking on or downloadable
  2601. if (get_post_meta($product_id, 'mp_track_limit', true) || $file = get_post_meta($product_id, 'mp_file', true)) {
  2602. $limit = empty($file) ? maybe_unserialize(get_post_meta($product_id, 'mp_limit', true)) : array($variation => 1);
  2603. if ($limit[$variation] && $limit[$variation] < $quant) {
  2604. $this->cart_checkout_error( sprintf(__('Sorry, there is a per order limit of %1$s for "%2$s".', 'mp'), number_format_i18n($limit[$variation]), get_the_title($product_id)) );
  2605. continue;
  2606. }
  2607. }
  2608.  
  2609. $global_cart[$bid][$product_id][$variation] = $quant;
  2610. } else {
  2611. unset($global_cart[$bid][$product_id][$variation]);
  2612. }
  2613. }
  2614.  
  2615. if (is_multisite())
  2616. switch_to_blog($current_blog_id);
  2617. }
  2618.  
  2619. //remove items
  2620. if (is_array($_POST['remove'])) {
  2621. foreach ($_POST['remove'] as $pbid) {
  2622. list($bid, $product_id, $variation) = split(':', $pbid);
  2623. unset($global_cart[$bid][$product_id][$variation]);
  2624. }
  2625.  
  2626. $this->cart_update_message( __('Item(s) Removed', 'mp') );
  2627. }
  2628.  
  2629. //save items to cookie
  2630. $this->set_global_cart_cookie($global_cart);
  2631.  
  2632. //add coupon code
  2633. if (!empty($_POST['coupon_code'])) {
  2634. if ($this->check_coupon($_POST['coupon_code'])) {
  2635. //get coupon code
  2636. if (is_multisite()) {
  2637. global $blog_id;
  2638. $_SESSION['mp_cart_coupon_' . $blog_id] = $_POST['coupon_code'];
  2639. } else {
  2640. $_SESSION['mp_cart_coupon'] = $_POST['coupon_code'];
  2641. }
  2642. $this->cart_update_message( __('Coupon Successfully Applied', 'mp') );
  2643. } else {
  2644. $this->cart_checkout_error( __('Invalid Coupon Code', 'mp') );
  2645. }
  2646. }
  2647.  
  2648. } else if (isset($_GET['remove_coupon'])) {
  2649.  
  2650. //remove coupon code
  2651. if (is_multisite()) {
  2652. global $blog_id;
  2653. unset($_SESSION['mp_cart_coupon_' . $blog_id]);
  2654. } else {
  2655. unset($_SESSION['mp_cart_coupon']);
  2656. }
  2657. $this->cart_update_message( __('Coupon Removed', 'mp') );
  2658.  
  2659. } else if (isset($_POST['mp_shipping_submit'])) { //save shipping info
  2660.  
  2661. //check checkout info
  2662. if (!is_email($_POST['email']))
  2663. $this->cart_checkout_error( __('Please enter a valid Email Address.', 'mp'), 'email');
  2664.  
  2665. //only require these fields if not a download only cart
  2666. if (!$this->download_only_cart($this->get_cart_contents())) {
  2667.  
  2668. if (empty($_POST['name']))
  2669. $this->cart_checkout_error( __('Please enter your Full Name.', 'mp'), 'name');
  2670.  
  2671. if (empty($_POST['address1']))
  2672. $this->cart_checkout_error( __('Please enter your Street Address.', 'mp'), 'address1');
  2673.  
  2674. if (empty($_POST['city']))
  2675. $this->cart_checkout_error( __('Please enter your City.', 'mp'), 'city');
  2676.  
  2677. if (($_POST['country'] == 'US' || $_POST['country'] == 'CA') && empty($_POST['state']))
  2678. $this->cart_checkout_error( __('Please enter your State/Province/Region.', 'mp'), 'state');
  2679.  
  2680. if ($_POST['country'] == 'US' && !array_key_exists(strtoupper($_POST['state']), $this->usa_states))
  2681. $this->cart_checkout_error( __('Please enter a valid two-letter State abbreviation.', 'mp'), 'state');
  2682. else if ($_POST['country'] == 'CA' && !array_key_exists(strtoupper($_POST['state']), $this->canadian_provinces))
  2683. $this->cart_checkout_error( __('Please enter a valid two-letter Canadian Province abbreviation.', 'mp'), 'state');
  2684. else
  2685. $_POST['state'] = strtoupper($_POST['state']);
  2686.  
  2687. if (empty($_POST['zip']))
  2688. $this->cart_checkout_error( __('Please enter your Zip/Postal Code.', 'mp'), 'zip');
  2689.  
  2690. if (empty($_POST['country']) || strlen($_POST['country']) != 2)
  2691. $this->cart_checkout_error( __('Please enter your Country.', 'mp'), 'country');
  2692.  
  2693. if ($_POST['no_shipping_options'] == '1'){
  2694. $this->cart_checkout_error( __('No valid shipping options found. Please check your address carefully.', 'mp' ), 'no_shipping_options');
  2695. }
  2696. }
  2697.  
  2698. //save to session
  2699. global $current_user;
  2700. $meta = get_user_meta($current_user->ID, 'mp_shipping_info', true);
  2701. $_SESSION['mp_shipping_info']['email'] = ($_POST['email']) ? trim(stripslashes($_POST['email'])) : (isset($meta['email']) ? $meta['email']: $current_user->user_email);
  2702. $_SESSION['mp_shipping_info']['name'] = ($_POST['name']) ? trim(stripslashes($_POST['name'])) : (isset($meta['name']) ? $meta['name'] : $current_user->user_firstname . ' ' . $current_user->user_lastname);
  2703. $_SESSION['mp_shipping_info']['address1'] = ($_POST['address1']) ? trim(stripslashes($_POST['address1'])) : $meta['address1'];
  2704. $_SESSION['mp_shipping_info']['address2'] = ($_POST['address2']) ? trim(stripslashes($_POST['address2'])) : $meta['address2'];
  2705. $_SESSION['mp_shipping_info']['city'] = ($_POST['city']) ? trim(stripslashes($_POST['city'])) : $meta['city'];
  2706. $_SESSION['mp_shipping_info']['state'] = ($_POST['state']) ? trim(stripslashes($_POST['state'])) : $meta['state'];
  2707. $_SESSION['mp_shipping_info']['zip'] = ($_POST['zip']) ? trim(stripslashes($_POST['zip'])) : $meta['zip'];
  2708. $_SESSION['mp_shipping_info']['country'] = ($_POST['country']) ? trim($_POST['country']) : $meta['country'];
  2709. $_SESSION['mp_shipping_info']['phone'] = ($_POST['phone']) ? preg_replace('/[^0-9-\(\) ]/', '', trim($_POST['phone'])) : $meta['phone'];
  2710. if (isset($_POST['special_instructions']))
  2711. $_SESSION['mp_shipping_info']['special_instructions'] = trim(stripslashes($_POST['special_instructions']));
  2712.  
  2713. //for checkout plugins
  2714. do_action( 'mp_shipping_process' );
  2715.  
  2716. //save to user meta
  2717. if ($current_user->ID)
  2718. update_user_meta($current_user->ID, 'mp_shipping_info', $_SESSION['mp_shipping_info']);
  2719.  
  2720. //if no errors send to next checkout step
  2721. if ($this->checkout_error == false) {
  2722.  
  2723. //check for $0 checkout to skip gateways
  2724.  
  2725. //loop through cart items
  2726. $global_cart = $this->get_cart_contents(true);
  2727. if (!$this->global_cart) //get subset if needed
  2728. $selected_cart[$blog_id] = $global_cart[$blog_id];
  2729. else
  2730. $selected_cart = $global_cart;
  2731.  
  2732. $totals = array();
  2733. $shipping_prices = array();
  2734. $tax_prices = array();
  2735. foreach ($selected_cart as $bid => $cart) {
  2736.  
  2737. if (is_multisite())
  2738. switch_to_blog($bid);
  2739.  
  2740. foreach ($cart as $product_id => $variations) {
  2741. foreach ($variations as $data) {
  2742. $totals[] = $data['price'] * $data['quantity'];
  2743. }
  2744. }
  2745. if ( ($shipping_price = $this->shipping_price()) !== false )
  2746. $shipping_prices[] = $shipping_price;
  2747.  
  2748. if ( ($tax_price = $this->tax_price()) !== false )
  2749. $tax_prices[] = $tax_price;
  2750. }
  2751.  
  2752. //go back to original blog
  2753. if (is_multisite())
  2754. switch_to_blog($current_blog_id);
  2755.  
  2756. $total = array_sum($totals);
  2757.  
  2758. //coupon line
  2759. if ( $coupon = $this->coupon_value($this->get_coupon_code(), $total) )
  2760. $total = $coupon['new_total'];
  2761.  
  2762. //shipping
  2763. if ( $shipping_price = array_sum($shipping_prices) )
  2764. $total = $total + $shipping_price;
  2765.  
  2766. //tax line
  2767. if ( $tax_price = array_sum($tax_prices) )
  2768. $total = $total + $tax_price;
  2769.  
  2770. if ($total > 0) {
  2771. $network_settings = get_site_option( 'mp_network_settings' );
  2772. //can we skip the payment form page?
  2773. if ( $this->global_cart ) {
  2774. $skip = apply_filters('mp_payment_form_skip_' . $network_settings['global_gateway'], false);
  2775. } else {
  2776. $skip = apply_filters('mp_payment_form_skip_' . $settings['gateways']['allowed'][0], false);
  2777. }
  2778. if ( (!$this->global_cart && count((array)$settings['gateways']['allowed']) > 1) || !$skip ) {
  2779. wp_safe_redirect(mp_checkout_step_url('checkout'));
  2780. exit;
  2781. } else {
  2782. if ( $this->global_cart )
  2783. $_SESSION['mp_payment_method'] = $network_settings['global_gateway'];
  2784. else
  2785. $_SESSION['mp_payment_method'] = $settings['gateways']['allowed'][0];
  2786. do_action( 'mp_payment_submit_' . $_SESSION['mp_payment_method'], $this->get_cart_contents($this->global_cart), $_SESSION['mp_shipping_info'] );
  2787. //if no errors send to next checkout step
  2788. if ($this->checkout_error == false) {
  2789. wp_safe_redirect(mp_checkout_step_url('confirm-checkout'));
  2790. exit;
  2791. } else {
  2792. wp_safe_redirect(mp_checkout_step_url('checkout'));
  2793. exit;
  2794. }
  2795. }
  2796. } else { //empty price, create order already
  2797. //loop through and create orders
  2798. foreach ($selected_cart as $bid => $cart) {
  2799. $totals = array();
  2800. if (is_multisite())
  2801. switch_to_blog($bid);
  2802.  
  2803. foreach ($cart as $product_id => $variations) {
  2804. foreach ($variations as $data) {
  2805. $totals[] = $data['price'] * $data['quantity'];
  2806. }
  2807. }
  2808. $total = array_sum($totals);
  2809.  
  2810. //coupon line
  2811. if ( $coupon = $this->coupon_value($this->get_coupon_code(), $total) )
  2812. $total = $coupon['new_total'];
  2813.  
  2814. //shipping
  2815. if ( ($shipping_price = $this->shipping_price()) !== false )
  2816. $total = $total + $shipping_price;
  2817.  
  2818. //tax line
  2819. if ( ($tax_price = $this->tax_price()) !== false )
  2820. $total = $total + $tax_price;
  2821.  
  2822. //setup our payment details
  2823. $timestamp = time();
  2824. $settings = get_option('mp_settings');
  2825. $payment_info['gateway_public_name'] = __('Manual Checkout', 'mp');
  2826. $payment_info['gateway_private_name'] = __('Manual Checkout', 'mp');
  2827. $payment_info['method'][] = __('N/A - Free order', 'mp');
  2828. $payment_info['transaction_id'][] = __('N/A', 'mp');
  2829. $payment_info['status'][$timestamp] = __('Completed', 'mp');
  2830. $payment_info['total'] = $total;
  2831. $payment_info['currency'] = $settings['currency'];
  2832. $this->create_order(false, $cart, $_SESSION['mp_shipping_info'], $payment_info, true);
  2833. }
  2834.  
  2835. //go back to original blog
  2836. if (is_multisite())
  2837. switch_to_blog($current_blog_id);
  2838.  
  2839. $_SESSION['mp_payment_method'] = 'manual'; //so we don't get an error message on confirmation page
  2840.  
  2841. //redirect to final page
  2842. wp_safe_redirect(mp_checkout_step_url('confirmation'));
  2843. exit;
  2844. }
  2845. }
  2846.  
  2847. } else if (isset($_POST['mp_choose_gateway'])) { //check and save payment info
  2848. $_SESSION['mp_payment_method'] = $_POST['mp_choose_gateway'];
  2849. //processing script is only for selected gateway plugin
  2850. do_action( 'mp_payment_submit_' . $_SESSION['mp_payment_method'], $this->get_cart_contents($this->global_cart), $_SESSION['mp_shipping_info'] );
  2851. //if no errors send to next checkout step
  2852. if ($this->checkout_error == false) {
  2853. wp_safe_redirect(mp_checkout_step_url('confirm-checkout'));
  2854. exit;
  2855. }
  2856. } else if (isset($_POST['mp_payment_confirm'])) { //create order and process payment
  2857. do_action( 'mp_payment_confirm_' . $_SESSION['mp_payment_method'], $this->get_cart_contents($this->global_cart), $_SESSION['mp_shipping_info'] );
  2858.  
  2859. //if no errors send to next checkout step
  2860. if ($this->checkout_error == false) {
  2861. wp_safe_redirect(mp_checkout_step_url('confirmation'));
  2862. exit;
  2863. }
  2864. }
  2865. }
  2866.  
  2867. function cart_update_message($msg) {
  2868. $content = 'return "<div id=\"mp_cart_updated_msg\">' . $msg . '</div>";';
  2869. add_filter( 'mp_cart_updated_msg', create_function('', $content) );
  2870. }
  2871.  
  2872. function cart_checkout_error($msg, $context = 'checkout') {
  2873. $msg = str_replace('"', '\"', $msg); //prevent double quotes from causing errors.
  2874. $content = 'return "<div class=\"mp_checkout_error\">' . $msg . '</div>";';
  2875. add_action( 'mp_checkout_error_' . $context, create_function('', $content) );
  2876. $this->checkout_error = true;
  2877. }
  2878.  
  2879. //returns any coupon code saved in $_SESSION. Will only reliably work on checkout pages
  2880. function get_coupon_code() {
  2881. //get coupon code
  2882. if (is_multisite()) {
  2883. global $blog_id;
  2884. $coupon_code = $_SESSION['mp_cart_coupon_' . $blog_id];
  2885. } else {
  2886. $coupon_code = $_SESSION['mp_cart_coupon'];
  2887. }
  2888.  
  2889. return $coupon_code;
  2890. }
  2891.  
  2892. //checks a coupon code for validity. Return boolean
  2893. function check_coupon($code) {
  2894. $coupon_code = preg_replace('/[^A-Z0-9_-]/', '', strtoupper($code));
  2895.  
  2896. //empty code
  2897. if (!$coupon_code)
  2898. return false;
  2899.  
  2900. $coupons = get_option('mp_coupons');
  2901.  
  2902. //no record for code
  2903. if (!is_array($coupons[$coupon_code]))
  2904. return false;
  2905.  
  2906. //start date not valid yet
  2907. if (time() < $coupons[$coupon_code]['start'])
  2908. return false;
  2909.  
  2910. //if end date and expired
  2911. if ($coupons[$coupon_code]['end'] && time() > $coupons[$coupon_code]['end'])
  2912. return false;
  2913.  
  2914. //check remaining uses
  2915. if ($coupons[$coupon_code]['uses'] && (intval($coupons[$coupon_code]['uses']) - intval($coupons[$coupon_code]['used'])) <= 0)
  2916. return false;
  2917.  
  2918. //everything passed so it's valid
  2919. return true;
  2920. }
  2921.  
  2922. //get coupon value. Returns array(discount, new_total) or false for invalid code
  2923. function coupon_value($code, $total) {
  2924. if ($this->check_coupon($code)) {
  2925. $coupons = get_option('mp_coupons');
  2926. $coupon_code = preg_replace('/[^A-Z0-9_-]/', '', strtoupper($code));
  2927. if ($coupons[$coupon_code]['discount_type'] == 'amt') {
  2928. $settings = get_option('mp_settings');
  2929. $new_total = round($total - $coupons[$coupon_code]['discount'], 2);
  2930. $new_total = ($new_total < 0) ? 0.00 : $new_total;
  2931. $discount = '-' . $this->format_currency('', $coupons[$coupon_code]['discount']);
  2932. return array('discount' => $discount, 'new_total' => $new_total);
  2933. } else {
  2934. $new_total = round($total - ($total * ($coupons[$coupon_code]['discount'] * 0.01)), 2);
  2935. $new_total = ($new_total < 0) ? 0.00 : $new_total;
  2936. $discount = '-' . $coupons[$coupon_code]['discount'] . '%';
  2937. return array('discount' => $discount, 'new_total' => $new_total);
  2938. }
  2939.  
  2940. } else {
  2941. return false;
  2942. }
  2943. }
  2944.  
  2945. //record coupon use. Returns boolean successful
  2946. function use_coupon($code) {
  2947. if ($this->check_coupon($code)) {
  2948. $coupons = get_option('mp_coupons');
  2949. $coupon_code = preg_replace('/[^A-Z0-9_-]/', '', strtoupper($code));
  2950.  
  2951. //increment count
  2952. $coupons[$coupon_code]['used']++;
  2953. update_option('mp_coupons', $coupons);
  2954.  
  2955. return true;
  2956. } else {
  2957. return false;
  2958. }
  2959. }
  2960.  
  2961. //returns a new unique order id.
  2962. function generate_order_id() {
  2963. global $wpdb;
  2964.  
  2965. $count = true;
  2966. while ($count) { //make sure it's unique
  2967. $order_id = substr(sha1(uniqid('')), rand(1, 24), 12);
  2968. $count = $wpdb->get_var("SELECT COUNT(*) FROM " . $wpdb->posts . " WHERE post_title = '" . $order_id . "' AND post_type = 'mp_order'");
  2969. }
  2970.  
  2971. $order_id = apply_filters( 'mp_order_id', $order_id ); //Very important to make sure order numbers are unique and not sequential if filtering
  2972.  
  2973. //save it to session
  2974. $_SESSION['mp_order'] = $order_id;
  2975.  
  2976. return $order_id;
  2977. }
  2978.  
  2979. //called on checkout to create a new order
  2980. function create_order($order_id, $cart, $shipping_info, $payment_info, $paid, $user_id = false, $shipping_total = false, $tax_total = false, $coupon_code = false) {
  2981. $settings = get_option('mp_settings');
  2982.  
  2983. //order id can be null
  2984. if (empty($order_id))
  2985. $order_id = $this->generate_order_id();
  2986. else if ($this->get_order($order_id)) //don't continue if the order exists
  2987. return false;
  2988.  
  2989. //insert post type
  2990. $order = array();
  2991. $order['post_title'] = $order_id;
  2992. $order['post_name'] = $order_id;
  2993. $order['post_content'] = serialize($cart).serialize($shipping_info); //this is purely so you can search by cart contents
  2994. $order['post_status'] = ($paid) ? 'order_paid' : 'order_received';
  2995. $order['post_type'] = 'mp_order';
  2996. $post_id = wp_insert_post($order);
  2997.  
  2998. /* add post meta */
  2999.  
  3000. //filter tax included products in cart
  3001. $filtered_cart = $cart;
  3002. foreach ($cart as $product_id => $variations) {
  3003. foreach ($variations as $variation => $data) {
  3004. $filtered_cart[$product_id][$variation]['price'] = $this->before_tax_price($data['price'], $product_id);
  3005. }
  3006. }
  3007.  
  3008. //cart info
  3009. add_post_meta($post_id, 'mp_cart_info', $filtered_cart, true);
  3010. //shipping info
  3011. add_post_meta($post_id, 'mp_shipping_info', $shipping_info, true);
  3012. //payment info
  3013. add_post_meta($post_id, 'mp_payment_info', $payment_info, true);
  3014.  
  3015. //loop through cart items
  3016. foreach ($cart as $product_id => $variations) {
  3017. foreach ($variations as $variation => $data) {
  3018. $items[] = $data['quantity'];
  3019.  
  3020. //adjust product stock quantities
  3021. if (get_post_meta($product_id, 'mp_track_inventory', true)) {
  3022. $stock = maybe_unserialize(get_post_meta($product_id, 'mp_inventory', true));
  3023. if (!is_array($stock))
  3024. $stock[0] = $stock;
  3025. $stock[$variation] = $stock[$variation] - $data['quantity'];
  3026. update_post_meta($product_id, 'mp_inventory', $stock);
  3027.  
  3028. if ($stock[$variation] <= $settings['inventory_threshold']) {
  3029. $this->low_stock_notification($product_id, $variation, $stock[$variation]);
  3030. }
  3031. }//check stock
  3032.  
  3033. //update sales count
  3034. $count = get_post_meta($product_id, 'mp_sales_count', true);
  3035. $count = $count + $data['quantity'];
  3036. update_post_meta($product_id, 'mp_sales_count', $count);
  3037.  
  3038. //for plugins into product sales
  3039. do_action( 'mp_product_sale', $product_id, $variation, $data, $paid );
  3040. }
  3041. }
  3042. $item_count = array_sum($items);
  3043.  
  3044. //coupon info
  3045. $code = $coupon_code ? $coupon_code : $this->get_coupon_code();
  3046. if ( $coupon = $this->coupon_value($code, 9999999999) ) {
  3047. add_post_meta($post_id, 'mp_discount_info', array('code' => $code, 'discount' => $coupon['discount']), true);
  3048.  
  3049. //mark coupon as used
  3050. $this->use_coupon($code);
  3051. }
  3052.  
  3053. //payment info
  3054. add_post_meta($post_id, 'mp_order_total', $payment_info['total'], true);
  3055. add_post_meta($post_id, 'mp_shipping_total', ($shipping_total ? $shipping_total : $this->shipping_price(false, $cart)), true);
  3056. add_post_meta($post_id, 'mp_tax_total', ($tax_total ? $tax_total : $this->tax_price(false, $cart)), true);
  3057. add_post_meta($post_id, 'mp_order_items', $item_count, true);
  3058.  
  3059. $timestamp = time();
  3060. add_post_meta($post_id, 'mp_received_time', $timestamp, true);
  3061.  
  3062. //set paid time if we already have a confirmed payment
  3063. if ($paid) {
  3064. add_post_meta($post_id, 'mp_paid_time', $timestamp, true);
  3065. do_action( 'mp_order_paid', $this->get_order($order_id) );
  3066. }
  3067.  
  3068. //empty cart cookie
  3069. $this->set_cart_cookie(array());
  3070.  
  3071. //clear coupon code
  3072. if (is_multisite()) {
  3073. global $blog_id;
  3074. unset($_SESSION['mp_cart_coupon_' . $blog_id]);
  3075. } else {
  3076. unset($_SESSION['mp_cart_coupon']);
  3077. }
  3078.  
  3079. //save order history
  3080. if (!$user_id)
  3081. $user_id = get_current_user_id();
  3082.  
  3083. if ($user_id) { //save to user_meta if logged in
  3084.  
  3085. if (is_multisite()) {
  3086. global $blog_id;
  3087. $meta_id = 'mp_order_history_' . $blog_id;
  3088. } else {
  3089. $meta_id = 'mp_order_history';
  3090. }
  3091.  
  3092. $orders = get_user_meta($user_id, $meta_id, true);
  3093. $timestamp = time();
  3094. $orders[$timestamp] = array('id' => $order_id, 'total' => $payment_info['total']);
  3095. update_user_meta($user_id, $meta_id, $orders);
  3096.  
  3097. } else { //save to cookie instead
  3098.  
  3099. if (is_multisite()) {
  3100. global $blog_id;
  3101. $cookie_id = 'mp_order_history_' . $blog_id . '_' . COOKIEHASH;
  3102. } else {
  3103. $cookie_id = 'mp_order_history_' . COOKIEHASH;
  3104. }
  3105.  
  3106. if (isset($_COOKIE[$cookie_id]))
  3107. $orders = unserialize($_COOKIE[$cookie_id]);
  3108.  
  3109. $timestamp = time();
  3110. $orders[$timestamp] = array('id' => $order_id, 'total' => $payment_info['total']);
  3111.  
  3112. //set cookie
  3113. $expire = time() + 31536000; //1 year expire
  3114. setcookie($cookie_id, serialize($orders), $expire, COOKIEPATH, COOKIEDOMAIN);
  3115. }
  3116.  
  3117. //send new order email
  3118. $this->order_notification($order_id);
  3119.  
  3120. //hook for new orders
  3121. do_action( 'mp_new_order', $this->get_order($order_id) );
  3122.  
  3123. //if paid and the cart is only digital products mark it shipped
  3124. if ($paid && $this->download_only_cart($cart)) {
  3125. $this->skip_shipping_notice = true;
  3126. $this->update_order_status($order_id, 'shipped');
  3127. }
  3128.  
  3129. return $order_id;
  3130. }
  3131.  
  3132. //returns the full order details as an object
  3133. function get_order($order_id) {
  3134. $id = (is_int($order_id)) ? $order_id : $this->order_to_post_id($order_id);
  3135.  
  3136. if (empty($id))
  3137. return false;
  3138.  
  3139. $order = get_post($id);
  3140. if (!$order)
  3141. return false;
  3142.  
  3143. $meta = get_post_custom($id);
  3144.  
  3145. //unserialize a and add to object
  3146. foreach ($meta as $key => $val)
  3147. $order->$key = maybe_unserialize($meta[$key][0]);
  3148.  
  3149. return $order;
  3150. }
  3151.  
  3152. //serves the 'order_paid' : 'order_received'
  3153. function export_orders_csv() {
  3154. global $wpdb;
  3155.  
  3156. //check permissions
  3157. $post_type_object = get_post_type_object('mp_order');
  3158. if ( !current_user_can($post_type_object->cap->edit_posts) )
  3159. wp_die(__('Cheatin&#8217; uh?'));
  3160.  
  3161. $query = "SELECT ID, post_title, post_date, post_status FROM {$wpdb->posts} WHERE post_type = 'mp_order'";
  3162.  
  3163. if (isset($_POST['order_status']) && $_POST['order_status'] != 'all')
  3164. $query .= $wpdb->prepare(' AND post_status = %s', $_POST['order_status']);
  3165.  
  3166. // If a month is specified in the querystring, load that month
  3167. if ( isset($_POST['m']) && $_POST['m'] > 0 ) {
  3168. $_POST['m'] = '' . preg_replace('|[^0-9]|', '', $_POST['m']);
  3169. $query .= " AND YEAR($wpdb->posts.post_date)=" . substr($_POST['m'], 0, 4);
  3170. if ( strlen($_POST['m']) > 5 )
  3171. $query .= " AND MONTH($wpdb->posts.post_date)=" . substr($_POST['m'], 4, 2);
  3172. if ( strlen($_POST['m']) > 7 )
  3173. $query .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($_POST['m'], 6, 2);
  3174. if ( strlen($_POST['m']) > 9 )
  3175. $query .= " AND HOUR($wpdb->posts.post_date)=" . substr($_POST['m'], 8, 2);
  3176. if ( strlen($_POST['m']) > 11 )
  3177. $query .= " AND MINUTE($wpdb->posts.post_date)=" . substr($_POST['m'], 10, 2);
  3178. if ( strlen($_POST['m']) > 13 )
  3179. $query .= " AND SECOND($wpdb->posts.post_date)=" . substr($_POST['m'], 12, 2);
  3180. }
  3181.  
  3182. $query .= " ORDER BY post_date DESC";
  3183.  
  3184. $orders = $wpdb->get_results($query);
  3185.  
  3186. // Keep up to 12MB in memory, if becomes bigger write to temp file
  3187. $file = fopen('php://temp/maxmemory:'. (12*1024*1024), 'r+');
  3188. fputcsv( $file, array('order_id', 'status', 'received_date', 'paid_date', 'shipped_date', 'tax', 'shipping', 'total', 'coupon_discount', 'coupon_code', 'item_count', 'email', 'name', 'address1', 'address2', 'city', 'state', 'zipcode', 'country', 'phone', 'shipping_method', 'shipping_method_option', 'special_instructions', 'gateway', 'gateway_method', 'payment_currency', 'transaction_id' ) );
  3189.  
  3190. //loop through orders and add rows
  3191. foreach ($orders as $order) {
  3192. $meta = get_post_custom($order->ID);
  3193.  
  3194. //unserialize a and add to object
  3195. foreach ($meta as $key => $val)
  3196. $order->$key = maybe_unserialize($meta[$key][0]);
  3197.  
  3198. $fields = array();
  3199. $fields['order_id'] = $order->post_title;
  3200. $fields['status'] = $order->post_status;
  3201. $fields['received_date'] = $order->post_date;
  3202. $fields['paid_date'] = isset($order->mp_paid_time) ? date('Y-m-d H:i:s', $order->mp_paid_time) : null;
  3203. $fields['shipped_date'] = isset($order->mp_shipped_time) ? date('Y-m-d H:i:s', $order->mp_paid_time) : null;
  3204. $fields['tax'] = $order->mp_tax_total;
  3205. $fields['shipping'] = $order->mp_shipping_total;
  3206. $fields['total'] = $order->mp_order_total;
  3207. $fields['coupon_discount'] = @$order->mp_discount_info['discount'];
  3208. $fields['coupon_code'] = @$order->mp_discount_info['code'];
  3209. $fields['item_count'] = $order->mp_order_items;
  3210. $fields['email'] = @$order->mp_shipping_info['email'];
  3211. $fields['name'] = @$order->mp_shipping_info['name'];
  3212. $fields['address1'] = @$order->mp_shipping_info['address1'];
  3213. $fields['address2'] = @$order->mp_shipping_info['address2'];
  3214. $fields['city'] = @$order->mp_shipping_info['city'];
  3215. $fields['state'] = @$order->mp_shipping_info['state'];
  3216. $fields['zipcode'] = @$order->mp_shipping_info['zip'];
  3217. $fields['country'] = @$order->mp_shipping_info['country'];
  3218. $fields['phone'] = @$order->mp_shipping_info['phone'];
  3219. $fields['shipping_method'] = @$order->mp_shipping_info['shipping_option'];
  3220. $fields['shipping_method_option'] = @$order->mp_shipping_info['shipping_sub_option'];
  3221. $fields['special_instructions'] = @$order->mp_shipping_info['email'];
  3222. $fields['gateway'] = @$order->mp_payment_info['gateway_private_name'];
  3223. $fields['gateway_method'] = @$order->mp_payment_info['method'];
  3224. $fields['payment_currency'] = @$order->mp_payment_info['currency'];
  3225. $fields['transaction_id'] = @$order->mp_payment_info['transaction_id'];
  3226.  
  3227. fputcsv( $file, $fields );
  3228. }
  3229.  
  3230. //create our filename
  3231. $filename = 'orders_export';
  3232. $filename .= isset($_POST['m']) ? '_' . $_POST['m'] : '';
  3233. $filename .= '_' . time() . '.csv';
  3234.  
  3235. //serve the file
  3236. rewind($file);
  3237. ob_end_clean(); //kills any buffers set by other plugins
  3238. header('Content-Description: File Transfer');
  3239. header('Content-Type: text/csv');
  3240. header('Content-Disposition: attachment; filename="'.$filename.'"');
  3241. header('Content-Transfer-Encoding: binary');
  3242. header('Expires: 0');
  3243. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  3244. header('Pragma: public');
  3245. $output = stream_get_contents($file);
  3246. $output = $output . "\xEF\xBB\xBF"; // UTF-8 BOM
  3247. header('Content-Length: ' . strlen($output));
  3248. fclose($file);
  3249. die($output);
  3250. }
  3251.  
  3252. //converts the pretty order id to an actual post ID
  3253. function order_to_post_id($order_id) {
  3254. global $wpdb;
  3255. return $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_name = %s AND post_type = 'mp_order'", $order_id));
  3256. }
  3257.  
  3258. //$new_status can be 'received', 'paid', 'shipped', 'closed'
  3259. function update_order_status($order_id, $new_status) {
  3260. global $wpdb;
  3261.  
  3262. $statuses = array('received' => 'order_received', 'paid' => 'order_paid', 'shipped' => 'order_shipped', 'closed' => 'order_closed');
  3263. if (!array_key_exists($new_status, $statuses))
  3264. return false;
  3265.  
  3266. //get the order
  3267. $order = $this->get_order($order_id);
  3268. if (!$order)
  3269. return false;
  3270.  
  3271. switch ($new_status) {
  3272.  
  3273. case 'paid':
  3274. //update paid time, can't be adjusted as we don't want to loose gateway info
  3275. if (!get_post_meta($order->ID, 'mp_paid_time', true))
  3276. update_post_meta($order->ID, 'mp_paid_time', time());
  3277. break;
  3278.  
  3279. case 'shipped':
  3280. //update paid time if paid step was skipped
  3281. if (!get_post_meta($order->ID, 'mp_paid_time', true))
  3282. update_post_meta($order->ID, 'mp_paid_time', time());
  3283. //update shipped time, can be adjusted
  3284. update_post_meta($order->ID, 'mp_shipped_time', time());
  3285.  
  3286. //send email
  3287. $this->order_shipped_notification($order->ID);
  3288. break;
  3289.  
  3290. case 'closed':
  3291. //update paid time if paid step was skipped
  3292. if (!get_post_meta($order->ID, 'mp_paid_time', true))
  3293. update_post_meta($order->ID, 'mp_paid_time', time());
  3294. //update shipped time if shipped step was skipped
  3295. if (!get_post_meta($order->ID, 'mp_shipped_time', true))
  3296. update_post_meta($order->ID, 'mp_shipped_time', time());
  3297. //update closed
  3298. update_post_meta($order->ID, 'mp_closed_time', time());
  3299. break;
  3300.  
  3301. }
  3302.  
  3303. if ( $statuses[$new_status] == $order->post_status )
  3304. return;
  3305.  
  3306. $wpdb->update( $wpdb->posts, array( 'post_status' => $statuses[$new_status] ), array( 'ID' => $order->ID ) );
  3307.  
  3308. $old_status = $order->post_status;
  3309. $order->post_status = $statuses[$new_status];
  3310. wp_transition_post_status($statuses[$new_status], $old_status, $order);
  3311. }
  3312.  
  3313. //checks if a given cart is only downloadable products
  3314. function download_only_cart($cart) {
  3315. //always show shipping fields with global cart. TODO - make aware of global carts
  3316. if ($this->global_cart)
  3317. return false;
  3318.  
  3319. foreach ((array)$cart as $product_id => $variations) {
  3320. foreach ((array)$variations as $variation => $data) {
  3321. if (!is_array($data['download']))
  3322. return false;
  3323. }
  3324. }
  3325. return true;
  3326. }
  3327.  
  3328. //returns formatted download url for a given product. Returns false if no download
  3329. function get_download_url($product_id, $order_id) {
  3330. $url = get_post_meta($product_id, 'mp_file', true);
  3331. if (!$url)
  3332. return false;
  3333.  
  3334. return get_permalink($product_id) . "?orderid=$order_id";
  3335. }
  3336.  
  3337. //serves a downloadble product file
  3338. function serve_download($product_id) {
  3339. $settings = get_option('mp_settings');
  3340.  
  3341. if (!isset($_GET['orderid']))
  3342. return false;
  3343.  
  3344. //get the order
  3345. $order = $this->get_order($_GET['orderid']);
  3346. if (!$order)
  3347. wp_die( __('Sorry, the link is invalid for this download.', 'mp') );
  3348.  
  3349. //check that order is paid
  3350. if ($order->post_status == 'order_received')
  3351. wp_die( __('Sorry, your order has been marked as unpaid.', 'mp') );
  3352.  
  3353. $url = get_post_meta($product_id, 'mp_file', true);
  3354.  
  3355. //get cart count
  3356. if (isset($order->mp_cart_info[$product_id][0]['download']))
  3357. $download = $order->mp_cart_info[$product_id][0]['download'];
  3358.  
  3359. //if new url is not set try to grab it from the order history
  3360. if (!$url && isset($download['url']))
  3361. $url = $download['url'];
  3362. else if (!$url)
  3363. wp_die( __('Whoops, we were unable to find the file for this download. Please contact us for help.', 'mp') );
  3364.  
  3365. //check for too many downloads
  3366. $max_downloads = intval($settings['max_downloads']) ? intval($settings['max_downloads']) : 5;
  3367. if (intval($download['downloaded']) >= $max_downloads)
  3368. wp_die( sprintf( __("Sorry, our records show you've downloaded this file %d out of %d times allowed. Please contact us if you still need help.", 'mp'), intval($download['downloaded']), $max_downloads ) );
  3369.  
  3370. //for plugins to hook into the download script. Don't forget to increment the download count, then exit!
  3371. do_action('mp_serve_download', $url, $order, $download);
  3372.  
  3373. //allows you to simply filter the url
  3374. $url = apply_filters('mp_download_url', $url, $order, $download);
  3375.  
  3376. //if your getting out of memory errors with large downloads, you can use a redirect instead, it's not so secure though
  3377. if ( defined('MP_LARGE_DOWNLOADS') && MP_LARGE_DOWNLOADS ) {
  3378. //attempt to record a download attempt
  3379. if (isset($download['downloaded'])) {
  3380. $order->mp_cart_info[$product_id][0]['download']['downloaded'] = $download['downloaded'] + 1;
  3381. update_post_meta($order->ID, 'mp_cart_info', $order->mp_cart_info);
  3382. }
  3383. wp_redirect($url);
  3384. exit;
  3385. } else {
  3386.  
  3387. //create unique filename
  3388. $ext = ltrim(strrchr(basename($url), '.'), '.');
  3389. $filename = sanitize_file_name( strtolower( get_the_title($product_id) ) . '.' . $ext );
  3390.  
  3391. // Determine if this file is in our server
  3392. $dirs = wp_upload_dir();
  3393. $location = str_replace($dirs['baseurl'], $dirs['basedir'], $url);
  3394. if ( file_exists($location) ) {
  3395. $tmp = $location;
  3396. $not_delete = true;
  3397. } else {
  3398. require_once(ABSPATH . '/wp-admin/includes/file.php');
  3399.  
  3400. $tmp = download_url($url); //we download the url so we can serve it via php, completely obfuscating original source
  3401.  
  3402. if ( is_wp_error($tmp) ) {
  3403. @unlink($tmp);
  3404. trigger_error("MarketPress was unable to download the file $url for serving as download: ".$tmp->get_error_message(), E_USER_WARNING);
  3405. wp_die( __('Whoops, there was a problem loading up this file for your download. Please contact us for help.', 'mp') );
  3406. }
  3407. }
  3408.  
  3409. if (file_exists($tmp)) {
  3410. ob_end_clean(); //kills any buffers set by other plugins
  3411. header('Content-Description: File Transfer');
  3412. header('Content-Type: application/octet-stream');
  3413. header('Content-Disposition: attachment; filename="'.$filename.'"');
  3414. header('Content-Transfer-Encoding: binary');
  3415. header('Expires: 0');
  3416. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  3417. header('Pragma: public');
  3418. header('Content-Length: ' . filesize($tmp));
  3419. //readfile($tmp); //seems readfile chokes on large files
  3420. $chunksize = 1 * (1024 * 1024); // how many bytes per chunk
  3421. $buffer = '';
  3422. $cnt = 0;
  3423. $handle = fopen( $tmp, 'rb' );
  3424. if ( $handle === false ) {
  3425. trigger_error("MarketPress was unable to read the file $tmp for serving as download.", E_USER_WARNING);
  3426. return false;
  3427. }
  3428. while ( !feof( $handle ) ) {
  3429. $buffer = fread( $handle, $chunksize );
  3430. echo $buffer;
  3431. ob_flush();
  3432. flush();
  3433. if ( $retbytes ) {
  3434. $cnt += strlen( $buffer );
  3435. }
  3436. }
  3437. fclose( $handle );
  3438.  
  3439. if (!$not_delete)
  3440. @unlink($tmp);
  3441. }
  3442.  
  3443. //attempt to record a download attempt
  3444. if (isset($download['downloaded'])) {
  3445. $order->mp_cart_info[$product_id][0]['download']['downloaded'] = $download['downloaded'] + 1;
  3446. update_post_meta($order->ID, 'mp_cart_info', $order->mp_cart_info);
  3447. }
  3448. exit;
  3449. }
  3450.  
  3451. return false;
  3452. }
  3453.  
  3454. // Update profile fields
  3455. function user_profile_update() {
  3456. $user_id = $_REQUEST['user_id'];
  3457.  
  3458. // Billing Info
  3459. $meta = get_user_meta($user_id, 'mp_billing_info', true);
  3460.  
  3461. if (!isset($_POST['mp_billing_info']['email'])) {
  3462. $meta['email'] = '';
  3463. }
  3464. if (!isset($_POST['mp_billing_info']['name'])) {
  3465. $meta['name'] = '';
  3466. }
  3467. if (!isset($_POST['mp_billing_info']['address1'])) {
  3468. $meta['address1'] = '';
  3469. }
  3470. if (!isset($_POST['mp_billing_info']['address2'])) {
  3471. $meta['address2'] = '';
  3472. }
  3473. if (!isset($_POST['mp_billing_info']['city'])) {
  3474. $meta['city'] = '';
  3475. }
  3476. if (!isset($_POST['mp_billing_info']['state'])) {
  3477. $meta['state'] = '';
  3478. }
  3479. if (!isset($_POST['mp_billing_info']['zip'])) {
  3480. $meta['zip'] = '';
  3481. }
  3482. if (!isset($_POST['mp_billing_info']['country'])) {
  3483. $meta['country'] = '';
  3484. }
  3485. if (!isset($_POST['mp_billing_info']['phone'])) {
  3486. $meta['phone'] = '';
  3487. }
  3488.  
  3489. $email = isset($_POST['mp_billing_info']['email']) ? $_POST['mp_billing_info']['email'] : $meta['email'];
  3490. $name = isset($_POST['mp_billing_info']['name']) ? $_POST['mp_billing_info']['name'] : $meta['name'];
  3491. $address1 = isset($_POST['mp_billing_info']['address1']) ? $_POST['mp_billing_info']['address1'] : $meta['address1'];
  3492. $address2 = isset($_POST['mp_billing_info']['address2']) ? $_POST['mp_billing_info']['address2'] : $meta['address2'];
  3493. $city = isset($_POST['mp_billing_info']['city']) ? $_POST['mp_billing_info']['city'] : $meta['city'];
  3494. $state = isset($_POST['mp_billing_info']['state']) ? $_POST['mp_billing_info']['state'] : $meta['state'];
  3495. $zip = isset($_POST['mp_billing_info']['zip']) ? $_POST['mp_billing_info']['zip'] : $meta['zip'];
  3496. $country = isset($_POST['mp_billing_info']['country']) ? $_POST['mp_billing_info']['country'] : $meta['country'];
  3497. $phone = isset($_POST['mp_billing_info']['phone']) ? $_POST['mp_billing_info']['phone'] : $meta['phone'];
  3498.  
  3499. $billing_meta = array('email' => $email,
  3500. 'name' => $name,
  3501. 'address1' => $address1,
  3502. 'address2' => $address2,
  3503. 'city' => $city,
  3504. 'state' => $state,
  3505. 'zip' => $zip,
  3506. 'country' => $country,
  3507. 'phone' => $phone);
  3508.  
  3509. update_user_meta($user_id, 'mp_billing_info', $billing_meta);
  3510.  
  3511. // Shipping Info
  3512. $meta = get_user_meta($user_id, 'mp_shipping_info', true);
  3513.  
  3514. if (!isset($_POST['mp_shipping_info']['email'])) {
  3515. $meta['email'] = '';
  3516. }
  3517. if (!isset($_POST['mp_shipping_info']['name'])) {
  3518. $meta['name'] = '';
  3519. }
  3520. if (!isset($_POST['mp_shipping_info']['address1'])) {
  3521. $meta['address1'] = '';
  3522. }
  3523. if (!isset($_POST['mp_shipping_info']['address2'])) {
  3524. $meta['address2'] = '';
  3525. }
  3526. if (!isset($_POST['mp_shipping_info']['city'])) {
  3527. $meta['city'] = '';
  3528. }
  3529. if (!isset($_POST['mp_shipping_info']['state'])) {
  3530. $meta['state'] = '';
  3531. }
  3532. if (!isset($_POST['mp_shipping_info']['zip'])) {
  3533. $meta['zip'] = '';
  3534. }
  3535. if (!isset($_POST['mp_shipping_info']['country'])) {
  3536. $meta['country'] = '';
  3537. }
  3538.  
  3539. $email = isset($_POST['mp_shipping_info']['email']) ? $_POST['mp_shipping_info']['email'] : $meta['email'];
  3540. $name = isset($_POST['mp_shipping_info']['name']) ? $_POST['mp_shipping_info']['name'] : $meta['name'];
  3541. $address1 = isset($_POST['mp_shipping_info']['address1']) ? $_POST['mp_shipping_info']['address1'] : $meta['address1'];
  3542. $address2 = isset($_POST['mp_shipping_info']['address2']) ? $_POST['mp_shipping_info']['address2'] : $meta['address2'];
  3543. $city = isset($_POST['mp_shipping_info']['city']) ? $_POST['mp_shipping_info']['city'] : $meta['city'];
  3544. $state = isset($_POST['mp_shipping_info']['state']) ? $_POST['mp_shipping_info']['state'] : $meta['state'];
  3545. $zip = isset($_POST['mp_shipping_info']['zip']) ? $_POST['mp_shipping_info']['zip'] : $meta['zip'];
  3546. $country = isset($_POST['mp_shipping_info']['country']) ? $_POST['mp_shipping_info']['country'] : $meta['country'];
  3547. $phone = isset($_POST['mp_shipping_info']['phone']) ? $_POST['mp_shipping_info']['phone'] : $meta['phone'];
  3548.  
  3549. $shipping_meta = array('email' => $email,
  3550. 'name' => $name,
  3551. 'address1' => $address1,
  3552. 'address2' => $address2,
  3553. 'city' => $city,
  3554. 'state' => $state,
  3555. 'zip' => $zip,
  3556. 'country' => $country,
  3557. 'phone' => $phone);
  3558.  
  3559. update_user_meta($user_id, 'mp_shipping_info', $shipping_meta);
  3560. }
  3561.  
  3562. function user_profile_fields() {
  3563. global $current_user;
  3564.  
  3565. if (isset($_REQUEST['user_id'])) {
  3566. $user_id = $_REQUEST['user_id'];
  3567. } else {
  3568. $user_id = $current_user->ID;
  3569. }
  3570.  
  3571. $settings = get_option('mp_settings');
  3572.  
  3573. $meta = get_user_meta($user_id, 'mp_billing_info', true);
  3574. $email = (!empty($_SESSION['mp_billing_info']['email'])) ? $_SESSION['mp_billing_info']['email'] : $meta['email'];
  3575. $name = (!empty($_SESSION['mp_billing_info']['name'])) ? $_SESSION['mp_billing_info']['name'] : $meta['name'];
  3576. $address1 = (!empty($_SESSION['mp_billing_info']['address1'])) ? $_SESSION['mp_billing_info']['address1'] : $meta['address1'];
  3577. $address2 = (!empty($_SESSION['mp_billing_info']['address2'])) ? $_SESSION['mp_billing_info']['address2'] : $meta['address2'];
  3578. $city = (!empty($_SESSION['mp_billing_info']['city'])) ? $_SESSION['mp_billing_info']['city'] : $meta['city'];
  3579. $state = (!empty($_SESSION['mp_billing_info']['state'])) ? $_SESSION['mp_billing_info']['state'] : $meta['state'];
  3580. $zip = (!empty($_SESSION['mp_billing_info']['zip'])) ? $_SESSION['mp_billing_info']['zip'] : $meta['zip'];
  3581. $country = (!empty($_SESSION['mp_billing_info']['country'])) ? $_SESSION['mp_billing_info']['country'] : $meta['country'];
  3582. if (!$country)
  3583. $country = $settings['base_country'];
  3584. $phone = (!empty($_SESSION['mp_billing_info']['phone'])) ? $_SESSION['mp_billing_info']['phone'] : $meta['phone'];
  3585.  
  3586. ?>
  3587. <h3><?php _e('Billing Info', 'mp'); ?></h3>
  3588. <a name="mp_billing_info"></a>
  3589. <table class="form-table">
  3590. <tr>
  3591. <th align="right"><label for="mp_billing_info_email"><?php _e('Email:', 'mp'); ?>&nbsp;</label></th><td>
  3592. <?php echo apply_filters( 'mp_billing_info_error_email', ''); ?>
  3593. <input size="35" id="mp_billing_info_email" name="mp_billing_info[email]" type="text" value="<?php echo esc_attr($email); ?>" /></td>
  3594. </tr>
  3595. <tr>
  3596. <th align="right"><label for="mp_billing_info_name"><?php _e('Full Name:', 'mp'); ?>&nbsp;</label></th><td>
  3597. <?php echo apply_filters( 'mp_billing_info_error_name', ''); ?>
  3598. <input size="35" id="mp_billing_info_name" name="mp_billing_info[name]" type="text" value="<?php echo esc_attr($name); ?>" /> </td>
  3599. </tr>
  3600. <tr>
  3601. <th align="right"><label for="mp_billing_info_address1"><?php _e('Address:', 'mp'); ?>&nbsp;</label></th><td>
  3602. <?php echo apply_filters( 'mp_billing_info_error_address1', ''); ?>
  3603. <input size="45" id="mp_billing_info_address1" name="mp_billing_info[address1]" type="text" value="<?php echo esc_attr($address1); ?>" /><br />
  3604. <small><em><?php _e('Street address, P.O. box, company name, c/o', 'mp'); ?></em></small>
  3605. </td>
  3606. </tr>
  3607. <tr>
  3608. <th align="right"><label for="mp_billing_info_address2"><?php _e('Address 2:', 'mp'); ?>&nbsp;</label></th><td>
  3609. <?php echo apply_filters( 'mp_billing_info_error_address2', ''); ?>
  3610. <input size="45" id="mp_billing_info_address2" name="mp_billing_info[address2]" type="text" value="<?php echo esc_attr($address2); ?>" /><br />
  3611. <small><em><?php _e('Apartment, suite, unit, building, floor, etc.', 'mp'); ?></em></small>
  3612. </td>
  3613. </tr>
  3614. <tr>
  3615. <th align="right"><label for="mp_billing_info_city"><?php _e('City:', 'mp'); ?>&nbsp;</label></th><td>
  3616. <?php echo apply_filters( 'mp_billing_info_error_city', ''); ?>
  3617. <input size="25" id="mp_billing_info_city" name="mp_billing_info[city]" type="text" value="<?php echo esc_attr($city); ?>" /></td>
  3618. </tr>
  3619. <tr>
  3620. <th align="right"><label for="mp_billing_info_state"><?php _e('State/Province/Region:', 'mp'); ?>&nbsp;</label></th><td>
  3621. <?php echo apply_filters( 'mp_billing_info_error_state', ''); ?>
  3622. <input size="15" id="mp_billing_info_state" name="mp_billing_info[state]" type="text" value="<?php echo esc_attr($state); ?>" /></td>
  3623. </tr>
  3624. <tr>
  3625. <th align="right"><label for="mp_billing_info_zip"><?php _e('Postal/Zip Code:', 'mp'); ?>&nbsp;</label></th><td>
  3626. <?php echo apply_filters( 'mp_billing_info_error_zip', ''); ?>
  3627. <input size="10" id="mp_billing_info_zip" name="mp_billing_info[zip]" type="text" value="<?php echo esc_attr($zip); ?>" /></td>
  3628. </tr>
  3629. <tr>
  3630. <th align="right"><label for="mp_billing_info_country"><?php _e('Country:', 'mp'); ?>&nbsp;</label></th><td>
  3631. <?php echo apply_filters( 'mp_billing_info_error_country', ''); ?>
  3632. <select id="mp_billing_info_country" name="mp_billing_info[country]">
  3633. <?php
  3634. foreach ($settings['shipping']['allowed_countries'] as $code) {
  3635. ?><option value="<?php echo $code; ?>"<?php selected($country, $code); ?>><?php echo esc_attr($this->countries[$code]); ?></option><?php
  3636. }
  3637. ?>
  3638. </select>
  3639. </td>
  3640. </tr>
  3641. <tr>
  3642. <th align="right"><label for="mp_billing_info_phone"><?php _e('Phone Number:', 'mp'); ?>&nbsp;</label></th><td>
  3643. <?php echo apply_filters( 'mp_billing_info_error_phone', ''); ?>
  3644. <input size="20" id="mp_billing_info_phone" name="mp_billing_info[phone]" type="text" value="<?php echo esc_attr($phone); ?>" /></td>
  3645. </tr>
  3646. </table>
  3647. <?php
  3648. $meta = get_user_meta($user_id, 'mp_shipping_info', true);
  3649.  
  3650. $email = (!empty($_SESSION['mp_shipping_info']['email'])) ? $_SESSION['mp_shipping_info']['email'] : (!empty($meta['email'])?$meta['email']:$_SESSION['mp_shipping_info']['email']);
  3651. $name = (!empty($_SESSION['mp_shipping_info']['name'])) ? $_SESSION['mp_shipping_info']['name'] : (!empty($meta['name'])?$meta['name']:$_SESSION['mp_shipping_info']['name']);
  3652. $address1 = (!empty($_SESSION['mp_shipping_info']['address1'])) ? $_SESSION['mp_shipping_info']['address1'] : (!empty($meta['address1'])?$meta['address1']:$_SESSION['mp_shipping_info']['address1']);
  3653. $address2 = (!empty($_SESSION['mp_shipping_info']['address2'])) ? $_SESSION['mp_shipping_info']['address2'] : (!empty($meta['address2'])?$meta['address2']:$_SESSION['mp_shipping_info']['address2']);
  3654. $city = (!empty($_SESSION['mp_shipping_info']['city'])) ? $_SESSION['mp_shipping_info']['city'] : (!empty($meta['city'])?$meta['city']:$_SESSION['mp_shipping_info']['city']);
  3655. $state = (!empty($_SESSION['mp_shipping_info']['state'])) ? $_SESSION['mp_shipping_info']['state'] : (!empty($meta['state'])?$meta['state']:$_SESSION['mp_shipping_info']['state']);
  3656. $zip = (!empty($_SESSION['mp_shipping_info']['zip'])) ? $_SESSION['mp_shipping_info']['zip'] : (!empty($meta['zip'])?$meta['zip']:$_SESSION['mp_shipping_info']['zip']);
  3657. $country = (!empty($_SESSION['mp_shipping_info']['country'])) ? $_SESSION['mp_shipping_info']['country'] : (!empty($meta['country'])?$meta['country']:$_SESSION['mp_shipping_info']['country']);
  3658. if (!$country)
  3659. $country = $settings['base_country'];
  3660. $phone = (!empty($_SESSION['mp_shipping_info']['phone'])) ? $_SESSION['mp_shipping_info']['phone'] : (!empty($meta['phone'])?$meta['phone']:$_SESSION['mp_shipping_info']['phone']);
  3661.  
  3662. ?>
  3663. <h3><?php _e('Shipping Info', 'mp'); ?></h3>
  3664. <a name="mp_shipping_info"></a>
  3665. <span class="mp_action" ><a href="javascript:mp_copy_billing('mp_shipping_info');"><?php _e('Same as Billing', 'mp'); ?></a></span>
  3666. <table class="form-table">
  3667. <tr>
  3668. <th align="right"><label for="mp_shipping_info_email"><?php _e('Email:', 'mp'); ?>&nbsp;</label></th><td>
  3669. <?php echo apply_filters( 'mp_shipping_info_error_email', ''); ?>
  3670. <input size="35" id="mp_shipping_info_email" name="mp_shipping_info[email]" type="text" value="<?php echo esc_attr($email); ?>" /></td>
  3671. </tr>
  3672. <tr>
  3673. <th align="right"><label for="mp_shipping_info_name"><?php _e('Full Name:', 'mp'); ?>&nbsp;</label></th><td>
  3674. <?php echo apply_filters( 'mp_checkout_error_name', ''); ?>
  3675. <input size="35" id="mp_shipping_info_name" name="mp_shipping_info[name]" type="text" value="<?php echo esc_attr($name); ?>" /> </td>
  3676. </tr>
  3677. <tr>
  3678. <th align="right"><label for="mp_shipping_info_address1"><?php _e('Address:', 'mp'); ?>&nbsp;</label></th><td>
  3679. <?php echo apply_filters( 'mp_shipping_info_error_address1', ''); ?>
  3680. <input size="45" id="mp_shipping_info_address1" name="mp_shipping_info[address1]" type="text" value="<?php echo esc_attr($address1); ?>" /><br />
  3681. <small><em><?php _e('Street address, P.O. box, company name, c/o', 'mp'); ?></em></small>
  3682. </td>
  3683. </tr>
  3684. <tr>
  3685. <th align="right"><label for="mp_shipping_info_address2"><?php _e('Address 2:', 'mp'); ?>&nbsp;</label></th><td>
  3686. <?php echo apply_filters( 'mp_shipping_info_error_address2', ''); ?>
  3687. <input size="45" id="mp_shipping_info_address2" name="mp_shipping_info[address2]" type="text" value="<?php echo esc_attr($address2); ?>" /><br />
  3688. <small><em><?php _e('Apartment, suite, unit, building, floor, etc.', 'mp'); ?></em></small>
  3689. </td>
  3690. </tr>
  3691. <tr>
  3692. <th align="right"><label for="mp_shipping_info_city"><?php _e('City:', 'mp'); ?>&nbsp;</label></th><td>
  3693. <?php echo apply_filters( 'mp_shipping_info_error_city', ''); ?>
  3694. <input size="25" id="mp_shipping_info_city" name="mp_shipping_info[city]" type="text" value="<?php echo esc_attr($city); ?>" /></td>
  3695. </tr>
  3696. <tr>
  3697. <th align="right"><label for="mp_shipping_info_state"><?php _e('State/Province/Region:', 'mp'); ?>&nbsp;</label></th><td>
  3698. <?php echo apply_filters( 'mp_shipping_info_error_state', ''); ?>
  3699. <input size="15" id="mp_shipping_info_state" name="mp_shipping_info[state]" type="text" value="<?php echo esc_attr($state); ?>" /></td>
  3700. </tr>
  3701. <tr>
  3702. <th align="right"><label for="mp_shipping_info_zip"><?php _e('Postal/Zip Code:', 'mp'); ?>&nbsp;</label></th><td>
  3703. <?php echo apply_filters( 'mp_shipping_info_error_zip', ''); ?>
  3704. <input size="10" id="mp_shipping_info_zip" name="mp_shipping_info[zip]" type="text" value="<?php echo esc_attr($zip); ?>" /></td>
  3705. </tr>
  3706. <tr>
  3707. <th align="right"><label for="mp_shipping_info_country"><?php _e('Country:', 'mp'); ?>&nbsp;</label></th><td>
  3708. <?php echo apply_filters( 'mp_shipping_info_error_country', ''); ?>
  3709. <select id="mp_shipping_info_country" name="mp_shipping_info[country]">
  3710. <?php
  3711. foreach ($settings['shipping']['allowed_countries'] as $code) {
  3712. ?><option value="<?php echo $code; ?>"<?php selected($country, $code); ?>><?php echo esc_attr($this->countries[$code]); ?></option><?php
  3713. }
  3714. ?>
  3715. </select>
  3716. </td>
  3717. </tr>
  3718. <tr>
  3719. <th align="right"><label for="mp_shipping_info_phone"><?php _e('Phone Number:', 'mp'); ?>&nbsp;</label></th><td>
  3720. <?php echo apply_filters( 'mp_shipping_info_error_phone', ''); ?>
  3721. <input size="20" id="mp_shipping_info_phone" name="mp_shipping_info[phone]" type="text" value="<?php echo esc_attr($phone); ?>" /></td>
  3722. </tr>
  3723. </table>
  3724. <script type="text/javascript">
  3725. function mp_copy_billing(prefix) {
  3726. _mp_profile_billing_fields = ['emal', 'name', 'address1', 'address2', 'city', 'state', 'zip', 'country', 'phone'];
  3727.  
  3728. for (_i=0; _i<_mp_profile_billing_fields.length; _i++) {
  3729. jQuery('form #'+prefix+'_'+_mp_profile_billing_fields[_i]).val(jQuery('form #mp_billing_info_'+_mp_profile_billing_fields[_i]).val());
  3730. }
  3731. }
  3732. </script>
  3733. <?php
  3734. }
  3735.  
  3736. //called by payment gateways to update order statuses
  3737. function update_order_payment_status($order_id, $status, $paid) {
  3738. //get the order
  3739. $order = $this->get_order($order_id);
  3740. if (!$order)
  3741. return false;
  3742.  
  3743. //get old status
  3744. $payment_info = $order->mp_payment_info;
  3745. $timestamp = time();
  3746. $payment_info['status'][$timestamp] = $status;
  3747. //update post meta
  3748. update_post_meta($order->ID, 'mp_payment_info', $payment_info);
  3749.  
  3750. if ($paid) {
  3751. if ($order->post_status == 'order_received') {
  3752. $this->update_order_status($order->ID, 'paid');
  3753. do_action( 'mp_order_paid', $order );
  3754.  
  3755. //if paid and the cart is only digital products mark it shipped
  3756. if (is_array($order->mp_cart_info) && $this->download_only_cart($order->mp_cart_info))
  3757. $this->update_order_status($order->ID, 'shipped');
  3758. } else {
  3759. //update payment time if somehow it was skipped
  3760. if (!get_post_meta($order->ID, 'mp_paid_time', true))
  3761. update_post_meta($order->ID, 'mp_paid_time', time());
  3762. }
  3763. } else {
  3764. $this->update_order_status($order->ID, 'received');
  3765. }
  3766.  
  3767. //return merged payment info
  3768. return $payment_info;
  3769. }
  3770.  
  3771. //filters wp_mail headers
  3772. function mail($to, $subject, $msg) {
  3773. $settings = get_option('mp_settings');
  3774.  
  3775. //remove any other filters
  3776. remove_all_filters( 'wp_mail_from' );
  3777. remove_all_filters( 'wp_mail_from_name' );
  3778.  
  3779. //add our own filters
  3780. add_filter( 'wp_mail_from_name', create_function('', 'return get_bloginfo("name");') );
  3781. add_filter( 'wp_mail_from', create_function('', '$settings = get_option("mp_settings");return isset($settings["store_email"]) ? $settings["store_email"] : get_option("admin_email");') );
  3782.  
  3783. return wp_mail($to, $subject, $msg);
  3784. }
  3785.  
  3786. //replaces shortcodes in email msgs with dynamic content
  3787. function filter_email($order, $text) {
  3788. $settings = get_option('mp_settings');
  3789.  
  3790. //// order info
  3791. if (is_array($order->mp_cart_info) && count($order->mp_cart_info)) {
  3792. $order_info = __('Items:', 'mp') . "\n";
  3793. foreach ($order->mp_cart_info as $product_id => $variations) {
  3794. foreach ($variations as $variation => $data) {
  3795. $order_info .= "\t" . $data['name'] . ': ' . number_format_i18n($data['quantity']) . ' * ' . number_format_i18n($data['price'], 2) . ' = '. number_format_i18n($data['price'] * $data['quantity'], 2) . ' ' . $order->mp_payment_info['currency'] . "\n";
  3796.  
  3797. //show download link if set
  3798. if ($order->post_status != 'order_received' && $download_url = $this->get_download_url($product_id, $order->post_title))
  3799. $order_info .= "\t\t" . __('Download: ', 'mp') . $download_url . "\n";
  3800. }
  3801. }
  3802. $order_info .= "\n";
  3803. }
  3804. //coupon line
  3805. if ( $order->mp_discount_info ) {
  3806. $order_info .= "\n" . __('Coupon Discount:', 'mp') . ' ' . str_replace('%', __(' Percent', 'mp'), $order->mp_discount_info['discount']); //have to escape % sign so sprintf doesn't choke
  3807. }
  3808. //shipping line
  3809. if ( $order->mp_shipping_total ) {
  3810. $order_info .= "\n" . __('Shipping:', 'mp') . ' ' . number_format_i18n($order->mp_shipping_total, 2) . ' ' . $order->mp_payment_info['currency'];
  3811. }
  3812. //tax line
  3813. if ( $order->mp_tax_total ) {
  3814. $order_info .= "\n" . __('Taxes:', 'mp') . ' ' . number_format_i18n($order->mp_tax_total, 2) . ' ' . $order->mp_payment_info['currency'];
  3815. }
  3816. //total line
  3817. $order_info .= "\n" . __('Order Total:', 'mp') . ' ' . number_format_i18n($order->mp_order_total, 2) . ' ' . $order->mp_payment_info['currency'];
  3818.  
  3819. //// Shipping Info
  3820.  
  3821. if (is_array($order->mp_cart_info) && $this->download_only_cart($order->mp_cart_info)) { //if the cart is only digital products
  3822. $shipping_info = __('No shipping required for this order.', 'mp');
  3823. } else {
  3824. $shipping_info = __('Full Name:', 'mp') . ' ' . $order->mp_shipping_info['name'];
  3825. $shipping_info .= "\n" . __('Address:', 'mp') . ' ' . $order->mp_shipping_info['address1'];
  3826. if ($order->mp_shipping_info['address2'])
  3827. $shipping_info .= "\n" . __('Address 2:', 'mp') . ' ' . $order->mp_shipping_info['address2'];
  3828. $shipping_info .= "\n" . __('City:', 'mp') . ' ' . $order->mp_shipping_info['city'];
  3829. if ($order->mp_shipping_info['state'])
  3830. $shipping_info .= "\n" . __('State/Province/Region:', 'mp') . ' ' . $order->mp_shipping_info['state'];
  3831. $shipping_info .= "\n" . __('Postal/Zip Code:', 'mp') . ' ' . $order->mp_shipping_info['zip'];
  3832. $shipping_info .= "\n" . __('Country:', 'mp') . ' ' . $order->mp_shipping_info['country'];
  3833. if ($order->mp_shipping_info['phone'])
  3834. $shipping_info .= "\n" . __('Phone Number:', 'mp') . ' ' . $order->mp_shipping_info['phone'];
  3835. if (isset($order->mp_shipping_info['method']) && $order->mp_shipping_info['method'] != 'other')
  3836. $shipping_info .= "\n" . __('Shipping Method:', 'mp') . ' ' . $order->mp_shipping_info['method'];
  3837. if ($order->mp_shipping_info['tracking_num'])
  3838. $shipping_info .= "\n" . __('Tracking Number:', 'mp') . ' ' . $order->mp_shipping_info['tracking_num'];
  3839. }
  3840.  
  3841. if ($order->mp_order_notes)
  3842. $order_notes = __('Order Notes:', 'mp') . "\n" . $order->mp_order_notes;
  3843.  
  3844. //// Payment Info
  3845. $payment_info = __('Payment Method:', 'mp') . ' ' . $order->mp_payment_info['gateway_public_name'];
  3846.  
  3847. if ($order->mp_payment_info['method'])
  3848. $payment_info .= "\n" . __('Payment Type:', 'mp') . ' ' . $order->mp_payment_info['method'];
  3849.  
  3850. if ($order->mp_payment_info['transaction_id'])
  3851. $payment_info .= "\n" . __('Transaction ID:', 'mp') . ' ' . $order->mp_payment_info['transaction_id'];
  3852.  
  3853. $payment_info .= "\n" . __('Payment Total:', 'mp') . ' ' . number_format_i18n($order->mp_payment_info['total'], 2) . ' ' . $order->mp_payment_info['currency'];
  3854. $payment_info .= "\n\n";
  3855. if ($order->post_status == 'order_received') {
  3856. $payment_info .= __('Your payment for this order is not yet complete. Here is the latest status:', 'mp') . "\n";
  3857. $statuses = $order->mp_payment_info['status'];
  3858. krsort($statuses); //sort with latest status at the top
  3859. $status = reset($statuses);
  3860. $timestamp = key($statuses);
  3861. $payment_info .= date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $timestamp) . ': ' . $status;
  3862. } else {
  3863. $payment_info .= __('Your payment for this order is complete.', 'mp');
  3864. }
  3865.  
  3866. //total
  3867. $order_total = number_format_i18n($order->mp_payment_info['total'], 2) . ' ' . $order->mp_payment_info['currency'];
  3868.  
  3869. //tracking URL
  3870. $tracking_url = apply_filters('wpml_marketpress_tracking_url', mp_orderstatus_link(false, true) . $order->post_title . '/');
  3871.  
  3872. //setup filters
  3873. $search = array('CUSTOMERNAME', 'ORDERID', 'ORDERINFO', 'SHIPPINGINFO', 'PAYMENTINFO', 'TOTAL', 'TRACKINGURL', 'ORDERNOTES');
  3874. $replace = array($order->mp_shipping_info['name'], $order->post_title, $order_info, $shipping_info, $payment_info, $order_total, $tracking_url, $order_notes);
  3875.  
  3876. //replace
  3877. $text = str_replace($search, $replace, $text);
  3878.  
  3879. return $text;
  3880. }
  3881.  
  3882. //sends email for new orders
  3883. function order_notification($order_id) {
  3884. $settings = get_option('mp_settings');
  3885.  
  3886. //get the order
  3887. $order = $this->get_order($order_id);
  3888. if (!$order)
  3889. return false;
  3890.  
  3891. $subject = apply_filters('mp_order_notification_subject', $this->filter_email($order, stripslashes($settings['email']['new_order_subject'])), $order);
  3892. $msg = apply_filters('mp_order_notification_body', $this->filter_email($order, stripslashes($settings['email']['new_order_txt'])), $order);
  3893. $msg = apply_filters('mp_order_notification_' . $_SESSION['mp_payment_method'], $msg, $order );
  3894.  
  3895. $this->mail($order->mp_shipping_info['email'], $subject, $msg);
  3896.  
  3897. //send message to admin
  3898. $subject = __('New Order Notification: ORDERID', 'mp');
  3899. $msg = __("A new order (ORDERID) was created in your store:
  3900.  
  3901. Order Information:
  3902. ORDERINFO
  3903.  
  3904. Shipping Information:
  3905. SHIPPINGINFO
  3906.  
  3907. Email: %s
  3908.  
  3909. Payment Information:
  3910. PAYMENTINFO
  3911.  
  3912. You can manage this order here: %s", 'mp');
  3913.  
  3914. $subject = $this->filter_email($order, $subject);
  3915. $subject = apply_filters( 'mp_order_notification_admin_subject', $subject, $order );
  3916. $msg = $this->filter_email($order, $msg);
  3917. $msg = sprintf($msg, $order->mp_shipping_info['email'], admin_url('edit.php?post_type=product&page=marketpress-orders&order_id=') . $order->ID);
  3918. $msg = apply_filters( 'mp_order_notification_admin_msg', $msg, $order );
  3919. $store_email = isset($settings['store_email']) ? $settings['store_email'] : get_option("admin_email");
  3920. $this->mail($store_email, $subject, $msg);
  3921. }
  3922.  
  3923. //sends email for orders marked as shipped
  3924. function order_shipped_notification($order_id) {
  3925. $settings = get_option('mp_settings');
  3926.  
  3927. //get the order
  3928. $order = $this->get_order($order_id);
  3929. if (!$order)
  3930. return false;
  3931.  
  3932. //skip notice for paid download only carts
  3933. if ($this->skip_shipping_notice)
  3934. return false;
  3935.  
  3936. $subject = apply_filters('mp_shipped_order_notification_subject', stripslashes($settings['email']['shipped_order_subject']), $order);
  3937. $subject = $this->filter_email($order, $subject);
  3938. $msg = apply_filters( 'mp_shipped_order_notification_body', stripslashes($settings['email']['shipped_order_txt']), $order );
  3939. $msg = $this->filter_email($order, $msg);
  3940. $msg = apply_filters( 'mp_shipped_order_notification', $msg, $order );
  3941.  
  3942. $this->mail($order->mp_shipping_info['email'], $subject, $msg);
  3943.  
  3944. }
  3945.  
  3946. //sends email to admin for low stock notification
  3947. function low_stock_notification($product_id, $variation, $stock) {
  3948. $settings = get_option('mp_settings');
  3949.  
  3950. //skip if sent already and not 0
  3951. if ( get_post_meta($product_id, 'mp_stock_email_sent', true) && $stock > 0 )
  3952. return;
  3953.  
  3954. $var_names = maybe_unserialize(get_post_meta($product_id, 'mp_var_name', true));
  3955. if (is_array($var_names) && count($var_names) > 1)
  3956. $name = get_the_title($product_id) . ': ' . $var_names[$variation];
  3957. else
  3958. $name = get_the_title($product_id);
  3959.  
  3960. $subject = __('Low Product Inventory Notification', 'mp');
  3961. $msg = __('This message is being sent to notify you of low stock of a product in your online store according to your preferences.
  3962.  
  3963. Product: %s
  3964. Current Inventory: %s
  3965. Link: %s
  3966.  
  3967. Edit Product: %s
  3968. Notification Preferences: %s', 'mp');
  3969. $msg = sprintf($msg, $name, number_format_i18n($stock), get_permalink($product_id), get_edit_post_link($product_id), admin_url('edit.php?post_type=product&page=marketpress#mp-inventory-setting'));
  3970. $msg = apply_filters( 'mp_low_stock_notification', $msg, $product_id );
  3971. $store_email = isset($settings['store_email']) ? $settings['store_email'] : get_option("admin_email");
  3972. $this->mail($store_email, $subject, $msg);
  3973.  
  3974. //save so we don't send an email every time
  3975. update_post_meta($product_id, 'mp_stock_email_sent', 1);
  3976. }
  3977.  
  3978. //round and display currency with padded zeros
  3979. function display_currency( $amount ) {
  3980. $settings = get_option('mp_settings');
  3981.  
  3982. if ( $settings['curr_decimal'] === '0' )
  3983. return number_format( round( $amount ), 0, '.', '');
  3984. else
  3985. return number_format( round( $amount, 2 ), 2, '.', '');
  3986. }
  3987.  
  3988. //display currency symbol
  3989. function format_currency($currency = '', $amount = false) {
  3990. $settings = get_option('mp_settings');
  3991.  
  3992. if (!$currency)
  3993. $currency = $settings['currency'];
  3994.  
  3995. // get the currency symbol
  3996. $symbol = $this->currencies[$currency][1];
  3997. // if many symbols are found, rebuild the full symbol
  3998. $symbols = explode(', ', $symbol);
  3999. if (is_array($symbols)) {
  4000. $symbol = "";
  4001. foreach ($symbols as $temp) {
  4002. $symbol .= '&#x'.$temp.';';
  4003. }
  4004. } else {
  4005. $symbol = '&#x'.$symbol.';';
  4006. }
  4007.  
  4008. //check decimal option
  4009. if ( $settings['curr_decimal'] === '0' ) {
  4010. $decimal_place = 0;
  4011. $zero = '0';
  4012. } else {
  4013. $decimal_place = 2;
  4014. $zero = '0.00';
  4015. }
  4016.  
  4017. //format currency amount according to preference
  4018. if ($amount) {
  4019.  
  4020. if ($settings['curr_symbol_position'] == 1 || !$settings['curr_symbol_position'])
  4021. return $symbol . number_format_i18n($amount, $decimal_place);
  4022. else if ($settings['curr_symbol_position'] == 2)
  4023. return $symbol . ' ' . number_format_i18n($amount, $decimal_place);
  4024. else if ($settings['curr_symbol_position'] == 3)
  4025. return number_format_i18n($amount, $decimal_place) . $symbol;
  4026. else if ($settings['curr_symbol_position'] == 4)
  4027. return number_format_i18n($amount, $decimal_place) . ' ' . $symbol;
  4028.  
  4029. } else if ($amount === false) {
  4030. return $symbol;
  4031. } else {
  4032. if ($settings['curr_symbol_position'] == 1 || !$settings['curr_symbol_position'])
  4033. return $symbol . $zero;
  4034. else if ($settings['curr_symbol_position'] == 2)
  4035. return $symbol . ' ' . $zero;
  4036. else if ($settings['curr_symbol_position'] == 3)
  4037. return $zero . $symbol;
  4038. else if ($settings['curr_symbol_position'] == 4)
  4039. return $zero . ' ' . $symbol;
  4040. }
  4041. }
  4042.  
  4043. //replaces wp_trim_excerpt in our custom loops
  4044. function product_excerpt($excerpt, $content, $product_id) {
  4045. $excerpt_more = ' <a class="mp_product_more_link" href="' . get_permalink($product_id) . '">' . __('More Info &raquo;', 'mp') . '</a>';
  4046. if ($excerpt) {
  4047. return $excerpt . $excerpt_more;
  4048. } else {
  4049. $text = strip_shortcodes( $content );
  4050. //$text = apply_filters('the_content', $text);
  4051. $text = str_replace(']]>', ']]&gt;', $text);
  4052. $text = strip_tags($text);
  4053. $excerpt_length = apply_filters('excerpt_length', 55);
  4054. $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
  4055. if ( count($words) > $excerpt_length ) {
  4056. array_pop($words);
  4057. $text = implode(' ', $words);
  4058. $text = $text . $excerpt_more;
  4059. } else {
  4060. $text = implode(' ', $words);
  4061. }
  4062. }
  4063. return $text;
  4064. }
  4065.  
  4066. //returns the js needed to record ecommerce transactions. $project should be an array of id, title
  4067. function create_ga_ecommerce($order) {
  4068. $settings = get_option('mp_settings');
  4069.  
  4070. if (!is_object($order))
  4071. return false;
  4072.  
  4073. if ($settings['ga_ecommerce'] == 'old') {
  4074.  
  4075. $js = '<script type="text/javascript">
  4076. try{
  4077. pageTracker._addTrans(
  4078. "'.esc_js($order->post_title).'", // order ID - required
  4079. "'.esc_js(get_bloginfo('blogname')).'", // affiliation or store name
  4080. "'.$order->mp_order_total.'", // total - required
  4081. "'.$order->mp_tax_total.'", // tax
  4082. "'.$order->mp_shipping_total.'", // shipping
  4083. "'.esc_js($order->mp_shipping_info['city']).'", // city
  4084. "'.esc_js($order->mp_shipping_info['state']).'", // state or province
  4085. "'.esc_js($order->mp_shipping_info['country']).'" // country
  4086. );';
  4087.  
  4088. if (is_array($order->mp_cart_info) && count($order->mp_cart_info)) {
  4089. foreach ($order->mp_cart_info as $product_id => $variations) {
  4090. foreach ($variations as $variation => $data) {
  4091. $sku = !empty($data['SKU']) ? esc_js($data['SKU']) : $product_id;
  4092. $js .= 'pageTracker._addItem(
  4093. "'.esc_js($order->post_title).'", // order ID - necessary to associate item with transaction
  4094. "'.$sku.'", // SKU/code - required
  4095. "'.esc_js($data['name']).'", // product name
  4096. "'.$data['price'].'", // unit price - required
  4097. "'.$data['quantity'].'" // quantity - required
  4098. );';
  4099. }
  4100. }
  4101. }
  4102. $js .= 'pageTracker._trackTrans(); //submits transaction to the Analytics servers
  4103. } catch(err) {}
  4104. </script>
  4105. ';
  4106.  
  4107. } else if ($settings['ga_ecommerce'] == 'new') {
  4108.  
  4109. $js = '<script type="text/javascript">
  4110. _gaq.push(["_addTrans",
  4111. "'.esc_attr($order->post_title).'", // order ID - required
  4112. "'.esc_attr(get_bloginfo('blogname')).'", // affiliation or store name
  4113. "'.$order->mp_order_total.'", // total - required
  4114. "'.$order->mp_tax_total.'", // tax
  4115. "'.$order->mp_shipping_total.'", // shipping
  4116. "'.esc_attr($order->mp_shipping_info['city']).'", // city
  4117. "'.esc_attr($order->mp_shipping_info['state']).'", // state or province
  4118. "'.esc_attr($order->mp_shipping_info['country']).'" // country
  4119. ]);';
  4120.  
  4121. if (is_array($order->mp_cart_info) && count($order->mp_cart_info)) {
  4122. foreach ($order->mp_cart_info as $product_id => $variations) {
  4123. foreach ($variations as $variation => $data) {
  4124. $sku = !empty($data['SKU']) ? esc_attr($data['SKU']) : $product_id;
  4125. $js .= '_gaq.push(["_addItem",
  4126. "'.esc_attr($order->post_title).'", // order ID - necessary to associate item with transaction
  4127. "'.$sku.'", // SKU/code - required
  4128. "'.esc_attr($data['name']).'", // product name
  4129. "", // category
  4130. "'.$data['price'].'", // unit price - required
  4131. "'.$data['quantity'].'" // quantity - required
  4132. ]);';
  4133. }
  4134. }
  4135. }
  4136. $js .= '_gaq.push(["_trackTrans"]);
  4137. </script>
  4138. ';
  4139.  
  4140. }
  4141.  
  4142. //add to footer
  4143. if ( !empty($js) ) {
  4144. $function = "echo '$js';";
  4145. add_action( 'wp_footer', create_function('', $function), 99999 );
  4146. }
  4147. }
  4148.  
  4149. //displays the detail page of an order
  4150. function single_order_page() {
  4151. $order = $this->get_order((int)$_GET['order_id']);
  4152.  
  4153. if ( !$order )
  4154. wp_die(__('Invalid Order ID', 'mp'));
  4155.  
  4156. $settings = get_option('mp_settings');
  4157. $max_downloads = intval($settings['max_downloads']) ? intval($settings['max_downloads']) : 5;
  4158.  
  4159. //save tracking number
  4160. if (isset($_POST['mp_tracking_number'])) {
  4161. $order->mp_shipping_info['tracking_num'] = stripslashes(trim($_POST['mp_tracking_number']));
  4162. $order->mp_shipping_info['method'] = stripslashes(trim($_POST['mp_shipping_method']));
  4163. update_post_meta($order->ID, 'mp_shipping_info', $order->mp_shipping_info);
  4164.  
  4165. if (isset($_POST['add-tracking-shipped'])) {
  4166. $this->update_order_status($order->ID, 'shipped');
  4167. $order->post_status = 'order_shipped';
  4168. ?><div class="updated fade"><p><?php _e('This order has been marked as Shipped.', 'mp'); ?></p></div><?php
  4169. }
  4170.  
  4171. if (!current_user_can('unfiltered_html'))
  4172. $_POST['mp_order_notes'] = wp_filter_post_kses(trim(stripslashes($_POST['mp_order_notes'])));
  4173.  
  4174. $order->mp_order_notes = stripslashes($_POST['mp_order_notes']);
  4175. update_post_meta($order->ID, 'mp_order_notes', $_POST['mp_order_notes']);
  4176. ?><div class="updated fade"><p><?php _e('Order details have been saved!', 'mp'); ?></p></div><?php
  4177. }
  4178. ?>
  4179. <div class="wrap">
  4180. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/shopping-cart.png'; ?>" /></div>
  4181. <h2><?php echo sprintf(__('Order Details (%s)', 'mp'), esc_attr($order->post_title)); ?></h2>
  4182.  
  4183. <div id="poststuff" class="metabox-holder mp-settings has-right-sidebar">
  4184.  
  4185. <div id="side-info-column" class="inner-sidebar">
  4186. <div id='side-sortables' class='meta-box-sortables'>
  4187.  
  4188. <div id="submitdiv" class="postbox mp-order-actions">
  4189. <h3 class='hndle'><span><?php _e('Order Actions', 'mp'); ?></span></h3>
  4190. <div class="inside">
  4191. <div id="submitpost" class="submitbox">
  4192. <div class="misc-pub-section"><strong><?php _e('Change Order Status:', 'mp'); ?></strong></div>
  4193. <?php
  4194. $actions = array();
  4195. if ($order->post_status == 'order_received') {
  4196. $actions['received current'] = __('Received', 'mp');
  4197. $actions['paid'] = "<a title='" . esc_attr(__('Mark as Paid', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=paid&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Paid', 'mp') . "</a>";
  4198. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  4199. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  4200. } else if ($order->post_status == 'order_paid') {
  4201. $actions['received'] = __('Received', 'mp');
  4202. $actions['paid current'] = __('Paid', 'mp');
  4203. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  4204. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  4205. } else if ($order->post_status == 'order_shipped') {
  4206. $actions['received'] = __('Received', 'mp');
  4207. $actions['paid'] = __('Paid', 'mp');
  4208. $actions['shipped current'] = __('Shipped', 'mp');
  4209. $actions['closed'] = "<a title='" . esc_attr(__('Mark as Closed', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=closed&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Closed', 'mp') . "</a>";
  4210. } else if ($order->post_status == 'order_closed') {
  4211. $actions['received'] = "<a title='" . esc_attr(__('Mark as Received', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=received&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Received', 'mp') . "</a>";
  4212. $actions['paid'] = "<a title='" . esc_attr(__('Mark as Paid', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=paid&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Paid', 'mp') . "</a>";
  4213. $actions['shipped'] = "<a title='" . esc_attr(__('Mark as Shipped', 'mp')) . "' href='" . wp_nonce_url( admin_url( 'edit.php?post_type=product&amp;page=marketpress-orders&amp;action=shipped&amp;post=' . $order->ID), 'update-order-status' ) . "'>" . __('Shipped', 'mp') . "</a>";
  4214. $actions['closed current'] = __('Closed', 'mp');
  4215. }
  4216.  
  4217. $action_count = count($actions);
  4218. $i = 0;
  4219. echo '<div id="mp-single-statuses" class="misc-pub-section">';
  4220. foreach ( $actions as $action => $link ) {
  4221. ++$i;
  4222. ( $i == $action_count ) ? $sep = '' : $sep = ' &raquo; ';
  4223. echo "<span class='$action'>$link</span>$sep";
  4224. }
  4225. echo '</div>';
  4226. ?>
  4227.  
  4228. <div id="major-publishing-actions">
  4229. <form id="mp-single-order-form" action="<?php echo admin_url('edit.php'); ?>" method="get">
  4230. <div id="mp-single-order-buttons">
  4231. <input type="hidden" name="post_type" class="post_status_page" value="product" />
  4232. <input type="hidden" name="page" class="post_status_page" value="marketpress-orders" />
  4233. <input name="save" class="button-primary" id="publish" tabindex="1" value="<?php _e('&laquo; Back', 'mp'); ?>" type="submit" />
  4234. </div>
  4235. </form>
  4236. <div class="clear"></div>
  4237. </div>
  4238. </div>
  4239. </div>
  4240. </div>
  4241.  
  4242. <div id="mp-order-status" class="postbox">
  4243. <h3 class='hndle'><span><?php _e('Current Status', 'mp'); ?></span></h3>
  4244. <div class="inside">
  4245. <?php
  4246. //get times
  4247. $received = date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $order->mp_received_time);
  4248. if ($order->mp_paid_time)
  4249. $paid = date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $order->mp_paid_time);
  4250. if ($order->mp_shipped_time)
  4251. $shipped = date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $order->mp_shipped_time);
  4252. if ($order->mp_closed_time)
  4253. $closed = date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $order->mp_closed_time);
  4254.  
  4255. if ($order->post_status == 'order_received') {
  4256. echo '<div id="major-publishing-actions" class="misc-pub-section">' . __('Received:', 'mp') . ' <strong>' . $received . '</strong></div>';
  4257. } else if ($order->post_status == 'order_paid') {
  4258. echo '<div id="major-publishing-actions" class="misc-pub-section">' . __('Paid:', 'mp') . ' <strong>' . $paid . '</strong></div>';
  4259. echo '<div class="misc-pub-section">' . __('Received:', 'mp') . ' <strong>' . $received . '</strong></div>';
  4260. } else if ($order->post_status == 'order_shipped') {
  4261. echo '<div id="major-publishing-actions" class="misc-pub-section">' . __('Shipped:', 'mp') . ' <strong>' . $shipped . '</strong></div>';
  4262. echo '<div class="misc-pub-section">' . __('Paid:', 'mp') . ' <strong>' . $paid . '</strong></div>';
  4263. echo '<div class="misc-pub-section">' . __('Received:', 'mp') . ' <strong>' . $received . '</strong></div>';
  4264. } else if ($order->post_status == 'order_closed') {
  4265. echo '<div id="major-publishing-actions" class="misc-pub-section">' . __('Closed:', 'mp') . ' <strong>' . $closed . '</strong></div>';
  4266. echo '<div class="misc-pub-section">' . __('Shipped:', 'mp') . ' <strong>' . $shipped . '</strong></div>';
  4267. echo '<div class="misc-pub-section">' . __('Paid:', 'mp') . ' <strong>' . $paid . '</strong></div>';
  4268. echo '<div class="misc-pub-section">' . __('Received:', 'mp') . ' <strong>' . $received . '</strong></div>';
  4269. }
  4270. ?>
  4271. </div>
  4272. </div>
  4273.  
  4274. <div id="mp-order-payment" class="postbox">
  4275. <h3 class='hndle'><span><?php _e('Payment Information', 'mp'); ?></span></h3>
  4276. <div class="inside">
  4277. <div id="mp_payment_gateway" class="misc-pub-section">
  4278. <?php _e('Payment Gateway:', 'mp'); ?>
  4279. <strong><?php echo $order->mp_payment_info['gateway_private_name']; ?></strong>
  4280. </div>
  4281. <?php if ($order->mp_payment_info['method']) { ?>
  4282. <div id="mp_payment_method" class="misc-pub-section">
  4283. <?php _e('Payment Type:', 'mp'); ?>
  4284. <strong><?php echo $order->mp_payment_info['method']; ?></strong>
  4285. </div>
  4286. <?php } ?>
  4287. <?php if ($order->mp_payment_info['transaction_id']) { ?>
  4288. <div id="mp_transaction" class="misc-pub-section">
  4289. <?php _e('Transaction ID:', 'mp'); ?>
  4290. <strong><?php echo $order->mp_payment_info['transaction_id']; ?></strong>
  4291. </div>
  4292. <?php } ?>
  4293. <div id="major-publishing-actions" class="misc-pub-section">
  4294. <?php _e('Payment Total:', 'mp'); ?>
  4295. <strong><?php echo $this->format_currency($order->mp_payment_info['currency'], $order->mp_payment_info['total']) . ' ' . $order->mp_payment_info['currency']; ?></strong>
  4296. </div>
  4297. </div>
  4298. </div>
  4299.  
  4300. <?php if (is_array($order->mp_payment_info['status']) && count($order->mp_payment_info['status'])) { ?>
  4301. <div id="mp-order-payment-history" class="postbox">
  4302. <h3 class='hndle'><span><?php _e('Payment Transaction History', 'mp'); ?></span></h3>
  4303. <div class="inside">
  4304. <?php
  4305. $statuses = $order->mp_payment_info['status'];
  4306. krsort($statuses); //sort with latest status at the top
  4307. $first = true;
  4308. foreach ($statuses as $timestamp => $status) {
  4309. if ($first) {
  4310. echo '<div id="major-publishing-actions" class="misc-pub-section">';
  4311. $first = false;
  4312. } else {
  4313. echo '<div id="mp_payment_gateway" class="misc-pub-section">';
  4314. }
  4315. ?>
  4316. <strong><?php echo date_i18n(get_option('date_format') . ' - ' . get_option('time_format'), $timestamp); ?>:</strong>
  4317. <?php echo esc_html($status); ?>
  4318. </div>
  4319. <?php } ?>
  4320.  
  4321. </div>
  4322. </div>
  4323. <?php } ?>
  4324.  
  4325. </div></div>
  4326.  
  4327. <div id="post-body">
  4328. <div id="post-body-content">
  4329.  
  4330. <div id='normal-sortables' class='meta-box-sortables'>
  4331.  
  4332. <div id="mp-order-products" class="postbox">
  4333. <h3 class='hndle'><span><?php _e('Order Information', 'mp'); ?></span></h3>
  4334. <div class="inside">
  4335.  
  4336. <table id="mp-order-product-table" class="widefat">
  4337. <thead><tr>
  4338. <th class="mp_cart_col_thumb">&nbsp;</th>
  4339. <th class="mp_cart_col_sku"><?php _e('SKU', 'mp'); ?></th>
  4340. <th class="mp_cart_col_product"><?php _e('Item', 'mp'); ?></th>
  4341. <th class="mp_cart_col_quant"><?php _e('Quantity', 'mp'); ?></th>
  4342. <th class="mp_cart_col_price"><?php _e('Price', 'mp'); ?></th>
  4343. <th class="mp_cart_col_subtotal"><?php _e('Subtotal', 'mp'); ?></th>
  4344. <th class="mp_cart_col_downloads"><?php _e('Downloads', 'mp'); ?></th>
  4345. </tr></thead>
  4346. <tbody>
  4347. <?php
  4348. if (is_array($order->mp_cart_info) && count($order->mp_cart_info)) {
  4349. foreach ($order->mp_cart_info as $product_id => $variations) {
  4350. //for compatibility for old orders from MP 1.0
  4351. if (isset($variations['name'])) {
  4352. $data = $variations;
  4353. echo '<tr>';
  4354. echo ' <td class="mp_cart_col_thumb">' . mp_product_image( false, 'widget', $product_id ) . '</td>';
  4355. echo ' <td class="mp_cart_col_sku">' . esc_attr($data['SKU']) . '</td>';
  4356. echo ' <td class="mp_cart_col_product"><a href="' . get_permalink($product_id) . '">' . esc_attr($data['name']) . '</a></td>';
  4357. echo ' <td class="mp_cart_col_quant">' . number_format_i18n($data['quantity']) . '</td>';
  4358. echo ' <td class="mp_cart_col_price">' . $this->format_currency('', $data['price']) . '</td>';
  4359. echo ' <td class="mp_cart_col_subtotal">' . $this->format_currency('', $data['price'] * $data['quantity']) . '</td>';
  4360. echo ' <td class="mp_cart_col_downloads">' . __('N/A', 'mp') . '</td>';
  4361. echo '</tr>';
  4362. } else {
  4363. foreach ($variations as $variation => $data) {
  4364. echo '<tr>';
  4365. echo ' <td class="mp_cart_col_thumb">' . mp_product_image( false, 'widget', $product_id ) . '</td>';
  4366. echo ' <td class="mp_cart_col_sku">' . esc_attr($data['SKU']) . '</td>';
  4367. echo ' <td class="mp_cart_col_product"><a href="' . get_permalink($product_id) . '">' . esc_attr($data['name']) . '</a></td>';
  4368. echo ' <td class="mp_cart_col_quant">' . number_format_i18n($data['quantity']) . '</td>';
  4369. echo ' <td class="mp_cart_col_price">' . $this->format_currency('', $data['price']) . '</td>';
  4370. echo ' <td class="mp_cart_col_subtotal">' . $this->format_currency('', $data['price'] * $data['quantity']) . '</td>';
  4371. if (is_array($data['download']))
  4372. echo ' <td class="mp_cart_col_downloads">' . number_format_i18n($data['download']['downloaded']) . (($data['download']['downloaded'] >= $max_downloads) ? __(' (Limit Reached)', 'mp') : '') . '</td>';
  4373. else
  4374. echo ' <td class="mp_cart_col_downloads">' . __('N/A', 'mp') . '</td>';
  4375. echo '</tr>';
  4376. }
  4377. }
  4378. }
  4379. } else {
  4380. echo '<tr><td colspan="7">' . __('No products could be found for this order', 'mp') . '</td></tr>';
  4381. }
  4382. ?>
  4383. </tbody>
  4384. </table><br />
  4385.  
  4386. <?php //coupon line
  4387. if ( $order->mp_discount_info ) { ?>
  4388. <h3><?php _e('Coupon Discount:', 'mp'); ?></h3>
  4389. <p><?php echo $order->mp_discount_info['discount']; ?> (<?php echo $order->mp_discount_info['code']; ?>)</p>
  4390. <?php } ?>
  4391.  
  4392. <?php //shipping line
  4393. if ( $order->mp_shipping_total ) { ?>
  4394. <h3><?php _e('Shipping:', 'mp'); ?></h3>
  4395. <p><?php echo $this->format_currency('', $order->mp_shipping_total); ?></p>
  4396. <?php } ?>
  4397.  
  4398. <?php //tax line
  4399. if ( $order->mp_tax_total ) { ?>
  4400. <h3><?php _e('Taxes:', 'mp'); ?></h3>
  4401. <p><?php echo $this->format_currency('', $order->mp_tax_total); ?></p>
  4402. <?php } ?>
  4403.  
  4404. <h3><?php _e('Cart Total:', 'mp'); ?></h3>
  4405. <p><?php echo $this->format_currency('', $order->mp_order_total); ?></p>
  4406.  
  4407. <?php //special instructions line
  4408. if ( !empty($order->mp_shipping_info['special_instructions']) ) { ?>
  4409. <h3><?php _e('Special Instructions:', 'mp'); ?></h3>
  4410. <p><?php echo wpautop(esc_html($order->mp_shipping_info['special_instructions'])); ?></p>
  4411. <?php } ?>
  4412.  
  4413. </div>
  4414. </div>
  4415.  
  4416. <form id="mp-shipping-form" action="" method="post">
  4417. <div id="mp-order-shipping-info" class="postbox">
  4418. <h3 class='hndle'><span><?php _e('Shipping Information', 'mp'); ?></span></h3>
  4419. <div class="inside">
  4420. <h3><?php _e('Address:', 'mp'); ?></h3>
  4421. <table>
  4422. <tr>
  4423. <td align="right"><?php _e('Full Name:', 'mp'); ?></td><td>
  4424. <?php esc_attr_e($order->mp_shipping_info['name']); ?></td>
  4425. </tr>
  4426.  
  4427. <tr>
  4428. <td align="right"><?php _e('Email:', 'mp'); ?></td><td>
  4429. <?php esc_attr_e($order->mp_shipping_info['email']); ?></td>
  4430. </tr>
  4431.  
  4432. <tr>
  4433. <td align="right"><?php _e('Address:', 'mp'); ?></td>
  4434. <td><?php esc_attr_e($order->mp_shipping_info['address1']); ?></td>
  4435. </tr>
  4436.  
  4437. <?php if ($order->mp_shipping_info['address2']) { ?>
  4438. <tr>
  4439. <td align="right"><?php _e('Address 2:', 'mp'); ?></td>
  4440. <td><?php esc_attr_e($order->mp_shipping_info['address2']); ?></td>
  4441. </tr>
  4442. <?php } ?>
  4443.  
  4444. <tr>
  4445. <td align="right"><?php _e('City:', 'mp'); ?></td>
  4446. <td><?php esc_attr_e($order->mp_shipping_info['city']); ?></td>
  4447. </tr>
  4448.  
  4449. <?php if ($order->mp_shipping_info['state']) { ?>
  4450. <tr>
  4451. <td align="right"><?php _e('State/Province/Region:', 'mp'); ?></td>
  4452. <td><?php esc_attr_e($order->mp_shipping_info['state']); ?></td>
  4453. </tr>
  4454. <?php } ?>
  4455.  
  4456. <tr>
  4457. <td align="right"><?php _e('Postal/Zip Code:', 'mp'); ?></td>
  4458. <td><?php esc_attr_e($order->mp_shipping_info['zip']); ?></td>
  4459. </tr>
  4460.  
  4461. <tr>
  4462. <td align="right"><?php _e('Country:', 'mp'); ?></td>
  4463. <td><?php echo $this->countries[$order->mp_shipping_info['country']]; ?></td>
  4464. </tr>
  4465.  
  4466. <?php if ($order->mp_shipping_info['phone']) { ?>
  4467. <tr>
  4468. <td align="right"><?php _e('Phone Number:', 'mp'); ?></td>
  4469. <td><?php esc_attr_e($order->mp_shipping_info['phone']); ?></td>
  4470. </tr>
  4471. <?php } ?>
  4472. </table>
  4473.  
  4474. <h3><?php _e('Cost:', 'mp'); ?></h3>
  4475. <p><?php echo $this->format_currency('', $order->mp_shipping_total); ?></p>
  4476.  
  4477. <h3><?php _e('Shipping Method & Tracking Number:', 'mp'); ?></h3>
  4478. <p>
  4479. <select name="mp_shipping_method">
  4480. <option value="other"><?php _e('Choose Method:', 'mp'); ?></option>
  4481. <option value="UPS"<?php selected($order->mp_shipping_info['method'], 'UPS'); ?>>UPS</option>
  4482. <option value="FedEx"<?php selected($order->mp_shipping_info['method'], 'FedEx'); ?>>FedEx</option>
  4483. <option value="USPS"<?php selected($order->mp_shipping_info['method'], 'USPS'); ?>>USPS</option>
  4484. <option value="DHL"<?php selected($order->mp_shipping_info['method'], 'DHL'); ?>>DHL</option>
  4485. <option value="other"<?php selected($order->mp_shipping_info['method'], 'other'); ?>><?php _e('Other', 'mp'); ?></option>
  4486. </select>
  4487. <input type="text" name="mp_tracking_number" value="<?php esc_attr_e($order->mp_shipping_info['tracking_num']); ?>" size="25" />
  4488. <input type="submit" name="add-tracking" value="<?php _e('Save &raquo;', 'mp'); ?>" /><?php if ($order->post_status == 'order_received' ||$order->post_status == 'order_paid') { ?><input type="submit" name="add-tracking-shipped" value="<?php _e('Save & Mark as Shipped &raquo;', 'mp'); ?>" /><?php } ?>
  4489. </p>
  4490.  
  4491. <?php //note line if set by gateway
  4492. if ( $order->mp_payment_info['note'] ) { ?>
  4493. <h3><?php _e('Special Note:', 'mp'); ?></h3>
  4494. <p><?php esc_html_e($order->mp_payment_info['note']); ?></p>
  4495. <?php } ?>
  4496.  
  4497. <?php do_action('mp_single_order_display_shipping', $order); ?>
  4498.  
  4499. </div>
  4500. </div>
  4501.  
  4502. <div id="mp-order-notes" class="postbox">
  4503. <h3 class='hndle'><span><?php _e('Order Notes', 'mp'); ?></span> - <span class="description"><?php _e('These notes will be displayed on the order status page', 'mp'); ?></span></h3>
  4504. <div class="inside">
  4505. <p>
  4506. <textarea name="mp_order_notes" rows="5" style="width: 100%;"><?php echo esc_textarea($order->mp_order_notes); ?></textarea><br />
  4507. <input type="submit" name="save-note" value="<?php _e('Save &raquo;', 'mp'); ?>" />
  4508. </p>
  4509. </div>
  4510. </div>
  4511. </form>
  4512.  
  4513. <?php do_action('mp_single_order_display_box', $order); ?>
  4514.  
  4515. </div>
  4516.  
  4517. <div id='advanced-sortables' class='meta-box-sortables'>
  4518. </div>
  4519.  
  4520. </div>
  4521. </div>
  4522. <br class="clear" />
  4523. </div><!-- /poststuff -->
  4524.  
  4525. </div><!-- /wrap -->
  4526. <?php
  4527. }
  4528.  
  4529. function orders_page() {
  4530.  
  4531. //load single order view if id is set
  4532. if (isset($_GET['order_id'])) {
  4533. $this->single_order_page();
  4534. return;
  4535. }
  4536.  
  4537. //force post type
  4538. global $wpdb, $post_type, $wp_query, $wp_locale, $current_screen;
  4539. $post_type = 'mp_order';
  4540. $_GET['post_type'] = $post_type;
  4541.  
  4542. $post_type_object = get_post_type_object($post_type);
  4543.  
  4544. if ( !current_user_can($post_type_object->cap->edit_posts) )
  4545. wp_die(__('Cheatin&#8217; uh?'));
  4546.  
  4547. $pagenum = isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 0;
  4548. if ( empty($pagenum) )
  4549. $pagenum = 1;
  4550. $per_page = 'edit_' . $post_type . '_per_page';
  4551. $per_page = (int) get_user_option( $per_page );
  4552. if ( empty( $per_page ) || $per_page < 1 )
  4553. $per_page = 15;
  4554. // @todo filter based on type
  4555. $per_page = apply_filters( 'edit_posts_per_page', $per_page );
  4556.  
  4557. // Handle bulk actions
  4558. if ( isset($_GET['doaction']) || isset($_GET['doaction2']) || isset($_GET['bulk_edit']) || isset($_GET['action']) ) {
  4559. check_admin_referer('update-order-status');
  4560. $sendback = remove_query_arg( array('received', 'paid', 'shipped', 'closed', 'ids'), wp_get_referer() );
  4561.  
  4562. if ( ( $_GET['action'] != -1 || $_GET['action2'] != -1 ) && ( isset($_GET['post']) || isset($_GET['ids']) ) ) {
  4563. $post_ids = isset($_GET['post']) ? array_map( 'intval', (array) $_GET['post'] ) : explode(',', $_GET['ids']);
  4564. $doaction = ($_GET['action'] != -1) ? $_GET['action'] : $_GET['action2'];
  4565. }
  4566.  
  4567. switch ( $doaction ) {
  4568. case 'received':
  4569. $received = 0;
  4570. foreach( (array) $post_ids as $post_id ) {
  4571. $this->update_order_status($post_id, 'received');
  4572. $received++;
  4573. }
  4574. $msg = sprintf( _n( '%s order marked as Received.', '%s orders marked as Received.', $received, 'mp' ), number_format_i18n( $received ) );
  4575. break;
  4576. case 'paid':
  4577. $paid = 0;
  4578. foreach( (array) $post_ids as $post_id ) {
  4579. $this->update_order_status($post_id, 'paid');
  4580. $paid++;
  4581. }
  4582. $msg = sprintf( _n( '%s order marked as Paid.', '%s orders marked as Paid.', $paid, 'mp' ), number_format_i18n( $paid ) );
  4583. break;
  4584. case 'shipped':
  4585. $shipped = 0;
  4586. foreach( (array) $post_ids as $post_id ) {
  4587. $this->update_order_status($post_id, 'shipped');
  4588. $shipped++;
  4589. }
  4590. $msg = sprintf( _n( '%s order marked as Shipped.', '%s orders marked as Shipped.', $shipped, 'mp' ), number_format_i18n( $shipped ) );
  4591. break;
  4592. case 'closed':
  4593. $closed = 0;
  4594. foreach( (array) $post_ids as $post_id ) {
  4595. $this->update_order_status($post_id, 'closed');
  4596. $closed++;
  4597. }
  4598. $msg = sprintf( _n( '%s order Closed.', '%s orders Closed.', $closed, 'mp' ), number_format_i18n( $closed ) );
  4599. break;
  4600.  
  4601. }
  4602.  
  4603. }
  4604.  
  4605. $avail_post_stati = wp_edit_posts_query();
  4606.  
  4607. $num_pages = $wp_query->max_num_pages;
  4608.  
  4609. $mode = 'list';
  4610. ?>
  4611.  
  4612. <div class="wrap">
  4613. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/shopping-cart.png'; ?>" /></div>
  4614. <h2><?php _e('Manage Orders', 'mp');
  4615. if ( isset($_GET['s']) && $_GET['s'] )
  4616. printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', get_search_query() ); ?>
  4617. </h2>
  4618.  
  4619. <?php if ( isset($msg) ) { ?>
  4620. <div class="updated fade"><p>
  4621. <?php echo $msg; ?>
  4622. </p></div>
  4623. <?php } ?>
  4624.  
  4625. <form id="posts-filter" action="<?php echo admin_url('edit.php'); ?>" method="get">
  4626.  
  4627. <ul class="subsubsub">
  4628. <?php
  4629. if ( empty($locked_post_status) ) :
  4630. $status_links = array();
  4631. $num_posts = wp_count_posts( $post_type, 'readable' );
  4632. $class = '';
  4633. $allposts = '';
  4634.  
  4635. $total_posts = array_sum( (array) $num_posts );
  4636.  
  4637. // Subtract post types that are not included in the admin all list.
  4638. foreach ( get_post_stati( array('show_in_admin_all_list' => false) ) as $state )
  4639. $total_posts -= $num_posts->$state;
  4640.  
  4641. $class = empty($class) && empty($_GET['post_status']) ? ' class="current"' : '';
  4642. $status_links[] = "<li><a href='edit.php?page=marketpress-orders&post_type=product{$allposts}'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts' ), number_format_i18n( $total_posts ) ) . '</a>';
  4643.  
  4644. foreach ( get_post_stati(array('post_type' => 'mp_order'), 'objects') as $status ) {
  4645. $class = '';
  4646.  
  4647. $status_name = $status->name;
  4648.  
  4649. if ( !in_array( $status_name, $avail_post_stati ) )
  4650. continue;
  4651.  
  4652. if ( empty( $num_posts->$status_name ) )
  4653. continue;
  4654.  
  4655. if ( isset($_GET['post_status']) && $status_name == $_GET['post_status'] )
  4656. $class = ' class="current"';
  4657.  
  4658. $status_links[] = "<li><a href='edit.php?page=marketpress-orders&amp;post_status=$status_name&amp;post_type=product'$class>" . sprintf( _n( $status->label_count[0], $status->label_count[1], $num_posts->$status_name ), number_format_i18n( $num_posts->$status_name ) ) . '</a>';
  4659. }
  4660. echo implode( " |</li>\n", $status_links ) . '</li>';
  4661. unset( $status_links );
  4662. endif;
  4663. ?>
  4664. </ul>
  4665.  
  4666. <p class="search-box">
  4667. <label class="screen-reader-text" for="post-search-input"><?php _e('Search Orders', 'mp'); ?>:</label>
  4668. <input type="text" id="post-search-input" name="s" value="<?php the_search_query(); ?>" />
  4669. <input type="submit" value="<?php _e('Search Orders', 'mp'); ?>" class="button" />
  4670. </p>
  4671.  
  4672. <input type="hidden" name="post_type" class="post_status_page" value="product" />
  4673. <input type="hidden" name="page" class="post_status_page" value="marketpress-orders" />
  4674. <?php if (!empty($_GET['post_status'])) { ?>
  4675. <input type="hidden" name="post_status" class="post_status_page" value="<?php echo esc_attr($_GET['post_status']); ?>" />
  4676. <?php } ?>
  4677.  
  4678. <?php if ( have_posts() ) { ?>
  4679.  
  4680. <div class="tablenav">
  4681. <?php
  4682. $page_links = paginate_links( array(
  4683. 'base' => add_query_arg( 'paged', '%#%' ),
  4684. 'format' => '',
  4685. 'prev_text' => __('&laquo;'),
  4686. 'next_text' => __('&raquo;'),
  4687. 'total' => $num_pages,
  4688. 'current' => $pagenum
  4689. ));
  4690.  
  4691. ?>
  4692.  
  4693. <div class="alignleft actions">
  4694. <select name="action">
  4695. <option value="-1" selected="selected"><?php _e('Change Status', 'mp'); ?></option>
  4696. <option value="received"><?php _e('Received', 'mp'); ?></option>
  4697. <option value="paid"><?php _e('Paid', 'mp'); ?></option>
  4698. <option value="shipped"><?php _e('Shipped', 'mp'); ?></option>
  4699. <option value="closed"><?php _e('Closed', 'mp'); ?></option>
  4700. </select>
  4701. <input type="submit" value="<?php esc_attr_e('Apply'); ?>" name="doaction" id="doaction" class="button-secondary action" />
  4702. <?php wp_nonce_field('update-order-status'); ?>
  4703.  
  4704. <?php // view filters
  4705. if ( !is_singular() ) {
  4706. $arc_query = $wpdb->prepare("SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = %s ORDER BY post_date DESC", $post_type);
  4707.  
  4708. $arc_result = $wpdb->get_results( $arc_query );
  4709.  
  4710. $month_count = count($arc_result);
  4711.  
  4712. if ( $month_count && !( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) {
  4713. $m = isset($_GET['m']) ? (int)$_GET['m'] : 0;
  4714. ?>
  4715. <select name='m'>
  4716. <option<?php selected( $m, 0 ); ?> value='0'><?php _e('Show all dates'); ?></option>
  4717. <?php
  4718. foreach ($arc_result as $arc_row) {
  4719. if ( $arc_row->yyear == 0 )
  4720. continue;
  4721. $arc_row->mmonth = zeroise( $arc_row->mmonth, 2 );
  4722.  
  4723. if ( $arc_row->yyear . $arc_row->mmonth == $m )
  4724. $default = ' selected="selected"';
  4725. else
  4726. $default = '';
  4727.  
  4728. echo "<option$default value='" . esc_attr("$arc_row->yyear$arc_row->mmonth") . "'>";
  4729. echo $wp_locale->get_month($arc_row->mmonth) . " $arc_row->yyear";
  4730. echo "</option>\n";
  4731. }
  4732. ?>
  4733. </select>
  4734. <?php } ?>
  4735.  
  4736. <input type="submit" id="post-query-submit" value="<?php esc_attr_e('Filter'); ?>" class="button-secondary" />
  4737. <?php } ?>
  4738. </div>
  4739.  
  4740. <?php if ( $page_links ) { ?>
  4741. <div class="tablenav-pages"><?php
  4742. $count_posts = $post_type_object->hierarchical ? $wp_query->post_count : $wp_query->found_posts;
  4743. $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of %s' ) . '</span>%s',
  4744. number_format_i18n( ( $pagenum - 1 ) * $per_page + 1 ),
  4745. number_format_i18n( min( $pagenum * $per_page, $count_posts ) ),
  4746. number_format_i18n( $count_posts ),
  4747. $page_links
  4748. );
  4749. echo $page_links_text;
  4750. ?></div>
  4751. <?php } ?>
  4752.  
  4753. <div class="clear"></div>
  4754. </div>
  4755.  
  4756. <div class="clear"></div>
  4757.  
  4758. <table class="widefat <?php echo $post_type_object->hierarchical ? 'page' : 'post'; ?> fixed" cellspacing="0">
  4759. <thead>
  4760. <tr>
  4761. <?php print_column_headers( $current_screen ); ?>
  4762. </tr>
  4763. </thead>
  4764.  
  4765. <tfoot>
  4766. <tr>
  4767. <?php print_column_headers($current_screen, false); ?>
  4768. </tr>
  4769. </tfoot>
  4770.  
  4771. <tbody>
  4772. <?php
  4773. if ( function_exists('post_rows') ) {
  4774. post_rows();
  4775. } else {
  4776. $wp_list_table = _get_list_table('WP_Posts_List_Table');
  4777. $wp_list_table->display_rows();
  4778. }
  4779. ?>
  4780. </tbody>
  4781. </table>
  4782.  
  4783. <div class="tablenav">
  4784.  
  4785. <?php
  4786. if ( $page_links )
  4787. echo "<div class='tablenav-pages'>$page_links_text</div>";
  4788. ?>
  4789.  
  4790. <div class="alignleft actions">
  4791. <select name="action2">
  4792. <option value="-1" selected="selected"><?php _e('Change Status', 'mp'); ?></option>
  4793. <option value="received"><?php _e('Received', 'mp'); ?></option>
  4794. <option value="paid"><?php _e('Paid', 'mp'); ?></option>
  4795. <option value="shipped"><?php _e('Shipped', 'mp'); ?></option>
  4796. <option value="closed"><?php _e('Closed', 'mp'); ?></option>
  4797. </select>
  4798. <input type="submit" value="<?php esc_attr_e('Apply'); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
  4799. <br class="clear" />
  4800. </div>
  4801. <br class="clear" />
  4802. </div>
  4803.  
  4804. <?php } else { // have_posts() ?>
  4805. <div class="clear"></div>
  4806. <p><?php _e('No Orders Yet', 'mp'); ?></p>
  4807. <?php } ?>
  4808.  
  4809. </form>
  4810.  
  4811. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/download.png'; ?>" /></div>
  4812. <h2><?php _e('Export Orders', 'mp'); ?></h2>
  4813. <form action="<?php echo admin_url('admin-ajax.php?action=mp-orders-export'); ?>" method="post">
  4814. <?php
  4815. $months = $wpdb->get_results( $wpdb->prepare( "
  4816. SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
  4817. FROM $wpdb->posts
  4818. WHERE post_type = %s
  4819. ORDER BY post_date DESC
  4820. ", 'mp_order' ) );
  4821.  
  4822. $month_count = count( $months );
  4823.  
  4824. if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
  4825. return;
  4826.  
  4827. $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
  4828. ?>
  4829. <select name='m'>
  4830. <option<?php selected( $m, 0 ); ?> value='0'><?php _e( 'Show all dates' ); ?></option>
  4831. <?php
  4832. foreach ( $months as $arc_row ) {
  4833. if ( 0 == $arc_row->year )
  4834. continue;
  4835.  
  4836. $month = zeroise( $arc_row->month, 2 );
  4837. $year = $arc_row->year;
  4838.  
  4839. printf( "<option %s value='%s'>%s</option>\n",
  4840. selected( $m, $year . $month, false ),
  4841. esc_attr( $arc_row->year . $month ),
  4842. $wp_locale->get_month( $month ) . " $year"
  4843. );
  4844. }
  4845.  
  4846. $status = isset( $_GET['post_status'] ) ? $_GET['post_status'] : 'all';
  4847. ?>
  4848. </select>
  4849. <select name="order_status">
  4850. <option<?php selected( $status, 'all' ); ?> value="all" selected="selected"><?php _e('All Statuses', 'mp'); ?></option>
  4851. <option<?php selected( $status, 'order_received' ); ?> value="order_received"><?php _e('Received', 'mp'); ?></option>
  4852. <option<?php selected( $status, 'order_paid' ); ?> value="order_paid"><?php _e('Paid', 'mp'); ?></option>
  4853. <option<?php selected( $status, 'order_shipped' ); ?> value="order_shipped"><?php _e('Shipped', 'mp'); ?></option>
  4854. <option<?php selected( $status, 'order_closed' ); ?> value="order_closed"><?php _e('Closed', 'mp'); ?></option>
  4855. </select>
  4856. <input type="submit" value="<?php _e('Download &raquo;', 'mp'); ?>" name="export_orders" class="button-secondary" />
  4857. </form>
  4858.  
  4859.  
  4860. <br class="clear">
  4861. </div>
  4862. <?php
  4863. }
  4864.  
  4865. function admin_page() {
  4866. global $wpdb;
  4867.  
  4868. //double-check rights
  4869. if(!current_user_can('manage_options')) {
  4870. echo "<p>" . __('Nice Try...', 'mp') . "</p>"; //If accessed properly, this message doesn't appear.
  4871. return;
  4872. }
  4873.  
  4874. $settings = get_option('mp_settings');
  4875. ?>
  4876. <div class="wrap">
  4877. <h3 class="nav-tab-wrapper">
  4878. <?php
  4879. $tab = ( !empty($_GET['tab']) ) ? $_GET['tab'] : 'main';
  4880.  
  4881. if (!$settings['disable_cart']) {
  4882. $tabs = array(
  4883. 'coupons' => __('Coupons', 'mp'),
  4884. 'presentation' => __('Presentation', 'mp'),
  4885. 'messages' => __('Messages', 'mp'),
  4886. 'shipping' => __('Shipping', 'mp'),
  4887. 'gateways' => __('Payments', 'mp'),
  4888. 'shortcodes' => __('Shortcodes', 'mp'),
  4889. 'importers' => __('Importers', 'mp')
  4890. );
  4891. } else {
  4892. $tabs = array( 'presentation' => __('Presentation', 'mp') );
  4893. }
  4894. $tabhtml = array();
  4895.  
  4896. // If someone wants to remove or add a tab
  4897. $tabs = apply_filters( 'marketpress_tabs', $tabs );
  4898.  
  4899. $class = ( 'main' == $tab ) ? ' nav-tab-active' : '';
  4900. $tabhtml[] = ' <a href="' . admin_url( 'edit.php?post_type=product&amp;page=marketpress' ) . '" class="nav-tab'.$class.'">' . __('General', 'mp') . '</a>';
  4901.  
  4902. foreach ( $tabs as $stub => $title ) {
  4903. $class = ( $stub == $tab ) ? ' nav-tab-active' : '';
  4904. $tabhtml[] = ' <a href="' . admin_url( 'edit.php?post_type=product&amp;page=marketpress&amp;tab=' . $stub ) . '" class="nav-tab'.$class.'">'.$title.'</a>';
  4905. }
  4906.  
  4907. echo implode( "\n", $tabhtml );
  4908. ?>
  4909. </h3>
  4910. <div class="clear"></div>
  4911.  
  4912. <?php
  4913. switch( $tab ) {
  4914. //---------------------------------------------------//
  4915. case "main":
  4916.  
  4917. //save settings
  4918. if (isset($_POST['marketplace_settings'])) {
  4919.  
  4920. //allow plugins to verify settings before saving
  4921. if (isset($_POST['mp']['tax']['canada_rate'])) {
  4922. foreach ($_POST['mp']['tax']['canada_rate'] as $key => $rate) {
  4923. $tax_rate = $rate * .01;
  4924. $_POST['mp']['tax']['canada_rate'][$key] = ($tax_rate < 1 && $tax_rate >= 0) ? $tax_rate : 0;
  4925. }
  4926. } else {
  4927. $tax_rate = $_POST['mp']['tax']['rate'] * .01;
  4928. $_POST['mp']['tax']['rate'] = ($tax_rate < 1 && $tax_rate >= 0) ? $tax_rate : 0;
  4929. }
  4930. $settings = array_merge($settings, apply_filters('mp_main_settings_filter', $_POST['mp']));
  4931. update_option('mp_settings', $settings);
  4932.  
  4933. echo '<div class="updated fade"><p>'.__('Settings saved.', 'mp').'</p></div>';
  4934. }
  4935. ?>
  4936. <script type="text/javascript">
  4937. jQuery(document).ready(function($) {
  4938. $("#mp-country-select, #mp-currency-select").change(function() {
  4939. $("#mp-main-form").submit();
  4940. });
  4941. });
  4942. </script>
  4943. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/settings.png'; ?>" /></div>
  4944. <h2><?php _e('General Settings', 'mp'); ?></h2>
  4945. <div id="poststuff" class="metabox-holder mp-settings">
  4946.  
  4947. <form id="mp-main-form" method="post" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=main">
  4948. <input type="hidden" name="marketplace_settings" value="1" />
  4949.  
  4950. <div class="postbox">
  4951. <h3 class='hndle'><span><?php _e('Location Settings', 'mp') ?></span></h3>
  4952. <div class="inside">
  4953. <span class="description"><?php _e('This is the base location that shipping and tax rates will be calculated from.', 'mp') ?></span>
  4954. <table class="form-table">
  4955. <tr>
  4956. <th scope="row"><?php _e('Base Country', 'mp') ?></th>
  4957. <td>
  4958. <select id="mp-country-select" name="mp[base_country]">
  4959. <?php
  4960. foreach ($this->countries as $key => $value) {
  4961. ?><option value="<?php echo $key; ?>"<?php selected($settings['base_country'], $key); ?>><?php echo esc_attr($value); ?></option><?php
  4962. }
  4963. ?>
  4964. </select>
  4965. </td>
  4966. </tr>
  4967.  
  4968. <?php
  4969. switch ($settings['base_country']) {
  4970. case 'US':
  4971. $list = $this->usa_states;
  4972. break;
  4973.  
  4974. case 'CA':
  4975. $list = $this->canadian_provinces;
  4976. break;
  4977.  
  4978. case 'GB':
  4979. $list = $this->uk_counties;
  4980. break;
  4981.  
  4982. case 'AU':
  4983. $list = $this->australian_states;
  4984. break;
  4985.  
  4986. default:
  4987. $list = false;
  4988. }
  4989.  
  4990. //only show if correct country
  4991. if (is_array($list)) {
  4992. ?>
  4993. <tr>
  4994. <th scope="row"><?php _e('Base State/Province/Region', 'mp') ?></th>
  4995. <td>
  4996. <select name="mp[base_province]">
  4997. <?php
  4998. foreach ($list as $key => $value) {
  4999. ?><option value="<?php echo esc_attr($key); ?>"<?php selected($settings['base_province'], $key); ?>><?php echo esc_attr($value); ?></option><?php
  5000. }
  5001. ?>
  5002. </select>
  5003. </td>
  5004. </tr>
  5005. <?php }
  5006. //only show if correct country or US province
  5007. if ( is_array($list) || in_array( $settings['base_country'], array('UM','AS','FM','GU','MH','MP','PW','PR','PI') ) ) {
  5008. ?>
  5009. <tr>
  5010. <th scope="row"><?php _e('Base Zip/Postal Code', 'mp') ?></th>
  5011. <td>
  5012. <input value="<?php echo esc_attr($settings['base_zip']); ?>" size="10" name="mp[base_zip]" type="text" />
  5013. </td>
  5014. </tr>
  5015. <?php } ?>
  5016. </table>
  5017. </div>
  5018. </div>
  5019.  
  5020. <div class="postbox">
  5021. <h3 class='hndle'><span><?php _e('Tax Settings', 'mp') ?></span></h3>
  5022. <div class="inside">
  5023. <table class="form-table">
  5024. <?php
  5025. switch ($settings['base_country']) {
  5026. case 'US':
  5027. ?>
  5028. <tr>
  5029. <th scope="row"><?php echo sprintf(__('%s Tax Rate', 'mp'), esc_attr($this->usa_states[$settings['base_province']])); ?></th>
  5030. <td>
  5031. <input value="<?php echo $settings['tax']['rate'] * 100; ?>" size="3" name="mp[tax][rate]" type="text" style="text-align:right;" />%
  5032. </td>
  5033. </tr>
  5034. <?php
  5035. break;
  5036.  
  5037. case 'CA':
  5038. ?>
  5039. <tr>
  5040. <th scope="row"><a href="http://sbinfocanada.about.com/od/pst/a/PSTecommerce.htm" target="_blank"><?php _e('Total Tax Rates (VAT,GST,PST,HST)', 'mp'); ?></a></th>
  5041. <td>
  5042. <span class="description"><a href="http://en.wikipedia.org/wiki/Sales_taxes_in_Canada" target="_blank"><?php _e('Current Rates &raquo;', 'mp'); ?></a></span>
  5043. <table cellspacing="0" cellpadding="0">
  5044. <?php foreach ($this->canadian_provinces as $key => $label) { ?>
  5045. <tr>
  5046. <td style="padding: 0 5px;"><label for="mp_tax_<?php echo $key; ?>"><?php echo esc_attr($label); ?></label></td>
  5047. <td style="padding: 0 5px;"><input value="<?php echo $settings['tax']['canada_rate'][$key] * 100; ?>" size="3" id="mp_tax_<?php echo $key; ?>" name="mp[tax][canada_rate][<?php echo $key; ?>]" type="text" style="text-align:right;" />%</td>
  5048. </tr>
  5049. <?php } ?>
  5050. </table>
  5051. </td>
  5052. </tr>
  5053. <?php
  5054. break;
  5055.  
  5056. case 'GB':
  5057. ?>
  5058. <tr>
  5059. <th scope="row"><?php _e('VAT Tax Rate', 'mp') ?></th>
  5060. <td>
  5061. <input value="<?php echo $settings['tax']['rate'] * 100; ?>" size="3" name="mp[tax][rate]" type="text" style="text-align:right;" />%
  5062. </td>
  5063. </tr>
  5064. <?php
  5065. break;
  5066.  
  5067. case 'AU':
  5068. ?>
  5069. <tr>
  5070. <th scope="row"><?php _e('GST Tax Rate', 'mp') ?></th>
  5071. <td>
  5072. <input value="<?php echo $settings['tax']['rate'] * 100; ?>" size="3" name="mp[tax][rate]" type="text" style="text-align:right;" />%
  5073. </td>
  5074. </tr>
  5075. <?php
  5076. break;
  5077.  
  5078. default:
  5079. //in european union
  5080. if ( in_array($settings['base_country'], $this->eu_countries) ) {
  5081. ?>
  5082. <tr>
  5083. <th scope="row"><?php _e('VAT Tax Rate', 'mp') ?></th>
  5084. <td>
  5085. <input value="<?php echo $settings['tax']['rate'] * 100; ?>" size="3" name="mp[tax][rate]" type="text" style="text-align:right;" />%
  5086. </td>
  5087. </tr>
  5088. <?php
  5089. } else { //all other countries
  5090. ?>
  5091. <tr>
  5092. <th scope="row"><?php _e('Country Total Tax Rate (VAT, GST, Etc.)', 'mp') ?></th>
  5093. <td>
  5094. <input value="<?php echo $settings['tax']['rate'] * 100; ?>" size="3" name="mp[tax][rate]" type="text" style="text-align:right;" />%
  5095. </td>
  5096. </tr>
  5097. <tr>
  5098. <th scope="row"><?php _e('Tax Orders Outside Your Base Country?', 'mp'); ?></th>
  5099. <td>
  5100. <label><input value="1" name="mp[tax][tax_outside]" type="radio"<?php checked($settings['tax']['tax_outside'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5101. <label><input value="0" name="mp[tax][tax_outside]" type="radio"<?php checked($settings['tax']['tax_outside'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5102. </td>
  5103. </tr>
  5104. <?php
  5105. }
  5106. break;
  5107. }
  5108. ?>
  5109. <tr>
  5110. <th scope="row"><?php _e('Apply Tax To Shipping Fees?', 'mp') ?></th>
  5111. <td>
  5112. <label><input value="1" name="mp[tax][tax_shipping]" type="radio"<?php checked($settings['tax']['tax_shipping'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5113. <label><input value="0" name="mp[tax][tax_shipping]" type="radio"<?php checked($settings['tax']['tax_shipping'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5114. <br /><span class="description"><?php _e('Please see your local tax laws. Most areas charge tax on shipping fees.', 'mp') ?></span>
  5115. </td>
  5116. </tr>
  5117. <tr>
  5118. <th scope="row"><?php _e('Enter Prices Inclusive of Tax?', 'mp') ?></th>
  5119. <td>
  5120. <label><input value="1" name="mp[tax][tax_inclusive]" type="radio"<?php checked($settings['tax']['tax_inclusive'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5121. <label><input value="0" name="mp[tax][tax_inclusive]" type="radio"<?php checked($settings['tax']['tax_inclusive'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5122. <br /><span class="description"><?php _e('Enabling this option allows you to enter and show all prices inclusive of tax, while still listing the tax total as a line item in shopping carts. Please see your local tax laws.', 'mp') ?></span>
  5123. </td>
  5124. </tr>
  5125. </table>
  5126. </div>
  5127. </div>
  5128.  
  5129. <div class="postbox">
  5130. <h3 class='hndle'><span><?php _e('Currency Settings', 'mp') ?></span></h3>
  5131. <div class="inside">
  5132. <span class="description"><?php _e('These preferences affect display only. Your payment gateway of choice may not support every currency listed here.', 'mp') ?></span>
  5133. <table class="form-table">
  5134. <tr valign="top">
  5135. <th scope="row"><?php _e('Store Currency', 'mp') ?></th>
  5136. <td>
  5137. <select id="mp-currency-select" name="mp[currency]">
  5138. <?php
  5139. foreach ($this->currencies as $key => $value) {
  5140. ?><option value="<?php echo $key; ?>"<?php selected($settings['currency'], $key); ?>><?php echo esc_attr($value[0]) . ' - ' . $this->format_currency($key); ?></option><?php
  5141. }
  5142. ?>
  5143. </select>
  5144. </td>
  5145. </tr>
  5146. <tr valign="top">
  5147. <th scope="row"><?php _e('Currency Symbol Position', 'mp') ?></th>
  5148. <td>
  5149. <label><input value="1" name="mp[curr_symbol_position]" type="radio"<?php checked($settings['curr_symbol_position'], 1); ?>>
  5150. <?php echo $this->format_currency($settings['currency']); ?>100</label><br />
  5151. <label><input value="2" name="mp[curr_symbol_position]" type="radio"<?php checked($settings['curr_symbol_position'], 2); ?>>
  5152. <?php echo $this->format_currency($settings['currency']); ?> 100</label><br />
  5153. <label><input value="3" name="mp[curr_symbol_position]" type="radio"<?php checked($settings['curr_symbol_position'], 3); ?>>
  5154. 100<?php echo $this->format_currency($settings['currency']); ?></label><br />
  5155. <label><input value="4" name="mp[curr_symbol_position]" type="radio"<?php checked($settings['curr_symbol_position'], 4); ?>>
  5156. 100 <?php echo $this->format_currency($settings['currency']); ?></label>
  5157. </td>
  5158. </tr>
  5159. <tr valign="top">
  5160. <th scope="row"><?php _e('Show Decimal in Prices', 'mp') ?></th>
  5161. <td>
  5162. <label><input value="1" name="mp[curr_decimal]" type="radio"<?php checked( ( ($settings['curr_decimal'] !== 0) ? 1 : 0 ), 1); ?>>
  5163. <?php _e('Yes', 'mp') ?></label>
  5164. <label><input value="0" name="mp[curr_decimal]" type="radio"<?php checked($settings['curr_decimal'], 0); ?>>
  5165. <?php _e('No', 'mp') ?></label>
  5166. </td>
  5167. </tr>
  5168. </table>
  5169. </div>
  5170. </div>
  5171.  
  5172. <div class="postbox">
  5173. <h3 class='hndle'><span><?php _e('Miscellaneous Settings', 'mp') ?></span></h3>
  5174. <div class="inside">
  5175. <table class="form-table">
  5176. <tr id="mp-inventory-setting">
  5177. <th scope="row"><?php _e('Inventory Warning Threshold', 'mp') ?></th>
  5178. <td>
  5179. <span class="description"><?php _e('At what low stock count do you want to be warned for products you have enabled inventory tracking for?', 'mp') ?></span><br />
  5180. <select name="mp[inventory_threshhold]">
  5181. <?php
  5182. $inventory_threshhold = isset($settings['inventory_threshhold']) ? intval($settings['inventory_threshhold']) : 3;
  5183. for ($i=0; $i<=100; $i++) {
  5184. $selected = ($inventory_threshhold == $i) ? ' selected="selected"' : '';
  5185. echo '<option value="' . $i . '"' . $selected . '">' . $i . '</option>';
  5186. }
  5187. ?>
  5188. </select>
  5189. </td>
  5190. </tr>
  5191. <tr id="mp-downloads-setting">
  5192. <th scope="row"><?php _e('Maximum Downloads', 'mp') ?></th>
  5193. <td>
  5194. <span class="description"><?php _e('How many times may a customer download a file they have purchased? (It\'s best to set this higher than one in case they have any problems downloading)', 'mp') ?></span><br />
  5195. <select name="mp[max_downloads]">
  5196. <?php
  5197. $max_downloads = intval($settings['max_downloads']) ? intval($settings['max_downloads']) : 5;
  5198. for ($i=1; $i<=100; $i++) {
  5199. $selected = ($max_downloads == $i) ? ' selected="selected"' : '';
  5200. echo '<option value="' . $i . '"' . $selected . '">' . $i . '</option>';
  5201. }
  5202. ?>
  5203. </select>
  5204. </td>
  5205. </tr>
  5206. <tr>
  5207. <th scope="row"><?php _e('Force Login', 'mp') ?></th>
  5208. <td>
  5209. <?php $force_login = ($settings['force_login']) ? 1 : 0; ?>
  5210. <label><input value="1" name="mp[force_login]" type="radio"<?php checked($force_login, 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5211. <label><input value="0" name="mp[force_login]" type="radio"<?php checked($force_login, 0) ?> /> <?php _e('No', 'mp') ?></label>
  5212. <br /><span class="description"><?php _e('Whether or not customers must be registered and logged in to checkout. (Not recommended: Enabling this can lower conversions)', 'mp') ?></span>
  5213. </td>
  5214. </tr>
  5215. <tr>
  5216. <th scope="row"><?php _e('Product Listings Only', 'mp') ?></th>
  5217. <td>
  5218. <label><input value="1" name="mp[disable_cart]" type="radio"<?php checked($settings['disable_cart'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5219. <label><input value="0" name="mp[disable_cart]" type="radio"<?php checked($settings['disable_cart'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5220. <br /><span class="description"><?php _e('This option turns MarketPress into more of a product listing plugin, disabling shopping carts, checkout, and order management. This is useful if you simply want to list items you can buy in a store somewhere else, optionally linking the "Buy Now" buttons to an external site. Some examples are a car dealership, or linking to songs/albums in itunes, or linking to products on another site with your own affiliate links.', 'mp') ?></span>
  5221. </td>
  5222. </tr>
  5223. <tr>
  5224. <th scope="row"><?php _e('Google Analytics Ecommerce Tracking', 'mp') ?></th>
  5225. <td>
  5226. <select name="mp[ga_ecommerce]">
  5227. <option value="none"<?php selected($settings['ga_ecommerce'], 'none') ?>><?php _e('None', 'mp') ?></option>
  5228. <option value="new"<?php selected($settings['ga_ecommerce'], 'new') ?>><?php _e('Asynchronous Tracking Code', 'mp') ?></option>
  5229. <option value="old"<?php selected($settings['ga_ecommerce'], 'old') ?>><?php _e('Old Tracking Code', 'mp') ?></option>
  5230. </select>
  5231. <br /><span class="description"><?php _e('If you already use Google Analytics for your website, you can track detailed ecommerce information by enabling this setting. Choose whether you are using the new asynchronous or old tracking code. Before Google Analytics can report ecommerce activity for your website, you must enable ecommerce tracking on the profile settings page for your website. Also keep in mind that some gateways do not reliably show the receipt page, so tracking may not be accurate in those cases. It is recommended to use the PayPal gateway for the most accurate data. <a href="http://analytics.blogspot.com/2009/05/how-to-use-ecommerce-tracking-in-google.html" target="_blank">More information &raquo;</a>', 'mp') ?></span>
  5232. </td>
  5233. </tr>
  5234. <tr>
  5235. <th scope="row"><?php _e('Special Instructions Field', 'mp') ?></th>
  5236. <td>
  5237. <label><input value="1" name="mp[special_instructions]" type="radio"<?php checked($settings['special_instructions'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5238. <label><input value="0" name="mp[special_instructions]" type="radio"<?php checked($settings['special_instructions'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5239. <br /><span class="description"><?php printf(__('Enabling this field will display a textbox on the shipping checkout page for users to enter special instructions for their order. Useful for product personalization, etc. Note you may want to <a href="%s">adjust the message on the shipping page.', 'mp'), admin_url('edit.php?post_type=product&page=marketpress&tab=messages#mp_msgs_shipping')); ?></span>
  5240. </td>
  5241. </tr>
  5242. </table>
  5243. </div>
  5244. </div>
  5245.  
  5246. <?php
  5247. //for adding additional settings for a shipping module
  5248. do_action('mp_general_settings');
  5249. ?>
  5250.  
  5251. <p class="submit">
  5252. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Changes', 'mp') ?>" />
  5253. </p>
  5254. </form>
  5255. </div>
  5256. <?php
  5257. break;
  5258.  
  5259.  
  5260. //---------------------------------------------------//
  5261. case "coupons":
  5262.  
  5263. $coupons = get_option('mp_coupons');
  5264.  
  5265. //delete checked coupons
  5266. if (isset($_POST['allcoupon_delete'])) {
  5267. //check nonce
  5268. check_admin_referer('mp_coupons');
  5269.  
  5270. if (is_array($_POST['coupons_checks'])) {
  5271. //loop through and delete
  5272. foreach ($_POST['coupons_checks'] as $del_code)
  5273. unset($coupons[$del_code]);
  5274.  
  5275. update_option('mp_coupons', $coupons);
  5276. //display message confirmation
  5277. echo '<div class="updated fade"><p>'.__('Coupon(s) succesfully deleted.', 'mp').'</p></div>';
  5278. }
  5279. }
  5280.  
  5281. //save or add coupon
  5282. if (isset($_POST['submit_settings'])) {
  5283. //check nonce
  5284. check_admin_referer('mp_coupons');
  5285.  
  5286. $error = false;
  5287.  
  5288. $new_coupon_code = preg_replace('/[^A-Z0-9_-]/', '', strtoupper($_POST['coupon_code']));
  5289. if (!$new_coupon_code)
  5290. $error[] = __('Please enter a valid Coupon Code', 'mp');
  5291.  
  5292. $coupons[$new_coupon_code]['discount'] = round($_POST['discount'], 2);
  5293. if ($coupons[$new_coupon_code]['discount'] <= 0)
  5294. $error[] = __('Please enter a valid Discount Amount', 'mp');
  5295.  
  5296. $coupons[$new_coupon_code]['discount_type'] = $_POST['discount_type'];
  5297. if ($coupons[$new_coupon_code]['discount_type'] != 'amt' && $coupons[$new_coupon_code]['discount_type'] != 'pct')
  5298. $error[] = __('Please choose a valid Discount Type', 'mp');
  5299.  
  5300. $coupons[$new_coupon_code]['start'] = strtotime($_POST['start']);
  5301. if ($coupons[$new_coupon_code]['start'] === false)
  5302. $error[] = __('Please enter a valid Start Date', 'mp');
  5303.  
  5304. $coupons[$new_coupon_code]['end'] = strtotime($_POST['end']);
  5305. if ($coupons[$new_coupon_code]['end'] && $coupons[$new_coupon_code]['end'] < $coupons[$new_coupon_code]['start'])
  5306. $error[] = __('Please enter a valid End Date not earlier than the Start Date', 'mp');
  5307.  
  5308. $coupons[$new_coupon_code]['uses'] = (is_numeric($_POST['uses'])) ? (int)$_POST['uses'] : '';
  5309.  
  5310. if (!$error) {
  5311. update_option('mp_coupons', $coupons);
  5312. $new_coupon_code = '';
  5313. echo '<div class="updated fade"><p>'.__('Coupon succesfully saved.', 'mp').'</p></div>';
  5314. }
  5315. }
  5316.  
  5317. //if editing a coupon
  5318. if (isset($_GET['code'])) {
  5319. $new_coupon_code = $_GET['code'];
  5320. }
  5321.  
  5322. ?>
  5323. <script type="text/javascript">
  5324. jQuery(document).ready(function ($) {
  5325. jQuery.datepicker.setDefaults(jQuery.datepicker.regional['<?php echo $this->language; ?>']);
  5326. jQuery('.pickdate').datepicker({dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true, minDate: 0, firstDay: <?php echo (get_option('start_of_week')=='0') ? 7 : get_option('start_of_week'); ?>});
  5327. });
  5328. </script>
  5329. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/service.png'; ?>" /></div>
  5330. <h2><?php _e('Coupons', 'mp') ?></h2>
  5331. <p><?php _e('You can create, delete, or update coupon codes for your store here.', 'mp') ?></p>
  5332.  
  5333. <?php
  5334. $apage = isset( $_GET['apage'] ) ? intval( $_GET['apage'] ) : 1;
  5335. $num = isset( $_GET['num'] ) ? intval( $_GET['num'] ) : 10;
  5336.  
  5337. $coupon_list = get_option('mp_coupons');
  5338. $total = (is_array($coupon_list)) ? count($coupon_list) : 0;
  5339.  
  5340. if ($total)
  5341. $coupon_list = array_slice($coupon_list, intval(($apage-1) * $num), intval($num));
  5342.  
  5343. $coupon_navigation = paginate_links( array(
  5344. 'base' => add_query_arg( 'apage', '%#%' ).$url2,
  5345. 'format' => '',
  5346. 'total' => ceil($total / $num),
  5347. 'current' => $apage
  5348. ));
  5349. $page_link = ($apage > 1) ? '&amp;apage='.$apage : '';
  5350. ?>
  5351.  
  5352. <form id="form-coupon-list" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=coupons<?php echo $page_link; ?>" method="post">
  5353. <?php wp_nonce_field('mp_coupons') ?>
  5354. <div class="tablenav">
  5355. <?php if ( $coupon_navigation ) echo "<div class='tablenav-pages'>$coupon_navigation</div>"; ?>
  5356.  
  5357. <div class="alignleft">
  5358. <input type="submit" value="<?php _e('Delete', 'mp') ?>" name="allcoupon_delete" class="button-secondary delete" />
  5359. <br class="clear" />
  5360. </div>
  5361. </div>
  5362.  
  5363. <br class="clear" />
  5364.  
  5365. <?php
  5366. // define the columns to display, the syntax is 'internal name' => 'display name'
  5367. $posts_columns = array(
  5368. 'code' => __('Coupon Code', 'mp'),
  5369. 'discount' => __('Discount', 'mp'),
  5370. 'start' => __('Start Date', 'mp'),
  5371. 'end' => __('Expire Date', 'mp'),
  5372. 'used' => __('Used', 'mp'),
  5373. 'remaining' => __('Remaining Uses', 'mp'),
  5374. 'edit' => __('Edit', 'mp')
  5375. );
  5376. ?>
  5377.  
  5378. <table width="100%" cellpadding="3" cellspacing="3" class="widefat">
  5379. <thead>
  5380. <tr>
  5381. <th scope="col" class="check-column"><input type="checkbox" /></th>
  5382. <?php foreach($posts_columns as $column_id => $column_display_name) {
  5383. $col_url = $column_display_name;
  5384. ?>
  5385. <th scope="col"><?php echo $col_url ?></th>
  5386. <?php } ?>
  5387. </tr>
  5388. </thead>
  5389. <tbody id="the-list">
  5390. <?php
  5391. if ( is_array($coupon_list) && count($coupon_list) ) {
  5392. $bgcolor = $class = '';
  5393. foreach ($coupon_list as $coupon_code => $coupon) {
  5394. $class = ('alternate' == $class) ? '' : 'alternate';
  5395.  
  5396. //assign classes based on coupon availability
  5397. $class = ($this->check_coupon($coupon_code)) ? $class . ' coupon-active' : $class . ' coupon-inactive';
  5398.  
  5399. echo '<tr class="'.$class.' blog-row">
  5400. <th scope="row" class="check-column">
  5401. <input type="checkbox" name="coupons_checks[]"" value="'.$coupon_code.'" />
  5402. </th>';
  5403.  
  5404. foreach( $posts_columns as $column_name=>$column_display_name ) {
  5405. switch($column_name) {
  5406. case 'code': ?>
  5407. <th scope="row">
  5408. <?php echo $coupon_code; ?>
  5409. </th>
  5410. <?php
  5411. break;
  5412.  
  5413. case 'discount': ?>
  5414. <th scope="row">
  5415. <?php
  5416. if ($coupon['discount_type'] == 'pct') {
  5417. echo $coupon['discount'].'%';
  5418. } else if ($coupon['discount_type'] == 'amt') {
  5419. echo $this->format_currency('', $coupon['discount']);
  5420. }
  5421. ?>
  5422. </th>
  5423. <?php
  5424. break;
  5425.  
  5426. case 'start': ?>
  5427. <th scope="row">
  5428. <?php echo date_i18n( get_option('date_format'), $coupon['start'] ); ?>
  5429. </th>
  5430. <?php
  5431. break;
  5432.  
  5433. case 'end': ?>
  5434. <th scope="row">
  5435. <?php echo ($coupon['end']) ? date_i18n( get_option('date_format'), $coupon['end'] ) : __('No End', 'mp'); ?>
  5436. </th>
  5437. <?php
  5438. break;
  5439.  
  5440. case 'used': ?>
  5441. <th scope="row">
  5442. <?php echo ($coupon['used']) ? number_format_i18n($coupon['used']) : 0; ?>
  5443. </th>
  5444. <?php
  5445. break;
  5446.  
  5447. case 'remaining': ?>
  5448. <th scope="row">
  5449. <?php
  5450. if ($coupon['uses'])
  5451. echo number_format_i18n(intval($coupon['uses']) - intval($coupon['used']));
  5452. else
  5453. _e('Unlimited', 'mp');
  5454. ?>
  5455. </th>
  5456. <?php
  5457. break;
  5458.  
  5459. case 'edit': ?>
  5460. <th scope="row">
  5461. <a href="edit.php?post_type=product&amp;page=marketpress&amp;tab=coupons<?php echo $page_link; ?>&amp;code=<?php echo $coupon_code; ?>#add_coupon"><?php _e('Edit', 'mp') ?>&raquo;</a>
  5462. </th>
  5463. <?php
  5464. break;
  5465.  
  5466. }
  5467. }
  5468. ?>
  5469. </tr>
  5470. <?php
  5471. }
  5472. } else { ?>
  5473. <tr style='background-color: <?php echo $bgcolor; ?>'>
  5474. <td colspan="7"><?php _e('No coupons yet.', 'mp') ?></td>
  5475. </tr>
  5476. <?php
  5477. } // end if coupons
  5478. ?>
  5479.  
  5480. </tbody>
  5481. <tfoot>
  5482. <tr>
  5483. <th scope="col" class="check-column"><input type="checkbox" /></th>
  5484. <?php foreach($posts_columns as $column_id => $column_display_name) {
  5485. $col_url = $column_display_name;
  5486. ?>
  5487. <th scope="col"><?php echo $col_url ?></th>
  5488. <?php } ?>
  5489. </tr>
  5490. </tfoot>
  5491. </table>
  5492.  
  5493. <div class="tablenav">
  5494. <?php if ( $coupon_navigation ) echo "<div class='tablenav-pages'>$coupon_navigation</div>"; ?>
  5495. </div>
  5496.  
  5497. <div id="poststuff" class="metabox-holder mp-settings">
  5498.  
  5499. <div class="postbox">
  5500. <h3 class='hndle'><span>
  5501. <?php
  5502. if ( isset($_GET['code']) || $error ) {
  5503. _e('Edit Coupon', 'mp');
  5504. } else {
  5505. _e('Add Coupon', 'mp');
  5506. }
  5507. ?></span></h3>
  5508. <div class="inside">
  5509. <?php
  5510. //display error message if it exists
  5511. if ($error) {
  5512. ?><div class="error"><p><?php echo $error[0]; ?></p></div><?php
  5513. }
  5514.  
  5515. //setup defaults
  5516. if ($new_coupon_code) {
  5517. $discount = ($coupons[$new_coupon_code]['discount'] && $coupons[$new_coupon_code]['discount_type'] == 'amt') ? round($coupons[$new_coupon_code]['discount'], 2) : $coupons[$new_coupon_code]['discount'];
  5518. $discount_type = $coupons[$new_coupon_code]['discount_type'];
  5519. $start = ($coupons[$new_coupon_code]['start']) ? date('Y-m-d', $coupons[$new_coupon_code]['start']) : date('Y-m-d');
  5520. $end = ($coupons[$new_coupon_code]['end']) ? date('Y-m-d', $coupons[$new_coupon_code]['end']) : '';
  5521. $uses = $coupons[$new_coupon_code]['uses'];
  5522. }
  5523. ?>
  5524. <table id="add_coupon">
  5525. <thead>
  5526. <tr>
  5527. <th>
  5528. <?php _e('Coupon Code', 'mp') ?><br />
  5529. <small style="font-weight: normal;"><?php _e('Letters and Numbers only', 'mp') ?></small>
  5530. </th>
  5531. <th><?php _e('Discount', 'mp') ?></th>
  5532. <th><?php _e('Start Date', 'mp') ?></th>
  5533. <th>
  5534. <?php _e('Expire Date', 'mp') ?><br />
  5535. <small style="font-weight: normal;"><?php _e('No end if blank', 'mp') ?></small>
  5536. </th>
  5537. <th>
  5538. <?php _e('Allowed Uses', 'mp') ?><br />
  5539. <small style="font-weight: normal;"><?php _e('Unlimited if blank', 'mp') ?></small>
  5540. </th>
  5541. </tr>
  5542. </thead>
  5543. <tbody>
  5544. <tr>
  5545. <td>
  5546. <input value="<?php echo $new_coupon_code ?>" name="coupon_code" type="text" style="text-transform: uppercase;" />
  5547. </td>
  5548. <td>
  5549. <input value="<?php echo $discount; ?>" size="3" name="discount" type="text" />
  5550. <select name="discount_type">
  5551. <option value="amt"<?php selected($discount_type, 'amt') ?>><?php echo $this->format_currency(); ?></option>
  5552. <option value="pct"<?php selected($discount_type, 'pct') ?>>%</option>
  5553. </select>
  5554. </td>
  5555. <td>
  5556. <input value="<?php echo $start; ?>" class="pickdate" size="11" name="start" type="text" />
  5557. </td>
  5558. <td>
  5559. <input value="<?php echo $end; ?>" class="pickdate" size="11" name="end" type="text" />
  5560. </td>
  5561. <td>
  5562. <input value="<?php echo $uses; ?>" size="4" name="uses" type="text" />
  5563. </td>
  5564. </tr>
  5565. </tbody>
  5566. </table>
  5567.  
  5568. <p class="submit">
  5569. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Coupon', 'mp') ?>" />
  5570. </p>
  5571. </div>
  5572. </div>
  5573.  
  5574. </div>
  5575. </form>
  5576. <?php
  5577. break;
  5578.  
  5579.  
  5580. //---------------------------------------------------//
  5581. case "presentation":
  5582.  
  5583. //save settings
  5584. if (isset($_POST['marketplace_settings'])) {
  5585. //get old store slug
  5586. $old_slug = $settings['slugs']['store'];
  5587.  
  5588. //filter slugs
  5589. $_POST['mp']['slugs'] = array_map('sanitize_title', $_POST['mp']['slugs']);
  5590.  
  5591. // Fixing http://premium.wpmudev.org/forums/topic/store-page-content-overwritten
  5592. $new_slug = $_POST['mp']['slugs']['store'];
  5593. $new_post_id = $wpdb->get_var("SELECT ID FROM " . $wpdb->posts . " WHERE post_name = '$new_slug' AND post_type = 'page'");
  5594.  
  5595. if ($new_slug != $old_slug && $new_post_id != 0) {
  5596. echo '<div class="error fade"><p>'.__('Store base URL conflicts with another page', 'mp').'</p></div>';
  5597. } else {
  5598. $settings = array_merge($settings, apply_filters('mp_presentation_settings_filter', $_POST['mp']));
  5599. update_option('mp_settings', $settings);
  5600.  
  5601. $this->create_store_page($old_slug);
  5602.  
  5603. //flush rewrite rules due to product slugs
  5604. $this->flush_rewrite();
  5605.  
  5606. echo '<div class="updated fade"><p>'.__('Settings saved.', 'mp').'</p></div>';
  5607. }
  5608. }
  5609. ?>
  5610. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/my_work.png'; ?>" /></div>
  5611. <h2><?php _e('Presentation Settings', 'mp'); ?></h2>
  5612. <div id="poststuff" class="metabox-holder mp-settings">
  5613.  
  5614. <form method="post" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=presentation">
  5615. <input type="hidden" name="marketplace_settings" value="1" />
  5616.  
  5617. <div class="postbox">
  5618. <h3 class='hndle'><span><?php _e('General Settings', 'mp') ?></span></h3>
  5619. <div class="inside">
  5620. <table class="form-table">
  5621. <th scope="row"><?php _e('Store Style', 'mp') ?></th>
  5622. <td>
  5623. <?php $this->store_themes_select(); ?>
  5624. <br /><span class="description"><?php _e('This option changes the built-in css styles for store pages.', 'mp') ?></span>
  5625. <?php if ((is_multisite() && is_super_admin()) || !is_multisite()) { ?>
  5626. <br /><span class="description"><?php printf(__('For a custom css style, save your css file with the "MarketPress Style: NAME" header in the "%s/marketpress-styles/" folder and it will appear in this list so you may select it. You can also select "None" and create custom theme templates and css to make your own completely unique store design. More information on that <a href="%sthemes/Themeing_MarketPress.txt">here &raquo;</a>', 'mp'), WP_CONTENT_DIR, $this->plugin_url); ?></span>
  5627. <h4><?php _e('Full-featured MarketPress Themes:', 'mp') ?></h4>
  5628. <div class="mp-theme-preview"><a title="<?php _e('Download Now &raquo;', 'mp') ?>" href="http://premium.wpmudev.org/project/frame-market-theme"><img alt="FrameMarket Theme" src="http://premium.wpmudev.org/wp-content/projects/219/listing-image-thumb.png" />
  5629. <strong><?php _e('FrameMarket/GridMarket', 'mp') ?></strong></a><br />
  5630. <?php _e('The ultimate MarkePress theme brings visual perfection to WordPress e-commerce. This professional front-end does all the work for you!', 'mp') ?></div>
  5631. <div class="mp-theme-preview"><a title="<?php _e('Download Now &raquo;', 'mp') ?>" href="http://premium.wpmudev.org/project/simplemarket"><img alt="SimpleMarket Theme" src="http://premium.wpmudev.org/wp-content/projects/237/listing-image-thumb.png" />
  5632. <strong><?php _e('SimpleMarket', 'mp') ?></strong></a><br />
  5633. <?php _e('The FREE SimpleMarket Theme uses an HTML 5 responsive design so your e-commerce site looks great across all screen-sizes and devices such as smartphones or tablets!', 'mp') ?></div>
  5634. <?php } ?>
  5635. </td>
  5636. </tr>
  5637. </table>
  5638. </div>
  5639. </div>
  5640.  
  5641. <div class="postbox">
  5642. <h3 class='hndle'><span><?php _e('Single Product Settings', 'mp') ?></span></h3>
  5643. <div class="inside">
  5644. <table class="form-table">
  5645. <tr>
  5646. <th scope="row"><?php _e('Checkout Button Type', 'mp') ?></th>
  5647. <td>
  5648. <label><input value="addcart" name="mp[product_button_type]" type="radio"<?php checked($settings['product_button_type'], 'addcart') ?> /> <?php _e('Add To Cart', 'mp') ?></label><br />
  5649. <label><input value="buynow" name="mp[product_button_type]" type="radio"<?php checked($settings['product_button_type'], 'buynow') ?> /> <?php _e('Buy Now', 'mp') ?></label>
  5650. </td>
  5651. </tr>
  5652. <tr>
  5653. <th scope="row"><?php _e('Show Quantity Option', 'mp') ?></th>
  5654. <td>
  5655. <label><input value="1" name="mp[show_quantity]" type="radio"<?php checked($settings['show_quantity'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5656. <label><input value="0" name="mp[show_quantity]" type="radio"<?php checked($settings['show_quantity'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5657. </td>
  5658. </tr>
  5659. <tr>
  5660. <th scope="row"><?php _e('Show Product Image', 'mp') ?></th>
  5661. <td>
  5662. <label><input value="1" name="mp[show_img]" type="radio"<?php checked($settings['show_img'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5663. <label><input value="0" name="mp[show_img]" type="radio"<?php checked($settings['show_img'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5664. </td>
  5665. </tr>
  5666. <tr>
  5667. <th scope="row"><?php _e('Product Image Size', 'mp') ?></th>
  5668. <td>
  5669. <label><input value="thumbnail" name="mp[product_img_size]" type="radio"<?php checked($settings['product_img_size'], 'thumbnail') ?> /> <a href="options-media.php"><?php _e('WP Thumbnail size', 'mp') ?></a></label><br />
  5670. <label><input value="medium" name="mp[product_img_size]" type="radio"<?php checked($settings['product_img_size'], 'medium') ?> /> <a href="options-media.php"><?php _e('WP Medium size', 'mp') ?></a></label><br />
  5671. <label><input value="large" name="mp[product_img_size]" type="radio"<?php checked($settings['product_img_size'], 'large') ?> /> <a href="options-media.php"><?php _e('WP Large size', 'mp') ?></a></label><br />
  5672. <label><input value="custom" name="mp[product_img_size]" type="radio"<?php checked($settings['product_img_size'], 'custom') ?> /> <?php _e('Custom', 'mp') ?></label>:&nbsp;&nbsp;
  5673. <label><?php _e('Height', 'mp') ?><input size="3" name="mp[product_img_height]" value="<?php echo esc_attr($settings['product_img_height']) ?>" type="text" /></label>&nbsp;
  5674. <label><?php _e('Width', 'mp') ?><input size="3" name="mp[product_img_width]" value="<?php echo esc_attr($settings['product_img_width']) ?>" type="text" /></label>
  5675. </td>
  5676. </tr>
  5677. <tr>
  5678. <th scope="row"><?php _e('Show Image Lightbox', 'mp') ?></th>
  5679. <td>
  5680. <label><input value="1" name="mp[show_lightbox]" type="radio"<?php checked($settings['show_lightbox'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5681. <label><input value="0" name="mp[show_lightbox]" type="radio"<?php checked($settings['show_lightbox'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5682. <br /><span class="description"><?php _e('Makes clicking the single product image open an instant zoomed preview.', 'mp') ?></span>
  5683. </td>
  5684. </tr>
  5685. </table>
  5686. </div>
  5687. </div>
  5688.  
  5689. <div class="postbox">
  5690. <h3 class='hndle'><span><?php _e('Product List Settings', 'mp') ?></span></h3>
  5691. <div class="inside">
  5692. <table class="form-table">
  5693. <?php /* ?>
  5694. <tr>
  5695. <th scope="row"><?php _e('Product List View', 'mp') ?></th>
  5696. <td>
  5697. <label><input value="list" name="mp[list_view]" type="radio"<?php checked($settings['list_view'], 'list') ?> /> <?php _e('List View', 'mp') ?></label><br />
  5698. <label><input value="grid" name="mp[list_view]" type="radio"<?php checked($settings['list_view'], 'grid') ?> /> <?php _e('Grid View', 'mp') ?></label>
  5699. </td>
  5700. </tr>
  5701. <?php */ ?>
  5702. <tr>
  5703. <th scope="row"><?php _e('Checkout Button Type', 'mp') ?></th>
  5704. <td>
  5705. <label><input value="addcart" name="mp[list_button_type]" type="radio"<?php checked($settings['list_button_type'], 'addcart') ?> /> <?php _e('Add To Cart', 'mp') ?></label><br />
  5706. <label><input value="buynow" name="mp[list_button_type]" type="radio"<?php checked($settings['list_button_type'], 'buynow') ?> /> <?php _e('Buy Now', 'mp') ?></label>
  5707. </td>
  5708. </tr>
  5709. <tr>
  5710. <th scope="row"><?php _e('Show Product Thumbnail', 'mp') ?></th>
  5711. <td>
  5712. <label><input value="1" name="mp[show_thumbnail]" type="radio"<?php checked($settings['show_thumbnail'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5713. <label><input value="0" name="mp[show_thumbnail]" type="radio"<?php checked($settings['show_thumbnail'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5714. </td>
  5715. </tr>
  5716. <tr>
  5717. <th scope="row"><?php _e('Product Thumbnail Size', 'mp') ?></th>
  5718. <td>
  5719. <label><input value="thumbnail" name="mp[list_img_size]" type="radio"<?php checked($settings['list_img_size'], 'thumbnail') ?> /> <a href="options-media.php"><?php _e('WP Thumbnail size', 'mp') ?></a></label><br />
  5720. <label><input value="medium" name="mp[list_img_size]" type="radio"<?php checked($settings['list_img_size'], 'medium') ?> /> <a href="options-media.php"><?php _e('WP Medium size', 'mp') ?></a></label><br />
  5721. <label><input value="large" name="mp[list_img_size]" type="radio"<?php checked($settings['list_img_size'], 'large') ?> /> <a href="options-media.php"><?php _e('WP Large size', 'mp') ?></a></label><br />
  5722. <label><input value="custom" name="mp[list_img_size]" type="radio"<?php checked($settings['list_img_size'], 'custom') ?> /> <?php _e('Custom', 'mp') ?></label>:&nbsp;&nbsp;
  5723. <label><?php _e('Height', 'mp') ?><input size="3" name="mp[list_img_height]" value="<?php echo esc_attr($settings['list_img_height']) ?>" type="text" /></label>&nbsp;
  5724. <label><?php _e('Width', 'mp') ?><input size="3" name="mp[list_img_width]" value="<?php echo esc_attr($settings['list_img_width']) ?>" type="text" /></label>
  5725. </td>
  5726. </tr>
  5727. <tr>
  5728. <th scope="row"><?php _e('Show Excerpts', 'mp') ?></th>
  5729. <td>
  5730. <label><input value="1" name="mp[show_excerpt]" type="radio"<?php checked($settings['show_excerpt'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5731. <label><input value="0" name="mp[show_excerpt]" type="radio"<?php checked($settings['show_excerpt'], 0) ?> /> <?php _e('No', 'mp') ?></label>
  5732. </td>
  5733. </tr>
  5734. <tr>
  5735. <th scope="row"><?php _e('Paginate Products', 'mp') ?></th>
  5736. <td>
  5737. <label><input value="1" name="mp[paginate]" type="radio"<?php checked($settings['paginate'], 1) ?> /> <?php _e('Yes', 'mp') ?></label>
  5738. <label><input value="0" name="mp[paginate]" type="radio"<?php checked($settings['paginate'], 0) ?> /> <?php _e('No', 'mp') ?></label>&nbsp;&nbsp;
  5739. <label><input value="<?php echo esc_attr($settings['per_page']) ?>" name="mp[per_page]" type="text" size="2" /> <?php _e('Products per page', 'mp') ?></label>
  5740. </td>
  5741. </tr>
  5742. <tr>
  5743. <th scope="row"><?php _e('Order Products By', 'mp') ?></th>
  5744. <td>
  5745. <select name="mp[order_by]">
  5746. <option value="title"<?php selected($settings['order_by'], 'title') ?>><?php _e('Product Name', 'mp') ?></option>
  5747. <option value="date"<?php selected($settings['order_by'], 'date') ?>><?php _e('Publish Date', 'mp') ?></option>
  5748. <option value="ID"<?php selected($settings['order_by'], 'ID') ?>><?php _e('Product ID', 'mp') ?></option>
  5749. <option value="author"<?php selected($settings['order_by'], 'author') ?>><?php _e('Product Author', 'mp') ?></option>
  5750. <option value="sales"<?php selected($settings['order_by'], 'sales') ?>><?php _e('Number of Sales', 'mp') ?></option>
  5751. <option value="price"<?php selected($settings['order_by'], 'price') ?>><?php _e('Product Price', 'mp') ?></option>
  5752. <option value="rand"<?php selected($settings['order_by'], 'rand') ?>><?php _e('Random', 'mp') ?></option>
  5753. </select>
  5754. <label><input value="DESC" name="mp[order]" type="radio"<?php checked($settings['order'], 'DESC') ?> /> <?php _e('Descending', 'mp') ?></label>
  5755. <label><input value="ASC" name="mp[order]" type="radio"<?php checked($settings['order'], 'ASC') ?> /> <?php _e('Ascending', 'mp') ?></label>
  5756. </td>
  5757. </tr>
  5758. </table>
  5759. </div>
  5760. </div>
  5761.  
  5762. <div class="postbox">
  5763. <h3 class='hndle'><span><?php _e('Store URL Slugs', 'mp') ?></span></h3>
  5764. <div class="inside">
  5765. <span class="description"><?php _e('Customizes the url structure of your store', 'mp') ?></span>
  5766. <table class="form-table">
  5767. <tr valign="top">
  5768. <th scope="row"><?php _e('Store Base', 'mp') ?></th>
  5769. <td>/<input type="text" name="mp[slugs][store]" value="<?php echo esc_attr($settings['slugs']['store']); ?>" size="20" maxlength="50" />/<br />
  5770. <span class="description"><?php _e('This page will be created so you can change it\'s content and the order in which it appears in navigation menus if your theme supports it.', 'mp') ?></span></td>
  5771. </tr>
  5772. <tr valign="top">
  5773. <th scope="row"><?php _e('Products List', 'mp') ?></th>
  5774. <td>/<?php echo esc_attr($settings['slugs']['store']); ?>/<input type="text" name="mp[slugs][products]" value="<?php echo esc_attr($settings['slugs']['products']); ?>" size="20" maxlength="50" />/</td>
  5775. </tr>
  5776. <tr valign="top">
  5777. <th scope="row"><?php _e('Shopping Cart Page', 'mp') ?></th>
  5778. <td>/<?php echo esc_attr($settings['slugs']['store']); ?>/<input type="text" name="mp[slugs][cart]" value="<?php echo esc_attr($settings['slugs']['cart']); ?>" size="20" maxlength="50" />/</td>
  5779. </tr>
  5780. <tr valign="top">
  5781. <th scope="row"><?php _e('Order Status Page', 'mp') ?></th>
  5782. <td>/<?php echo esc_attr($settings['slugs']['store']); ?>/<input type="text" name="mp[slugs][orderstatus]" value="<?php echo esc_attr($settings['slugs']['orderstatus']); ?>" size="20" maxlength="50" />/</td>
  5783. </tr>
  5784. <tr valign="top">
  5785. <th scope="row"><?php _e('Product Category', 'mp') ?></th>
  5786. <td>/<?php echo esc_attr($settings['slugs']['store']); ?>/<?php echo esc_attr($settings['slugs']['products']); ?>/<input type="text" name="mp[slugs][category]" value="<?php echo esc_attr($settings['slugs']['category']); ?>" size="20" maxlength="50" />/</td>
  5787. </tr>
  5788. <tr valign="top">
  5789. <th scope="row"><?php _e('Product Tag', 'mp') ?></th>
  5790. <td>/<?php echo esc_attr($settings['slugs']['store']); ?>/<?php echo esc_attr($settings['slugs']['products']); ?>/<input type="text" name="mp[slugs][tag]" value="<?php echo esc_attr($settings['slugs']['tag']); ?>" size="20" maxlength="50" />/</td>
  5791. </tr>
  5792. </table>
  5793. </div>
  5794. </div>
  5795.  
  5796. <?php do_action('mp_presentation_settings'); ?>
  5797.  
  5798. <p class="submit">
  5799. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Changes', 'mp') ?>" />
  5800. </p>
  5801. </form>
  5802. </div>
  5803. <?php
  5804. break;
  5805.  
  5806.  
  5807. //---------------------------------------------------//
  5808. case "messages":
  5809. //save settings
  5810. if (isset($_POST['messages_settings'])) {
  5811.  
  5812. //strip slashes
  5813. $_POST['mp']['msg'] = array_map('stripslashes', $_POST['mp']['msg']);
  5814.  
  5815. //remove html from emails
  5816. $_POST['mp']['email'] = array_map('wp_filter_nohtml_kses', $_POST['mp']['email']);
  5817.  
  5818. //filter msg inputs if necessary
  5819. if (!current_user_can('unfiltered_html')) {
  5820. $_POST['mp']['msg'] = array_map('wp_kses_post', $_POST['mp']['msg']);
  5821. }
  5822.  
  5823. $settings = array_merge($settings, apply_filters('mp_messages_settings_filter', $_POST['mp']));
  5824. update_option('mp_settings', $settings);
  5825.  
  5826. echo '<div class="updated fade"><p>'.__('Settings saved.', 'mp').'</p></div>';
  5827. }
  5828.  
  5829. //strip slashes
  5830. $settings['email'] = array_map('stripslashes', $settings['email']);
  5831. ?>
  5832. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/messages.png'; ?>" /></div>
  5833. <h2><?php _e('Messages Settings', 'mp'); ?></h2>
  5834. <div id="poststuff" class="metabox-holder mp-settings">
  5835.  
  5836. <form id="mp-messages-form" method="post" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=messages">
  5837. <input type="hidden" name="messages_settings" value="1" />
  5838.  
  5839. <div class="postbox">
  5840. <h3 class='hndle'><span><?php _e('Email Notifications', 'mp') ?></span></h3>
  5841. <div class="inside">
  5842. <table class="form-table">
  5843. <tr>
  5844. <th scope="row"><?php _e('Store Admin Email', 'mp'); ?></th>
  5845. <td>
  5846. <?php $store_email = isset($settings['store_email']) ? $settings['store_email'] : get_option("admin_email"); ?>
  5847. <span class="description"><?php _e('The email address that new order notifications are sent to and received from.', 'mp') ?></span><br />
  5848. <input name="mp[store_email]" value="<?php echo esc_attr($store_email); ?>" maxlength="150" size="50" />
  5849. </td>
  5850. </tr>
  5851. <tr>
  5852. <th scope="row"><?php _e('New Order', 'mp'); ?></th>
  5853. <td>
  5854. <span class="description"><?php _e('The email text sent to your customer to confirm a new order. These codes will be replaced with order details: CUSTOMERNAME, ORDERID, ORDERINFO, SHIPPINGINFO, PAYMENTINFO, TOTAL, TRACKINGURL, ORDERNOTES. No HTML allowed.', 'mp') ?></span><br />
  5855. <label><?php _e('Subject:', 'mp'); ?><br />
  5856. <input class="mp_emails_sub" name="mp[email][new_order_subject]" value="<?php echo esc_attr($settings['email']['new_order_subject']); ?>" maxlength="150" /></label><br />
  5857. <label><?php _e('Text:', 'mp'); ?><br />
  5858. <textarea class="mp_emails_txt" name="mp[email][new_order_txt]"><?php echo esc_textarea($settings['email']['new_order_txt']); ?></textarea>
  5859. </label>
  5860. </td>
  5861. </tr>
  5862. <tr>
  5863. <th scope="row"><?php _e('Order Shipped', 'mp'); ?></th>
  5864. <td>
  5865. <span class="description"><?php _e('The email text sent to your customer when you mark an order as "Shipped". These codes will be replaced with order details: CUSTOMERNAME, ORDERID, ORDERINFO, SHIPPINGINFO, PAYMENTINFO, TOTAL, TRACKINGURL, ORDERNOTES. No HTML allowed.', 'mp') ?></span><br />
  5866. <label><?php _e('Subject:', 'mp'); ?><br />
  5867. <input class="mp_emails_sub" name="mp[email][shipped_order_subject]" value="<?php echo esc_attr($settings['email']['shipped_order_subject']); ?>" maxlength="150" /></label><br />
  5868. <label><?php _e('Text:', 'mp'); ?><br />
  5869. <textarea class="mp_emails_txt" name="mp[email][shipped_order_txt]"><?php echo esc_textarea($settings['email']['shipped_order_txt']); ?></textarea>
  5870. </label>
  5871. </td>
  5872. </tr>
  5873. </table>
  5874. </div>
  5875. </div>
  5876.  
  5877. <div class="postbox mp-pages-msgs">
  5878. <h3 class='hndle'><span><?php _e('Store Pages', 'mp') ?></span></h3>
  5879. <div class="inside">
  5880. <table class="form-table">
  5881. <tr>
  5882. <th scope="row"><?php _e('Store Page', 'mp'); ?></th>
  5883. <td>
  5884. <span class="description"><?php _e('The main store page is an actual page on your site. You can edit it here:', 'mp') ?></span>
  5885. <?php
  5886. $post_id = get_option('mp_store_page');
  5887. edit_post_link(__('Edit Page &raquo;', 'mp'), '', '', $post_id);
  5888. ?>
  5889. </td>
  5890. </tr>
  5891. <tr>
  5892. <th scope="row"><?php _e('Product Listing Pages', 'mp'); ?></th>
  5893. <td>
  5894. <span class="description"><?php _e('Displayed at the top of the product listing pages. Optional, HTML allowed.', 'mp') ?></span><br />
  5895. <?php wp_editor( $settings['msg']['product_list'], 'product_list', array('textarea_name'=>'mp[msg][product_list]') ); ?>
  5896. </td>
  5897. </tr>
  5898. <tr>
  5899. <th scope="row"><?php _e('Order Status Page', 'mp'); ?></th>
  5900. <td>
  5901. <span class="description"><?php _e('Displayed at the top of the Order Status page. Optional, HTML allowed.', 'mp') ?></span><br />
  5902. <?php wp_editor( $settings['msg']['order_status'], 'order_status', array('textarea_name'=>'mp[msg][order_status]') ); ?>
  5903. </td>
  5904. </tr>
  5905. </table>
  5906. </div>
  5907. </div>
  5908.  
  5909. <div class="postbox mp-pages-msgs">
  5910. <h3 class='hndle'><span><?php _e('Shopping Cart Pages', 'mp') ?></span></h3>
  5911. <div class="inside">
  5912. <table class="form-table">
  5913. <tr>
  5914. <th scope="row"><?php _e('Shopping Cart Page', 'mp'); ?></th>
  5915. <td>
  5916. <span class="description"><?php _e('Displayed at the top of the Shopping Cart page. Optional, HTML allowed.', 'mp') ?></span><br />
  5917. <?php wp_editor( $settings['msg']['cart'], 'cart', array('textarea_name'=>'mp[msg][cart]') ); ?>
  5918. </td>
  5919. </tr>
  5920. <tr id="mp_msgs_shipping">
  5921. <th scope="row"><?php _e('Shipping Form Page', 'mp'); ?></th>
  5922. <td>
  5923. <span class="description"><?php _e('Displayed at the top of the Shipping Form page. Optional, HTML allowed.', 'mp') ?></span><br />
  5924. <?php wp_editor( $settings['msg']['shipping'], 'shipping', array('textarea_name'=>'mp[msg][shipping]') ); ?>
  5925. </td>
  5926. </tr>
  5927. <tr>
  5928. <th scope="row"><?php _e('Payment Form Page', 'mp'); ?></th>
  5929. <td>
  5930. <span class="description"><?php _e('Displayed at the top of the Payment Form page. Optional, HTML allowed.', 'mp') ?></span><br />
  5931. <?php wp_editor( $settings['msg']['checkout'], 'checkout', array('textarea_name'=>'mp[msg][checkout]') ); ?>
  5932. </td>
  5933. </tr>
  5934. <tr>
  5935. <th scope="row"><?php _e('Order Confirmation Page', 'mp'); ?></th>
  5936. <td>
  5937. <span class="description"><?php _e('Displayed at the top of the final Order Confirmation page. HTML allowed.', 'mp') ?></span><br />
  5938. <?php wp_editor( $settings['msg']['confirm_checkout'], 'confirm_checkout', array('textarea_name'=>'mp[msg][confirm_checkout]') ); ?>
  5939. </td>
  5940. </tr>
  5941. <tr>
  5942. <th scope="row"><?php _e('Order Complete Page', 'mp'); ?></th>
  5943. <td>
  5944. <span class="description"><?php _e('Displayed at the top of the page notifying customers of a successful order. HTML allowed.', 'mp') ?></span><br />
  5945. <?php wp_editor( $settings['msg']['success'], 'success', array('textarea_name'=>'mp[msg][success]') ); ?>
  5946. </td>
  5947. </tr>
  5948. </table>
  5949. </div>
  5950. </div>
  5951.  
  5952. <?php
  5953. //for adding additional messages
  5954. do_action('mp_messages_settings', $settings);
  5955. ?>
  5956.  
  5957. <p class="submit">
  5958. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Changes', 'mp') ?>" />
  5959. </p>
  5960. </form>
  5961. </div>
  5962. <?php
  5963. break;
  5964.  
  5965.  
  5966. //---------------------------------------------------//
  5967. case "shipping":
  5968. global $mp_shipping_plugins;
  5969.  
  5970. //save settings
  5971. if (isset($_POST['shipping_settings'])) {
  5972. echo '<div class="updated fade"><p>'.__('Settings saved.', 'mp').'</p></div>';
  5973. }
  5974. ?>
  5975. <script type="text/javascript">
  5976. jQuery(document).ready(function ($) {
  5977. $("#mp-select-all").click(function() {
  5978. $("#mp-target-countries input[type='checkbox']").attr('checked', true);
  5979. return false;
  5980. });
  5981. $("#mp-select-eu").click(function() {
  5982. $("#mp-target-countries input[type='checkbox'].eu").attr('checked', true);
  5983. return false;
  5984. });
  5985. $("#mp-select-none").click(function() {
  5986. $("#mp-target-countries input[type='checkbox']").attr('checked', false);
  5987. return false;
  5988. });
  5989. $(".mp-shipping-method").change(function() {
  5990. $("#mp-shipping-form").submit();
  5991. });
  5992. });
  5993. </script>
  5994. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/delivery.png'; ?>" /></div>
  5995. <h2><?php _e('Shipping Settings', 'mp'); ?></h2>
  5996. <div id="poststuff" class="metabox-holder mp-settings">
  5997.  
  5998. <form id="mp-shipping-form" method="post" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=shipping">
  5999. <input type="hidden" name="shipping_settings" value="1" />
  6000.  
  6001. <div id="mp_flat_rate" class="postbox">
  6002. <h3 class='hndle'><span><?php _e('General Settings', 'mp') ?></span></h3>
  6003. <div class="inside">
  6004. <table class="form-table">
  6005.  
  6006. <tr>
  6007. <th scope="row"><?php _e('Choose Target Countries', 'mp') ?></th>
  6008. <td>
  6009. <div><?php _e('Select:', 'mp') ?> <a id="mp-select-all" href="#"><?php _e('All', 'mp') ?></a>&nbsp; <a id="mp-select-eu" href="#"><?php _e('EU', 'mp') ?></a>&nbsp; <a id="mp-select-none" href="#"><?php _e('None', 'mp') ?></a></div>
  6010. <div id="mp-target-countries">
  6011. <?php
  6012. foreach ($this->countries as $code => $name) {
  6013. ?><label><input type="checkbox"<?php echo (in_array($code, $this->eu_countries)) ? ' class="eu"' : ''; ?> name="mp[shipping][allowed_countries][]" value="<?php echo $code; ?>"<?php echo (in_array($code, (array)$settings['shipping']['allowed_countries'])) ? ' checked="checked"' : ''; ?> /> <?php echo esc_attr($name); ?></label><br /><?php
  6014. }
  6015. ?>
  6016. </div><br />
  6017. <span class="description"><?php _e('These are the countries you will sell and ship to.', 'mp') ?></span>
  6018. </td>
  6019. </tr>
  6020.  
  6021. <tr>
  6022. <th scope="row"><?php _e('Select Shipping Method', 'mp') ?></th>
  6023. <td>
  6024. <select name="mp[shipping][method]" class="mp-shipping-method">
  6025. <option value="none"<?php selected($settings['shipping']['method'], 'none'); ?>><?php _e('No Shipping', 'mp'); ?></option>
  6026. <?php
  6027. $calculated_methods = 0;
  6028. foreach ((array)$mp_shipping_plugins as $code => $plugin) {
  6029. if ($plugin[2]) {
  6030. $calculated_methods++;
  6031. continue;
  6032. }
  6033. ?><option value="<?php echo $code; ?>"<?php selected($settings['shipping']['method'], $code); ?>><?php echo esc_attr($plugin[1]); ?></option><?php
  6034. }
  6035. if ($calculated_methods) {
  6036. ?><option value="calculated"<?php selected($settings['shipping']['method'], 'calculated'); ?>><?php _e('Calculated Options', 'mp'); ?></option><?php
  6037. }
  6038. ?>
  6039. </select>
  6040. </td>
  6041. </tr>
  6042. <?php
  6043. if ($calculated_methods && $settings['shipping']['method'] == 'calculated') {
  6044. ?>
  6045. <tr>
  6046. <th scope="row"><?php _e('Select Shipping Options', 'mp') ?></th>
  6047. <td>
  6048. <span class="description"><?php _e('Select which calculated shipping methods the customer will be able to choose from:', 'mp') ?></span><br />
  6049. <?php
  6050. foreach ((array)$mp_shipping_plugins as $code => $plugin) {
  6051. if (!$plugin[2]) continue; //skip non calculated
  6052. ?><label><input type="checkbox" class="mp-shipping-method" name="mp[shipping][calc_methods][<?php echo $code; ?>]" value="<?php echo $code; ?>"<?php echo (isset($settings['shipping']['calc_methods'][$code])) ? ' checked="checked"' : ''; ?> /> <?php echo esc_attr($plugin[1]); ?></label><br /><?php
  6053. }
  6054. ?>
  6055. </td>
  6056. </tr>
  6057. <?php
  6058. }
  6059. ?>
  6060. <tr>
  6061. <th scope="row"><?php _e('Measurement System', 'mp') ?></th>
  6062. <td>
  6063. <label><input value="english" name="mp[shipping][system]" type="radio"<?php checked($settings['shipping']['system'], 'english') ?> /> <?php _e('Engish (Pounds)', 'mp') ?></label>
  6064. <label><input value="metric" name="mp[shipping][system]" type="radio"<?php checked($settings['shipping']['system'], 'metric') ?> /> <?php _e('Metric (Kilograms)', 'mp') ?></label>
  6065. </td>
  6066. </tr>
  6067. </table>
  6068. </div>
  6069. </div>
  6070.  
  6071. <?php
  6072. //for adding additional settings for a shipping module
  6073. do_action('mp_shipping_settings', $settings);
  6074. ?>
  6075.  
  6076. <p class="submit">
  6077. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Changes', 'mp') ?>" />
  6078. </p>
  6079. </form>
  6080. </div>
  6081. <?php
  6082. break;
  6083.  
  6084.  
  6085. //---------------------------------------------------//
  6086. case "gateways":
  6087. global $mp_gateway_plugins;
  6088.  
  6089. //save settings
  6090. if (isset($_POST['gateway_settings'])) {
  6091. echo '<div class="updated fade"><p>'.__('Settings saved.', 'mp').'</p></div>';
  6092. }
  6093. ?>
  6094. <script type="text/javascript">
  6095. jQuery(document).ready(function ($) {
  6096. $("input.mp_allowed_gateways").change(function() {
  6097. $("#mp-gateways-form").submit();
  6098. });
  6099. });
  6100. </script>
  6101. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/credit-cards.png'; ?>" /></div>
  6102. <h2><?php _e('Payment Settings', 'mp'); ?></h2>
  6103. <div id="poststuff" class="metabox-holder mp-settings">
  6104.  
  6105. <form id="mp-gateways-form" method="post" action="edit.php?post_type=product&amp;page=marketpress&amp;tab=gateways">
  6106. <input type="hidden" name="gateway_settings" value="1" />
  6107.  
  6108. <?php if (!$this->global_cart) { ?>
  6109. <div id="mp_gateways" class="postbox">
  6110. <h3 class='hndle'><span><?php _e('General Settings', 'mp') ?></span></h3>
  6111. <div class="inside">
  6112. <table class="form-table">
  6113. <tr>
  6114. <th scope="row"><?php _e('Select Payment Gateway(s)', 'mp') ?></th>
  6115. <td>
  6116. <?php
  6117. //check network permissions
  6118. if (is_multisite() && !is_main_site()) {
  6119. $network_settings = get_site_option( 'mp_network_settings' );
  6120. foreach ((array)$mp_gateway_plugins as $code => $plugin) {
  6121. if ($network_settings['allowed_gateways'][$code] == 'full') {
  6122. $allowed_plugins[$code] = $plugin;
  6123. } else if ($network_settings['allowed_gateways'][$code] == 'supporter' && function_exists('is_pro_site') && is_pro_site(false, $network_settings['gateways_pro_level'][$code]) ) {
  6124.  
  6125. $allowed_plugins[$code] = $plugin;
  6126. }
  6127. }
  6128. $mp_gateway_plugins = $allowed_plugins;
  6129. }
  6130.  
  6131. foreach ((array)$mp_gateway_plugins as $code => $plugin) {
  6132. if ($plugin[3]) { //if demo
  6133. ?><label><input type="checkbox" class="mp_allowed_gateways" name="mp[gateways][allowed][]" value="<?php echo $code; ?>" disabled="disabled" /> <?php echo esc_attr($plugin[1]); ?></label> <a class="mp-pro-update" href="http://premium.wpmudev.org/project/e-commerce" title="<?php _e('Upgrade', 'mp'); ?> &raquo;"><?php _e('Pro Only &raquo;', 'mp'); ?></a><br /><?php
  6134. } else {
  6135. ?><label><input type="checkbox" class="mp_allowed_gateways" name="mp[gateways][allowed][]" value="<?php echo $code; ?>"<?php echo (in_array($code, (array)$settings['gateways']['allowed'])) ? ' checked="checked"' : ''; ?> /> <?php echo esc_attr($plugin[1]); ?></label><br /><?php
  6136. }
  6137. }
  6138. ?>
  6139. </td>
  6140. </tr>
  6141. </table>
  6142. </div>
  6143. </div>
  6144. <?php } ?>
  6145.  
  6146. <?php
  6147. //for adding additional settings for a payment gateway plugin
  6148. do_action('mp_gateway_settings', $settings);
  6149. ?>
  6150.  
  6151. <p class="submit">
  6152. <input class="button-primary" type="submit" name="submit_settings" value="<?php _e('Save Changes', 'mp') ?>" />
  6153. </p>
  6154. </form>
  6155. </div>
  6156. <?php
  6157. break;
  6158.  
  6159.  
  6160. //---------------------------------------------------//
  6161. case "shortcodes":
  6162. ?>
  6163. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/help.png'; ?>" /></div>
  6164. <h2><?php _e('MarketPress Shortcodes', 'mp'); ?></h2>
  6165. <div id="poststuff" class="metabox-holder mp-settings">
  6166.  
  6167. <!--
  6168. <div class="postbox">
  6169. <h3 class='hndle'><span><?php _e('General Information', 'mp') ?></span></h3>
  6170. <div class="inside">
  6171. <iframe src="http://premium.wpmudev.org/wdp-un.php?action=help&id=144" width="100%" height="400px"></iframe>
  6172. </div>
  6173. </div>
  6174. -->
  6175.  
  6176. <div class="postbox">
  6177. <h3 class='hndle'><span><?php _e('Shortcodes', 'mp') ?></span></h3>
  6178. <div class="inside">
  6179. <p><?php _e('Shortcodes allow you to include dynamic store content in posts and pages on your site. Simply type or paste them into your post or page content where you would like them to appear. Optional attributes can be added in a format like <em>[shortcode attr1="value" attr2="value"]</em>.', 'mp') ?></p>
  6180. <table class="form-table">
  6181. <tr>
  6182. <th scope="row"><?php _e('Product Tag Cloud', 'mp') ?></th>
  6183. <td>
  6184. <strong>[mp_tag_cloud]</strong> -
  6185. <span class="description"><?php _e('Displays a cloud or list of your product tags.', 'mp') ?></span>
  6186. <a href="http://codex.wordpress.org/Template_Tags/wp_tag_cloud"><?php _e('Optional Attributes &raquo;', 'mp') ?></a>
  6187. </td>
  6188. </tr>
  6189. <tr>
  6190. <th scope="row"><?php _e('Product Categories List', 'mp') ?></th>
  6191. <td>
  6192. <strong>[mp_list_categories]</strong> -
  6193. <span class="description"><?php _e('Displays an HTML list of your product categories.', 'mp') ?></span>
  6194. <a href="http://codex.wordpress.org/Template_Tags/wp_list_categories"><?php _e('Optional Attributes &raquo;', 'mp') ?></a>
  6195. </td>
  6196. </tr>
  6197. <tr>
  6198. <th scope="row"><?php _e('Product Categories Dropdown', 'mp') ?></th>
  6199. <td>
  6200. <strong>[mp_dropdown_categories]</strong> -
  6201. <span class="description"><?php _e('Displays an HTML dropdown of your product categories.', 'mp') ?></span>
  6202. <a href="http://codex.wordpress.org/Template_Tags/wp_dropdown_categories"><?php _e('Optional Attributes &raquo;', 'mp') ?></a>
  6203. </td>
  6204. </tr>
  6205. <tr>
  6206. <th scope="row"><?php _e('Popular Products List', 'mp') ?></th>
  6207. <td>
  6208. <strong>[mp_popular_products]</strong> -
  6209. <span class="description"><?php _e('Displays a list of popular products ordered by sales.', 'mp') ?></span>
  6210. <p>
  6211. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6212. <ul class="mp-shortcode-options">
  6213. <li><?php _e('"number" - max number of products to display. Defaults to 5.', 'mp') ?></li>
  6214. <li><?php _e('Example:', 'mp') ?> <em>[mp_popular_products number="5"]</em></li>
  6215. </ul></p>
  6216. </td>
  6217. </tr>
  6218. <tr>
  6219. <th scope="row"><?php _e('Products List', 'mp') ?></th>
  6220. <td>
  6221. <strong>[mp_list_products]</strong> -
  6222. <span class="description"><?php _e('Displays a list of products according to preference. Optional attributes default to the values in Presentation Settings -> Product List.', 'mp') ?></span>
  6223. <p>
  6224. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6225. <ul class="mp-shortcode-options">
  6226. <li><?php _e('"paginate" - Whether to paginate the product list. This is useful to only show a subset.', 'mp') ?></li>
  6227. <li><?php _e('"page" - The page number to display in the product list if "paginate" is set to true.', 'mp') ?></li>
  6228. <li><?php _e('"per_page" - How many products to display in the product list if "paginate" is set to true.', 'mp') ?></li>
  6229. <li><?php _e('"order_by" - What field to order products by. Can be: title, date, ID, author, price, sales, rand (random).', 'mp') ?></li>
  6230. <li><?php _e('"order" - Direction to order products by. Can be: DESC, ASC', 'mp') ?></li>
  6231. <li><?php _e('"category" - Limits list to a specific product category. Use the category Slug', 'mp') ?></li>
  6232. <li><?php _e('"tag" - Limits list to a specific product tag. Use the tag Slug', 'mp') ?></li>
  6233. <li><?php _e('Example:', 'mp') ?> <em>[mp_list_products paginate="true" page="1" per_page="10" order_by="price" order="DESC" category="downloads"]</em></li>
  6234. </ul></p>
  6235. </td>
  6236. </tr>
  6237. <tr>
  6238. <th scope="row"><?php _e('Single Product', 'mp') ?></th>
  6239. <td>
  6240. <strong>[mp_product]</strong> -
  6241. <span class="description"><?php _e('Displays a single product according to preference.', 'mp') ?></span>
  6242. <p>
  6243. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6244. <ul class="mp-shortcode-options">
  6245. <li><?php _e('"product_id" - The ID of the product to display.', 'mp') ?></li>
  6246. <li><?php _e('"title" - Whether to display the product title.', 'mp') ?></li>
  6247. <li><?php _e('"content" - Whether and what type of content to display. Options are false/0, "full", or "excerpt". Default "full"', 'mp') ?></li>
  6248. <li><?php _e('"image" - Whether and what context of image size to display. Options are false/0, "single", or "list". Default "single"', 'mp') ?></li>
  6249. <li><?php _e('"meta" - Whether to display the product meta (price, buy button).', 'mp') ?></li>
  6250. <li><?php _e('Example:', 'mp') ?> <em>[mp_product product_id="1" title="1" content="excerpt" image="single" meta="1"]</em></li>
  6251. </ul></p>
  6252. </td>
  6253. </tr>
  6254. <tr>
  6255. <th scope="row"><?php _e('Product Image', 'mp') ?></th>
  6256. <td>
  6257. <strong>[mp_product_image]</strong> -
  6258. <span class="description"><?php _e('Displays the featured image of a given product.', 'mp') ?></span>
  6259. <p>
  6260. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6261. <ul class="mp-shortcode-options">
  6262. <li><?php _e('"product_id" - The ID for the product. Optional if shortcode is in the loop.', 'mp') ?></li>
  6263. <li><?php _e('"context" - What context for preset size options. Options are list, single, or widget, default single.', 'mp') ?></li>
  6264. <li><?php _e('"size" - Set a custom pixel width/height. If omitted defaults to the size set by "context".', 'mp') ?></li>
  6265. <li><?php _e('Example:', 'mp') ?> <em>[mp_product_image product_id="1" size="150"]</em></li>
  6266. </ul></p>
  6267. </td>
  6268. </tr>
  6269. <tr>
  6270. <th scope="row"><?php _e('Product Buy Button', 'mp') ?></th>
  6271. <td>
  6272. <strong>[mp_buy_button]</strong> -
  6273. <span class="description"><?php _e('Displays the buy or add to cart button.', 'mp') ?></span>
  6274. <p>
  6275. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6276. <ul class="mp-shortcode-options">
  6277. <li><?php _e('"product_id" - The ID for the product. Optional if shortcode is in the loop.', 'mp') ?></li>
  6278. <li><?php _e('"context" - What context for display. Options are list or single, default single which shows all variations.', 'mp') ?></li>
  6279. <li><?php _e('Example:', 'mp') ?> <em>[mp_buy_button product_id="1" context="single"]</em></li>
  6280. </ul></p>
  6281. </td>
  6282. </tr>
  6283. <tr>
  6284. <th scope="row"><?php _e('Product Price', 'mp') ?></th>
  6285. <td>
  6286. <strong>[mp_product_price]</strong> -
  6287. <span class="description"><?php _e('Displays the product price (and sale price).', 'mp') ?></span>
  6288. <p>
  6289. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6290. <ul class="mp-shortcode-options">
  6291. <li><?php _e('"product_id" - The ID for the product. Optional if shortcode is in the loop.', 'mp') ?></li>
  6292. <li><?php _e('"label" - A label to prepend to the price. Defaults to "Price: ".', 'mp') ?></li>
  6293. <li><?php _e('Example:', 'mp') ?> <em>[mp_product_price product_id="1" label="Buy this thing now!"]</em></li>
  6294. </ul></p>
  6295. </td>
  6296. </tr>
  6297. <tr>
  6298. <th scope="row"><?php _e('Product Meta', 'mp') ?></th>
  6299. <td>
  6300. <strong>[mp_product_meta]</strong> -
  6301. <span class="description"><?php _e('Displays the full product meta box with price and buy now/add to cart button.', 'mp') ?></span>
  6302. <p>
  6303. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6304. <ul class="mp-shortcode-options">
  6305. <li><?php _e('"product_id" - The ID for the product. Optional if shortcode is in the loop.', 'mp') ?></li>
  6306. <li><?php _e('"label" - A label to prepend to the price. Defaults to "Price: ".', 'mp') ?></li>
  6307. <li><?php _e('"context" - What context for display. Options are list or single, default single which shows all variations.', 'mp') ?></li>
  6308. <li><?php _e('Example:', 'mp') ?> <em>[mp_product_meta product_id="1" label="Buy this thing now!"]</em></li>
  6309. </ul></p>
  6310. </td>
  6311. </tr>
  6312. <tr>
  6313. <th scope="row"><?php _e('Store Links', 'mp') ?></th>
  6314. <td>
  6315. <strong>[mp_cart_link]</strong> -
  6316. <span class="description"><?php _e('Displays a link or url to the current shopping cart page.', 'mp') ?></span><br />
  6317. <strong>[mp_store_link]</strong> -
  6318. <span class="description"><?php _e('Displays a link or url to the current store page.', 'mp') ?></span><br />
  6319. <strong>[mp_products_link]</strong> -
  6320. <span class="description"><?php _e('Displays a link or url to the current products list page.', 'mp') ?></span><br />
  6321. <strong>[mp_orderstatus_link]</strong> -
  6322. <span class="description"><?php _e('Displays a link or url to the order status page.', 'mp') ?></span><br />
  6323. <p>
  6324. <strong><?php _e('Optional Attributes:', 'mp') ?></strong>
  6325. <ul class="mp-shortcode-options">
  6326. <li><?php _e('"url" - Whether to return a clickable link or url. Can be: true, false. Defaults to showing link.', 'mp') ?></li>
  6327. <li><?php _e('"link_text" - The text to show in the link.', 'mp') ?></li>
  6328. <li><?php _e('Example:', 'mp') ?> <em>[mp_cart_link link_text="Go here!"]</em></li>
  6329. </ul></p>
  6330. </td>
  6331. </tr>
  6332. <tr>
  6333. <th scope="row"><?php _e('Store Navigation List', 'mp') ?></th>
  6334. <td>
  6335. <strong>[mp_store_navigation]</strong> -
  6336. <span class="description"><?php _e('Displays a list of links to your store pages.', 'mp') ?></span>
  6337. </td>
  6338. </tr>
  6339. </table>
  6340. </div>
  6341. </div>
  6342.  
  6343. <?php
  6344. //for adding additional help content boxes
  6345. do_action('mp_help_page', $settings);
  6346. ?>
  6347. </div>
  6348. <?php
  6349. break;
  6350.  
  6351. //---------------------------------------------------//
  6352. case "importers":
  6353. ?>
  6354. <div class="icon32"><img src="<?php echo $this->plugin_url . 'images/import.png'; ?>" /></div>
  6355. <form id="mp-import-form" method="post" action="" enctype="multipart/form-data">
  6356. <h2><?php _e('Import Products', 'mp'); ?></h2>
  6357. <div id="poststuff" class="metabox-holder mp-importer">
  6358. <?php do_action('marketpress_add_importer'); ?>
  6359. </div>
  6360. </form>
  6361. </div>
  6362. <?php
  6363. break;
  6364.  
  6365. } //end switch
  6366.  
  6367. //hook to create a new admin screen.
  6368. do_action('marketpress_add_screen', $tab);
  6369.  
  6370. echo '</div>';
  6371.  
  6372. }
  6373.  
  6374. } //end class
  6375.  
  6376. global $mp;
  6377. $mp = new MarketPress();
  6378.  
  6379.  
  6380. //Shopping cart widget
  6381. class MarketPress_Shopping_Cart extends WP_Widget {
  6382.  
  6383. function MarketPress_Shopping_Cart() {
  6384. $widget_ops = array('classname' => 'mp_cart_widget', 'description' => __('Shows dynamic shopping cart contents along with a checkout button for your MarketPress store.', 'mp') );
  6385. $this->WP_Widget('mp_cart_widget', __('Shopping Cart', 'mp'), $widget_ops);
  6386. }
  6387.  
  6388. function widget($args, $instance) {
  6389. global $mp;
  6390. $settings = get_option('mp_settings');
  6391.  
  6392. if ( get_query_var('pagename') == 'cart' )
  6393. return;
  6394.  
  6395. if ($instance['only_store_pages'] && !mp_is_shop_page())
  6396. return;
  6397.  
  6398. extract( $args );
  6399.  
  6400. echo $before_widget;
  6401. $title = $instance['title'];
  6402. if ( !empty( $title ) ) { echo $before_title . apply_filters('widget_title', $title) . $after_title; };
  6403.  
  6404. if ( !empty($instance['custom_text']) )
  6405. echo '<div class="custom_text">' . $instance['custom_text'] . '</div>';
  6406.  
  6407. echo '<div class="mp_cart_widget_content">';
  6408. mp_show_cart('widget');
  6409. echo '</div>';
  6410.  
  6411. echo $after_widget;
  6412. }
  6413.  
  6414. function update( $new_instance, $old_instance ) {
  6415. $instance = $old_instance;
  6416. $instance['title'] = stripslashes( wp_filter_nohtml_kses( $new_instance['title']) );
  6417. $instance['custom_text'] = stripslashes( wp_filter_kses( $new_instance['custom_text']) );
  6418. $instance['only_store_pages'] = !empty($new_instance['only_store_pages']) ? 1 : 0;
  6419. /*
  6420. $instance['show_thumbnail'] = !empty($new_instance['show_thumbnail']) ? 1 : 0;
  6421. $instance['size'] = !empty($new_instance['size']) ? intval($new_instance['size']) : 25;
  6422. */
  6423.  
  6424. return $instance;
  6425. }
  6426.  
  6427. function form( $instance ) {
  6428. $instance = wp_parse_args( (array) $instance, array( 'title' => __('Shopping Cart', 'mp'), 'custom_text' => '', 'only_store_pages' => 0 ) );
  6429. $title = $instance['title'];
  6430. $custom_text = $instance['custom_text'];
  6431. $only_store_pages = isset( $instance['only_store_pages'] ) ? (bool) $instance['only_store_pages'] : false;
  6432. /*
  6433. $show_thumbnail = isset( $instance['show_thumbnail'] ) ? (bool) $instance['show_thumbnail'] : false;
  6434. $size = !empty($instance['size']) ? intval($instance['size']) : 25;
  6435. */
  6436. ?>
  6437. <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'mp') ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  6438. <p><label for="<?php echo $this->get_field_id('custom_text'); ?>"><?php _e('Custom Text:', 'mp') ?><br />
  6439. <textarea class="widefat" id="<?php echo $this->get_field_id('custom_text'); ?>" name="<?php echo $this->get_field_name('custom_text'); ?>"><?php echo esc_attr($custom_text); ?></textarea></label>
  6440. </p>
  6441. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('only_store_pages'); ?>" name="<?php echo $this->get_field_name('only_store_pages'); ?>"<?php checked( $only_store_pages ); ?> />
  6442. <label for="<?php echo $this->get_field_id('only_store_pages'); ?>"><?php _e( 'Only show on store pages', 'mp' ); ?></label></p>
  6443. <?php
  6444. /* Disable untill we can mod the cart
  6445. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('show_thumbnail'); ?>" name="<?php echo $this->get_field_name('show_thumbnail'); ?>"<?php checked( $show_thumbnail ); ?> />
  6446. <label for="<?php echo $this->get_field_id('show_thumbnail'); ?>"><?php _e( 'Show Thumbnail', 'mp' ); ?></label><br />
  6447. <label for="<?php echo $this->get_field_id('size'); ?>"><?php _e('Thumbnail Size:', 'mp') ?> <input id="<?php echo $this->get_field_id('size'); ?>" name="<?php echo $this->get_field_name('size'); ?>" type="text" size="3" value="<?php echo $size; ?>" /></label></p>
  6448. */
  6449. }
  6450. }
  6451.  
  6452. //Product listing widget
  6453. class MarketPress_Product_List extends WP_Widget {
  6454.  
  6455. function MarketPress_Product_List() {
  6456. $widget_ops = array('classname' => 'mp_product_list_widget', 'description' => __('Shows a customizable list of products from your MarketPress store.', 'mp') );
  6457. $this->WP_Widget('mp_product_list_widget', __('Product List', 'mp'), $widget_ops);
  6458. }
  6459.  
  6460. function widget($args, $instance) {
  6461. global $mp;
  6462. $settings = get_option('mp_settings');
  6463.  
  6464. if ($instance['only_store_pages'] && !mp_is_shop_page())
  6465. return;
  6466.  
  6467. extract( $args );
  6468.  
  6469. echo $before_widget;
  6470. $title = $instance['title'];
  6471. if ( !empty( $title ) ) { echo $before_title . apply_filters('widget_title', $title) . $after_title; };
  6472.  
  6473. if ( !empty($instance['custom_text']) )
  6474. echo '<div id="custom_text">' . $instance['custom_text'] . '</div>';
  6475.  
  6476. /* setup our custom query */
  6477.  
  6478. //setup taxonomy if applicable
  6479. if ($instance['taxonomy_type'] == 'category') {
  6480. $taxonomy_query = '&product_category=' . $instance['taxonomy'];
  6481. } else if ($instance['taxonomy_type'] == 'tag') {
  6482. $taxonomy_query = '&product_tag=' . $instance['taxonomy'];
  6483. }
  6484.  
  6485. //figure out perpage
  6486. if (isset($instance['num_products']) && intval($instance['num_products']) > 0) {
  6487. $paginate_query = '&posts_per_page='.intval($instance['num_products']).'&paged=1';
  6488. } else {
  6489. $paginate_query = '&posts_per_page=10&paged=1';
  6490. }
  6491.  
  6492. //get order by
  6493. if ($instance['order_by']) {
  6494. if ($instance['order_by'] == 'price')
  6495. $order_by_query = '&meta_key=mp_price&orderby=mp_price';
  6496. else if ($instance['order_by'] == 'sales')
  6497. $order_by_query = '&meta_key=mp_sales_count&orderby=mp_sales_count';
  6498. else
  6499. $order_by_query = '&orderby='.$instance['order_by'];
  6500. } else {
  6501. $order_by_query = '&orderby=title';
  6502. }
  6503.  
  6504. //get order direction
  6505. if ($instance['order']) {
  6506. $order_query = '&order='.$instance['order'];
  6507. } else {
  6508. $order_query = '&orderby=DESC';
  6509. }
  6510.  
  6511. //The Query
  6512. $custom_query = new WP_Query('post_type=product' . $taxonomy_query . $paginate_query . $order_by_query . $order_query);
  6513.  
  6514. //do we have products?
  6515. if (count($custom_query->posts)) {
  6516. echo '<ul id="mp_product_list">';
  6517. foreach ($custom_query->posts as $post) {
  6518.  
  6519. echo '<li '.mp_product_class(false, 'mp_product', $post->ID).'>';
  6520. echo '<h3 class="mp_product_name"><a href="' . get_permalink( $post->ID ) . '">' . esc_attr($post->post_title) . '</a></h3>';
  6521. if ($instance['show_thumbnail'])
  6522. mp_product_image( true, 'widget', $post->ID, $instance['size'] );
  6523.  
  6524. if ($instance['show_excerpt'])
  6525. echo '<div class="mp_product_content">' . $mp->product_excerpt($post->post_excerpt, $post->post_content, $post->ID) . '</div>';
  6526.  
  6527. if ($instance['show_price'] || $instance['show_button']) {
  6528. echo '<div class="mp_product_meta">';
  6529.  
  6530. if ($instance['show_price'])
  6531. echo mp_product_price(false, $post->ID, '');
  6532.  
  6533. if ($instance['show_button'])
  6534. echo mp_buy_button(false, 'list', $post->ID);
  6535.  
  6536. echo '</div>';
  6537. }
  6538. $content .= '</li>';
  6539. }
  6540. echo '</ul>';
  6541. } else {
  6542. ?>
  6543. <div class="widget-error">
  6544. <?php _e('No Products', 'mp') ?>
  6545. </div>
  6546. <?php
  6547. }
  6548.  
  6549. echo $after_widget;
  6550. }
  6551.  
  6552. function update( $new_instance, $old_instance ) {
  6553. $instance = $old_instance;
  6554. $instance['title'] = stripslashes( wp_filter_nohtml_kses( $new_instance['title'] ) );
  6555. $instance['custom_text'] = stripslashes( wp_filter_kses( $new_instance['custom_text'] ) );
  6556.  
  6557. $instance['num_products'] = intval($new_instance['num_products']);
  6558. $instance['order_by'] = $new_instance['order_by'];
  6559. $instance['order'] = $new_instance['order'];
  6560. $instance['taxonomy_type'] = $new_instance['taxonomy_type'];
  6561. $instance['taxonomy'] = ($new_instance['taxonomy_type']) ? sanitize_title($new_instance['taxonomy']) : '';
  6562.  
  6563. $instance['show_thumbnail'] = !empty($new_instance['show_thumbnail']) ? 1 : 0;
  6564. $instance['size'] = !empty($new_instance['size']) ? intval($new_instance['size']) : 50;
  6565. $instance['show_excerpt'] = !empty($new_instance['show_excerpt']) ? 1 : 0;
  6566. $instance['show_price'] = !empty($new_instance['show_price']) ? 1 : 0;
  6567. $instance['show_button'] = !empty($new_instance['show_button']) ? 1 : 0;
  6568.  
  6569. $instance['only_store_pages'] = !empty($new_instance['only_store_pages']) ? 1 : 0;
  6570.  
  6571. return $instance;
  6572. }
  6573.  
  6574. function form( $instance ) {
  6575. $instance = wp_parse_args( (array) $instance, array( 'title' => __('Our Products', 'mp'), 'custom_text' => '', 'num_products' => 10, 'order_by' => 'title', 'order' => 'DESC', 'show_thumbnail' => 1, 'size' => 50, 'only_store_pages' => 0 ) );
  6576. $title = $instance['title'];
  6577. $custom_text = $instance['custom_text'];
  6578.  
  6579. $num_products = intval($instance['num_products']);
  6580. $order_by = $instance['order_by'];
  6581. $order = $instance['order'];
  6582. $taxonomy_type = $instance['taxonomy_type'];
  6583. $taxonomy = $instance['taxonomy'];
  6584.  
  6585. $show_thumbnail = isset( $instance['show_thumbnail'] ) ? (bool) $instance['show_thumbnail'] : false;
  6586. $size = !empty($instance['size']) ? intval($instance['size']) : 50;
  6587. $show_excerpt = isset( $instance['show_excerpt'] ) ? (bool) $instance['show_excerpt'] : false;
  6588. $show_price = isset( $instance['show_price'] ) ? (bool) $instance['show_price'] : false;
  6589. $show_button = isset( $instance['show_button'] ) ? (bool) $instance['show_button'] : false;
  6590.  
  6591. $only_store_pages = isset( $instance['only_store_pages'] ) ? (bool) $instance['only_store_pages'] : false;
  6592. ?>
  6593. <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'mp') ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  6594. <p><label for="<?php echo $this->get_field_id('custom_text'); ?>"><?php _e('Custom Text:', 'mp') ?><br />
  6595. <textarea class="widefat" id="<?php echo $this->get_field_id('custom_text'); ?>" name="<?php echo $this->get_field_name('custom_text'); ?>"><?php echo esc_attr($custom_text); ?></textarea></label>
  6596. </p>
  6597.  
  6598. <h3><?php _e('List Settings', 'mp'); ?></h3>
  6599. <p>
  6600. <label for="<?php echo $this->get_field_id('num_products'); ?>"><?php _e('Number of Products:', 'mp') ?> <input id="<?php echo $this->get_field_id('num_products'); ?>" name="<?php echo $this->get_field_name('num_products'); ?>" type="text" size="3" value="<?php echo $num_products; ?>" /></label><br />
  6601. </p>
  6602. <p>
  6603. <label for="<?php echo $this->get_field_id('order_by'); ?>"><?php _e('Order Products By:', 'mp') ?></label><br />
  6604. <select id="<?php echo $this->get_field_id('order_by'); ?>" name="<?php echo $this->get_field_name('order_by'); ?>">
  6605. <option value="title"<?php selected($order_by, 'title') ?>><?php _e('Product Name', 'mp') ?></option>
  6606. <option value="date"<?php selected($order_by, 'date') ?>><?php _e('Publish Date', 'mp') ?></option>
  6607. <option value="ID"<?php selected($order_by, 'ID') ?>><?php _e('Product ID', 'mp') ?></option>
  6608. <option value="author"<?php selected($order_by, 'author') ?>><?php _e('Product Author', 'mp') ?></option>
  6609. <option value="sales"<?php selected($order_by, 'sales') ?>><?php _e('Number of Sales', 'mp') ?></option>
  6610. <option value="price"<?php selected($order_by, 'price') ?>><?php _e('Product Price', 'mp') ?></option>
  6611. <option value="rand"<?php selected($order_by, 'rand') ?>><?php _e('Random', 'mp') ?></option>
  6612. </select><br />
  6613. <label><input value="DESC" name="<?php echo $this->get_field_name('order'); ?>" type="radio"<?php checked($order, 'DESC') ?> /> <?php _e('Descending', 'mp') ?></label>
  6614. <label><input value="ASC" name="<?php echo $this->get_field_name('order'); ?>" type="radio"<?php checked($order, 'ASC') ?> /> <?php _e('Ascending', 'mp') ?></label>
  6615. </p>
  6616. <p>
  6617. <label><?php _e('Taxonomy Filter:', 'mp') ?></label><br />
  6618. <select id="<?php echo $this->get_field_id('taxonomy_type'); ?>" name="<?php echo $this->get_field_name('taxonomy_type'); ?>">
  6619. <option value=""<?php selected($taxonomy_type, '') ?>><?php _e('No Filter', 'mp') ?></option>
  6620. <option value="category"<?php selected($taxonomy_type, 'category') ?>><?php _e('Category', 'mp') ?></option>
  6621. <option value="tag"<?php selected($taxonomy_type, 'tag') ?>><?php _e('Tag', 'mp') ?></option>
  6622. </select>
  6623. <input id="<?php echo $this->get_field_id('taxonomy'); ?>" name="<?php echo $this->get_field_name('taxonomy'); ?>" type="text" size="17" value="<?php echo $taxonomy; ?>" title="<?php _e('Enter the Slug', 'mp'); ?>" />
  6624. </p>
  6625.  
  6626. <h3><?php _e('Display Settings', 'mp'); ?></h3>
  6627. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('show_thumbnail'); ?>" name="<?php echo $this->get_field_name('show_thumbnail'); ?>"<?php checked( $show_thumbnail ); ?> />
  6628. <label for="<?php echo $this->get_field_id('show_thumbnail'); ?>"><?php _e( 'Show Thumbnail', 'mp' ); ?></label><br />
  6629. <label for="<?php echo $this->get_field_id('size'); ?>"><?php _e('Thumbnail Size:', 'mp') ?> <input id="<?php echo $this->get_field_id('size'); ?>" name="<?php echo $this->get_field_name('size'); ?>" type="text" size="3" value="<?php echo $size; ?>" /></label></p>
  6630.  
  6631. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('show_excerpt'); ?>" name="<?php echo $this->get_field_name('show_excerpt'); ?>"<?php checked( $show_excerpt ); ?> />
  6632. <label for="<?php echo $this->get_field_id('show_excerpt'); ?>"><?php _e( 'Show Excerpt', 'mp' ); ?></label><br />
  6633. <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('show_price'); ?>" name="<?php echo $this->get_field_name('show_price'); ?>"<?php checked( $show_price ); ?> />
  6634. <label for="<?php echo $this->get_field_id('show_price'); ?>"><?php _e( 'Show Price', 'mp' ); ?></label><br />
  6635. <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('show_button'); ?>" name="<?php echo $this->get_field_name('show_button'); ?>"<?php checked( $show_button ); ?> />
  6636. <label for="<?php echo $this->get_field_id('show_button'); ?>"><?php _e( 'Show Buy Button', 'mp' ); ?></label></p>
  6637.  
  6638. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('only_store_pages'); ?>" name="<?php echo $this->get_field_name('only_store_pages'); ?>"<?php checked( $only_store_pages ); ?> />
  6639. <label for="<?php echo $this->get_field_id('only_store_pages'); ?>"><?php _e( 'Only show on store pages', 'mp' ); ?></label></p>
  6640. <?php
  6641. }
  6642. }
  6643.  
  6644. //Product categories widget
  6645. class MarketPress_Categories_Widget extends WP_Widget {
  6646.  
  6647. function MarketPress_Categories_Widget() {
  6648. $widget_ops = array( 'classname' => 'mp_categories_widget', 'description' => __( "A list or dropdown of product categories from your MarketPress store.", 'mp' ) );
  6649. $this->WP_Widget('mp_categories_widget', __('Product Categories', 'mp'), $widget_ops);
  6650. }
  6651.  
  6652. function widget( $args, $instance ) {
  6653.  
  6654. if ($instance['only_store_pages'] && !mp_is_shop_page())
  6655. return;
  6656.  
  6657. extract( $args );
  6658.  
  6659. $title = apply_filters('widget_title', empty( $instance['title'] ) ? __('Product Categories', 'mp') : $instance['title'], $instance, $this->id_base);
  6660. $c = $instance['count'] ? '1' : '0';
  6661. $h = $instance['hierarchical'] ? '1' : '0';
  6662. $d = $instance['dropdown'] ? '1' : '0';
  6663.  
  6664. echo $before_widget;
  6665. if ( $title )
  6666. echo $before_title . $title . $after_title;
  6667.  
  6668. $cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h);
  6669.  
  6670. if ( $d ) {
  6671. $cat_args['show_option_none'] = __('Select Category');
  6672. $cat_args['taxonomy'] = 'product_category';
  6673. $cat_args['id'] = 'mp_category_dropdown';
  6674. mp_dropdown_categories( true, $cat_args );
  6675. } else {
  6676. ?>
  6677. <ul id="mp_category_list">
  6678. <?php
  6679. $cat_args['title_li'] = '';
  6680. $cat_args['taxonomy'] = 'product_category';
  6681. wp_list_categories( $cat_args );
  6682. ?>
  6683. </ul>
  6684. <?php
  6685. }
  6686.  
  6687. echo $after_widget;
  6688. }
  6689.  
  6690. function update( $new_instance, $old_instance ) {
  6691. $instance = $old_instance;
  6692. $instance['title'] = strip_tags($new_instance['title']);
  6693. $instance['count'] = !empty($new_instance['count']) ? 1 : 0;
  6694. $instance['hierarchical'] = !empty($new_instance['hierarchical']) ? 1 : 0;
  6695. $instance['dropdown'] = !empty($new_instance['dropdown']) ? 1 : 0;
  6696. $instance['only_store_pages'] = !empty($new_instance['only_store_pages']) ? 1 : 0;
  6697.  
  6698. return $instance;
  6699. }
  6700.  
  6701. function form( $instance ) {
  6702. //Defaults
  6703. $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'only_store_pages' => 0 ) );
  6704. $title = esc_attr( $instance['title'] );
  6705. $count = isset($instance['count']) ? (bool) $instance['count'] :false;
  6706. $hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
  6707. $dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
  6708. $only_store_pages = isset( $instance['only_store_pages'] ) ? (bool) $instance['only_store_pages'] : false;
  6709. ?>
  6710. <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:' ); ?></label>
  6711. <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
  6712.  
  6713. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> />
  6714. <label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Show as dropdown' ); ?></label><br />
  6715.  
  6716. <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> />
  6717. <label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show product counts', 'mp' ); ?></label><br />
  6718.  
  6719. <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> />
  6720. <label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p>
  6721.  
  6722. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('only_store_pages'); ?>" name="<?php echo $this->get_field_name('only_store_pages'); ?>"<?php checked( $only_store_pages ); ?> />
  6723. <label for="<?php echo $this->get_field_id('only_store_pages'); ?>"><?php _e( 'Only show on store pages', 'mp' ); ?></label></p>
  6724. <?php
  6725. }
  6726. }
  6727.  
  6728. //Product tags cloud
  6729. class MarketPress_Tag_Cloud_Widget extends WP_Widget {
  6730.  
  6731. function MarketPress_Tag_Cloud_Widget() {
  6732. $widget_ops = array( 'classname' => 'mp_tag_cloud_widget', 'description' => __( "Your most used product tags in cloud format from your MarketPress store.") );
  6733. $this->WP_Widget('mp_tag_cloud_widget', __('Product Tag Cloud', 'mp'), $widget_ops);
  6734. }
  6735.  
  6736. function widget( $args, $instance ) {
  6737.  
  6738. if ($instance['only_store_pages'] && !mp_is_shop_page())
  6739. return;
  6740.  
  6741. extract($args);
  6742. $current_taxonomy = 'product_tag';
  6743. if ( !empty($instance['title']) ) {
  6744. $title = $instance['title'];
  6745. }
  6746. $title = apply_filters('widget_title', $title, $instance, $this->id_base);
  6747.  
  6748. echo $before_widget;
  6749. if ( $title )
  6750. echo $before_title . $title . $after_title;
  6751. echo '<div>';
  6752. wp_tag_cloud( apply_filters('widget_tag_cloud_args', array('taxonomy' => $current_taxonomy) ) );
  6753. echo "</div>\n";
  6754. echo $after_widget;
  6755. }
  6756.  
  6757. function update( $new_instance, $old_instance ) {
  6758. $instance['title'] = strip_tags(stripslashes($new_instance['title']));
  6759. $instance['only_store_pages'] = !empty($new_instance['only_store_pages']) ? 1 : 0;
  6760. return $instance;
  6761. }
  6762.  
  6763. function form( $instance ) {
  6764. $instance = wp_parse_args( (array) $instance, array( 'title' => __('Product Tags', 'mp'), 'only_store_pages' => 0 ) );
  6765. $only_store_pages = isset( $instance['only_store_pages'] ) ? (bool) $instance['only_store_pages'] : false;
  6766. ?>
  6767. <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
  6768. <input type="text" class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php if (isset ( $instance['title'])) {echo esc_attr( $instance['title'] );} ?>" /></p>
  6769.  
  6770. <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('only_store_pages'); ?>" name="<?php echo $this->get_field_name('only_store_pages'); ?>"<?php checked( $only_store_pages ); ?> />
  6771. <label for="<?php echo $this->get_field_id('only_store_pages'); ?>"><?php _e( 'Only show on store pages', 'mp' ); ?></label></p>
  6772. <?php
  6773. }
  6774. }
  6775.  
  6776. ///////////////////////////////////////////////////////////////////////////
  6777.  
  6778. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement