Přidání nového stavu objednávky a emailu do WooCommerce

Poměrně často dostávám od svých klientů požadavek na přidání custom stavu objednávky do WooCommerce (např. nový stav Doručeno) a odeslání emailu při přepnutí objednávky do tohoto stavu.

Dá se pro to samozřejmě využít spousta pluginů, ale protože nový status je opravdu zásadní funkcionalita, na kterou bývá navázána další logika, většinou doporučuji přidat nový status a email do WooCommerce pomocí kódu.

Nový stav objednávky do WooCommerce přidáme jednoduše pomocí dvou funkcí. První zaregistruje nový stav, druhá ho přidá do WooCommerce.

add_action( 'init', array( $this, 'register_custom_order_statuses' ) );
add_filter( 'wc_order_statuses', array( $this, 'add_custom_order_statuses_to_wc' ) );


/** * Register custom post statuses */ function register_custom_order_statuses() { register_post_status( 'wc-backordered', array( 'label' => 'Na objednávku', 'public' => true, 'exclude_from_search' => false, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, 'label_count' => _n_noop( 'Na objednávku <span class="count">(%s)</span>', 'Na objednávku <span class="count">(%s)</span>' ), ) ); } /** * Add custom order statuses to WooCommerce * * @param $order_statuses * * @return array */ function add_custom_order_statuses_to_wc( $order_statuses ) { $order_statuses['wc-backordered'] = 'Na objednávku'; return $order_statuses; }

Přidání emailu do WooCommerce je o něco složitější. Je potřeba nejprve vytvořit třídu, která rozšiřuje třídu WC_Email. Základní třída může vypadat asi takto:

<?php

namespace WPProgramator;

if ( ! defined( 'ABSPATH' ) ) {
  exit;
} // Exit if accessed directly

if ( class_exists( 'WC_Email' ) ) :

  class CustomerBackordered extends \WC_Email {

    /**
     * Set email defaults
     */
    public function __construct() {

      // Unique ID for custom email
      $this->id = 'vpp_backordered';

      // Is a customer email
      $this->customer_email = true;

      // Title field in WooCommerce Email settings
      $this->title = __( 'Backordered', 'wpp' );

      // Description field in WooCommerce email settings
      $this->description = __( 'This email is sent when the order status changes to backordered', 'nalehko' );

      $this->template_base  = WPP_PLUGIN_DIR . 'woocommerce/emails/';    // Fix the template base lookup for use on admin screen template path display
      $this->template_html  = 'emails/customer-backordered.php';
      $this->template_plain = 'emails/plain/customer-backordered.php';

      $this->placeholders = array(
        '{site_title}'   => $this->get_blogname(),
        '{order_date}'   => '',
        '{order_number}' => '',
      );

      parent::__construct();
    }

    /**
     * Get email subject.
     * @return string
     * @since  3.1.0
     */
    public function get_default_subject() {
      return __( 'Vaše objednávka je připravena', 'woocommerce' );
    }

    /**
     * Get email heading.
     * @return string
     * @since  3.1.0
     */
    public function get_default_heading() {
      return __( 'Vaše objednávka je připravena k vyzvednutí', 'woocommerce' );
    }


    /**
     * Prepares email content and triggers the email
     *
     * @param int $order_id
     */
    public function trigger( $order_id, $order = false ) {

      if ( $order_id && ! is_a( $order, 'WC_Order' ) ) {
        $order = wc_get_order( $order_id );
      }

      if ( is_a( $order, 'WC_Order' ) ) {

        $this->object = $order;

        $this->placeholders['{order_date}']   = wc_format_datetime( $this->object->get_date_created() );
        $this->placeholders['{order_number}'] = $this->object->get_order_number();

        /* Proceed with sending email */

        $this->recipient = $this->object->get_billing_email();

      }

      if ( ! $this->is_enabled() || ! $this->get_recipient() ) {

        return;
      }

      // All well, send the email
      $result = $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

      // add order note about the same
      $this->object->add_order_note( sprintf( __( '%s email sent to the customer.', 'woocommerce' ), $this->get_title() ) );

    }

    /**
     * get_content_html function.
     * @return string
     */
    public function get_content_html() {
      return wc_get_template_html( $this->template_html, array(
        'order'         => $this->object,
        'email_heading' => $this->get_heading(),
        'sent_to_admin' => false,
        'plain_text'    => false,
        'email'         => $this,
      ) );
    }


    /**
     * get_content_plain function.
     * @return string
     */
    public function get_content_plain() {
      return wc_get_template_html( $this->template_plain, array(
        'order'         => $this->object,
        'email_heading' => $this->get_heading(),
        'sent_to_admin' => false,
        'plain_text'    => true,
        'email'         => $this,
      ) );
    }


    /**
     * Initialize settings form fields
     */
    public function init_form_fields() {

      $this->form_fields = array(
        'enabled'    => array(
          'title'   => __( 'Enable/Disable', 'woocommerce' ),
          'type'    => 'checkbox',
          'label'   => 'Enable this email notification',
          'default' => 'yes',
        ),
        'subject'    => array(
          'title'       => __( 'Subject', 'woocommerce' ),
          'type'        => 'text',
          'desc_tip'    => true,
          'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->get_subject() ),
          'placeholder' => $this->get_default_subject(),
          'default'     => '',
        ),
        'heading'    => array(
          'title'       => __( 'Email Heading', 'woocommerce' ),
          'type'        => 'text',
          'desc_tip'    => true,
          'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->get_heading() ),
          'placeholder' => $this->get_default_heading(),
          'default'     => '',
        ),
        'email_type' => array(
          'title'       => __( 'Email type', 'woocommerce' ),
          'type'        => 'select',
          'description' => __( 'Choose which format of email to send.', 'woocommerce' ),
          'default'     => 'html',
          'class'       => 'email_type wc-enhanced-select',
          'options'     => $this->get_email_type_options(),
          'desc_tip'    => true,
        ),
      );
    }

  }

endif;

 

Pro to, aby se nový email zobrazil mezi emaily ve WooCommerce v administraci (WooCommerce – Nastavení – Emaily), stačí přidat naši novou třídu mezi emaily WooCommerce

      add_filter( 'woocommerce_email_classes', array( $this, 'custom_woocommerce_emails' ) );

public function custom_woocommerce_emails( $email_classes ) {
  $email_classes['CustomerBackordered'] = new CustomerBackordered(); // add to the list of email classes that WooCommerce loads
  return $email_classes;
}

Pro to, aby se nový email odeslal při přepnutí stavu objednávky na “Na objednávku”, je potřeba ještě nový email přidat do WooCommerce notifikací. K tomu slouží jeden filter a jedna action:

add_filter( 'woocommerce_email_actions', array( $this, 'custom_email_actions' ) );
add_action( 'woocommerce_order_status_backordered_notification', array( $this, 'send_notification_backordered' ) );

public function custom_email_actions( $actions ) {
  $actions[] = 'woocommerce_order_status_backordered';
  return $actions;
}
public function send_notification_backordered( $order_id ) {
  // Getting all WC_emails objects
  $email_notifications = WC()->mailer()->get_emails();
  $email_notifications['CustomerBackordered']->trigger( $order_id );
}

Posledním krokem je vytvoření šablon nového emailu. Stačí zkopírovat libovolnou šablonu ze složky woocommerce/templates/emails do složky child-šablony woocommerce/emails/, a pojmenovat ji tak, jak jsme si zvolili při přidávání třídy s emailem, v našem případě customer-backordered.php

Pokud jste postupovali podle návodu výše, měli byste vidět nový stav objednávky Na objednávku, v nastavení emailů WooCommerce by měl přibýt nový email Backordered a při přepnutí objednávky do stavu Na objednávku by měl odejít nový email s obsahem ze šablony woocommerce/emails/customer-backordered.php

Pokud budete potřebovat přidat nové stavy objednávek do WooCommerce nebo WooCommerce a WordPress jinak rozšířit, neváhejte se na mě obrátit.

Přidat komentář