diff --git a/Makefile b/Makefile index 5ac1bf5b9786989748be9f873f154b4c14f9c92a..b0a5abe7ce77ee7a4ab2803e91220aaab27d3e61 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -BASE=ordernumbers +BASE=shippingbyrules PLATTFORM=woocommerce VENDOR=opentools -VERSION=1.1 +VERSION=1.0 DIR = $(shell pwd) SVNDIR=wordpress-plugin-svn @@ -9,9 +9,9 @@ BUILDDIR=.build/ BASICBUILDDIR=$(VENDOR)-$(PLATTFORM)-$(BASE)-basic ADVBUILDDIR=$(VENDOR)-$(PLATTFORM)-$(BASE)-advanced -PLUGINFILES=library assets ordernumber_helper_woocommerce.php ordernumbers_woocommerce_basic.php readme.txt LICENSE.txt -BASICPLUGINFILES=woocommerce-basic-ordernumbers.php -ADVPLUGINFILES=woocommerce-advanced-ordernumbers.php ordernumbers_woocommerce.php +PLUGINFILES=library assets includes LICENSE.txt +BASICPLUGINFILES=shipping-by-rules.php readme.txt +ADVPLUGINFILES=advanced-shipping-by-rules.php readme-adv.txt TRANSLATIONS= diff --git a/advanced-shipping-by-rules.php b/advanced-shipping-by-rules.php new file mode 100644 index 0000000000000000000000000000000000000000..cb798a964df3fc55be9b9d759af6271a1a6c9e58 --- /dev/null +++ b/advanced-shipping-by-rules.php @@ -0,0 +1,284 @@ +<?php +/** + * Plugin Name: Advanced Shipping By Rules + * Plugin URI: http://open-tools.net/woocommerce/ + * Description: Define Shipping cost by very general and flexible (text-based) rules. The advanced version also provides mathematical expressions and functions + * Version: 1.0.0 + * Author: Open Tools, Reinhold Kainhofer + * Author URI: http://open-tools.net + * Text Domain: woocommerce-shipping-by-rules + * Domain Path: + * License: GPL2+ + * WC requires at least: 2.2 + * WC tested up to: 2.4 + + + * Copyright (C) 2015 Reinhold Kainhofer + * + * This file is part of WooCommerce Shipping By Rules, + * a plugin for WordPress and WooCommerce. + * + * WooCommerce Shipping By Rules is free software: + * You can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This software is distributed in the hope that + * it will be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WordPress. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class WooCommerce_Shipping_By_Rules_Advanced. + * + * Main Shipping by Rules class, add filters and handling all other files. + * + * @class WooCommerce_Shipping_By_Rules_Advanced + * @version 1.0.0 + * @author Reinhold Kainhofer + */ +class WooCommerce_Shipping_By_Rules_Advanced { + /** + * Version. + * + * @since 1.0.0 + * @var string $version Plugin version number. + */ + public $version = '1.0.0'; + + + /** + * Instance of WooCommerce_Shipping_By_Rules. + * + * @since 1.0.0 + * @access private + * @var object $instance The instance of WooCommerce_Shipping_By_Rules. + */ + private static $instance; + + + /** + * Constructor. + * + * @since 1.0.0 + */ + public function __construct() { + + if ( ! function_exists( 'is_plugin_active_for_network' ) ) + require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); + + // Check if WooCommerce is active + if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) : + if ( ! is_plugin_active_for_network( 'woocommerce/woocommerce.php' ) ) : + return; + endif; + endif; + + $this->init(); + + } + + + /** + * Instance. + * + * An global instance of the class. Used to retrieve the instance + * to use on other files/plugins/themes. + * + * @since 1.0.0 + * + * @return object Instance of the class. + */ + public static function instance() { + if ( is_null( self::$instance ) ) { + self::$instance = new self(); + } + return self::$instance; + } + + + /** + * Init. + * + * Initialize plugin parts. + * + * @since 1.0.0 + */ + public function init() { + $this->hooks(); + $this->load_textdomain(); + $this->update(); + + if (!class_exists("RulesShippingFrameworkWooCommerceAdvanced")) { + require_once( plugin_dir_path( __FILE__ ) . 'includes/rules_shipping_framework_woocommerce_advanced.php'); + } + $this->helper = RulesShippingFrameworkWooCommerceAdvanced::getHelper(); + + // Shipping method post type definition: + require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-post-type.php'; + $this->post_type = new Shipping_Rules_post_type($this->helper); + + // Links to docs and config in the plugin page + add_filter( 'plugin_row_meta', array( &$this, 'shippingbyrules_row_meta' ), 30, 2 ); + add_filter( 'plugin_action_links_'.plugin_basename(__FILE__), array( &$this, 'shippingbyrules_add_settings_link' ) ); + } + + + protected function shippingbyrules_row_meta($links, $file ) { + if ($file==plugin_basename(__FILE__)) { + $links['docs'] = '<a href="' . esc_url( 'http://open-tools.net/documentation/advanced-shipping-by-rules-for-woocommerce.html' ) . '" title="' . esc_attr( $this->helper->__( 'Plugin Documentation' ) ) . '">' . $this->helper->__( 'Plugin Documentation' ) . '</a>'; + $links['support'] = '<a href="' . esc_url( 'http://open-tools.net/support-forum/shiping-by-rules-for-woocommerce.html' ) . '" title="' . esc_attr( $this->helper->__( 'Support Forum' ) ) . '">' . $this->helper->__( 'Support Forum' ) . '</a>'; + } + return (array)$links; + } + /** + * Add settings link to plugins page + */ + protected function shippingbyrules_add_settings_link( $links ) { + $link = '<a href="admin.php?page=wc-settings&tab=shipping§ion=shipping_by_rules">'. $this->helper->__( 'Settings' ) . '</a>'; + array_push( $links, $link ); + return $links; + } + + + + /** + * Update. + * + * Runs when the plugin is updated and checks if there should be + * any data updated to be compatible for the new version. + * + * @since 1.0.0 + */ + public function update() { + + $db_version = get_option( 'shipping_by_rules_plugin_version', '1.0.0' ); + + // Stop current version is up to date + if ( $db_version >= $this->version ) : + return; + endif; + + // Update functions come here: + // From version 1.x.x to 1.x.y + // From version 1.x.y to 1.x.z + + update_option( 'shipping_by_rules_plugin_version', $this->version ); + + } + + + /** + * Hooks. + * + * Initialize all class hooks. + * + * @since 1.0.0 + */ + public function hooks() { + + // Initialize shipping method class + add_action( 'woocommerce_shipping_init', array( $this, 'shipping_by_rules_init' ) ); + + // Add shipping method + add_action( 'woocommerce_shipping_methods', array( $this, 'shipping_by_rules_add_shipping_method' ) ); + + // Enqueue scripts + add_action( 'admin_enqueue_scripts', array( $this, 'shipping_by_rules_admin_enqueue_scripts' ) ); + + } + + + /** + * Textdomain. + * + * Load the textdomain based on WP language. + * + * @since 1.0.0 + */ + public function load_textdomain() { + + // Load textdomain + load_plugin_textdomain('opentools-shippingrules', false, basename( dirname( __FILE__ ) ) . '/languages' ); + } + + + /** + * Shipping method. + * + * Include the WooCommerce shipping method class. + * + * @since 1.0.0 + */ + public function shipping_by_rules_init() { + require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-method.php'; + $this->rule_shipping_method = new Shipping_by_Rules(); + $this->rule_shipping_method->helper = $this->helper; + } + + + /** + * Add shipping method. + * + * Add shipping method to WooCommerce. + * + * @since 1.0.0 + */ + public function shipping_by_rules_add_shipping_method( $methods ) { + if ( class_exists( 'Shipping_by_Rules' ) ) : + $methods[] = 'Shipping_by_Rules'; + endif; + // TODO: Figure out a way to add each shipping by rules method as a + // separate WooCommerce shipping method (ie. their order can be + // defined in the WC configuration and not only in the Shipping by + // Rules Method configuration screen. + return $methods; + } + + + /** + * Enqueue scripts. + * + * Enqueue javascript and stylesheets to the admin area. + * + * @since 1.0.0 + */ + public function shipping_by_rules_admin_enqueue_scripts() { + // For some strange reason, WC does not define the select2.css style... + $assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/'; + wp_enqueue_style( 'select2', $assets_path . 'css/select2.css' ); + + wp_enqueue_style( 'shipping_by_rules-style', plugins_url( 'assets/css/admin-styles.css', __FILE__ ), array('select2'), $this->version ); + wp_enqueue_script( 'shipping-by-rules-config', plugins_url( 'assets/js/shipping-by-rules-config.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable', 'select2', 'wc-enhanced-select' ), $this->version, true ); + + } + + +} + + +/** + * The main function responsible for returning the WooCommerce_Shipping_By_Rules_Advanced object. + * + * Use this function like you would a global variable, except without needing to declare the global. + * + * Example: <?php OpenTools_ShippingByRules()->method_name(); ?> + * + * @since 1.0.0 + * + * @return object WooCommerce_Shipping_By_Rules_Advanced class object. + */ +if ( ! function_exists( 'OpenTools_ShippingByRules' ) ) : + + function OpenTools_ShippingByRules() { + return WooCommerce_Shipping_By_Rules_Advanced::instance(); + } + +endif; + +OpenTools_ShippingByRules(); diff --git a/assets/css/admin-styles.css b/assets/css/admin-styles.css index ecade0a26ebf04a15d146e404d823d353ff1d80e..94ac88b8ee0bfce0438d2a3f55fe28f338476f03 100644 --- a/assets/css/admin-styles.css +++ b/assets/css/admin-styles.css @@ -101,3 +101,43 @@ div.shipping_rules_ruleset { <h3 class="hndle ui-sortable-handle">Ruleset: <span class="input-wrap"><input type='text' class='ruleset_name' name='<?php echo $id; ?>[name]' placeholder='<?php _e('Name of the Ruleset', 'opentools-shippingrules'); ?>' value='<?php echo isset($ruleset['name'])?esc_attr($ruleset['name']):""; ?>'></span></h3> </div>*/ + +div#opentools-shippingbyrules-upgrade { +/* margin-top: 1em; */ +/* padding-left: 15px; */ +/* border-radius: 5px; */ +/* border: 1px solid red; */ +/* background: #ff8080; */ + padding: 5px 10px; +} +div#opentools-shippingbyrules-upgrade.postbox { + display: inline-block; +} +div#opentools-shippingbyrules-upgrade h3 { +/* margin-top: 5px; */ +/* margin-bottom: 5px; */ +/* padding: 0px 10px 5px 10px; */ +/* border-bottom: 1px solid #e0e0e0; */ +} +div#opentools-shippingbyrules-upgrade ul { + list-style: disc; +/* list-style-position: inside; */ + margin-left: 5px; + padding-left: 5px; +} +div#opentools-shippingbyrules-upgrade li { + margin-left: 2em; +} +div#opentools-shippingbyrules-upgrade .column1, div#opentools-shippingbyrules-upgrade .column2 { + float: left; +} + +div#opentools-shippingbyrules-upgrade .logoleft { + float: left; + padding-right: 10px; + position: absolute; + left: 15px; +} +div#opentools-shippingbyrules-upgrade .contents { + padding-left: 120px; +} \ No newline at end of file diff --git a/assets/css/shipping-rules-config.css b/assets/css/shipping-rules-config.css deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/assets/images/advlogo100.png b/assets/images/advlogo100.png new file mode 100644 index 0000000000000000000000000000000000000000..5f2c50e3a161fba5a2d10ebe925744f93136680a Binary files /dev/null and b/assets/images/advlogo100.png differ diff --git a/includes/admin/settings/settings-shipping-rules.php b/includes/admin/settings/settings-shipping-rules.php deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/includes/rules-shipping-method.php b/includes/rules-shipping-method.php index b88dd555bbf0456cf5e13d4091924458dba21e23..8d2cc10d5434021092f185af598f89068fb29441 100644 --- a/includes/rules-shipping-method.php +++ b/includes/rules-shipping-method.php @@ -17,11 +17,14 @@ class Shipping_by_Rules extends WC_Shipping_Method { * @return void */ public function __construct() { - if (!class_exists("RulesShippingFrameworkWooCommerce")) { - require_once( plugin_dir_path( __FILE__ ) . '/rules_shipping_framework_woocommerce.php'); + if (class_exists("RulesShippingFrameworkWooCommerceAdvanced")) { + $this->helper = RulesShippingFrameworkWooCommerceAdvanced::getHelper(); + } else { + if (!class_exists("RulesShippingFrameworkWooCommerce")) { + require_once( plugin_dir_path( __FILE__ ) . 'includes/rules_shipping_framework_woocommerce.php'); + } + $this->helper = RulesShippingFrameworkWooCommerce::getHelper(); } - $this->helper = RulesShippingFrameworkWooCommerce::getHelper(); - $this->id = 'shipping_by_rules'; // Id for your shipping method. Should be uunique. $this->title = $this->helper->__( 'Shipping By Rules <small>(displayed title changes according to configured methods)</small>'); $this->method_title = $this->helper->__( 'Shipping by Rules' ); // Title shown in admin @@ -54,22 +57,26 @@ class Shipping_by_Rules extends WC_Shipping_Method { * @return void */ public function init_form_fields() { - $this->form_fields = array( - 'enabled' => array( - 'title' => __( 'Enable/Disable', 'woocommerce' ), - 'type' => 'checkbox', - 'label' => $this->helper->__( 'Enable Shipping By Rules'), - 'default' => 'yes' - ), - 'methods' => array( - 'type' => 'rules_shipping_methods', - ), + add_filter( 'woocommerce_admin_field_opentools_shippingbyrules_upgrade', array( &$this, 'admin_field_opentools_shippingbyrules_upgrade') ); + $fields = array_merge( + $this->helper->getUpgradeNagSettings(), + array( + 'enabled' => array( + 'title' => __( 'Enable/Disable', 'woocommerce' ), + 'type' => 'checkbox', + 'label' => $this->helper->__( 'Enable Shipping By Rules'), + 'default' => 'yes' + ), + 'methods' => array( + 'type' => 'rules_shipping_methods', + ), + ) ); + $this->form_fields = $fields; } - /** - * generate_additional_costs_html function. + * generate_rules_shipping_methods_html function. * * @access public * @return string @@ -92,6 +99,28 @@ class Shipping_by_Rules extends WC_Shipping_Method { public function validate_rules_shipping_methods_field( $key ) { return false; } + + /** + * generate_rules_shipping_methods_html function. + * + * @access public + * @return string + */ + public function generate_opentools_shippingbyrules_upgrade_html($id, $settings) { + if (isset($settings['name'])) { + $settings['title'] = $settings['name']; + } + ob_start(); + ?> + <tr valign="top"> + <td colspan="2"> + <?php $this->helper->printUpgradeNagBox($settings); ?> + </td> + </tr> + <?php + return ob_get_clean(); + } + /** * Handle shipping rules settings diff --git a/includes/rules-shipping-post-type.php b/includes/rules-shipping-post-type.php index a2a52d75f0e3a1d8c0d673236f16f214181e54b7..63b53ea7067970042ecda6840dfe19971f54e1e6 100644 --- a/includes/rules-shipping-post-type.php +++ b/includes/rules-shipping-post-type.php @@ -16,15 +16,16 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly */ class Shipping_Rules_post_type { - + protected $helper = null; /** * Constructor. * * @since 1.0.0 */ - public function __construct() { - + public function __construct($helper) { + $this->helper = $helper; + // Register post type add_action( 'init', array( $this, 'shipping_rules_register_post_type' ) ); @@ -55,16 +56,16 @@ class Shipping_Rules_post_type { public function shipping_rules_register_post_type() { $labels = array( - 'name' => __( 'Shipping By Rules Methods', 'opentools-shippingrules' ), - 'singular_name' => __( 'Shipping By Rules method', 'opentools-shippingrules' ), - 'add_new' => __( 'Add New', 'opentools-shippingrules' ), - 'add_new_item' => __( 'Add New Shipping by Rules method', 'opentools-shippingrules' ), - 'edit_item' => __( 'Edit Shipping by Rules method', 'opentools-shippingrules' ), - 'new_item' => __( 'New Shipping by Rules method', 'opentools-shippingrules' ), - 'view_item' => __( 'View Shipping by Rules method', 'opentools-shippingrules' ), - 'search_items' => __( 'Search Shipping by Rules methods', 'opentools-shippingrules' ), - 'not_found' => __( 'No Shipping by Rules methods', 'opentools-shippingrules' ), - 'not_found_in_trash' => __( 'No Shipping by Rules methods found in Trash', 'opentools-shippingrules' ), + 'name' => $this->helper->__( 'Shipping By Rules Methods' ), + 'singular_name' => $this->helper->__( 'Shipping By Rules method' ), + 'add_new' => $this->helper->__( 'Add New' ), + 'add_new_item' => $this->helper->__( 'Add New Shipping by Rules method' ), + 'edit_item' => $this->helper->__( 'Edit Shipping by Rules method' ), + 'new_item' => $this->helper->__( 'New Shipping by Rules method' ), + 'view_item' => $this->helper->__( 'View Shipping by Rules method' ), + 'search_items' => $this->helper->__( 'Search Shipping by Rules methods' ), + 'not_found' => $this->helper->__( 'No Shipping by Rules methods' ), + 'not_found_in_trash' => $this->helper->__( 'No Shipping by Rules methods found in Trash' ), ); register_post_type( 'shipping_rules', array( @@ -103,27 +104,27 @@ class Shipping_Rules_post_type { $messages['shipping_rules'] = array( 0 => '', - 1 => __( 'Shipping by Rules method updated.', 'opentools-shippingrules' ), - 2 => __( 'Custom field updated.', 'opentools-shippingrules' ), - 3 => __( 'Custom field deleted.', 'opentools-shippingrules' ), - 4 => __( 'Shipping by Rules method updated.', 'opentools-shippingrules' ), + 1 => $this->helper->__( 'Shipping by Rules method updated.' ), + 2 => $this->helper->__( 'Custom field updated.' ), + 3 => $this->helper->__( 'Custom field deleted.' ), + 4 => $this->helper->__( 'Shipping by Rules method updated.' ), 5 => isset( $_GET['revision'] ) ? - sprintf( __( 'Shipping by Rules method restored to revision from %s', 'opentools-shippingrules' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) + sprintf( $this->helper->__( 'Shipping by Rules method restored to revision from %s' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => __( 'Shipping by Rules method published.', 'opentools-shippingrules' ), - 7 => __( 'Shipping by Rules method saved.', 'opentools-shippingrules' ), - 8 => __( 'Shipping by Rules method submitted.', 'opentools-shippingrules' ), + 6 => $this->helper->__( 'Shipping by Rules method published.' ), + 7 => $this->helper->__( 'Shipping by Rules method saved.' ), + 8 => $this->helper->__( 'Shipping by Rules method submitted.' ), 9 => sprintf( - __( 'Shipping by Rules method scheduled for: <strong>%1$s</strong>.', 'opentools-shippingrules' ), - date_i18n( __( 'M j, Y @ G:i', 'opentools-shippingrules' ), strtotime( $post->post_date ) ) + $this->helper->__( 'Shipping by Rules method scheduled for: <strong>%1$s</strong>.' ), + date_i18n( $this->helper->__( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) ), - 10 => __( 'Shipping by Rules method draft updated.', 'opentools-shippingrules' ), + 10 => $this->helper->__( 'Shipping by Rules method draft updated.' ), ); if ( 'shipping_rules' == $post_type ) : $overview_link = admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=shipping_by_rules' ); - $overview = sprintf( ' <a href="%s">%s</a>', esc_url( $overview_link ), __( 'Return to overview.', 'opentools-shippingrules' ) ); + $overview = sprintf( ' <a href="%s">%s</a>', esc_url( $overview_link ), $this->helper->__( 'Return to overview.' ) ); $messages[ $post_type ][1] .= $overview; $messages[ $post_type ][6] .= $overview; $messages[ $post_type ][9] .= $overview; @@ -154,16 +155,20 @@ class Shipping_Rules_post_type { */ public function shipping_rules_post_type_meta_box($post) { // my_add_notice( "shipping_rules_post_type_meta_box called", 'info'); - add_meta_box( 'shipping_rules_settings', __( 'Shipping settings', 'opentools-shippingrules' ), array( $this, 'render_shipping_rules_settings' ), 'shipping_rules', 'normal' ); + if (!$this->helper->isAdvanced()) { + add_meta_box( 'shipping_rules_upgrade', $this->helper->__( 'Upgrade to the ADVANCED VERSION of the OpenTools Shipping by Rules plugin + ' ), array( $this, 'render_shipping_upgrade' ), 'shipping_rules', 'normal' ); + } + add_meta_box( 'shipping_rules_settings', $this->helper->__( 'Shipping settings' ), array( $this, 'render_shipping_rules_settings' ), 'shipping_rules', 'normal' ); add_meta_box( /* ID */ 'shipping_rules_rulesets', - /* Title */ __( 'Rulesets', 'opentools-shippingrules' ), + /* Title */ $this->helper->__( 'Rulesets' ), /* Callback */array( $this, 'render_shipping_rulesets' ), /* Screen */ 'shipping_rules', /* Context */ 'advanced'); - add_meta_box( 'shipping_rules_help', __( 'Overview of the Rules Syntax', 'opentools-shippingrules' ), array( $this, 'render_shipping_rules_help' ), 'shipping_rules', 'side' ); + add_meta_box( 'shipping_rules_help', $this->helper->__( 'Overview of the Rules Syntax' ), array( $this, 'render_shipping_rules_help' ), 'shipping_rules', 'side' ); } @@ -174,6 +179,10 @@ class Shipping_Rules_post_type { * * @since 1.0.0 */ + public function render_shipping_upgrade($post, $metabox) { + $this->helper->printUpgradeNagBox($this->helper->getUpgradeNagSettings()['opentools_shippingbyrules_upgrade']); + } + public function render_shipping_rulesets($post, $metabox) { $rulesets = $this->get_rulesets($post); require_once plugin_dir_path( __FILE__ ) . 'admin/settings/meta-box-rulesets.php'; @@ -235,6 +244,12 @@ class Shipping_Rules_post_type { return $post_id; endif; + // Updating the method ordering should only be done when we are on the overview page and have all methods submitted as form controls. + // Otherwise, the update_post_meta would erase all methods! + if (!isset($_POST['_rules_shipping_ruleset']) or !isset($_POST['_rules_shipping_ordering'])) { + return $post_id; + } + $shipping_method_rulesets = $_POST['_rules_shipping_ruleset']; $shipping_method_ordering = $_POST['_rules_shipping_ordering']; @@ -242,7 +257,6 @@ class Shipping_Rules_post_type { foreach ($shipping_method_ordering as $o) { $rulesets[] = $shipping_method_rulesets[$o]; } - update_post_meta( $post_id, '_rules_shipping_ruleset', $rulesets ); } diff --git a/includes/rules_shipping_framework_woocommerce.php b/includes/rules_shipping_framework_woocommerce.php index e795d85487f588c9112e21f41209234734372584..0cf67c609b2d5addcdebc973b12e75813596908b 100644 --- a/includes/rules_shipping_framework_woocommerce.php +++ b/includes/rules_shipping_framework_woocommerce.php @@ -11,6 +11,26 @@ if ( !defined( 'ABSPATH' ) ) { } require_once( plugin_dir_path( __FILE__ ) . '/../library/rules_shipping_framework.php'); +/** + * Throw debugging output into Debug My Plugin (3rd party plugin) + * + * @param string $panel the panel name, default is 'main' + * @param string $type the type 'pr' or 'msg' + * @param string $hdr the message header + * @param mixed $msg the variable to dump ('pr') or print ('msg') + * @param string $file __FILE__ from calling location + * @param string $line __LINE__ from calling location + * @return null + */ +function render_ToDebugBar($hdr,$msg,$file=null,$line=null) { + if (!isset($GLOBALS['DebugMyPlugin'])) { return; } + if (is_string($msg)) { + $GLOBALS['DebugMyPlugin']->panels['main']->addMessage($hdr,$msg,$file,$line); + } else { + $GLOBALS['DebugMyPlugin']->panels['main']->addPR($hdr,$msg,$file,$line); + } +} + class RulesShippingFrameworkWooCommerce extends RulesShippingFramework { protected static $_method_ordering = 'woocommerce_shipping_rules_ordering'; @@ -30,16 +50,19 @@ class RulesShippingFrameworkWooCommerce extends RulesShippingFramework { return plugins_url('library/' . $type . '/' . $file, __FILE__); } + function isAdvanced() { + return false; + } function getCustomFunctions() { // Let other plugins add custom functions! - // The onVmShippingRulesRegisterCustomFunctions() trigger is expected to return an array of the form: + // The opentools_shipping_by_rules_replacements filter is expected to return an array of the form: // array ('functionname1' => 'function-to-be-called', // 'functionname2' => array($classobject, 'memberfunc')), // ...); return apply_filters( 'opentools_shipping_by_rules_replacements', array()); } - protected function printWarning($message) { + public function printWarning($message) { // Keep track of warning messages, so we don't print them twice: global $printed_warnings; if (!isset($printed_warnings)) @@ -198,7 +221,6 @@ class RulesShippingFrameworkWooCommerce extends RulesShippingFramework { 'categories' => $categories, 'tags' => $tags, 'shippingclasses' => $shipping_classes, - 'coupons' => $cart['applied_coupons'], ); } @@ -311,7 +333,45 @@ class RulesShippingFrameworkWooCommerce extends RulesShippingFramework { } protected function createMethodRule ($r, $countries, $ruleinfo) { - return new ShippingRule_Advanced($this, $r, $countries, $ruleinfo); + return new ShippingRule($this, $r, $countries, $ruleinfo); } + + public function getUpgradeNagSettings() { + $settings = array(); + if (!$this->isAdvanced()) { + $settings['opentools_shippingbyrules_upgrade'] = array( + 'name' => $this->__( 'Upgrade to the ADVANCED VERSION of the OpenTools Shipping by Rules plugin'), + 'type' => 'opentools_shippingbyrules_upgrade', + 'link' => 'http://open-tools.net/woocommerce/advanced-shipping-by-rules-for-woocommerce.html', + ); + } + return $settings; + } + + public function printUpgradeNagBox($settings) { + ?> + <div id="opentools-shippingbyrules-upgrade" class="rules_shipping rules_shipping_upgrade rules_shipping_meta_box rules_shipping_settings_meta_box postbox"> + <?php if (isset($settings['title'])) { ?><h3><?php echo esc_html($settings['title']); ?></h3><? } ?> + <div class="contents"> + <div class="logoleft"><a href="<?php echo esc_html($settings['link']); ?>"><img src="<?php echo plugins_url('../assets/images/advlogo100.png', __FILE__); ?>"></a></div> + <p>Advanced features not included in the free plugin include:</p> + <ul> + <li><b>Mathematical expressions</b>: shipping costs can be calculated from arbitrary mathematical expressions (depending on e.g. weight, dimensions, amount, etc.), e.g.: + <ul> + <li>Shipping costs per kg</li> + <li>Percentage shipping cost on the amount</li> + </ul> + <li><b>List functions</b>: conditions on certain products, categories, tags or shipping classes</li> + <li><b>Conditions for product subsets</b>: Conditions and shippind costs depending on values evaluated only for particular products, categories, tags or shipping classes + <li><b>Alphanumeric Postcodes</b>: Conditions on UK and Canadian postcodes</li> + <li><b>Coupon Codes</b>: conditions on coupon codes</li> + <li>...</li> + </ul> + <p>More information and purchase: <a class="button-primary" href="<?php echo esc_html($settings['link']); ?>" target="_blank">Get Support and advanced features</a></p> + </div> + </div> + <?php + } + } diff --git a/includes/rules_shipping_framework_woocommerce_advanced.php b/includes/rules_shipping_framework_woocommerce_advanced.php new file mode 100644 index 0000000000000000000000000000000000000000..8db8ea5af39f2763758728552770feea75cde688 --- /dev/null +++ b/includes/rules_shipping_framework_woocommerce_advanced.php @@ -0,0 +1,51 @@ +<?php +/** + * Shipping by Rules generic helper class (Joomla/VM-specific) + * Reinhold Kainhofer, Open Tools, office@open-tools.net + * @copyright (C) 2012-2015 - Reinhold Kainhofer + * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html +**/ + +if ( !defined( 'ABSPATH' ) ) { + die( 'Direct Access to ' . basename( __FILE__ ) . ' is not allowed.' ); +} +require_once( plugin_dir_path( __FILE__ ) . '/rules_shipping_framework_woocommerce.php'); + +class RulesShippingFrameworkWooCommerceAdvanced extends RulesShippingFrameworkWooCommerce { + + static function getHelper() { + static $helper = null; + if (!$helper) { + $helper = new RulesShippingFrameworkWooCommerceAdvanced(); + $helper->setup(); + } + return $helper; + } + function _construct() { + parent::_construct(); + } + function isAdvanced() { + return true; + } + protected function getOrderAddress ($cart, $method) { + $data = parent::getOrderAddress($this, $cart, $method); + $zip = isset($address['postcode'])?trim($address['postcode']):''; + if (isset($zip) && $zip!='') { + $data = array_merge($data, $this->getAddressZIP($zip); + } + return $data; + } + + protected function createMethodRule ($r, $countries, $ruleinfo) { + return new ShippingRule_Advanced($this, $r, $countries, $ruleinfo); + } + + protected function addCustomCartValues ($cart, $products, $method, &$values) { + $data = array( + 'coupons' => $cart['applied_coupons'], + ); + return $data; + } + + +} diff --git a/library/rules_shipping_framework.php b/library/rules_shipping_framework.php index 71c72d16a2f50b3fe7940aad3489d1cc8018f6b1..d2bcb008e49f566233e7d1d30ee8057740c09ef0 100644 --- a/library/rules_shipping_framework.php +++ b/library/rules_shipping_framework.php @@ -239,6 +239,46 @@ class RulesShippingFramework { protected function getOrderPrices ($cart, $products, $method) { return array(); } + + /** + * Extract information about non-numerical zip codes (UK and Canada) from the postal code + */ + protected function getAddressZIP ($zip) { + $values = array(); + + // Postal code Check for UK postal codes: Use regexp to determine if ZIP structure matches and also to extract the parts. + // Also handle UK overseas areas/islands that use four-letter outward codes rather than "A{1,2}0{1,2}A{0,1} 0AA" + $zip=strtoupper($zip); + if (isset($zip) and preg_match('/^\s*(([A-Z]{1,2})(\d{1,2})([A-Z]?)|[A-Z]{4}|GIR)\s*(\d[A-Z]{2})\s*$/', $zip, $match)) { + $values['uk_outward'] = $match[1]; + $values['uk_area'] = $match[2]; + $values['uk_district'] = $match[3]; + $values['uk_subdistrict'] = $match[4]; + $values['uk_inward'] = $match[5]; + } else { + $values['uk_outward'] = NULL; + $values['uk_area'] = NULL; + $values['uk_district'] = NULL; + $values['uk_subdistrict'] = NULL; + $values['uk_inward'] = NULL; + } + // Postal code Check for Canadian postal codes: Use regexp to determine if ZIP structure matches and also to extract the parts. + if (isset($zip) and preg_match('/^\s*(([A-Za-z])(\d)([A-Za-z]))\s*(\d[A-Za-z]\d)\s*$/', $zip, $match)) { + $values['canada_fsa'] = $match[1]; + $values['canada_area'] = $match[2]; + $values['canada_urban'] = $match[3]; + $values['canada_subarea'] = $match[4]; + $values['canada_ldu'] = $match[5]; + } else { + $values['canada_fsa'] = NULL; + $values['canada_area'] = NULL; + $values['canada_urban'] = NULL; + $values['canada_subarea'] = NULL; + $values['canada_ldu'] = NULL; + } + // print("<pre>values: ".print_r($values,1)."</pre>"); + return $values; + } /** Allow child classes to add additional variables for the rules or modify existing one */ @@ -702,9 +742,11 @@ class ShippingRule { if (count($conditionvals)<1) return $this->evaluateTerm($expr, $vals, $products, $cartvals_callback); + // TODO: Make this more general! $filterkeys = array( "evaluate_for_categories" => 'categories', "evaluate_for_products" => 'products', + "evaluate_for_skus" => 'products', "evaluate_for_vendors" => 'vendors', "evaluate_for_manufacturers" => 'manufacturers' ); diff --git a/shipping-by-rules.php b/shipping-by-rules.php index 5d58f96da8f95e2b8a01271778cc0a10f6edbccb..320fe603884fcffe3c0ae148ddf85255990d4bc7 100644 --- a/shipping-by-rules.php +++ b/shipping-by-rules.php @@ -1,7 +1,7 @@ <?php /** * Plugin Name: Shipping By Rules - * Plugin URI: http://open-tools.net/woocommerce/ + * Plugin URI: http://open-tools.net/woocommerce/advanced-shipping-by-rules-for-woocommerce.html * Description: Define Shipping cost by very general and flexible (text-based) rules. * Version: 1.0.0 * Author: Open Tools, Reinhold Kainhofer @@ -10,7 +10,7 @@ * Domain Path: * License: GPL2+ * WC requires at least: 2.2 - * WC tested up to: 2.3 + * WC tested up to: 2.4 * Copyright (C) 2015 Reinhold Kainhofer @@ -114,13 +114,40 @@ class WooCommerce_Shipping_By_Rules { $this->load_textdomain(); $this->update(); + if (!class_exists("RulesShippingFrameworkWooCommerce")) { + require_once( plugin_dir_path( __FILE__ ) . 'includes/rules_shipping_framework_woocommerce.php'); + } + $this->helper = RulesShippingFrameworkWooCommerce::getHelper(); + // Shipping method post type definition: require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-post-type.php'; - $this->post_type = new Shipping_Rules_post_type(); + $this->post_type = new Shipping_Rules_post_type($this->helper); + // Links to docs and config in the plugin page + add_filter( 'plugin_row_meta', array( &$this, 'shippingbyrules_row_meta' ), 30, 2 ); + add_filter( 'plugin_action_links_'.plugin_basename(__FILE__), array( &$this, 'shippingbyrules_add_settings_link' ) ); } + public function shippingbyrules_row_meta($links, $file ) { + if ($file==plugin_basename(__FILE__)) { + $links['docs'] = '<a href="' . esc_url( 'http://open-tools.net/documentation/advanced-shipping-by-rules-for-woocommerce.html' ) . '" title="' . esc_attr( $this->helper->__( 'Plugin Documentation' ) ) . '">' . $this->helper->__( 'Plugin Documentation' ) . '</a>'; + $links['support'] = '<a href="' . esc_url( 'http://open-tools.net/support-forum/shiping-by-rules-for-woocommerce.html' ) . '" title="' . esc_attr( $this->helper->__( 'Support Forum' ) ) . '">' . $this->helper->__( 'Support Forum' ) . '</a>'; + // ONLY IN BASIC VERSION: Purchase link + $links['advanced'] = '<a href="' . esc_url( 'http://open-tools.net/woocommerce/advanced-shipping-by-rules-for-woocommerce.html' ) . '" title="' . esc_attr( $this->helper->__('Purchase Advanced Version')) . '">' . $this->helper->__('Purchase Advanced Version') . '</a>'; + } + return (array)$links; + } + /** + * Add settings link to plugins page + */ + public function shippingbyrules_add_settings_link( $links ) { + $link = '<a href="admin.php?page=wc-settings&tab=shipping§ion=shipping_by_rules">'. $this->helper->__( 'Settings' ) . '</a>'; + array_push( $links, $link ); + return $links; + } + + /** * Update. * @@ -192,7 +219,6 @@ class WooCommerce_Shipping_By_Rules { public function shipping_by_rules_init() { require_once plugin_dir_path( __FILE__ ) . 'includes/rules-shipping-method.php'; $this->rule_shipping_method = new Shipping_by_Rules(); - } @@ -247,7 +273,7 @@ class WooCommerce_Shipping_By_Rules { * * @return object WooCommerce_Shipping_By_Rules class object. */ -if ( ! function_exists( 'Shipping_By_Rules' ) ) : +if ( ! function_exists( 'OpenTools_ShippingByRules' ) ) : function OpenTools_ShippingByRules() { return WooCommerce_Shipping_By_Rules::instance();