Как правильно написать свой плагин под wordpress для woocommerce?

182
11 июня 2019, 22:50

Я начал писать свой плагин под wordpress для woocommerce. Хочу написать плагин, который добавит дополнительный способ оплаты "Оплата по счету".

Отличительная особенность этого платежного шлюза заключается в том, что он имеет свою отдельную форму. И после заполнения формы и отправки данных, будет формироваться pdf файл.

Теперь о проблеме с которой я столкнулся в ходе написания плагина. Я не знаю как сделать правильно так, чтобы при выборе моего способа оплаты, менялась форма. Я попытался реализовать это через js, но это привело к некоторым проблемам: с проверкой валидацией, с тем что старая форма возвращается если обновить корзину и нажать на input.

Вот код моего плагина:

<?php
/**
 * Plugin Name: Оплата по счету для Woocommerce
 * Plugin URI: -
 * Description: Данный плагин предоставляет дополнительный способ олпаты предназначенный для юр. лиц.
 * Author: -
 * Author URI: -
 * Version: 0.0.1
 * Text Domain: wc-gateway-offline
 * Domain Path: /i18n/languages/
 *
 * Copyright: (c) 2015-2016 SkyVerge, Inc. (info@skyverge.com) and WooCommerce
 *
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 *
 * @package   WC-Gateway-Offline
 * @author    SkyVerge
 * @category  Admin
 * @copyright Copyright (c) 2015-2016, SkyVerge, Inc. and WooCommerce
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
 *
 * This offline gateway forks the WooCommerce core "Cheque" payment gateway to create another offline payment method.
 */
defined( 'ABSPATH' ) or exit;

// Make sure WooCommerce is active
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
    return;
}

/**
 * Add the gateway to WC Available Gateways
 *
 * @since 1.0.0
 * @param array $gateways all available WC gateways
 * @return array $gateways all WC gateways + offline gateway
 */
function wc_offline_add_to_gateways( $gateways ) {
    $gateways[] = 'WC_Gateway_Offline';
    return $gateways;
}
add_filter( 'woocommerce_payment_gateways', 'wc_offline_add_to_gateways' );

/**
 * Adds plugin page links
 *
 * @since 1.0.0
 * @param array $links all plugin links
 * @return array $links all plugin links + our custom links (i.e., "Settings")
 */
function wc_offline_gateway_plugin_links( $links ) {
    $plugin_links = array(
        '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=checkout&section=offline_gateway' ) . '">' . __( 'Configure', 'wc-gateway-offline' ) . '</a>'
    );
    return array_merge( $plugin_links, $links );
}
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'wc_offline_gateway_plugin_links' );

/**
 * Offline Payment Gateway
 *
 * Provides an Offline Payment Gateway; mainly for testing purposes.
 * We load it later to ensure WC is loaded first since we're extending it.
 *
 * @class       WC_Gateway_Offline
 * @extends     WC_Payment_Gateway
 * @version     1.0.0
 * @package     WooCommerce/Classes/Payment
 * @author      SkyVerge
 */
add_action( 'plugins_loaded', 'wc_offline_gateway_init', 11 );
function wc_offline_gateway_init() {
    class WC_Gateway_Offline extends WC_Payment_Gateway {
        /**
         * Constructor for the gateway.
         */
        public function __construct() {
            $this->plugin_url = trailingslashit(WP_PLUGIN_URL.'/'.dirname(plugin_basename(__FILE__)));
            $this->id                 = 'payment-on-account';
            $this->icon               = apply_filters('woocommerce_offline_icon', '');
            $this->has_fields         = false;
            $this->method_title       = __( 'Offline', 'wc-gateway-offline' );
            $this->method_description = __( 'Allows offline payments. Very handy if you use your cheque gateway for another payment method, and can help with testing. Orders are marked as "on-hold" when received.', 'wc-gateway-offline' );
            // Load the settings.
            $this->init_form_fields();
            $this->init_settings();
            // Define user set variables
            $this->title        = $this->get_option( 'title' );
            $this->description  = $this->get_option( 'description' );
            $this->instructions = $this->get_option( 'instructions', $this->description );
            // Actions
            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 );
            add_action('wp_print_scripts', array(&$this, 'include_scripts'));
        }
        function include_scripts() {
            wp_enqueue_script( 'pa-shape-change', $this->plugin_url . '/js/shape-change.js');
        }
        /**
         * Initialize Gateway Settings Form Fields
         */
        public function init_form_fields() {
            $this->form_fields = apply_filters( 'wc_offline_form_fields', array(
                'enabled' => array(
                    'title'   => __( 'Enable/Disable', 'wc-gateway-offline' ),
                    'type'    => 'checkbox',
                    'label'   => __( 'Enable Offline Payment', 'wc-gateway-offline' ),
                    'default' => 'yes'
                ),
                'title' => array(
                    'title'       => __( 'Title', 'wc-gateway-offline' ),
                    'type'        => 'text',
                    'description' => __( 'This controls the title for the payment method the customer sees during checkout.', 'wc-gateway-offline' ),
                    'default'     => __( 'Оплата по счету', 'wc-gateway-offline' ),
                    'desc_tip'    => true,
                ),
                'description' => array(
                    'title'       => __( 'Description', 'wc-gateway-offline' ),
                    'type'        => 'textarea',
                    'description' => __( 'Payment method description that the customer will see on your checkout.', 'wc-gateway-offline' ),
                    'default'     => __( 'Пожалуйста, отправьте платеж на имя магазина при получении или доставке.', 'wc-gateway-offline' ),
                    'desc_tip'    => true,
                ),
                'instructions' => array(
                    'title'       => __( 'Instructions', 'wc-gateway-offline' ),
                    'type'        => 'textarea',
                    'description' => __( 'Инструкции, которые будут добавлены на страницу благодарности и электронные письма.', 'wc-gateway-offline' ),
                    'default'     => '',
                    'desc_tip'    => true,
                ),
            ) );
        }

        /**
         * Output for the order received page.
         */
        public function thankyou_page() {
            if ( $this->instructions ) {
                echo wpautop( wptexturize( $this->instructions ) );
        echo 'test: bla bla';
            }
        }

        /**
         * 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 ) {
            if ( $this->instructions && ! $sent_to_admin && $this->id === $order->payment_method && $order->has_status( 'on-hold' ) ) {
                echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
            }
        }

        /**
         * 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 );
            // Mark as on-hold (we're awaiting the payment)
            $order->update_status( 'on-hold', __( 'Awaiting offline payment', 'wc-gateway-offline' ) );
            // Reduce stock levels
            $order->reduce_order_stock();
            // Remove cart
            WC()->cart->empty_cart();
            // Return thankyou redirect
            return array(
                'result'    => 'success',
                'redirect'  => $this->get_return_url( $order )
            );
        }
  } // end \WC_Gateway_Offline class
}

Вот код js файла:

window.onload = function() {
  console.log($().jquery);
  var formContent = $('#customer_details').html();
  var formDefault = true;
  $(document).ajaxComplete(function(header) {
    $('input').on('click', function() {
      console.log($(this).get(0).id);
      if($(this).get(0).id == 'payment_method_payment-on-account') {
        $('#customer_details').children('div').remove();
        formDefault = false;
        $('#customer_details').append("<div class='woocommerce-billing-fields'><div class='woocommerce-billing-fields__field-wrapper'><p class='form-row form-row-first validate-required' id='billing_first_name_field' data-priority='10'><label for='billing_first_name' class=''>Имя&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='text' class='input-text ' name='name-ep' id='billing_first_name' placeholder='Полное наименование организации или ИП' autocomplete='given-name'></span></p><p class='form-row form-row-wide validate-required validate-phone' id='billing_phone_field' data-priority='100'><label for='billing_phone' class=''>Телефон&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='tel' class='input-text ' name='enn' id='billing_phone' placeholder='ИНН' autocomplete='tel'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='kpp' id='billing_email' placeholder='КПП' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='legal-address' id='billing_email' placeholder='Юридический адрес' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='contact-number' id='billing_email' placeholder='Контактный телефон' autocomplete='email username'></span></p><p class='form-row form-row-wide validate-required validate-email' id='billing_email_field' data-priority='110'><label for='billing_email' class=''>Email&nbsp;<abbr class='required' title='обязательно'>*</abbr></label><span class='woocommerce-input-wrapper'><input type='email' class='input-text ' name='email' id='billing_email' placeholder='Электронная почта' autocomplete='email username'></span></p></div></div>");
      }
      else {
        if(formDefault != true) {
          $('#customer_details').children('div').remove();
          $('#customer_details').append(formContent);
        }
        formDefault = true;
      }
    });
  });
}

Пока "плагин" состоит из 2 файлов.

Что мне собственно нужно: я очень хочу разобраться в том, как это должно быть устроено. Так же было бы не плохо, если бы мне указали на мои ошибки, чтобы впредь я их больше не совершал.

P.s. Я искал информацию о том, как это сделать в google, но не нашел ответа. Буду рад любой информации или ссылке.

P.s.s. Я вообще это затеял, потому что не смог найти аналогичного решения, если вдруг он уже существует, буду рад получить ссылку на него.

READ ALSO
Как использовать класс в CLI

Как использовать класс в CLI

Есть такой вопросКак запускать класс из cli

169
Ajax обновление

Ajax обновление

В общем имеется страница с блоками в каждом фото, описание и кнопка с таймеромДанные загружаются из базы по циклу while

100