PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/jigoshop.php

https://github.com/ThemesWpFr/jigoshop
PHP | 1200 lines | 712 code | 245 blank | 243 comment | 130 complexity | e97890037a4de082f2955987d0c6acdc MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * ./////////////////////////////.
  4. * //////////////////////////////////
  5. * /////////// ///////////////////
  6. * //////// /////////////////////
  7. * ////// ////////////////////////
  8. * ///// ///////// ////////////
  9. * ////// ///////// /////////
  10. * ///////// ///////// ///////
  11. * /////////// ////////// /////
  12. * //////////////////////// //////
  13. * ///////////////////// /////////
  14. * /////////////////// ///////////
  15. * //////////////////////////////////
  16. * `//////////////////////////////`
  17. *
  18. *
  19. * Plugin Name: Jigoshop
  20. * Plugin URI: http://jigoshop.com/
  21. * Description: Jigoshop, a WordPress eCommerce plugin that works.
  22. * Author: Jigowatt
  23. * Author URI: http://jigowatt.co.uk
  24. *
  25. * Version: 1.5.1
  26. * Requires at least: 3.3
  27. * Tested up to: 3.5.1
  28. *
  29. * Text Domain: jigoshop
  30. * Domain Path: /languages/
  31. *
  32. * DISCLAIMER
  33. *
  34. * Do not edit or add directly to this file if you wish to upgrade Jigoshop to newer
  35. * versions in the future. If you wish to customise Jigoshop core for your needs,
  36. * please use our GitHub repository to publish essential changes for consideration.
  37. *
  38. * @package Jigoshop
  39. * @category Core
  40. * @author Jigowatt
  41. * @copyright Copyright Š 2011-2012 Jigowatt Ltd.
  42. * @license http://jigoshop.com/license/commercial-edition
  43. */
  44. if ( !defined( "JIGOSHOP_VERSION" )) define( "JIGOSHOP_VERSION", 1301280) ;
  45. if ( !defined( "JIGOSHOP_OPTIONS" )) define( "JIGOSHOP_OPTIONS", 'jigoshop_options' );
  46. if ( !defined( 'JIGOSHOP_TEMPLATE_URL' ) ) define( 'JIGOSHOP_TEMPLATE_URL', 'jigoshop/' );
  47. if ( !defined( "PHP_EOL" )) define( "PHP_EOL", "\r\n" );
  48. /**
  49. * Include core files and classes
  50. **/
  51. include_once( 'classes/abstract/jigoshop_base.class.php' );
  52. include_once( 'classes/abstract/jigoshop_singleton.class.php' );
  53. include_once( 'classes/jigoshop_options.class.php' );
  54. include_once( 'classes/jigoshop_session.class.php' );
  55. include_once( 'classes/jigoshop_sanitize.class.php' );
  56. include_once( 'classes/jigoshop_validation.class.php' );
  57. include_once( 'classes/jigoshop_forms.class.php' );
  58. include_once( 'jigoshop_taxonomy.php' );
  59. include_once( 'classes/jigoshop_countries.class.php' );
  60. include_once( 'classes/jigoshop_customer.class.php' );
  61. include_once( 'classes/jigoshop_product.class.php' );
  62. include_once( 'classes/jigoshop_product_variation.class.php' );
  63. include_once( 'classes/jigoshop_order.class.php' );
  64. include_once( 'classes/jigoshop_orders.class.php' );
  65. include_once( 'classes/jigoshop_tax.class.php' );
  66. include_once( 'classes/jigoshop_shipping.class.php' );
  67. include_once( 'classes/jigoshop_coupons.class.php' );
  68. include_once( 'gateways/gateways.class.php' );
  69. include_once( 'gateways/gateway.class.php' );
  70. include_once( 'gateways/bank_transfer.php' );
  71. include_once( 'gateways/cheque.php' );
  72. include_once( 'gateways/cod.php' );
  73. include_once( 'gateways/paypal.php' );
  74. include_once( 'gateways/skrill.php' );
  75. include_once( 'shipping/shipping_method.class.php' );
  76. include_once( 'shipping/jigoshop_calculable_shipping.php' );
  77. include_once( 'shipping/flat_rate.php' );
  78. include_once( 'shipping/free_shipping.php' );
  79. include_once( 'shipping/local_pickup.php' );
  80. include_once( 'classes/jigoshop_query.class.php' );
  81. include_once( 'classes/jigoshop.class.php' );
  82. include_once( 'classes/jigoshop_cart.class.php' );
  83. include_once( 'classes/jigoshop_checkout.class.php' );
  84. include_once( 'classes/jigoshop_cron.class.php' );
  85. include_once( 'shortcodes/init.php' );
  86. include_once( 'widgets/init.php' );
  87. include_once( 'jigoshop_templates.php' );
  88. include_once( 'jigoshop_template_actions.php' );
  89. include_once( 'jigoshop_emails.php' );
  90. include_once( 'jigoshop_actions.php' );
  91. /**
  92. * IIS compat fix/fallback
  93. **/
  94. if ( ! isset( $_SERVER['REQUEST_URI'] )) {
  95. $_SERVER['REQUEST_URI'] = substr( $_SERVER['PHP_SELF'], 1 );
  96. if ( isset( $_SERVER['QUERY_STRING'] )) { $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; }
  97. }
  98. // Load administration & check if we need to install
  99. if ( is_admin() ) {
  100. include_once( 'admin/jigoshop-admin.php' );
  101. register_activation_hook( __FILE__, 'install_jigoshop' );
  102. }
  103. /**
  104. * Jigoshop Inits
  105. **/
  106. add_action( 'init', 'jigoshop_init', 0 );
  107. function jigoshop_init() {
  108. /* ensure nothing is output to the browser prior to this (other than headers) */
  109. ob_start();
  110. // http://www.geertdedeckere.be/article/loading-wordpress-language-files-the-right-way
  111. // this means that all Jigoshop extensions, shipping modules and gateways must load their text domains on the 'init' action hook
  112. //
  113. // Override default translations with custom .mo's found in wp-content/languages/jigoshop first.
  114. load_textdomain( 'jigoshop', WP_LANG_DIR.'/jigoshop/jigoshop-'.get_locale().'.mo' );
  115. load_plugin_textdomain( 'jigoshop', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
  116. // instantiate options -after- loading text domains
  117. $jigoshop_options = Jigoshop_Base::get_options();
  118. jigoshop_post_type(); // register taxonomies
  119. new jigoshop_cron(); // -after- text domains and Options instantiation allows settings translations
  120. jigoshop_set_image_sizes(); // called -after- our Options are loaded
  121. // add Singletons here so that the taxonomies are loaded before calling them.
  122. jigoshop_session::instance(); // Start sessions if they aren't already
  123. jigoshop::instance(); // Utility functions, uses sessions
  124. jigoshop_customer::instance(); // Customer class, sorts session data such as location
  125. // Jigoshop will instantiate gateways and shipping methods on this same 'init' action hook
  126. // with a very low priority to ensure text domains are loaded first prior to installing any external options
  127. jigoshop_shipping::instance(); // Shipping class. loads shipping methods
  128. jigoshop_payment_gateways::instance(); // Payment gateways class. loads payment methods
  129. jigoshop_cart::instance(); // Cart class, uses sessions
  130. if ( ! is_admin()) {
  131. /* Catalog Filters */
  132. add_filter( 'loop-shop-query', create_function( '', 'return array("orderby" => "' . $jigoshop_options->get_option('jigoshop_catalog_sort_orderby') . '","order" => "' . $jigoshop_options->get_option('jigoshop_catalog_sort_direction') . '");' ) );
  133. add_filter( 'loop_shop_columns' , create_function( '', 'return ' . $jigoshop_options->get_option('jigoshop_catalog_columns') . ';' ) );
  134. add_filter( 'loop_shop_per_page', create_function( '', 'return ' . $jigoshop_options->get_option('jigoshop_catalog_per_page') . ';' ) );
  135. jigoshop_catalog_query::instance(); // front end queries class
  136. }
  137. jigoshop_roles_init();
  138. }
  139. function jigoshop_get_core_capabilities() {
  140. $capabilities = array();
  141. $capabilities['core'] = array(
  142. "manage_jigoshop",
  143. "view_jigoshop_reports"
  144. );
  145. $capability_types = array( 'product', 'shop_order', 'shop_coupon' );
  146. foreach( $capability_types as $capability_type ) {
  147. $capabilities[ $capability_type ] = array(
  148. // Post type
  149. "edit_{$capability_type}",
  150. "read_{$capability_type}",
  151. "delete_{$capability_type}",
  152. "edit_{$capability_type}s",
  153. "edit_others_{$capability_type}s",
  154. "publish_{$capability_type}s",
  155. "read_private_{$capability_type}s",
  156. "delete_{$capability_type}s",
  157. "delete_private_{$capability_type}s",
  158. "delete_published_{$capability_type}s",
  159. "delete_others_{$capability_type}s",
  160. "edit_private_{$capability_type}s",
  161. "edit_published_{$capability_type}s",
  162. // Terms
  163. "manage_{$capability_type}_terms",
  164. "edit_{$capability_type}_terms",
  165. "delete_{$capability_type}_terms",
  166. "assign_{$capability_type}_terms"
  167. );
  168. }
  169. return $capabilities;
  170. }
  171. function jigoshop_roles_init() {
  172. global $wp_roles;
  173. if ( class_exists('WP_Roles') )
  174. if ( ! isset( $wp_roles ) )
  175. $wp_roles = new WP_Roles();
  176. if ( is_object( $wp_roles ) ) {
  177. // Customer role
  178. add_role( 'customer', __('Customer', 'jigoshop'), array(
  179. 'read' => true,
  180. 'edit_posts' => false,
  181. 'delete_posts' => false
  182. ) );
  183. $capabilities = jigoshop_get_core_capabilities();
  184. foreach( $capabilities as $cap_group ) {
  185. foreach( $cap_group as $cap ) {
  186. $wp_roles->add_cap( 'administrator', $cap );
  187. }
  188. }
  189. }
  190. }
  191. /**
  192. * Include template functions here with a low priority so they are pluggable by themes
  193. **/
  194. add_action( 'init', 'jigoshop_load_template_functions', 999 );
  195. function jigoshop_load_template_functions() {
  196. include_once( 'jigoshop_template_functions.php' );
  197. }
  198. /**
  199. * Jigoshop Frontend Styles and Scripts
  200. **/
  201. add_action( 'template_redirect', 'jigoshop_frontend_scripts' );
  202. function jigoshop_frontend_scripts() {
  203. if ( ! is_jigoshop() && is_admin() ) return false;
  204. $jigoshop_options = Jigoshop_Base::get_options();
  205. /**
  206. * Frontend Styles
  207. *
  208. * For Jigoshop 1.3 or better there are 2 CSS related options
  209. * The ususal 'jigoshop_disable_css' must be off to use -any- Jigoshop CSS
  210. * otherwise the theme is expected to provide -all- CSS located wherever it likes, loaded by the theme
  211. * A user can also copy both frontend.less and frontend.css to a 'jigoshop' folder in the theme folder and
  212. * rename them to style.less and style.css and compile changes with SimpLESS
  213. * http://wearekiss.com/simpless
  214. * If Jigoshop finds this file, it will load -only- that file, or if not found will default to our frontend.css
  215. * A user can also with the second option 'jigoshop_frontend_with_theme_css' enabled, load -both- the default frontend.css
  216. * -and- any extra bits found in the same 'theme/jigoshop/style.css'
  217. * This allows only a few modifications to be added in after the default frontend.css
  218. * It will also allow for easier additions to frontend.css that get missed if themers don't upgrade their version.
  219. * With these 2 options, users should either provide the complete frontend.css (style.css in the theme jigoshop folder)
  220. * or just the few changes again in the style.css in the theme jigoshop folder and set the 2nd option accordingly
  221. */
  222. $frontend_css = jigoshop::assets_url() . '/assets/css/frontend.css';
  223. $theme_css = file_exists( get_stylesheet_directory() . '/jigoshop/style.css')
  224. ? get_stylesheet_directory_uri() . '/jigoshop/style.css'
  225. : jigoshop::assets_url() . '/assets/css/frontend.css';
  226. if ( $jigoshop_options->get_option( 'jigoshop_disable_css' ) == 'no' ) {
  227. if ( $jigoshop_options->get_option( 'jigoshop_frontend_with_theme_css' ) == 'yes' ) {
  228. wp_enqueue_style( 'jigoshop_frontend_styles', $frontend_css );
  229. }
  230. wp_enqueue_style( 'jigoshop_theme_styles', $theme_css );
  231. }
  232. if ( $jigoshop_options->get_option( 'jigoshop_disable_fancybox' ) == 'no' ) {
  233. wp_enqueue_style( 'jigoshop_fancybox_styles', jigoshop::assets_url() . '/assets/css/fancybox.css' );
  234. wp_enqueue_script( 'fancybox', jigoshop::assets_url().'/assets/js/jquery.fancybox-1.3.4.pack.js', array('jquery'));
  235. }
  236. wp_enqueue_style( 'jqueryui_styles', jigoshop::assets_url().'/assets/css/ui.css' );
  237. wp_enqueue_script( 'jqueryui', jigoshop::assets_url().'/assets/js/jquery-ui-1.9.2.min.js', array('jquery'), '1.9.2' );
  238. wp_enqueue_script( 'jigoshop_blockui', jigoshop::assets_url().'/assets/js/blockui.js', array('jquery'));
  239. wp_enqueue_script( 'jigoshop_frontend', jigoshop::assets_url().'/assets/js/jigoshop_frontend.js', array('jquery'));
  240. wp_enqueue_script( 'jigoshop_script', jigoshop::assets_url().'/assets/js/script.js', array('jquery'));
  241. /* Script.js variables */
  242. $jigoshop_params = array(
  243. 'ajax_url' => admin_url('admin-ajax.php'),
  244. 'assets_url' => jigoshop::assets_url(),
  245. 'checkout_url' => admin_url('admin-ajax.php?action=jigoshop-checkout'),
  246. 'countries' => json_encode(jigoshop_countries::$states),
  247. 'currency_symbol' => get_jigoshop_currency_symbol(),
  248. 'get_variation_nonce' => wp_create_nonce("get-variation"),
  249. 'load_fancybox' => $jigoshop_options->get_option( 'jigoshop_disable_fancybox' )=='no'?true:false,
  250. 'option_guest_checkout' => $jigoshop_options->get_option('jigoshop_enable_guest_checkout'),
  251. 'select_state_text' => __('Select a state&hellip;', 'jigoshop'),
  252. 'state_text' => __('state', 'jigoshop'),
  253. 'update_order_review_nonce' => wp_create_nonce("update-order-review"),
  254. 'billing_state' => jigoshop_customer::get_state(),
  255. 'shipping_state' => jigoshop_customer::get_shipping_state()
  256. );
  257. if ( isset( jigoshop_session::instance()->min_price ))
  258. $jigoshop_params['min_price'] = $_GET['min_price'];
  259. if ( isset( jigoshop_session::instance()->max_price ))
  260. $jigoshop_params['max_price'] = $_GET['max_price'];
  261. $jigoshop_params['is_checkout'] = ( is_page( jigoshop_get_page_id( 'checkout' )) || is_page( jigoshop_get_page_id( 'pay' )) );
  262. $jigoshop_params = apply_filters('jigoshop_params', $jigoshop_params);
  263. wp_localize_script( 'jigoshop_script', 'jigoshop_params', $jigoshop_params );
  264. }
  265. /**
  266. * Add a "Settings" link to the plugins.php page for Jigoshop
  267. **/
  268. add_filter( 'plugin_action_links', 'jigoshop_add_settings_link', 10, 2 );
  269. function jigoshop_add_settings_link( $links, $file ) {
  270. $this_plugin = plugin_basename( __FILE__ );
  271. if ( $file == $this_plugin ) {
  272. $settings_link = '<a href="admin.php?page=jigoshop_settings">' . __( 'Settings', 'jigoshop' ) . '</a>';
  273. array_unshift( $links, $settings_link );
  274. }
  275. return $links;
  276. }
  277. /**
  278. * Add post thumbnail support to WordPress if needed
  279. **/
  280. add_action( 'after_setup_theme', 'jigoshop_check_thumbnail_support', 99 );
  281. function jigoshop_check_thumbnail_support() {
  282. if ( ! current_theme_supports( 'post-thumbnails' ) ) {
  283. add_theme_support( 'post-thumbnails' );
  284. remove_post_type_support( 'post', 'thumbnail' );
  285. remove_post_type_support( 'page', 'thumbnail' );
  286. } else {
  287. add_post_type_support( 'product', 'thumbnail' );
  288. }
  289. }
  290. add_action( 'admin_enqueue_scripts', 'jigoshop_admin_styles' );
  291. function jigoshop_admin_styles() {
  292. /* Our setting icons */
  293. wp_enqueue_style( 'jigoshop_admin_icons_style', jigoshop::assets_url() . '/assets/css/admin-icons.css' );
  294. if ( ! jigoshop_is_admin_page() ) return false;
  295. wp_enqueue_style( 'jigoshop_admin_styles', jigoshop::assets_url() . '/assets/css/admin.css' );
  296. wp_enqueue_style( 'jigoshop-select2', jigoshop::assets_url() . '/assets/css/select2.css', '', '3.1', 'screen' );
  297. wp_enqueue_style( 'jquery-ui-jigoshop-styles', jigoshop::assets_url() . '/assets/css/jquery-ui-1.8.16.jigoshop.css' );
  298. wp_enqueue_style( 'thickbox' );
  299. }
  300. add_action( 'admin_print_scripts', 'jigoshop_admin_scripts' );
  301. function jigoshop_admin_scripts() {
  302. if ( !jigoshop_is_admin_page() ) return false;
  303. $pagenow = jigoshop_is_admin_page();
  304. wp_enqueue_script( 'jigoshop-select2', jigoshop::assets_url().'/assets/js/select2.min.js', array( 'jquery' ), '3.1' );
  305. wp_enqueue_script( 'jquery-ui-datepicker', jigoshop::assets_url().'/assets/js/jquery-ui-datepicker-1.8.16.min.js', array( 'jquery' ), '1.8.16' );
  306. wp_enqueue_script( 'jigoshop_blockui', jigoshop::assets_url() . '/assets/js/blockui.js', array( 'jquery' ), '2.4.6' );
  307. wp_enqueue_script( 'jigoshop_backend', jigoshop::assets_url() . '/assets/js/jigoshop_backend.js', array( 'jquery' ), '1.0' );
  308. wp_enqueue_script( 'thickbox' );
  309. if ( $pagenow == 'jigoshop_page_jigoshop_reports' || $pagenow == 'toplevel_page_jigoshop' ) {
  310. wp_enqueue_script('jquery_flot', jigoshop::assets_url().'/assets/js/jquery.flot.min.js', array( 'jquery' ), '1.0' );
  311. wp_enqueue_script('jquery_flot_pie', jigoshop::assets_url().'/assets/js/jquery.flot.pie.min.js', array( 'jquery' ), '1.0' );
  312. }
  313. /**
  314. * Disable autosaves on the order and coupon pages. Prevents the javascript alert when modifying.
  315. * `wp_deregister_script( 'autosave' )` would produce errors, so we use a filter instead.
  316. */
  317. if ( $pagenow == 'shop_order' || $pagenow == 'shop_coupon' )
  318. add_filter( 'script_loader_src', 'jigoshop_disable_autosave', 10, 2 );
  319. }
  320. //### Functions #########################################################
  321. /**
  322. * Set Jigoshop Product Image Sizes for WordPress based on Admin->Jigoshop->Settings->Images
  323. **/
  324. function jigoshop_set_image_sizes() {
  325. $jigoshop_options = Jigoshop_Base::get_options();
  326. $sizes = array(
  327. 'shop_tiny' => 'tiny',
  328. 'shop_thumbnail' => 'thumbnail',
  329. 'shop_small' => 'catalog',
  330. 'shop_large' => 'featured'
  331. );
  332. foreach ( $sizes as $size => $altSize )
  333. add_image_size(
  334. $size,
  335. $jigoshop_options->get_option('jigoshop_' . $size . '_w'),
  336. $jigoshop_options->get_option('jigoshop_' . $size . '_h'),
  337. ( $jigoshop_options->get_option( 'jigoshop_use_wordpress_' . $altSize . '_crop', 'no' ) == 'yes' )
  338. );
  339. /* The elephant in the room (._. ) */
  340. add_image_size( 'admin_product_list', 32, 32, $jigoshop_options->get_option( 'jigoshop_use_wordpress_tiny_crop', 'no' ) == 'yes' ? true : false );
  341. }
  342. /**
  343. * Get Jigoshop Product Image Size based on Admin->Jigoshop->Settings->Images
  344. * @param string $size - one of the 4 defined Jigoshop image sizes
  345. * @return array - an array containing the width and height of the required size
  346. * @since 0.9.9
  347. **/
  348. function jigoshop_get_image_size( $size ) {
  349. $jigoshop_options = Jigoshop_Base::get_options();
  350. if ( is_array( $size ) )
  351. return $size;
  352. switch ( $size ) :
  353. case 'admin_product_list':
  354. $image_size = array( 32, 32 );
  355. break;
  356. case 'shop_tiny':
  357. $image_size = array( $jigoshop_options->get_option('jigoshop_shop_tiny_w'), $jigoshop_options->get_option('jigoshop_shop_tiny_h') );
  358. break;
  359. case 'shop_thumbnail':
  360. $image_size = array( $jigoshop_options->get_option('jigoshop_shop_thumbnail_w'), $jigoshop_options->get_option('jigoshop_shop_thumbnail_h') );
  361. break;
  362. case 'shop_small':
  363. $image_size = array( $jigoshop_options->get_option('jigoshop_shop_small_w'), $jigoshop_options->get_option('jigoshop_shop_small_h') );
  364. break;
  365. case 'shop_large':
  366. $image_size = array( $jigoshop_options->get_option('jigoshop_shop_large_w'), $jigoshop_options->get_option('jigoshop_shop_large_h') );
  367. break;
  368. default:
  369. $image_size = array( $jigoshop_options->get_option('jigoshop_shop_small_w'), $jigoshop_options->get_option('jigoshop_shop_small_h') );
  370. break;
  371. endswitch;
  372. return $image_size;
  373. }
  374. function jigoshop_is_admin_page() {
  375. global $current_screen;
  376. if ( $current_screen->post_type == 'product' || $current_screen->post_type == 'shop_order' || $current_screen->post_type == 'shop_coupon' )
  377. return $current_screen->post_type;
  378. if ( strstr( $current_screen->id, 'jigoshop' ) )
  379. return $current_screen->id;
  380. return false;
  381. }
  382. function jigoshop_disable_autosave( $src, $handle ) {
  383. if ( 'autosave' != $handle ) return $src;
  384. return '';
  385. }
  386. /**
  387. * jigoshop_demo_store
  388. * Adds a demo store banner to the site
  389. */
  390. add_action( 'wp_footer', 'jigoshop_demo_store' );
  391. function jigoshop_demo_store() {
  392. if ( Jigoshop_Base::get_options()->get_option( 'jigoshop_demo_store' ) == 'yes' && is_jigoshop() ) :
  393. $bannner_text = apply_filters( 'jigoshop_demo_banner_text', __('This is a demo store for testing purposes &mdash; no orders shall be fulfilled.', 'jigoshop') );
  394. echo '<p class="demo_store">'.$bannner_text.'</p>';
  395. endif;
  396. }
  397. /**
  398. * jigoshop_sharethis
  399. * Adds social sharing code to footer
  400. */
  401. add_action( 'wp_footer', 'jigoshop_sharethis' );
  402. function jigoshop_sharethis() {
  403. $jigoshop_options = Jigoshop_Base::get_options();
  404. if (is_single() && $jigoshop_options->get_option('jigoshop_sharethis')) :
  405. if (is_ssl()) :
  406. $sharethis = 'https://ws.sharethis.com/button/buttons.js';
  407. else :
  408. $sharethis = 'http://w.sharethis.com/button/buttons.js';
  409. endif;
  410. echo '<script type="text/javascript">var switchTo5x=true;</script><script type="text/javascript" src="'.$sharethis.'"></script><script type="text/javascript">stLight.options({publisher:"'.$jigoshop_options->get_option('jigoshop_sharethis').'"});</script>';
  411. endif;
  412. }
  413. /**
  414. * Mail from name/email
  415. **/
  416. add_filter( 'wp_mail_from_name', 'jigoshop_mail_from_name' );
  417. function jigoshop_mail_from_name( $name ) {
  418. $name = get_bloginfo('name');
  419. $name = esc_attr($name);
  420. return $name;
  421. }
  422. /*
  423. add_filter( 'wp_mail_from', 'jigoshop_mail_from' );
  424. function jigoshop_mail_from( $email ) {
  425. $email = Jigoshop_Base::get_options()->get_option('jigoshop_email');
  426. return $email;
  427. }
  428. */
  429. /**
  430. * Allow product_cat in the permalinks for products.
  431. *
  432. * @param string $permalink The existing permalink URL.
  433. */
  434. add_filter( 'post_type_link', 'jigoshop_product_cat_filter_post_link', 10, 4 );
  435. function jigoshop_product_cat_filter_post_link( $permalink, $post, $leavename, $sample ) {
  436. if ($post->post_type!=='product') return $permalink;
  437. // Abort early if the placeholder rewrite tag isn't in the generated URL
  438. if ( false === strpos( $permalink, '%product_cat%' ) ) return $permalink;
  439. // Get the custom taxonomy terms in use by this post
  440. $terms = get_the_terms( $post->ID, 'product_cat' );
  441. if ( empty( $terms ) ) :
  442. // If no terms are assigned to this post, use a string instead
  443. $permalink = str_replace( '%product_cat%', _x('product', 'slug', 'jigoshop'), $permalink );
  444. else :
  445. // Replace the placeholder rewrite tag with the first term's slug
  446. $first_term = apply_filters( 'jigoshop_product_cat_permalink_terms', array_shift( $terms ), $terms);
  447. $permalink = str_replace( '%product_cat%', $first_term->slug, $permalink );
  448. endif;
  449. return $permalink;
  450. }
  451. /**
  452. * Evaluates to true only on the Shop page, not Product categories and tags
  453. * Note:is used to replace is_page( jigoshop_get_page_id( 'shop' ) )
  454. *
  455. * @return bool
  456. * @since 0.9.9
  457. */
  458. function is_shop() {
  459. return is_post_type_archive( 'product' ) || is_page( jigoshop_get_page_id('shop') );
  460. }
  461. /**
  462. * Evaluates to true only on the Category Pages
  463. *
  464. * @return bool
  465. * @since 0.9.9
  466. */
  467. function is_product_category() {
  468. return is_tax( 'product_cat' );
  469. }
  470. /**
  471. * Evaluates to true only on the Tag Pages
  472. *
  473. * @return bool
  474. * @since 0.9.9
  475. */
  476. function is_product_tag() {
  477. return is_tax( 'product_tag' );
  478. }
  479. /**
  480. * Evaluates to true only on the Single Product Page
  481. *
  482. * @return bool
  483. * @since 0.9.9
  484. */
  485. function is_product() {
  486. return is_singular( array('product') );
  487. }
  488. /**
  489. * Evaluates to true only on Shop, Product Category, and Product Tag pages
  490. *
  491. * @return bool
  492. * @since 0.9.9
  493. */
  494. function is_product_list() {
  495. $is_list = false;
  496. $is_list |= is_shop();
  497. $is_list |= is_product_tag();
  498. $is_list |= is_product_category();
  499. return $is_list;
  500. }
  501. /**
  502. * Evaluates to true for all Jigoshop pages
  503. *
  504. * @return bool
  505. * @since 0.9.9
  506. */
  507. function is_jigoshop() {
  508. $is_jigo = false;
  509. $is_jigo |= is_content_wrapped();
  510. $is_jigo |= is_account();
  511. $is_jigo |= is_cart();
  512. $is_jigo |= is_checkout();
  513. $is_jigo |= is_order_tracker();
  514. return $is_jigo;
  515. }
  516. /**
  517. * Evaluates to true only on the Shop, Category, Tag and Single Product Pages
  518. *
  519. * @return bool
  520. * @since 0.9.9.1
  521. */
  522. function is_content_wrapped() {
  523. $is_wrapped = false;
  524. $is_wrapped |= is_product_list();
  525. $is_wrapped |= is_product();
  526. return $is_wrapped;
  527. }
  528. /**
  529. * Jigoshop page IDs
  530. *
  531. * returns -1 if no page is found
  532. **/
  533. if (!function_exists('jigoshop_get_page_id')) {
  534. function jigoshop_get_page_id( $page ) {
  535. $jigoshop_options = Jigoshop_Base::get_options();
  536. $page = apply_filters('jigoshop_get_' . $page . '_page_id', $jigoshop_options->get_option('jigoshop_' . $page . '_page_id'));
  537. return ($page) ? $page : -1;
  538. }
  539. }
  540. /**
  541. * Evaluates to true only on the Order Tracking page
  542. *
  543. * @return bool
  544. * @since 0.9.9.1
  545. */
  546. function is_order_tracker() {
  547. return is_page( jigoshop_get_page_id('track_order'));
  548. }
  549. /**
  550. * Evaluates to true only on the Cart page
  551. *
  552. * @return bool
  553. * @since 0.9.8
  554. */
  555. function is_cart() {
  556. return is_page( jigoshop_get_page_id('cart'));
  557. }
  558. /**
  559. * Evaluates to true only on the Checkout or Pay pages
  560. *
  561. * @return bool
  562. * @since 0.9.8
  563. */
  564. function is_checkout() {
  565. return is_page( jigoshop_get_page_id('checkout')) | is_page( jigoshop_get_page_id('pay'));
  566. }
  567. /**
  568. * Evaluates to true only on the main Account or any sub-account pages
  569. *
  570. * @return bool
  571. * @since 0.9.9.1
  572. */
  573. function is_account() {
  574. $is_account = false;
  575. $is_account |= is_page( jigoshop_get_page_id('myaccount') );
  576. $is_account |= is_page( jigoshop_get_page_id('edit_address') );
  577. $is_account |= is_page( jigoshop_get_page_id('change_password') );
  578. $is_account |= is_page( jigoshop_get_page_id('view_order') );
  579. return $is_account;
  580. }
  581. if (!function_exists('is_ajax')) {
  582. function is_ajax() {
  583. if ( defined('DOING_AJAX') )
  584. return true;
  585. return ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' );
  586. }
  587. }
  588. function jigoshop_force_ssl() {
  589. if (is_checkout() && !is_ssl()) :
  590. wp_safe_redirect( str_replace('http:', 'https:', get_permalink(jigoshop_get_page_id('checkout'))), 301 );
  591. exit;
  592. endif;
  593. }
  594. if (!is_admin() && Jigoshop_Base::get_options()->get_option('jigoshop_force_ssl_checkout')=='yes') add_action( 'wp', 'jigoshop_force_ssl');
  595. function jigoshop_force_ssl_images( $content ) {
  596. if (is_ssl()) :
  597. if (is_array($content)) :
  598. $content = array_map('jigoshop_force_ssl_images', $content);
  599. else :
  600. $content = str_replace('http:', 'https:', $content);
  601. endif;
  602. endif;
  603. return $content;
  604. }
  605. add_filter('post_thumbnail_html', 'jigoshop_force_ssl_images');
  606. add_filter('widget_text', 'jigoshop_force_ssl_images');
  607. add_filter('wp_get_attachment_url', 'jigoshop_force_ssl_images');
  608. add_filter('wp_get_attachment_image_attributes', 'jigoshop_force_ssl_images');
  609. add_filter('wp_get_attachment_url', 'jigoshop_force_ssl_images');
  610. function jigoshop_force_ssl_urls( $url ) {
  611. if (is_ssl()) :
  612. $url = str_replace('http:', 'https:', $url);
  613. endif;
  614. return $url;
  615. }
  616. add_filter('option_siteurl', 'jigoshop_force_ssl_urls');
  617. add_filter('option_home', 'jigoshop_force_ssl_urls');
  618. add_filter('option_url', 'jigoshop_force_ssl_urls');
  619. add_filter('option_wpurl', 'jigoshop_force_ssl_urls');
  620. add_filter('option_stylesheet_url', 'jigoshop_force_ssl_urls');
  621. add_filter('option_template_url', 'jigoshop_force_ssl_urls');
  622. add_filter('script_loader_src', 'jigoshop_force_ssl_urls');
  623. add_filter('style_loader_src', 'jigoshop_force_ssl_urls');
  624. function get_jigoshop_currency_symbol() {
  625. $jigoshop_options = Jigoshop_Base::get_options();
  626. $currency = $jigoshop_options->get_option('jigoshop_currency');
  627. $symbols = jigoshop::currency_symbols();
  628. $currency_symbol = $symbols[$currency];
  629. return apply_filters('jigoshop_currency_symbol', $currency_symbol, $currency);
  630. }
  631. function jigoshop_price( $price, $args = array() ) {
  632. $jigoshop_options = Jigoshop_Base::get_options();
  633. extract(shortcode_atts(array(
  634. 'ex_tax_label' => 0, // 0 for no label, 1 for ex. tax, 2 for inc. tax
  635. 'with_currency' => true
  636. ), $args));
  637. $tax_label = '';
  638. if ($ex_tax_label === 1) {
  639. $tax_label = __(' <small>(ex. tax)</small>', 'jigoshop');
  640. } else if ($ex_tax_label === 2) {
  641. $tax_label = __(' <small>(inc. tax)</small>', 'jigoshop');
  642. } else {
  643. $tax_label = '';
  644. }
  645. $return = '';
  646. $price = number_format(
  647. (double) $price,
  648. (int) $jigoshop_options->get_option('jigoshop_price_num_decimals'),
  649. $jigoshop_options->get_option('jigoshop_price_decimal_sep'),
  650. $jigoshop_options->get_option('jigoshop_price_thousand_sep')
  651. );
  652. $return = $price;
  653. if ($with_currency) :
  654. $currency_pos = $jigoshop_options->get_option('jigoshop_currency_pos');
  655. $currency_symbol = get_jigoshop_currency_symbol();
  656. $currency_code = $jigoshop_options->get_option('jigoshop_currency');
  657. switch ($currency_pos) :
  658. case 'left' :
  659. $return = $currency_symbol . $price;
  660. break;
  661. case 'left_space' :
  662. $return = $currency_symbol . ' ' . $price;
  663. break;
  664. case 'right' :
  665. $return = $price . $currency_symbol;
  666. break;
  667. case 'right_space' :
  668. $return = $price . ' ' . $currency_symbol;
  669. break;
  670. case 'left_code' :
  671. $return = $currency_code . $price;
  672. break;
  673. case 'left_code_space' :
  674. $return = $currency_code . ' ' . $price;
  675. break;
  676. case 'right_code' :
  677. $return = $price . $currency_code;
  678. break;
  679. case 'right_code_space' :
  680. $return = $price . ' ' . $currency_code;
  681. break;
  682. case 'code_symbol' :
  683. $return = $currency_code . $price . $currency_symbol;
  684. break;
  685. case 'code_symbol_space' :
  686. $return = $currency_code . ' ' . $price . ' ' . $currency_symbol;
  687. break;
  688. case 'symbol_code' :
  689. $return = $currency_symbol . $price . $currency_code;
  690. break;
  691. case 'symbol_code_space' :
  692. $return = $currency_symbol . ' ' . $price . ' ' . $currency_code;
  693. break;
  694. endswitch;
  695. // only show tax label (ex. tax) if we are going to show the price with currency as well. Otherwise we just want the formatted price
  696. if ($jigoshop_options->get_option('jigoshop_calc_taxes')=='yes') $return .= $tax_label;
  697. endif;
  698. return $return;
  699. }
  700. /** Show variation info if set */
  701. function jigoshop_get_formatted_variation( $variation = '', $flat = false ) {
  702. if ($variation && is_array($variation)) :
  703. $return = '';
  704. if (!$flat) :
  705. $return = '<dl class="variation">';
  706. endif;
  707. $varation_list = array();
  708. foreach ($variation as $name => $value) :
  709. $name = str_replace('tax_', '', $name);
  710. if ( taxonomy_exists( 'pa_'.$name )) :
  711. $terms = get_terms( 'pa_'.$name, array( 'orderby' => 'slug', 'hide_empty' => '0' ) );
  712. foreach ( $terms as $term ) :
  713. if ( $term->slug == $value ) $value = $term->name;
  714. endforeach;
  715. $name = get_taxonomy( 'pa_'.$name )->labels->name;
  716. $name = jigoshop_product::attribute_label('pa_'.$name);
  717. endif;
  718. if ($flat) :
  719. $varation_list[] = $name.': '.$value;
  720. else :
  721. $varation_list[] = '<dt>'.$name.':</dt><dd>'.$value.'</dd>';
  722. endif;
  723. endforeach;
  724. if ($flat) :
  725. $return .= implode(', ', $varation_list);
  726. else :
  727. $return .= implode('', $varation_list);
  728. endif;
  729. if (!$flat) :
  730. $return .= '</dl>';
  731. endif;
  732. return $return;
  733. endif;
  734. }
  735. // Remove pingbacks/trackbacks from Comments Feed
  736. // betterwp.net/wordpress-tips/remove-pingbackstrackbacks-from-comments-feed/
  737. add_filter('request', 'jigoshop_filter_request');
  738. function jigoshop_filter_request($qv) {
  739. if (isset($qv['feed']) && !empty($qv['withcomments']))
  740. {
  741. add_filter('comment_feed_where', 'jigoshop_comment_feed_where');
  742. }
  743. return $qv;
  744. }
  745. function jigoshop_comment_feed_where($cwhere) {
  746. $cwhere .= " AND comment_type != 'jigoshop' ";
  747. return $cwhere;
  748. }
  749. function jigoshop_let_to_num($v) {
  750. $l = substr($v, -1);
  751. $ret = substr($v, 0, -1);
  752. switch(strtoupper($l)){
  753. case 'P':
  754. $ret *= 1024;
  755. case 'T':
  756. $ret *= 1024;
  757. case 'G':
  758. $ret *= 1024;
  759. case 'M':
  760. $ret *= 1024;
  761. case 'K':
  762. $ret *= 1024;
  763. break;
  764. }
  765. return $ret;
  766. }
  767. function jigowatt_clean( $var ) {
  768. return strip_tags(stripslashes(trim($var)));
  769. }
  770. // Returns a float value
  771. function jigoshop_sanitize_num( $var ) {
  772. // TODO: as it stands, it doesn't allow negative values (-JAP-)
  773. // should be - preg_replace("/^[^[\-\+]0-9\.]/","",$var)
  774. // currently only used for prices in product-data-save.php
  775. return strip_tags(stripslashes(floatval(preg_replace("/^[^0-9\.]/","",$var))));
  776. }
  777. // Author: Sergey Biryukov
  778. // Plugin URI: http://wordpress.org/extend/plugins/allow-cyrillic-usernames/
  779. add_filter('sanitize_user', 'jigoshop_sanitize_user', 10, 3);
  780. function jigoshop_sanitize_user($username, $raw_username, $strict) {
  781. $username = wp_strip_all_tags( $raw_username );
  782. $username = remove_accents( $username );
  783. $username = preg_replace( '|%([a-fA-F0-9][a-fA-F0-9])|', '', $username );
  784. $username = preg_replace( '/&.+?;/', '', $username ); // Kill entities
  785. if ( $strict )
  786. $username = preg_replace( '|[^a-z?-?0-9 _.\-@]|iu', '', $username );
  787. $username = trim( $username );
  788. $username = preg_replace( '|\s+|', ' ', $username );
  789. return $username;
  790. }
  791. add_action( 'wp_head', 'jigoshop_head_version' );
  792. function jigoshop_head_version() {
  793. echo "\n" . '<!-- Jigoshop Version: '.jigoshop::jigoshop_version().' -->' . "\n";
  794. }
  795. global $jigoshop_body_classes;
  796. add_action('wp_head', 'jigoshop_page_body_classes');
  797. function jigoshop_page_body_classes() {
  798. global $jigoshop_body_classes;
  799. $jigoshop_body_classes = (array) $jigoshop_body_classes;
  800. if ( is_order_tracker() ) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-tracker' ) );
  801. if ( is_checkout() ) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-checkout' ) );
  802. if ( is_cart() ) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-cart' ) );
  803. if ( is_page(jigoshop_get_page_id('thanks'))) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-thanks' ) );
  804. if ( is_page(jigoshop_get_page_id('pay'))) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-pay' ) );
  805. if ( is_account() ) jigoshop_add_body_class( array( 'jigoshop', 'jigoshop-myaccount' ) );
  806. }
  807. function jigoshop_add_body_class( $class = array() ) {
  808. global $jigoshop_body_classes;
  809. $jigoshop_body_classes = (array) $jigoshop_body_classes;
  810. $jigoshop_body_classes = array_unique( array_merge( $class, $jigoshop_body_classes ));
  811. }
  812. add_filter('body_class','jigoshop_body_class');
  813. function jigoshop_body_class($classes) {
  814. global $jigoshop_body_classes;
  815. $jigoshop_body_classes = (array) $jigoshop_body_classes;
  816. $classes = array_unique( array_merge( $classes, $jigoshop_body_classes ));
  817. return $classes;
  818. }
  819. //### Extra Review Field in comments #########################################################
  820. function jigoshop_add_comment_rating($comment_id) {
  821. if ( isset($_POST['rating']) ) :
  822. if (!$_POST['rating'] || $_POST['rating'] > 5 || $_POST['rating'] < 0) $_POST['rating'] = 5;
  823. add_comment_meta( $comment_id, 'rating', $_POST['rating'], true );
  824. endif;
  825. }
  826. add_action( 'comment_post', 'jigoshop_add_comment_rating', 1 );
  827. function jigoshop_check_comment_rating($comment_data) {
  828. // If posting a comment (not trackback etc) and not logged in
  829. if ( isset($_POST['rating']) && !jigoshop::verify_nonce('comment_rating') )
  830. wp_die( __('You have taken too long. Please go back and refresh the page.', 'jigoshop') );
  831. elseif ( isset($_POST['rating']) && empty($_POST['rating']) && $comment_data['comment_type']== '' ) {
  832. wp_die( __('Please rate the product.',"jigoshop") );
  833. exit;
  834. }
  835. return $comment_data;
  836. }
  837. add_filter('preprocess_comment', 'jigoshop_check_comment_rating', 0);
  838. //### Comments #########################################################
  839. function jigoshop_comments($comment, $args, $depth) {
  840. $GLOBALS['comment'] = $comment; global $post; ?>
  841. <li <?php comment_class(); ?> id="li-comment-<?php comment_ID() ?>">
  842. <div id="comment-<?php comment_ID(); ?>" class="comment_container">
  843. <?php echo get_avatar( $comment, $size='60' ); ?>
  844. <div class="comment-text">
  845. <?php if ( $rating = get_comment_meta( $comment->comment_ID, 'rating', true ) ): ?>
  846. <div class="star-rating" title="<?php echo esc_attr( $rating ); ?>">
  847. <span style="width:<?php echo $rating*16; ?>px"><?php echo $rating; ?> <?php _e('out of 5', 'jigoshop'); ?></span>
  848. </div>
  849. <?php endif; ?>
  850. <?php if ($comment->comment_approved == '0') : ?>
  851. <p class="meta"><em><?php _e('Your comment is awaiting approval','jigoshop'); ?></em></p>
  852. <?php else : ?>
  853. <p class="meta">
  854. <?php _e('Rating by','jigoshop'); ?> <strong class="reviewer vcard"><span class="fn"><?php comment_author(); ?></span></strong> <?php _e('on','jigoshop'); ?> <?php echo date_i18n(get_option('date_format'), strtotime(get_comment_date('Y-m-d'))); ?>:
  855. </p>
  856. <?php endif; ?>
  857. <div class="description"><?php comment_text(); ?></div>
  858. <div class="clear"></div>
  859. </div>
  860. <div class="clear"></div>
  861. </div>
  862. <?php
  863. }
  864. //### Exclude order comments from front end #########################################################
  865. add_filter( 'comments_clauses', 'jigoshop_exclude_order_admin_comments', 10, 1);
  866. function jigoshop_exclude_order_admin_comments( $clauses ) {
  867. // NOTE: bit of a hack, tests if we're in the admin & its an ajax call
  868. // Don't hide when viewing orders in admin
  869. if (is_admin() && is_ajax()) {
  870. return $clauses;
  871. }
  872. // Hide all those comments which aren't of type jigoshop
  873. $clauses['where'] .= ' AND comment_type != "jigoshop"';
  874. $clauses['where'] .= ' AND comment_type != "order_note"'; // Removes order notes
  875. return $clauses;
  876. }
  877. /**
  878. * Support for Import/Export
  879. *
  880. * WordPress import should work - however, it fails to import custom product attribute taxonomies.
  881. * This code grabs the file before it is imported and ensures the taxonomies are created.
  882. **/
  883. function jigoshop_import_start() {
  884. global $wpdb;
  885. $jigoshop_options = Jigoshop_Base::get_options();
  886. $id = (int) $_POST['import_id'];
  887. $file = get_attached_file( $id );
  888. $parser = new WXR_Parser();
  889. $import_data = $parser->parse( $file );
  890. if (isset($import_data['posts'])) :
  891. $posts = $import_data['posts'];
  892. if ($posts && sizeof($posts)>0) foreach ($posts as $post) :
  893. if ($post['post_type']=='product') :
  894. if ($post['terms'] && sizeof($post['terms'])>0) :
  895. foreach ($post['terms'] as $term) :
  896. $domain = $term['domain'];
  897. if (strstr($domain, 'pa_')) :
  898. // Make sure it exists!
  899. if (!taxonomy_exists( $domain )) :
  900. $nicename = sanitize_title(str_replace('pa_', '', $domain));
  901. $exists_in_db = $wpdb->get_var( $wpdb->prepare( "SELECT attribute_id FROM ".$wpdb->prefix . "jigoshop_attribute_taxonomies WHERE attribute_name = %s;", $nicename ) );
  902. // Create the taxonomy
  903. if (!$exists_in_db) :
  904. $wpdb->insert( $wpdb->prefix . "jigoshop_attribute_taxonomies", array( 'attribute_name' => $nicename, 'attribute_type' => 'select' ), array( '%s', '%s' ) );
  905. endif;
  906. // Register the taxonomy now so that the import works!
  907. register_taxonomy( $domain,
  908. array('product'),
  909. array(
  910. 'hierarchical' => true,
  911. 'labels' => array(
  912. 'name' => $nicename,
  913. 'singular_name' => $nicename,
  914. 'search_items' => __( 'Search ', 'jigoshop') . $nicename,
  915. 'all_items' => __( 'All ', 'jigoshop') . $nicename,
  916. 'parent_item' => __( 'Parent ', 'jigoshop') . $nicename,
  917. 'parent_item_colon'=> __( 'Parent ', 'jigoshop') . $nicename . ':',
  918. 'edit_item' => __( 'Edit ', 'jigoshop') . $nicename,
  919. 'update_item' => __( 'Update ', 'jigoshop') . $nicename,
  920. 'add_new_item' => __( 'Add New ', 'jigoshop') . $nicename,
  921. 'new_item_name' => __( 'New ', 'jigoshop') . $nicename
  922. ),
  923. 'show_ui' => false,
  924. 'query_var'=> true,
  925. 'rewrite' => array( 'slug'=> sanitize_title($nicename), 'with_front'=> false, 'hierarchical'=> true ),
  926. )
  927. );
  928. $jigoshop_options->set_option('jigowatt_update_rewrite_rules', '1');
  929. endif;
  930. endif;
  931. endforeach;
  932. endif;
  933. endif;
  934. endforeach;
  935. endif;
  936. }
  937. add_action('import_start', 'jigoshop_import_start');
  938. if(!function_exists('jigoshop_log')){
  939. /**
  940. * Logs to the debug log when you enable wordpress debug mode.
  941. *
  942. * @param string $from_class is the name of the php file that you are logging from.
  943. * defaults to jigoshop if non is supplied.
  944. * @param mixed $message this can be a regular string, array or object
  945. */
  946. function jigoshop_log( $message, $from_class = 'jigoshop' ) {
  947. if( WP_DEBUG === true ) :
  948. if( is_array( $message ) || is_object( $message ) ) :
  949. error_log( $from_class . ': ' . print_r( $message, true ) );
  950. else :
  951. error_log( $from_class . ': ' . $message );
  952. endif;
  953. endif;
  954. }
  955. }