PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/theme WP a cương/test_wp/wp-content/plugins/woocommerce/woocommerce.php

https://gitlab.com/hop23typhu/list-theme
PHP | 1438 lines | 807 code | 214 blank | 417 comment | 97 complexity | a89e3625b950bd3ec5ba7f55f20dff4a MD5 | raw file
  1. <?php
  2. /**
  3. * Plugin Name: WooCommerce
  4. * Plugin URI: http://www.woothemes.com/woocommerce/
  5. * Description: An e-commerce toolkit that helps you sell anything. Beautifully.
  6. * Version: 2.0.14
  7. * Author: WooThemes
  8. * Author URI: http://woothemes.com
  9. * Requires at least: 3.5
  10. * Tested up to: 3.5
  11. *
  12. * Text Domain: woocommerce
  13. * Domain Path: /i18n/languages/
  14. *
  15. * @package WooCommerce
  16. * @category Core
  17. * @author WooThemes
  18. */
  19. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  20. if ( ! class_exists( 'Woocommerce' ) ) {
  21. /**
  22. * Main WooCommerce Class
  23. *
  24. * Contains the main functions for WooCommerce, stores variables, and handles error messages
  25. *
  26. * @class Woocommerce
  27. * @version 2.0.0
  28. * @since 1.4
  29. * @package WooCommerce
  30. * @author WooThemes
  31. */
  32. class Woocommerce {
  33. /**
  34. * @var string
  35. */
  36. public $version = '2.0.14';
  37. /**
  38. * @var string
  39. */
  40. public $plugin_url;
  41. /**
  42. * @var string
  43. */
  44. public $plugin_path;
  45. /**
  46. * @var string
  47. */
  48. public $template_url;
  49. /**
  50. * @var array
  51. */
  52. public $errors = array();
  53. /**
  54. * @var array
  55. */
  56. public $messages = array();
  57. /**
  58. * @var WC_Query
  59. */
  60. public $query;
  61. /**
  62. * @var WC_Customer
  63. */
  64. public $customer;
  65. /**
  66. * @var WC_Product_Factory
  67. */
  68. public $product_factory;
  69. /**
  70. * @var WC_Cart
  71. */
  72. public $cart;
  73. /**
  74. * @var WC_Countries
  75. */
  76. public $countries;
  77. /**
  78. * @var WC_Email
  79. */
  80. public $woocommerce_email;
  81. /**
  82. * @var WC_Checkout
  83. */
  84. public $checkout;
  85. /**
  86. * @var WC_Integrations
  87. */
  88. public $integrations;
  89. /**
  90. * @var array
  91. */
  92. private $_body_classes = array();
  93. /**
  94. * @var string
  95. */
  96. private $_inline_js = '';
  97. /**
  98. * WooCommerce Constructor.
  99. *
  100. * @access public
  101. * @return void
  102. */
  103. public function __construct() {
  104. // Auto-load classes on demand
  105. if ( function_exists( "__autoload" ) ) {
  106. spl_autoload_register( "__autoload" );
  107. }
  108. spl_autoload_register( array( $this, 'autoload' ) );
  109. // Define version constant
  110. define( 'WOOCOMMERCE_VERSION', $this->version );
  111. // Installation
  112. register_activation_hook( __FILE__, array( $this, 'activate' ) );
  113. // Updates
  114. add_action( 'admin_init', array( $this, 'update' ), 5 );
  115. // Include required files
  116. $this->includes();
  117. // Init API
  118. $this->api = new WC_API();
  119. // Hooks
  120. add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'action_links' ) );
  121. add_filter( 'woocommerce_shipping_methods', array( $this, 'core_shipping' ) );
  122. add_filter( 'woocommerce_payment_gateways', array( $this, 'core_gateways' ) );
  123. add_action( 'widgets_init', array( $this, 'register_widgets' ) );
  124. add_action( 'init', array( $this, 'init' ), 0 );
  125. add_action( 'init', array( $this, 'include_template_functions' ), 25 );
  126. add_action( 'after_setup_theme', array( $this, 'compatibility' ) );
  127. // Loaded action
  128. do_action( 'woocommerce_loaded' );
  129. }
  130. /**
  131. * action_links function.
  132. *
  133. * @access public
  134. * @param mixed $links
  135. * @return void
  136. */
  137. public function action_links( $links ) {
  138. $plugin_links = array(
  139. '<a href="' . admin_url( 'admin.php?page=woocommerce_settings' ) . '">' . __( 'Settings', 'woocommerce' ) . '</a>',
  140. '<a href="http://docs.woothemes.com/documentation/plugins/woocommerce/">' . __( 'Docs', 'woocommerce' ) . '</a>',
  141. '<a href="http://support.woothemes.com/">' . __( 'Premium Support', 'woocommerce' ) . '</a>',
  142. );
  143. return array_merge( $plugin_links, $links );
  144. }
  145. /**
  146. * Auto-load in-accessible properties on demand.
  147. *
  148. * @access public
  149. * @param mixed $key
  150. * @return mixed
  151. */
  152. public function __get( $key ) {
  153. if ( 'payment_gateways' == $key ) {
  154. return $this->payment_gateways();
  155. }
  156. elseif ( 'shipping' == $key ) {
  157. return $this->shipping();
  158. }
  159. return false;
  160. }
  161. /**
  162. * Auto-load WC classes on demand to reduce memory consumption.
  163. *
  164. * @access public
  165. * @param mixed $class
  166. * @return void
  167. */
  168. public function autoload( $class ) {
  169. $class = strtolower( $class );
  170. if ( strpos( $class, 'wc_gateway_' ) === 0 ) {
  171. $path = $this->plugin_path() . '/classes/gateways/' . trailingslashit( substr( str_replace( '_', '-', $class ), 11 ) );
  172. $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
  173. if ( is_readable( $path . $file ) ) {
  174. include_once( $path . $file );
  175. return;
  176. }
  177. } elseif ( strpos( $class, 'wc_shipping_' ) === 0 ) {
  178. $path = $this->plugin_path() . '/classes/shipping/' . trailingslashit( substr( str_replace( '_', '-', $class ), 12 ) );
  179. $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
  180. if ( is_readable( $path . $file ) ) {
  181. include_once( $path . $file );
  182. return;
  183. }
  184. } elseif ( strpos( $class, 'wc_shortcode_' ) === 0 ) {
  185. $path = $this->plugin_path() . '/classes/shortcodes/';
  186. $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
  187. if ( is_readable( $path . $file ) ) {
  188. include_once( $path . $file );
  189. return;
  190. }
  191. }
  192. if ( strpos( $class, 'wc_' ) === 0 ) {
  193. $path = $this->plugin_path() . '/classes/';
  194. $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
  195. if ( is_readable( $path . $file ) ) {
  196. include_once( $path . $file );
  197. return;
  198. }
  199. }
  200. }
  201. /**
  202. * activate function.
  203. *
  204. * @access public
  205. * @return void
  206. */
  207. public function activate() {
  208. if ( woocommerce_get_page_id( 'shop' ) < 1 )
  209. update_option( '_wc_needs_pages', 1 );
  210. $this->install();
  211. }
  212. /**
  213. * update function.
  214. *
  215. * @access public
  216. * @return void
  217. */
  218. public function update() {
  219. if ( ! defined( 'IFRAME_REQUEST' ) && ( get_option( 'woocommerce_version' ) != $this->version || get_option( 'woocommerce_db_version' ) != $this->version ) )
  220. $this->install();
  221. }
  222. /**
  223. * upgrade function.
  224. *
  225. * @access public
  226. * @return void
  227. */
  228. function install() {
  229. include_once( 'admin/woocommerce-admin-install.php' );
  230. set_transient( '_wc_activation_redirect', 1, 60 * 60 );
  231. do_install_woocommerce();
  232. }
  233. /**
  234. * Include required core files used in admin and on the frontend.
  235. *
  236. * @access public
  237. * @return void
  238. */
  239. function includes() {
  240. if ( is_admin() )
  241. $this->admin_includes();
  242. if ( defined('DOING_AJAX') )
  243. $this->ajax_includes();
  244. if ( ! is_admin() || defined('DOING_AJAX') )
  245. $this->frontend_includes();
  246. // Functions
  247. include_once( 'woocommerce-core-functions.php' ); // Contains core functions for the front/back end
  248. // API Class
  249. include_once( 'classes/class-wc-api.php' );
  250. // Include abstract classes
  251. include_once( 'classes/abstracts/abstract-wc-product.php' ); // Products
  252. include_once( 'classes/abstracts/abstract-wc-settings-api.php' ); // Settings API (for gateways, shipping, and integrations)
  253. include_once( 'classes/abstracts/abstract-wc-shipping-method.php' ); // A Shipping method
  254. include_once( 'classes/abstracts/abstract-wc-payment-gateway.php' ); // A Payment gateway
  255. include_once( 'classes/abstracts/abstract-wc-integration.php' ); // An integration with a service
  256. // Classes (used on all pages)
  257. include_once( 'classes/class-wc-product-factory.php' ); // Product factory
  258. include_once( 'classes/class-wc-countries.php' ); // Defines countries and states
  259. include_once( 'classes/class-wc-integrations.php' ); // Loads integrations
  260. include_once( 'classes/class-wc-cache-helper.php' ); // Cache Helper
  261. // Include Core Integrations - these are included sitewide
  262. include_once( 'classes/integrations/google-analytics/class-wc-google-analytics.php' );
  263. include_once( 'classes/integrations/sharethis/class-wc-sharethis.php' );
  264. include_once( 'classes/integrations/shareyourcart/class-wc-shareyourcart.php' );
  265. include_once( 'classes/integrations/sharedaddy/class-wc-sharedaddy.php' );
  266. }
  267. /**
  268. * Include required admin files.
  269. *
  270. * @access public
  271. * @return void
  272. */
  273. public function admin_includes() {
  274. include_once( 'admin/woocommerce-admin-init.php' ); // Admin section
  275. }
  276. /**
  277. * Include required ajax files.
  278. *
  279. * @access public
  280. * @return void
  281. */
  282. public function ajax_includes() {
  283. include_once( 'woocommerce-ajax.php' ); // Ajax functions for admin and the front-end
  284. }
  285. /**
  286. * Include required frontend files.
  287. *
  288. * @access public
  289. * @return void
  290. */
  291. public function frontend_includes() {
  292. // Functions
  293. include_once( 'woocommerce-hooks.php' ); // Template hooks used on the front-end
  294. include_once( 'woocommerce-functions.php' ); // Contains functions for various front-end events
  295. // Classes
  296. include_once( 'classes/class-wc-query.php' ); // The main store queries
  297. include_once( 'classes/class-wc-cart.php' ); // The main cart class
  298. include_once( 'classes/class-wc-tax.php' ); // Tax class
  299. include_once( 'classes/class-wc-customer.php' ); // Customer class
  300. include_once( 'classes/abstracts/abstract-wc-session.php' ); // Abstract for session implementations
  301. include_once( 'classes/class-wc-session-handler.php' ); // WC Session class
  302. include_once( 'classes/class-wc-shortcodes.php' ); // Shortcodes class
  303. }
  304. /**
  305. * Function used to Init WooCommerce Template Functions - This makes them pluggable by plugins and themes.
  306. *
  307. * @access public
  308. * @return void
  309. */
  310. public function include_template_functions() {
  311. include_once( 'woocommerce-template.php' );
  312. }
  313. /**
  314. * core_gateways function.
  315. *
  316. * @access public
  317. * @param mixed $methods
  318. * @return void
  319. */
  320. function core_gateways( $methods ) {
  321. $methods[] = 'WC_Gateway_BACS';
  322. $methods[] = 'WC_Gateway_Cheque';
  323. $methods[] = 'WC_Gateway_COD';
  324. $methods[] = 'WC_Gateway_Mijireh';
  325. $methods[] = 'WC_Gateway_Paypal';
  326. return $methods;
  327. }
  328. /**
  329. * core_shipping function.
  330. *
  331. * @access public
  332. * @param mixed $methods
  333. * @return void
  334. */
  335. function core_shipping( $methods ) {
  336. $methods[] = 'WC_Shipping_Flat_Rate';
  337. $methods[] = 'WC_Shipping_Free_Shipping';
  338. $methods[] = 'WC_Shipping_International_Delivery';
  339. $methods[] = 'WC_Shipping_Local_Delivery';
  340. $methods[] = 'WC_Shipping_Local_Pickup';
  341. return $methods;
  342. }
  343. /**
  344. * register_widgets function.
  345. *
  346. * @access public
  347. * @return void
  348. */
  349. function register_widgets() {
  350. // Include - no need to use autoload as WP loads them anyway
  351. include_once( 'classes/widgets/class-wc-widget-cart.php' );
  352. include_once( 'classes/widgets/class-wc-widget-featured-products.php' );
  353. include_once( 'classes/widgets/class-wc-widget-layered-nav.php' );
  354. include_once( 'classes/widgets/class-wc-widget-layered-nav-filters.php' );
  355. include_once( 'classes/widgets/class-wc-widget-price-filter.php' );
  356. include_once( 'classes/widgets/class-wc-widget-product-categories.php' );
  357. include_once( 'classes/widgets/class-wc-widget-product-search.php' );
  358. include_once( 'classes/widgets/class-wc-widget-product-tag-cloud.php' );
  359. include_once( 'classes/widgets/class-wc-widget-recent-products.php' );
  360. include_once( 'classes/widgets/class-wc-widget-top-rated-products.php' );
  361. include_once( 'classes/widgets/class-wc-widget-recent-reviews.php' );
  362. include_once( 'classes/widgets/class-wc-widget-recently-viewed.php' );
  363. include_once( 'classes/widgets/class-wc-widget-best-sellers.php' );
  364. include_once( 'classes/widgets/class-wc-widget-onsale.php' );
  365. include_once( 'classes/widgets/class-wc-widget-random-products.php' );
  366. // Register widgets
  367. register_widget( 'WC_Widget_Recent_Products' );
  368. register_widget( 'WC_Widget_Featured_Products' );
  369. register_widget( 'WC_Widget_Product_Categories' );
  370. register_widget( 'WC_Widget_Product_Tag_Cloud' );
  371. register_widget( 'WC_Widget_Cart' );
  372. register_widget( 'WC_Widget_Layered_Nav' );
  373. register_widget( 'WC_Widget_Layered_Nav_Filters' );
  374. register_widget( 'WC_Widget_Price_Filter' );
  375. register_widget( 'WC_Widget_Product_Search' );
  376. register_widget( 'WC_Widget_Top_Rated_Products' );
  377. register_widget( 'WC_Widget_Recent_Reviews' );
  378. register_widget( 'WC_Widget_Recently_Viewed' );
  379. register_widget( 'WC_Widget_Best_Sellers' );
  380. register_widget( 'WC_Widget_Onsale' );
  381. register_widget( 'WC_Widget_Random_Products' );
  382. }
  383. /**
  384. * Init WooCommerce when WordPress Initialises.
  385. *
  386. * @access public
  387. * @return void
  388. */
  389. public function init() {
  390. //Before init action
  391. do_action( 'before_woocommerce_init' );
  392. // Set up localisation
  393. $this->load_plugin_textdomain();
  394. // Variables
  395. $this->template_url = apply_filters( 'woocommerce_template_url', 'woocommerce/' );
  396. // Load class instances
  397. $this->product_factory = new WC_Product_Factory(); // Product Factory to create new product instances
  398. $this->countries = new WC_Countries(); // Countries class
  399. $this->integrations = new WC_Integrations(); // Integrations class
  400. // Classes/actions loaded for the frontend and for ajax requests
  401. if ( ! is_admin() || defined('DOING_AJAX') ) {
  402. // Session class, handles session data for customers - can be overwritten if custom handler is needed
  403. $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
  404. $this->session = new $session_class();
  405. // Class instances
  406. $this->cart = new WC_Cart(); // Cart class, stores the cart contents
  407. $this->customer = new WC_Customer(); // Customer class, handles data such as customer location
  408. $this->query = new WC_Query(); // Query class, handles front-end queries and loops
  409. $this->shortcodes = new WC_Shortcodes(); // Shortcodes class, controls all frontend shortcodes
  410. // Load messages
  411. $this->load_messages();
  412. // Hooks
  413. add_action( 'get_header', array( $this, 'init_checkout' ) );
  414. add_filter( 'template_include', array( $this, 'template_loader' ) );
  415. add_filter( 'comments_template', array( $this, 'comments_template_loader' ) );
  416. add_filter( 'wp_redirect', array( $this, 'redirect' ), 1, 2 );
  417. add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
  418. add_action( 'wp_print_scripts', array( $this, 'check_jquery' ), 25 );
  419. add_action( 'wp_head', array( $this, 'generator' ) );
  420. add_action( 'wp_head', array( $this, 'wp_head' ) );
  421. add_filter( 'body_class', array( $this, 'output_body_class' ) );
  422. add_filter( 'post_class', array( $this, 'post_class' ), 20, 3 );
  423. add_action( 'wp_footer', array( $this, 'output_inline_js' ), 25 );
  424. // HTTPS urls with SSL on
  425. $filters = array( 'post_thumbnail_html', 'widget_text', 'wp_get_attachment_url', 'wp_get_attachment_image_attributes', 'wp_get_attachment_url', 'option_stylesheet_url', 'option_template_url', 'script_loader_src', 'style_loader_src', 'template_directory_uri', 'stylesheet_directory_uri', 'site_url' );
  426. foreach ( $filters as $filter )
  427. add_filter( $filter, array( $this, 'force_ssl' ) );
  428. }
  429. // Actions
  430. add_action( 'the_post', array( $this, 'setup_product_data' ) );
  431. add_action( 'admin_footer', array( $this, 'output_inline_js' ), 25 );
  432. // Email Actions
  433. $email_actions = array( 'woocommerce_low_stock', 'woocommerce_no_stock', 'woocommerce_product_on_backorder', 'woocommerce_order_status_pending_to_processing', 'woocommerce_order_status_pending_to_completed', 'woocommerce_order_status_pending_to_on-hold', 'woocommerce_order_status_failed_to_processing', 'woocommerce_order_status_failed_to_completed', 'woocommerce_order_status_pending_to_processing', 'woocommerce_order_status_pending_to_on-hold', 'woocommerce_order_status_completed', 'woocommerce_new_customer_note' );
  434. foreach ( $email_actions as $action )
  435. add_action( $action, array( $this, 'send_transactional_email') );
  436. // Register globals for WC environment
  437. $this->register_globals();
  438. // Init WooCommerce taxonomies
  439. $this->init_taxonomy();
  440. // Init Images sizes
  441. $this->init_image_sizes();
  442. // Init action
  443. do_action( 'woocommerce_init' );
  444. }
  445. /**
  446. * During checkout, ensure gateways and shipping classes are loaded so they can hook into the respective pages.
  447. *
  448. * @access public
  449. * @return void
  450. */
  451. public function init_checkout() {
  452. if ( is_checkout() || is_order_received_page() ) {
  453. $this->payment_gateways();
  454. $this->shipping();
  455. }
  456. }
  457. /**
  458. * Load Localisation files.
  459. *
  460. * Note: the first-loaded translation file overrides any following ones if the same translation is present
  461. *
  462. * @access public
  463. * @return void
  464. */
  465. public function load_plugin_textdomain() {
  466. $locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce' );
  467. $formal = 'yes' == get_option( 'woocommerce_informal_localisation_type' ) ? 'informal' : 'formal';
  468. load_textdomain( 'woocommerce', WP_LANG_DIR . "/woocommerce/woocommerce-$locale.mo" );
  469. // Load admin specific MO files
  470. if ( is_admin() ) {
  471. load_textdomain( 'woocommerce', WP_LANG_DIR . "/woocommerce/woocommerce-admin-$locale.mo" );
  472. load_textdomain( 'woocommerce', $this->plugin_path() . "/i18n/languages/woocommerce-admin-$locale.mo" );
  473. }
  474. load_plugin_textdomain( 'woocommerce', false, dirname( plugin_basename( __FILE__ ) ) . "/i18n/languages/$formal" );
  475. load_plugin_textdomain( 'woocommerce', false, dirname( plugin_basename( __FILE__ ) ) . "/i18n/languages" );
  476. }
  477. /**
  478. * Load a template.
  479. *
  480. * Handles template usage so that we can use our own templates instead of the themes.
  481. *
  482. * Templates are in the 'templates' folder. woocommerce looks for theme
  483. * overrides in /theme/woocommerce/ by default
  484. *
  485. * For beginners, it also looks for a woocommerce.php template first. If the user adds
  486. * this to the theme (containing a woocommerce() inside) this will be used for all
  487. * woocommerce templates.
  488. *
  489. * @access public
  490. * @param mixed $template
  491. * @return string
  492. */
  493. public function template_loader( $template ) {
  494. $find = array( 'woocommerce.php' );
  495. $file = '';
  496. if ( is_single() && get_post_type() == 'product' ) {
  497. $file = 'single-product.php';
  498. $find[] = $file;
  499. $find[] = $this->template_url . $file;
  500. } elseif ( is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
  501. $term = get_queried_object();
  502. $file = 'taxonomy-' . $term->taxonomy . '.php';
  503. $find[] = 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
  504. $find[] = $this->template_url . 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
  505. $find[] = $file;
  506. $find[] = $this->template_url . $file;
  507. } elseif ( is_post_type_archive( 'product' ) || is_page( woocommerce_get_page_id( 'shop' ) ) ) {
  508. $file = 'archive-product.php';
  509. $find[] = $file;
  510. $find[] = $this->template_url . $file;
  511. }
  512. if ( $file ) {
  513. $template = locate_template( $find );
  514. if ( ! $template ) $template = $this->plugin_path() . '/templates/' . $file;
  515. }
  516. return $template;
  517. }
  518. /**
  519. * comments_template_loader function.
  520. *
  521. * @access public
  522. * @param mixed $template
  523. * @return string
  524. */
  525. public function comments_template_loader( $template ) {
  526. if ( get_post_type() !== 'product' )
  527. return $template;
  528. if ( file_exists( STYLESHEETPATH . '/' . $this->template_url . 'single-product-reviews.php' ))
  529. return STYLESHEETPATH . '/' . $this->template_url . 'single-product-reviews.php';
  530. elseif ( file_exists( TEMPLATEPATH . '/' . $this->template_url . 'single-product-reviews.php' ))
  531. return TEMPLATEPATH . '/' . $this->template_url . 'single-product-reviews.php';
  532. else
  533. return $this->plugin_path() . '/templates/single-product-reviews.php';
  534. }
  535. /**
  536. * Register WC environment globals.
  537. *
  538. * @access public
  539. * @return void
  540. */
  541. public function register_globals() {
  542. $GLOBALS['product'] = null;
  543. }
  544. /**
  545. * When the_post is called, get product data too.
  546. *
  547. * @access public
  548. * @param mixed $post
  549. * @return WC_Product
  550. */
  551. public function setup_product_data( $post ) {
  552. if ( is_int( $post ) ) $post = get_post( $post );
  553. if ( $post->post_type !== 'product' ) return;
  554. unset( $GLOBALS['product'] );
  555. $GLOBALS['product'] = get_product( $post );
  556. return $GLOBALS['product'];
  557. }
  558. /**
  559. * Add Compatibility for various bits.
  560. *
  561. * @access public
  562. * @return void
  563. */
  564. public function compatibility() {
  565. // Post thumbnail support
  566. if ( ! current_theme_supports( 'post-thumbnails', 'product' ) ) {
  567. add_theme_support( 'post-thumbnails' );
  568. remove_post_type_support( 'post', 'thumbnail' );
  569. remove_post_type_support( 'page', 'thumbnail' );
  570. } else {
  571. add_post_type_support( 'product', 'thumbnail' );
  572. }
  573. // IIS
  574. if ( ! isset($_SERVER['REQUEST_URI'] ) ) {
  575. $_SERVER['REQUEST_URI'] = substr( $_SERVER['PHP_SELF'], 1 );
  576. if ( isset( $_SERVER['QUERY_STRING'] ) )
  577. $_SERVER['REQUEST_URI'].='?'.$_SERVER['QUERY_STRING'];
  578. }
  579. // NGINX Proxy
  580. if ( ! isset( $_SERVER['REMOTE_ADDR'] ) && isset( $_SERVER['HTTP_REMOTE_ADDR'] ) )
  581. $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_REMOTE_ADDR'];
  582. if ( ! isset( $_SERVER['HTTPS'] ) && ! empty( $_SERVER['HTTP_HTTPS'] ) )
  583. $_SERVER['HTTPS'] = $_SERVER['HTTP_HTTPS'];
  584. // Support for hosts which don't use HTTPS, and use HTTP_X_FORWARDED_PROTO
  585. if ( ! isset( $_SERVER['HTTPS'] ) && ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' )
  586. $_SERVER['HTTPS'] = '1';
  587. }
  588. /**
  589. * Output generator to aid debugging.
  590. *
  591. * @access public
  592. * @return void
  593. */
  594. public function generator() {
  595. echo "\n\n" . '<!-- WooCommerce Version -->' . "\n" . '<meta name="generator" content="WooCommerce ' . esc_attr( $this->version ) . '" />' . "\n\n";
  596. }
  597. /**
  598. * Add body classes.
  599. *
  600. * @access public
  601. * @return void
  602. */
  603. public function wp_head() {
  604. if ( is_woocommerce() ) {
  605. $this->add_body_class( 'woocommerce' );
  606. $this->add_body_class( 'woocommerce-page' );
  607. return;
  608. }
  609. if ( is_checkout() || is_order_received_page() ) {
  610. $this->add_body_class( 'woocommerce-checkout' );
  611. $this->add_body_class( 'woocommerce-page' );
  612. return;
  613. }
  614. if ( is_cart() ) {
  615. $this->add_body_class( 'woocommerce-cart' );
  616. $this->add_body_class( 'woocommerce-page' );
  617. return;
  618. }
  619. if ( is_account_page() ) {
  620. $this->add_body_class( 'woocommerce-account' );
  621. $this->add_body_class( 'woocommerce-page' );
  622. return;
  623. }
  624. }
  625. /**
  626. * Init WooCommerce taxonomies.
  627. *
  628. * @access public
  629. * @return void
  630. */
  631. public function init_taxonomy() {
  632. if ( post_type_exists('product') )
  633. return;
  634. /**
  635. * Slugs
  636. **/
  637. $permalinks = get_option( 'woocommerce_permalinks' );
  638. $shop_page_id = woocommerce_get_page_id( 'shop' );
  639. // Base slug is also used for the product post type archive
  640. $base_slug = $shop_page_id > 0 && get_page( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop';
  641. // Get bases
  642. $product_category_slug = empty( $permalinks['category_base'] ) ? _x( 'product-category', 'slug', 'woocommerce' ) : $permalinks['category_base'];
  643. $product_tag_slug = empty( $permalinks['tag_base'] ) ? _x( 'product-tag', 'slug', 'woocommerce' ) : $permalinks['tag_base'];
  644. $product_attribute_base = empty( $permalinks['attribute_base'] ) ? '' : trailingslashit( $permalinks['attribute_base'] );
  645. $product_permalink = empty( $permalinks['product_base'] ) ? _x( 'product', 'slug', 'woocommerce' ) : $permalinks['product_base'];
  646. if ( $product_permalink )
  647. $rewrite = array( 'slug' => untrailingslashit( $product_permalink ), 'with_front' => false, 'feeds' => true );
  648. else
  649. $rewrite = false;
  650. $show_in_menu = current_user_can( 'manage_woocommerce' ) ? 'woocommerce' : true;
  651. /**
  652. * Taxonomies
  653. **/
  654. do_action( 'woocommerce_register_taxonomy' );
  655. $admin_only_query_var = is_admin();
  656. register_taxonomy( 'product_type',
  657. apply_filters( 'woocommerce_taxonomy_objects_product_type', array('product') ),
  658. apply_filters( 'woocommerce_taxonomy_args_product_type', array(
  659. 'hierarchical' => false,
  660. 'update_count_callback' => '_update_post_term_count',
  661. 'show_ui' => false,
  662. 'show_in_nav_menus' => false,
  663. 'query_var' => $admin_only_query_var,
  664. 'rewrite' => false
  665. ) )
  666. );
  667. register_taxonomy( 'product_cat',
  668. apply_filters( 'woocommerce_taxonomy_objects_product_cat', array('product') ),
  669. apply_filters( 'woocommerce_taxonomy_args_product_cat', array(
  670. 'hierarchical' => true,
  671. 'update_count_callback' => '_woocommerce_term_recount',
  672. 'label' => __( 'Product Categories', 'woocommerce'),
  673. 'labels' => array(
  674. 'name' => __( 'Product Categories', 'woocommerce'),
  675. 'singular_name' => __( 'Product Category', 'woocommerce'),
  676. 'menu_name' => _x( 'Categories', 'Admin menu name', 'woocommerce' ),
  677. 'search_items' => __( 'Search Product Categories', 'woocommerce'),
  678. 'all_items' => __( 'All Product Categories', 'woocommerce'),
  679. 'parent_item' => __( 'Parent Product Category', 'woocommerce'),
  680. 'parent_item_colon' => __( 'Parent Product Category:', 'woocommerce'),
  681. 'edit_item' => __( 'Edit Product Category', 'woocommerce'),
  682. 'update_item' => __( 'Update Product Category', 'woocommerce'),
  683. 'add_new_item' => __( 'Add New Product Category', 'woocommerce'),
  684. 'new_item_name' => __( 'New Product Category Name', 'woocommerce')
  685. ),
  686. 'show_ui' => true,
  687. 'query_var' => true,
  688. 'capabilities' => array(
  689. 'manage_terms' => 'manage_product_terms',
  690. 'edit_terms' => 'edit_product_terms',
  691. 'delete_terms' => 'delete_product_terms',
  692. 'assign_terms' => 'assign_product_terms',
  693. ),
  694. 'rewrite' => array(
  695. 'slug' => $product_category_slug,
  696. 'with_front' => false,
  697. 'hierarchical' => true,
  698. //'ep_mask' => EP_CATEGORIES
  699. ),
  700. ) )
  701. );
  702. register_taxonomy( 'product_tag',
  703. apply_filters( 'woocommerce_taxonomy_objects_product_tag', array('product') ),
  704. apply_filters( 'woocommerce_taxonomy_args_product_tag', array(
  705. 'hierarchical' => false,
  706. 'update_count_callback' => '_woocommerce_term_recount',
  707. 'label' => __( 'Product Tags', 'woocommerce'),
  708. 'labels' => array(
  709. 'name' => __( 'Product Tags', 'woocommerce'),
  710. 'singular_name' => __( 'Product Tag', 'woocommerce'),
  711. 'menu_name' => _x( 'Tags', 'Admin menu name', 'woocommerce' ),
  712. 'search_items' => __( 'Search Product Tags', 'woocommerce'),
  713. 'all_items' => __( 'All Product Tags', 'woocommerce'),
  714. 'parent_item' => __( 'Parent Product Tag', 'woocommerce'),
  715. 'parent_item_colon' => __( 'Parent Product Tag:', 'woocommerce'),
  716. 'edit_item' => __( 'Edit Product Tag', 'woocommerce'),
  717. 'update_item' => __( 'Update Product Tag', 'woocommerce'),
  718. 'add_new_item' => __( 'Add New Product Tag', 'woocommerce'),
  719. 'new_item_name' => __( 'New Product Tag Name', 'woocommerce')
  720. ),
  721. 'show_ui' => true,
  722. 'query_var' => true,
  723. 'capabilities' => array(
  724. 'manage_terms' => 'manage_product_terms',
  725. 'edit_terms' => 'edit_product_terms',
  726. 'delete_terms' => 'delete_product_terms',
  727. 'assign_terms' => 'assign_product_terms',
  728. ),
  729. 'rewrite' => array( 'slug' => $product_tag_slug, 'with_front' => false ),
  730. ) )
  731. );
  732. register_taxonomy( 'product_shipping_class',
  733. apply_filters( 'woocommerce_taxonomy_objects_product_shipping_class', array('product', 'product_variation') ),
  734. apply_filters( 'woocommerce_taxonomy_args_product_shipping_class', array(
  735. 'hierarchical' => true,
  736. 'update_count_callback' => '_update_post_term_count',
  737. 'label' => __( 'Shipping Classes', 'woocommerce'),
  738. 'labels' => array(
  739. 'name' => __( 'Shipping Classes', 'woocommerce'),
  740. 'singular_name' => __( 'Shipping Class', 'woocommerce'),
  741. 'menu_name' => _x( 'Shipping Classes', 'Admin menu name', 'woocommerce' ),
  742. 'search_items' => __( 'Search Shipping Classes', 'woocommerce'),
  743. 'all_items' => __( 'All Shipping Classes', 'woocommerce'),
  744. 'parent_item' => __( 'Parent Shipping Class', 'woocommerce'),
  745. 'parent_item_colon' => __( 'Parent Shipping Class:', 'woocommerce'),
  746. 'edit_item' => __( 'Edit Shipping Class', 'woocommerce'),
  747. 'update_item' => __( 'Update Shipping Class', 'woocommerce'),
  748. 'add_new_item' => __( 'Add New Shipping Class', 'woocommerce'),
  749. 'new_item_name' => __( 'New Shipping Class Name', 'woocommerce')
  750. ),
  751. 'show_ui' => true,
  752. 'show_in_nav_menus' => false,
  753. 'query_var' => $admin_only_query_var,
  754. 'capabilities' => array(
  755. 'manage_terms' => 'manage_product_terms',
  756. 'edit_terms' => 'edit_product_terms',
  757. 'delete_terms' => 'delete_product_terms',
  758. 'assign_terms' => 'assign_product_terms',
  759. ),
  760. 'rewrite' => false,
  761. ) )
  762. );
  763. register_taxonomy( 'shop_order_status',
  764. apply_filters( 'woocommerce_taxonomy_objects_shop_order_status', array('shop_order') ),
  765. apply_filters( 'woocommerce_taxonomy_args_shop_order_status', array(
  766. 'hierarchical' => false,
  767. 'update_count_callback' => '_update_post_term_count',
  768. 'show_ui' => false,
  769. 'show_in_nav_menus' => false,
  770. 'query_var' => $admin_only_query_var,
  771. 'rewrite' => false,
  772. ) )
  773. );
  774. $attribute_taxonomies = $this->get_attribute_taxonomies();
  775. if ( $attribute_taxonomies ) {
  776. foreach ($attribute_taxonomies as $tax) {
  777. $name = $this->attribute_taxonomy_name( $tax->attribute_name );
  778. $hierarchical = true;
  779. if ($name) {
  780. $label = ( isset( $tax->attribute_label ) && $tax->attribute_label ) ? $tax->attribute_label : $tax->attribute_name;
  781. $show_in_nav_menus = apply_filters( 'woocommerce_attribute_show_in_nav_menus', false, $name );
  782. register_taxonomy( $name,
  783. apply_filters( 'woocommerce_taxonomy_objects_' . $name, array('product') ),
  784. apply_filters( 'woocommerce_taxonomy_args_' . $name, array(
  785. 'hierarchical' => $hierarchical,
  786. 'update_count_callback' => '_update_post_term_count',
  787. 'labels' => array(
  788. 'name' => $label,
  789. 'singular_name' => $label,
  790. 'search_items' => __( 'Search', 'woocommerce') . ' ' . $label,
  791. 'all_items' => __( 'All', 'woocommerce') . ' ' . $label,
  792. 'parent_item' => __( 'Parent', 'woocommerce') . ' ' . $label,
  793. 'parent_item_colon' => __( 'Parent', 'woocommerce') . ' ' . $label . ':',
  794. 'edit_item' => __( 'Edit', 'woocommerce') . ' ' . $label,
  795. 'update_item' => __( 'Update', 'woocommerce') . ' ' . $label,
  796. 'add_new_item' => __( 'Add New', 'woocommerce') . ' ' . $label,
  797. 'new_item_name' => __( 'New', 'woocommerce') . ' ' . $label
  798. ),
  799. 'show_ui' => false,
  800. 'query_var' => true,
  801. 'capabilities' => array(
  802. 'manage_terms' => 'manage_product_terms',
  803. 'edit_terms' => 'edit_product_terms',
  804. 'delete_terms' => 'delete_product_terms',
  805. 'assign_terms' => 'assign_product_terms',
  806. ),
  807. 'show_in_nav_menus' => $show_in_nav_menus,
  808. 'rewrite' => array( 'slug' => $product_attribute_base . sanitize_title( $tax->attribute_name ), 'with_front' => false, 'hierarchical' => $hierarchical ),
  809. ) )
  810. );
  811. }
  812. }
  813. }
  814. /**
  815. * Post Types
  816. **/
  817. do_action( 'woocommerce_register_post_type' );
  818. register_post_type( "product",
  819. apply_filters( 'woocommerce_register_post_type_product',
  820. array(
  821. 'labels' => array(
  822. 'name' => __( 'Products', 'woocommerce' ),
  823. 'singular_name' => __( 'Product', 'woocommerce' ),
  824. 'menu_name' => _x( 'Products', 'Admin menu name', 'woocommerce' ),
  825. 'add_new' => __( 'Add Product', 'woocommerce' ),
  826. 'add_new_item' => __( 'Add New Product', 'woocommerce' ),
  827. 'edit' => __( 'Edit', 'woocommerce' ),
  828. 'edit_item' => __( 'Edit Product', 'woocommerce' ),
  829. 'new_item' => __( 'New Product', 'woocommerce' ),
  830. 'view' => __( 'View Product', 'woocommerce' ),
  831. 'view_item' => __( 'View Product', 'woocommerce' ),
  832. 'search_items' => __( 'Search Products', 'woocommerce' ),
  833. 'not_found' => __( 'No Products found', 'woocommerce' ),
  834. 'not_found_in_trash' => __( 'No Products found in trash', 'woocommerce' ),
  835. 'parent' => __( 'Parent Product', 'woocommerce' )
  836. ),
  837. 'description' => __( 'This is where you can add new products to your store.', 'woocommerce' ),
  838. 'public' => true,
  839. 'show_ui' => true,
  840. 'capability_type' => 'product',
  841. 'map_meta_cap' => true,
  842. 'publicly_queryable' => true,
  843. 'exclude_from_search' => false,
  844. 'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records!
  845. 'rewrite' => $rewrite,
  846. 'query_var' => true,
  847. 'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', 'custom-fields', 'page-attributes' ),
  848. 'has_archive' => $base_slug,
  849. 'show_in_nav_menus' => true
  850. )
  851. )
  852. );
  853. // Sort out attachment urls (removed, breaks pagination) no alternatives add_rewrite_rule( '^' . $attachment_base . '([^/]*)/([^/]*)/([^/]*)/?', 'index.php?attachment=$matches[3]', 'top' );
  854. register_post_type( "product_variation",
  855. apply_filters( 'woocommerce_register_post_type_product_variation',
  856. array(
  857. 'labels' => array(
  858. 'name' => __( 'Variations', 'woocommerce' ),
  859. 'singular_name' => __( 'Variation', 'woocommerce' ),
  860. 'add_new' => __( 'Add Variation', 'woocommerce' ),
  861. 'add_new_item' => __( 'Add New Variation', 'woocommerce' ),
  862. 'edit' => __( 'Edit', 'woocommerce' ),
  863. 'edit_item' => __( 'Edit Variation', 'woocommerce' ),
  864. 'new_item' => __( 'New Variation', 'woocommerce' ),
  865. 'view' => __( 'View Variation', 'woocommerce' ),
  866. 'view_item' => __( 'View Variation', 'woocommerce' ),
  867. 'search_items' => __( 'Search Variations', 'woocommerce' ),
  868. 'not_found' => __( 'No Variations found', 'woocommerce' ),
  869. 'not_found_in_trash' => __( 'No Variations found in trash', 'woocommerce' ),
  870. 'parent' => __( 'Parent Variation', 'woocommerce' )
  871. ),
  872. 'public' => true,
  873. 'show_ui' => false,
  874. 'capability_type' => 'product',
  875. 'map_meta_cap' => true,
  876. 'publicly_queryable' => false,
  877. 'exclude_from_search' => true,
  878. 'hierarchical' => false,
  879. 'rewrite' => false,
  880. 'query_var' => true,
  881. 'supports' => array( 'title', 'editor', 'custom-fields', 'page-attributes', 'thumbnail' ),
  882. 'show_in_nav_menus' => false
  883. )
  884. )
  885. );
  886. $menu_name = _x('Orders', 'Admin menu name', 'woocommerce');
  887. if ( $order_count = woocommerce_processing_order_count() ) {
  888. $menu_name .= " <span class='awaiting-mod update-plugins count-$order_count'><span class='processing-count'>" . number_format_i18n( $order_count ) . "</span></span>" ;
  889. }
  890. register_post_type( "shop_order",
  891. apply_filters( 'woocommerce_register_post_type_shop_order',
  892. array(
  893. 'labels' => array(
  894. 'name' => __( 'Orders', 'woocommerce' ),
  895. 'singular_name' => __( 'Order', 'woocommerce' ),
  896. 'add_new' => __( 'Add Order', 'woocommerce' ),
  897. 'add_new_item' => __( 'Add New Order', 'woocommerce' ),
  898. 'edit' => __( 'Edit', 'woocommerce' ),
  899. 'edit_item' => __( 'Edit Order', 'woocommerce' ),
  900. 'new_item' => __( 'New Order', 'woocommerce' ),
  901. 'view' => __( 'View Order', 'woocommerce' ),
  902. 'view_item' => __( 'View Order', 'woocommerce' ),
  903. 'search_items' => __( 'Search Orders', 'woocommerce' ),
  904. 'not_found' => __( 'No Orders found', 'woocommerce' ),
  905. 'not_found_in_trash' => __( 'No Orders found in trash', 'woocommerce' ),
  906. 'parent' => __( 'Parent Orders', 'woocommerce' ),
  907. 'menu_name' => $menu_name
  908. ),
  909. 'description' => __( 'This is where store orders are stored.', 'woocommerce' ),
  910. 'public' => false,
  911. 'show_ui' => true,
  912. 'capability_type' => 'shop_order',
  913. 'map_meta_cap' => true,
  914. 'publicly_queryable' => false,
  915. 'exclude_from_search' => true,
  916. 'show_in_menu' => $show_in_menu,
  917. 'hierarchical' => false,
  918. 'show_in_nav_menus' => false,
  919. 'rewrite' => false,
  920. 'query_var' => false,
  921. 'supports' => array( 'title', 'comments', 'custom-fields' ),
  922. 'has_archive' => false,
  923. )
  924. )
  925. );
  926. register_post_type( "shop_coupon",
  927. apply_filters( 'woocommerce_register_post_type_shop_coupon',
  928. array(
  929. 'labels' => array(
  930. 'name' => __( 'Coupons', 'woocommerce' ),
  931. 'singular_name' => __( 'Coupon', 'woocommerce' ),
  932. 'menu_name' => _x( 'Coupons', 'Admin menu name', 'woocommerce' ),
  933. 'add_new' => __( 'Add Coupon', 'woocommerce' ),
  934. 'add_new_item' => __( 'Add New Coupon', 'woocommerce' ),
  935. 'edit' => __( 'Edit', 'woocommerce' ),
  936. 'edit_item' => __( 'Edit Coupon', 'woocommerce' ),
  937. 'new_item' => __( 'New Coupon', 'woocommerce' ),
  938. 'view' => __( 'View Coupons', 'woocommerce' ),
  939. 'view_item' => __( 'View Coupon', 'woocommerce' ),
  940. 'search_items' => __( 'Search Coupons', 'woocommerce' ),
  941. 'not_found' => __( 'No Coupons found', 'woocommerce' ),
  942. 'not_found_in_trash' => __( 'No Coupons found in trash', 'woocommerce' ),
  943. 'parent' => __( 'Parent Coupon', 'woocommerce' )
  944. ),
  945. 'description' => __( 'This is where you can add new coupons that customers can use in your store.', 'woocommerce' ),
  946. 'public' => true,
  947. 'show_ui' => true,
  948. 'capability_type' => 'shop_coupon',
  949. 'map_meta_cap' => true,
  950. 'publicly_queryable' => false,
  951. 'exclude_from_search' => true,
  952. 'show_in_menu' => $show_in_menu,
  953. 'hierarchical' => false,
  954. 'rewrite' => false,
  955. 'query_var' => false,
  956. 'supports' => array( 'title' ),
  957. 'show_in_nav_menus' => false
  958. )
  959. )
  960. );
  961. }
  962. /**
  963. * Init images.
  964. *
  965. * @access public
  966. * @return void
  967. */
  968. public function init_image_sizes() {
  969. $shop_thumbnail = $this->get_image_size( 'shop_thumbnail' );
  970. $shop_catalog = $this->get_image_size( 'shop_catalog' );
  971. $shop_single = $this->get_image_size( 'shop_single' );
  972. add_image_size( 'shop_thumbnail', $shop_thumbnail['width'], $shop_thumbnail['height'], $shop_thumbnail['crop'] );
  973. add_image_size( 'shop_catalog', $shop_catalog['width'], $shop_catalog['height'], $shop_catalog['crop'] );
  974. add_image_size( 'shop_single', $shop_single['width'], $shop_single['height'], $shop_single['crop'] );
  975. }
  976. /**
  977. * Register/queue frontend scripts.
  978. *
  979. * @access public
  980. * @return void
  981. */
  982. public function frontend_scripts() {
  983. global $post;
  984. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
  985. $lightbox_en = get_option( 'woocommerce_enable_lightbox' ) == 'yes' ? true : false;
  986. $chosen_en = get_option( 'woocommerce_enable_chosen' ) == 'yes' ? true : false;
  987. $ajax_cart_en = get_option( 'woocommerce_enable_ajax_add_to_cart' ) == 'yes' ? true : false;
  988. $frontend_script_path = $this->plugin_url() . '/assets/js/frontend/';
  989. // Register any scripts for later use, or used as dependencies
  990. wp_register_script( 'chosen', $this->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), '0.9.11', true );
  991. wp_register_script( 'jquery-blockui', $this->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.60', true );
  992. wp_register_script( 'jquery-placeholder', $this->plugin_url() . '/assets/js/jquery-placeholder/jquery.placeholder' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  993. wp_register_script( 'wc-add-to-cart-variation', $frontend_script_path . 'add-to-cart-variation' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  994. wp_register_script( 'wc-single-product', $frontend_script_path . 'single-product' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  995. wp_register_script( 'jquery-cookie', $this->plugin_url() . '/assets/js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.3.1', true );
  996. // Queue frontend scripts conditionally
  997. if ( $ajax_cart_en )
  998. wp_enqueue_script( 'wc-add-to-cart', $frontend_script_path . 'add-to-cart' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  999. if ( is_cart() )
  1000. wp_enqueue_script( 'wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  1001. if ( is_checkout() ) {
  1002. if ( $chosen_en ) {
  1003. wp_enqueue_script( 'wc-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), $this->version, true );
  1004. wp_enqueue_style( 'woocommerce_chosen_styles', $this->plugin_url() . '/assets/css/chosen.css' );
  1005. }
  1006. wp_enqueue_script( 'wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array( 'jquery', 'woocommerce' ), $this->version, true );
  1007. }
  1008. if ( $lightbox_en && ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) ) {
  1009. wp_enqueue_script( 'prettyPhoto', $this->plugin_url() . '/assets/js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true );
  1010. wp_enqueue_script( 'prettyPhoto-init', $this->plugin_url() . '/assets/js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery' ), $this->version, true );
  1011. wp_enqueue_style( 'woocommerce_prettyPhoto_css', $this->plugin_url() . '/assets/css/prettyPhoto.css' );
  1012. }
  1013. if ( is_product() )
  1014. wp_enqueue_script( 'wc-single-product' );
  1015. // Global frontend scripts
  1016. wp_enqueue_script( 'woocommerce', $frontend_script_path . 'woocommerce' . $suffix . '.js', array( 'jquery', 'jquery-blockui' ), $this->version, true );
  1017. wp_enqueue_script( 'wc-cart-fragments', $frontend_script_path . 'cart-fragments' . $suffix . '.js', array( 'jquery', 'jquery-cookie' ), $this->version, true );
  1018. wp_enqueue_script( 'jquery-placeholder' );
  1019. // Variables for JS scripts
  1020. $woocommerce_params = array(
  1021. 'countries' => json_encode( $this->countries->get_allowed_country_states() ),
  1022. 'plugin_url' => $this->plugin_url(),
  1023. 'ajax_url' => $this->ajax_url(),
  1024. 'ajax_loader_url' => apply_filters( 'woocommerce_ajax_loader_url', $this->plugin_url() . '/assets/images/ajax-loader@2x.gif' ),
  1025. 'i18n_select_state_text' => esc_attr__( 'Select an option&hellip;', 'woocommerce' ),
  1026. 'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'woocommerce' ),
  1027. 'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'woocommerce' ),
  1028. 'i18n_required_text' => esc_attr__( 'required', 'woocommerce' ),
  1029. 'i18n_view_cart' => esc_attr__( 'View Cart &rarr;', 'woocommerce' ),
  1030. 'review_rating_required' => get_option( 'woocommerce_review_rating_required' ),
  1031. 'update_order_review_nonce' => wp_create_nonce( "update-order-review" ),
  1032. 'apply_coupon_nonce' => wp_create_nonce( "apply-coupon" ),
  1033. 'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ),
  1034. 'checkout_url' => add_query_arg( 'action', 'woocommerce-checkout', $this->ajax_url() ),
  1035. 'is_checkout' => is_page( woocommerce_get_page_id( 'checkout' ) ) ? 1 : 0,
  1036. 'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ),
  1037. 'cart_url' => get_permalink( woocommerce_get_page_id( 'cart' ) ),
  1038. 'cart_redirect_after_add' => get_option( 'woocommerce_cart_redirect_after_add' )
  1039. );
  1040. if ( is_checkout() || is_cart() )
  1041. $woocommerce_params['locale'] = json_encode( $this->countries->get_country_locale() );
  1042. wp_localize_script( 'woocommerce', 'woocommerce_params', apply_filters( 'woocommerce_params', $woocommerce_params ) );
  1043. // CSS Styles
  1044. if ( ! defined( 'WOOCOMMERCE_USE_CSS' ) )
  1045. define( 'WOOCOMMERCE_USE_CSS', get_option( 'woocommerce_frontend_css' ) == 'yes' ? true : false );
  1046. if ( WOOCOMMERCE_USE_CSS ) {
  1047. $css = file_exists( get_stylesheet_directory() . '/woocommerce/style.css' ) ? get_stylesheet_directory_uri() . '/woocommerce/style.css' : $this->plugin_url() . '/assets/css/woocommerce.css';
  1048. wp_enqueue_style( 'woocommerce_frontend_styles', $css );
  1049. }
  1050. }
  1051. /**
  1052. * WC requires jQuery 1.7 since it uses functions like .on() for events.
  1053. * If, by the time wp_print_scrips is called, jQuery is outdated (i.e not
  1054. * using the version in core) we need to deregister it and register the
  1055. * core version of the file.
  1056. *
  1057. * @access public
  1058. * @return void
  1059. */
  1060. public function check_jquery() {
  1061. global $wp_scripts;
  1062. // Enforce minimum version of jQuery
  1063. if ( ! empty( $wp_scripts->registered['jquery']->ver ) && ! empty( $wp_scripts->registered['jquery']->src ) && 0 >= version_compare( $wp_scripts->registered['jquery']->ver, '1.7' ) ) {
  1064. wp_deregister_script( 'jquery' );
  1065. wp_register_script( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.7' );
  1066. wp_enqueue_script( 'jquery' );
  1067. }
  1068. }
  1069. /** Load Instances on demand **********************************************/
  1070. /**
  1071. * Get Checkout Class.
  1072. *
  1073. * @access public
  1074. * @return WC_Checkout
  1075. */
  1076. public function checkout() {
  1077. if ( empty( $this->checkout ) )
  1078. $this->checkout = new WC_Checkout();
  1079. return $this->checkout;
  1080. }
  1081. /**
  1082. * Get gateways class
  1083. *
  1084. * @access public
  1085. * @return WC_Payment_Gateways
  1086. */
  1087. public function payment_gateways() {
  1088. if ( empty( $this->payment_gateways ) )
  1089. $this->payment_gateways = new WC_Payment_Gateways();
  1090. return $this->payment_gateways;
  1091. }
  1092. /**
  1093. * Get shipping class
  1094. *
  1095. * @access public
  1096. * @return WC_Shipping
  1097. */
  1098. public function shipping() {
  1099. if ( empty( $this->shipping ) )
  1100. $this->shipping = new WC_Shipping();
  1101. return $this->shipping;
  1102. }
  1103. /**
  1104. * Get Logging Class.
  1105. *
  1106. * @access public
  1107. * @return WC_Logger
  1108. */
  1109. public function logger() {
  1110. return new WC_Logger();
  1111. }
  1112. /**
  1113. * Get Validation Class.
  1114. *
  1115. * @access public
  1116. * @return WC_Validation
  1117. */
  1118. public function validation() {
  1119. return new WC_Validation();
  1120. }
  1121. /**
  1122. * Init the mailer and call the notifications for the current filter.
  1123. *
  1124. * @access public
  1125. * @param array $args (default: array())
  1126. * @return void
  1127. */
  1128. public function send_transactional_email( $args = array() ) {
  1129. $this->mailer();
  1130. do_action( current_filter() . '_notification', $args );
  1131. }
  1132. /**
  1133. * Email Class.
  1134. *
  1135. * @access public
  1136. * @return WC_Email
  1137. */
  1138. public function mailer() {
  1139. if ( empty( $this->woocommerce_email ) ) {
  1140. $this->woocommerce_email = new WC_Emails();
  1141. }
  1142. return $this->woocommerce_email;
  1143. }
  1144. /** Helper functions ******************************************************/
  1145. /**
  1146. * Get the plugin url.
  1147. *
  1148. * @access public
  1149. * @return string
  1150. */
  1151. public function plugin_url() {
  1152. if ( $this->plugin_url ) return $this->plugin_url;
  1153. return $this->plugin_url = untrailingslashit( plugins_url( '/', __FILE__ ) );
  1154. }
  1155. /**
  1156. * Get the plugin path.
  1157. *
  1158. * @access public
  1159. * @return string
  1160. */
  1161. public function plugin_path() {
  1162. if ( $this->plugin_path ) return $this->plugin_path;
  1163. return $this->plugin_path = untrailingslashit( plugin_dir_path( __FILE__ ) );
  1164. }
  1165. /**
  1166. * Get Ajax URL.
  1167. *
  1168. * @access public
  1169. * @return string
  1170. */
  1171. public function ajax_url() {
  1172. return admin_url( 'admin-ajax.php', 'relative' );
  1173. }
  1174. /**
  1175. * Return the WC API URL for a given request
  1176. *
  1177. * @access public
  1178. * @param mixed $request
  1179. * @param mixed $ssl (default: null)
  1180. * @return string
  1181. */
  1182. public function api_request_url( $request, $ssl = null ) {
  1183. if ( is_null( $ssl ) ) {
  1184. $scheme = parse_url( get_option( 'home' ), PHP_URL_SCHEME );
  1185. } elseif ( $ssl ) {
  1186. $scheme = 'https';
  1187. } else {
  1188. $scheme = 'http';
  1189. }
  1190. if ( get_option('permalink_structure') ) {
  1191. return esc_url_raw( trailingslashit( home_url( '/wc-api/' . $request, $scheme ) ) );
  1192. } else {
  1193. return esc_url_raw( add_query_arg( 'wc-api', $request, trailingslashit( home_url( '', $scheme ) ) ) );
  1194. }
  1195. }
  1196. /**
  1197. * force_ssl function.
  1198. *
  1199. * @access public
  1200. * @param mixed $content
  1201. * @return void
  1202. */
  1203. public function force_ssl( $content ) {
  1204. if ( is_ssl() ) {
  1205. if ( is_array($content) )
  1206. $content = array_map( array( $this, 'force_ssl' ) , $content );
  1207. else
  1208. $content = str_replace( 'http:', 'https:', $content );
  1209. }
  1210. return $content;
  1211. }
  1212. /**
  1213. * Get an image size.
  1214. *
  1215. * Variable is filtered by woocommerce_get_image_size_{image_size}
  1216. *
  1217. * @access public
  1218. * @param mixed $image_size
  1219. * @return string
  1220. */
  1221. public function get_image_size( $image_size ) {
  1222. // Only return sizes we define in settings
  1223. if ( ! in_array( $image_size, array( 'shop_thumbnail', 'shop_catalog', 'shop_single' ) ) )
  1224. return apply_filters( 'wooc