<?php
|
|
/**
|
|
* WooCommerce Cash On Pickup
|
|
* Copyright (C) 2013-2014 Pinch Of Code. All rights reserved.
|
|
* Copyright (C) 2017-2018 Marian Kadanka. All rights reserved.
|
|
* Copyright (C) 2020 Björn Hase, Tentakelfabrik. All rights reserved.
|
|
*
|
|
* This program 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 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
/**
|
|
* Main plugin class
|
|
*
|
|
* Provides a Cash on Pickup Payment Gateway.
|
|
*
|
|
* @class WooChop_Gateway_Cash_On_Pickup
|
|
* @extends WC_Payment_Gateway
|
|
*/
|
|
class WooChop_Gateway_Cash_On_Pickup extends WC_Payment_Gateway
|
|
{
|
|
const WOO_CHOP_ID = WOOCHOP_CASH_ON_PICKUP_ID;
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
public function __construct()
|
|
{
|
|
load_plugin_textdomain('woochop-cash-on-pickup', false, dirname(dirname(plugin_basename( __FILE__ ))).'/i18n/');
|
|
|
|
// Setup general properties
|
|
$this->setup_properties();
|
|
|
|
// Load the settings
|
|
$this->init_form_fields();
|
|
$this->init_settings();
|
|
|
|
// Get settings
|
|
$this->enabled = $this->get_option('enabled');
|
|
$this->title = $this->get_option('title');
|
|
$this->description = $this->get_option('description');
|
|
$this->instructions = $this->get_option('instructions');
|
|
$this->enable_for_methods = $this->get_option('enable_for_methods', array() );
|
|
$this->default_order_status = $this->get_option('default_order_status', apply_filters('wc_cop_default_order_status', 'on-hold'));
|
|
$this->exclusive_for_local = $this->get_option('exclusive_for_local');
|
|
$this->enable_for_virtual = $this->get_option('enable_for_virtual', 'yes') === 'yes' ? true : false;
|
|
|
|
add_action('woocommerce_update_options_payment_gateways_'.$this->id, array($this, 'process_admin_options'));
|
|
add_action('woocommerce_thankyou_' . $this->id, array($this, 'thankyou_page'));
|
|
|
|
// Customer Emails
|
|
add_action('woocommerce_email_before_order_table', array($this, 'email_instructions'), 10, 3);
|
|
|
|
if (!is_admin()) {
|
|
|
|
// Disable other payment methods if local pickup shippings
|
|
if ('yes' === $this->enabled && 'yes' === $this->exclusive_for_local) {
|
|
add_filter('woocommerce_available_payment_gateways', array($this, 'maybe_cop_only_if_local_pickup_shipping'));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup general properties for the gateway.
|
|
*/
|
|
protected function setup_properties() {
|
|
$this->id = self::WOO_CHOP_ID;
|
|
$this->icon = apply_filters('woocommerce_cop_icon', '');
|
|
$this->method_title = __('Cash on pickup', 'woochop-cash-on-pickup');
|
|
$this->method_description = __('Have your customers pay with cash on pickup.', 'woochop-cash-on-pickup');
|
|
$this->has_fields = false;
|
|
}
|
|
|
|
/**
|
|
* Get part of a string before :.
|
|
*
|
|
* Used for example in shipping methods ids where they take the format
|
|
* method_id:instance_id
|
|
*
|
|
* @param string $string
|
|
* @return string
|
|
*/
|
|
private function get_string_before_colon( $string )
|
|
{
|
|
return trim(current(explode(':', (string) $string)));
|
|
}
|
|
|
|
/**
|
|
* Check if every of the shipping methods is local pickup
|
|
*
|
|
* @param array $shipping_methods Shipping methods to check.
|
|
* @return bool
|
|
*/
|
|
private function only_local_pickups_selected( $shipping_methods )
|
|
{
|
|
// Local Pickup Plus fix
|
|
unset($shipping_methods['undefined']);
|
|
|
|
foreach($shipping_methods as $shipping_method) {
|
|
if (strpos($shipping_method, 'local_pickup') === false) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* COP will be the only payment method available if each of the shipping methods chosen is local pickup only
|
|
*
|
|
* @param array $gateways Payment methods to filter.
|
|
* @return array of filtered methods
|
|
*/
|
|
public function maybe_cop_only_if_local_pickup_shipping($gateways)
|
|
{
|
|
if (WC()->session) {
|
|
$chosen_shipping_methods_session = WC()->session->get('chosen_shipping_methods');
|
|
|
|
if ($chosen_shipping_methods_session && $this->only_local_pickups_selected($chosen_shipping_methods_session)) {
|
|
if (isset($gateways[self::WOO_CHOP_ID])) {
|
|
return array(self::WOO_CHOP_ID => $gateways[self::WOO_CHOP_ID]);
|
|
} else {
|
|
return array();
|
|
}
|
|
}
|
|
}
|
|
|
|
return $gateways;
|
|
}
|
|
|
|
/**
|
|
* Initialise Gateway Settings Form Fields.
|
|
*/
|
|
public function init_form_fields()
|
|
{
|
|
$shipping_methods = array();
|
|
$order_statuses = array();
|
|
|
|
if (is_admin()) {
|
|
foreach (WC()->shipping->load_shipping_methods() as $method) {
|
|
$shipping_methods[$method->id] = $method->get_method_title();
|
|
}
|
|
|
|
$statuses = function_exists('wc_get_order_statuses') ? wc_get_order_statuses() : array();
|
|
foreach ($statuses as $status => $status_name) {
|
|
$order_statuses[substr( $status, 3)] = $status_name;
|
|
}
|
|
}
|
|
|
|
$this->form_fields = array(
|
|
'enabled' => array(
|
|
'title' => __('Enable/Disable', 'woocommerce'),
|
|
'label' => __('Enable cash on pickup', 'woochop-cash-on-pickup'),
|
|
'type' => 'checkbox',
|
|
'description' => '',
|
|
'default' => 'no',
|
|
),
|
|
'title' => array(
|
|
'title' => __('Title', 'woocommerce'),
|
|
'type' => 'text',
|
|
'description' => __('Payment method description that the customer will see on your checkout.', 'woocommerce'),
|
|
'default' => __('Cash on pickup', 'woochop-cash-on-pickup'),
|
|
'desc_tip' => true,
|
|
),
|
|
'description' => array(
|
|
'title' => __('Description', 'woocommerce'),
|
|
'type' => 'textarea',
|
|
'description' => __('Payment method description that the customer will see on your website.', 'woocommerce'),
|
|
'default' => __('Pay with cash on pickup.', 'woochop-cash-on-pickup'),
|
|
'desc_tip' => true,
|
|
),
|
|
'instructions' => array(
|
|
'title' => __('Instructions', 'woocommerce'),
|
|
'type' => 'textarea',
|
|
'description' => __('Instructions that will be added to the thank you page.', 'woocommerce'),
|
|
'default' => __('Pay with cash on pickup.', 'woochop-cash-on-pickup'),
|
|
'desc_tip' => true,
|
|
),
|
|
'enable_for_methods' => array(
|
|
'title' => __('Enable for shipping methods', 'woocommerce'),
|
|
'type' => 'multiselect',
|
|
'class' => 'chosen_select',
|
|
'css' => 'width: 450px;',
|
|
'default' => '',
|
|
'description' => __('If COP is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woochop-cash-on-pickup'),
|
|
'options' => $shipping_methods,
|
|
'desc_tip' => true,
|
|
),
|
|
'default_order_status' => array(
|
|
'title' => __('Default order status', 'woochop-cash-on-pickup'),
|
|
'type' => 'select',
|
|
'default' => apply_filters('wc_cop_default_order_status', 'on-hold'),
|
|
'options' => $order_statuses,
|
|
),
|
|
'exclusive_for_local' => array(
|
|
'title' => __('Disable other payment methods if local pickup', 'woochop-cash-on-pickup'),
|
|
'label' => __('Cash on pickup will be the only payment method available if local pickup is selected on checkout', 'woochop-cash-on-pickup'),
|
|
'type' => 'checkbox',
|
|
'description' => '',
|
|
'default' => 'no',
|
|
),
|
|
'enable_for_virtual' => array(
|
|
'title' => __('Accept for virtual orders', 'woocommerce'),
|
|
'label' => __('Accept COP if the order is virtual', 'woochop-cash-on-pickup'),
|
|
'type' => 'checkbox',
|
|
'default' => 'yes',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check If The Gateway Is Available For Use.
|
|
*
|
|
* @return bool
|
|
*
|
|
*/
|
|
public function is_available()
|
|
{
|
|
$order = null;
|
|
$needs_shipping = false;
|
|
|
|
// Test if shipping is needed first
|
|
if (WC()->cart && WC()->cart->needs_shipping()) {
|
|
$needs_shipping = true;
|
|
} elseif (is_page(wc_get_page_id('checkout')) && 0 < get_query_var('order-pay')) {
|
|
$order_id = absint(get_query_var('order-pay'));
|
|
$order = wc_get_order($order_id);
|
|
|
|
// Test if order needs shipping.
|
|
if (0 < sizeof($order->get_items())) {
|
|
foreach ($order->get_items() as $item) {
|
|
if (version_compare( WC_VERSION, '3.0', '<')) {
|
|
$_product = $order->get_product_from_item($item);
|
|
} else {
|
|
$_product = $item->get_product();
|
|
}
|
|
|
|
if ($_product && $_product->needs_shipping()) {
|
|
$needs_shipping = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$needs_shipping = apply_filters('woocommerce_cart_needs_shipping', $needs_shipping);
|
|
|
|
// Virtual order, with virtual disabled
|
|
if (!$this->enable_for_virtual && ! $needs_shipping) {
|
|
return false;
|
|
}
|
|
|
|
// Only apply if all packages are being shipped via chosen method, or order is virtual.
|
|
if (!empty($this->enable_for_methods) && $needs_shipping) {
|
|
$chosen_shipping_methods = array();
|
|
|
|
if (is_object($order)) {
|
|
$chosen_shipping_methods = array_unique(array_map(array($this, 'get_string_before_colon'), $order->get_shipping_methods()));
|
|
} elseif ( $chosen_shipping_methods_session = WC()->session->get('chosen_shipping_methods')) {
|
|
$chosen_shipping_methods = array_unique(array_map(array($this, 'get_string_before_colon'), $chosen_shipping_methods_session));
|
|
}
|
|
|
|
// Local Pickup Plus fix
|
|
unset($chosen_shipping_methods['undefined']);
|
|
|
|
if ( 0 < count(array_diff($chosen_shipping_methods, $this->enable_for_methods)) && !('yes' === $this->exclusive_for_local && $this->only_local_pickups_selected($chosen_shipping_methods))) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return parent::is_available();
|
|
}
|
|
|
|
/**
|
|
* Process the payment and return the result.
|
|
*
|
|
* @param int $order_id
|
|
* @return array
|
|
*/
|
|
public function process_payment($order_id)
|
|
{
|
|
$order = wc_get_order($order_id);
|
|
$order->update_status(apply_filters('wc_cop_default_order_status', $this->default_order_status));
|
|
|
|
// Reduce stock levels
|
|
if (version_compare(WC_VERSION, '3.0', '>=')) {
|
|
wc_reduce_stock_levels($order_id);
|
|
} else {
|
|
$order->reduce_order_stock();
|
|
}
|
|
|
|
// Remove cart
|
|
WC()->cart->empty_cart();
|
|
|
|
// Return thankyou redirect
|
|
return array(
|
|
'result' => 'success',
|
|
'redirect' => $this->get_return_url($order),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Output for the order received page.
|
|
*/
|
|
public function thankyou_page()
|
|
{
|
|
if ($this->instructions) {
|
|
echo wp_kses_post(wpautop(wptexturize($this->instructions)));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add content to the WC emails.
|
|
*
|
|
* @access public
|
|
* @param WC_Order $order
|
|
* @param bool $sent_to_admin
|
|
* @param bool $plain_text
|
|
*/
|
|
public function email_instructions($order, $sent_to_admin, $plain_text = false)
|
|
{
|
|
$payment_method = version_compare(WC_VERSION, '3.0', '>=') ? $order->get_payment_method() : $order->payment_method;
|
|
|
|
if ($this->instructions && !$sent_to_admin && $this->id === $payment_method && $order->has_status($this->default_order_status)) {
|
|
echo wp_kses_post(wpautop(wptexturize($this->instructions)).PHP_EOL);
|
|
}
|
|
}
|
|
}
|