Categories
WooCommerce WordPress

Adding and Sending Custom WooCommerce Email for WooCommerce 3.0+

WooCommerce 3.0 was rolled out with lots of exciting features for end-users as well as developers. Several advancements including use of CRUD classes and others were introduced with this release to make WooCommerce more performance-friendly.

This also lead to changes in the way interaction between post types, taxonomies and related data happens. In one of our previous articles we showed you how could you (without using any plugin) add and send custom WooCommerce emails. And as we continually receive comments and requests about modifying the code to also make it compatible with WooCommerce 3.0+, I decided to quickly (yeah, I know this is very late šŸ™ ) get onto this.

This tutorial has been tested to work with WooCommerce 3.0+. So, if you are looking to add and send custom emails in WooCommerce 3.0+, follow the instructions below.

First things first!

It is highly recommended that any customization be kept separate from the theme. A plugin like WP Designer could come in handy if you want to add such a customization. This example requires you to FTP into your website and create custom directories and files inside wp-content > uploads directory. Following is a list of directories and files that need to be created:

  1. Create directory crwc-custom-emails inside wp-content > uploads.
  2. Create file crwc-email-functions.php in the root of crwc-custom-emails directory (crwc-custom-emails > crwc-email-functions.php).
  3. Create file class-crwc-welcome-email.php in the root of crwc-custom-emails directory (crwc-custom-emails > class-crwc-welcome-email.php).
  4. Create a sub-directory emails inside crwc-custom-emails directory.
  5. Create a new file crwc-welcome-email.php inside the emails directory (crwc-custom-emails > emails > crwc-welcome-email.php).
  6. You can also choose to create a sub-directory plain inside emails directory and then create crwc-welcome-email.php file inside plain directory (crwc-custom-emails > emails > plain > crwc-welcome-email.php). This will be used in case emails use plain content-type.

Building custom email class

The custom email class that we create would actually define the email trigger plus the email content. We can extend the default WC_Email class and hence make use of all of the parent email class methods & members that are available. This makes life really easy šŸ˜‰

Add the following code to class-crwc-welcome-email.php file.

<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if ( class_exists( 'WC_Email' ) ) :
class CRWC_Welcome_Email extends WC_Email {
	
	/**
	 * Set email defaults
	 */
	public function __construct() {
		// Unique ID for custom email
		$this-&gt;id = 'crwc_welcome_email';
		// Is a customer email
		$this-&gt;customer_email = true;
		
		// Title field in WooCommerce Email settings
		$this-&gt;title = __( 'Welcome Email', 'woocommerce' );
		// Description field in WooCommerce email settings
		$this-&gt;description = __( 'Welcome email is sent when an online training program account is created for the customer after the purchase of the online course.', 'woocommerce' );
		// these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
		$upload_dir = wp_upload_dir();
		
		$this-&gt;template_base  = WPD_BASE_DIR . '/wc-emails/';	// Fix the template base lookup for use on admin screen template path display
		$this-&gt;template_html  = 'emails/crwc-welcome-email.php';
		$this-&gt;template_plain = 'emails/plain/crwc-welcome-email.php';
		$this-&gt;placeholders   = array(
			'{site_title}'   =&gt; $this-&gt;get_blogname(),
			'{order_date}'   =&gt; '',
			'{order_number}' =&gt; '',
		);
		// Trigger email when payment is complete
		add_action( 'woocommerce_payment_complete', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_on-hold_to_processing_notification', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_on-hold_to_completed_notification', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
		
		// Call parent constructor to load any other defaults not explicity defined here
		parent::__construct();
	}
	/**
	 * Get email subject.
	 *
	 * @since  3.1.0
	 * @return string
	 */
	public function get_default_subject() {
		return __( 'XYZ Online Training Program', 'woocommerce' );
	}
	/**
	 * Get email heading.
	 *
	 * @since  3.1.0
	 * @return string
	 */
	public function get_default_heading() {
		return __( 'Welcome to Online Training Program', 'woocommerce' );
	}
	/**
	 * Prepares email content and triggers the email
	 *
	 * @param int $order_id
	 */
	public function trigger( $order_id, $order = false ) {
		if ( $order_id &amp;&amp; ! is_a( $order, 'WC_Order' ) ) {
			$order = wc_get_order( $order_id );
		}
			
		if ( is_a( $order, 'WC_Order' ) ) {
			
			$this-&gt;object = $order;
			
			$this-&gt;placeholders['{order_date}']   = wc_format_datetime( $this-&gt;object-&gt;get_date_created() );
			$this-&gt;placeholders['{order_number}'] = $this-&gt;object-&gt;get_order_number();
		
			//* Maybe include an additional check to make sure that the online training program account was created
			/* Uncomment and add your own conditional check
			$online_training_account_created = get_post_meta( $order_id, '_crwc_user_account_created', 1 );
			
			if ( ! empty( $online_training_account_created ) &amp;&amp; false === $online_training_account_created ) {
				return;
			}
			*/
			/* Proceed with sending email */
			
			$this-&gt;recipient = $this-&gt;object-&gt;get_billing_email();
		}
		// Send welcome email only once and not on every order status change		
		if ( get_post_meta( $order_id, '_crwc_welcome_email_sent', true ) ) {
			return;
		}
		if ( ! $this-&gt;is_enabled() || ! $this-&gt;get_recipient() ) {
			
			return;
		}
		// All well, send the email
		$this-&gt;send( $this-&gt;get_recipient(), $this-&gt;get_subject(), $this-&gt;get_content(), $this-&gt;get_headers(), $this-&gt;get_attachments() );
		
		// add order note about the same
		$this-&gt;object-&gt;add_order_note( sprintf( __( '%s email sent to the customer.', 'woocommerce' ), $this-&gt;get_title() ) );
		// Set order meta to indicate that the welcome email was sent
		update_post_meta( $order_id, '_crwc_welcome_email_sent', 1 );
		
	}
	
	/**
	 * get_content_html function.
	 *
	 * @return string
	 */
	public function get_content_html() {
		return wc_get_template_html( $this-&gt;template_html, array(
			'order'			=&gt; $this-&gt;object,
			'email_heading'		=&gt; $this-&gt;get_heading(),
			'sent_to_admin'		=&gt; false,
			'plain_text'		=&gt; false,
			'email'			=&gt; $this
		) );
	}
	/**
	 * get_content_plain function.
	 *
	 * @return string
	 */
	public function get_content_plain() {
		return wc_get_template_html( $this-&gt;template_plain, array(
			'order'			=&gt; $this-&gt;object,
			'email_heading'		=&gt; $this-&gt;get_heading(),
			'sent_to_admin'		=&gt; false,
			'plain_text'		=&gt; true,
			'email'			=&gt; $this
		) );
	}
	/**
	 * Initialize settings form fields
	 */
	public function init_form_fields() {
		$this-&gt;form_fields = array(
			'enabled'    =&gt; array(
				'title'   =&gt; __( 'Enable/Disable', 'woocommerce' ),
				'type'    =&gt; 'checkbox',
				'label'   =&gt; 'Enable this email notification',
				'default' =&gt; 'yes'
			),
			'subject'    =&gt; array(
				'title'       =&gt; __( 'Subject', 'woocommerce' ),
				'type'        =&gt; 'text',
				'desc_tip'    =&gt; true,
				'description' =&gt; sprintf( 'This controls the email subject line. Leave blank to use the default subject: &lt;code&gt;%s&lt;/code&gt;.', $this-&gt;get_subject() ),
				'placeholder' =&gt; $this-&gt;get_default_subject(),
				'default'     =&gt; ''
			),
			'heading'    =&gt; array(
				'title'       =&gt; __( 'Email Heading', 'woocommerce' ),
				'type'        =&gt; 'text',
				'desc_tip'    =&gt; true,
				'description' =&gt; sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: &lt;code&gt;%s&lt;/code&gt;.' ), $this-&gt;get_heading() ),
				'placeholder' =&gt; $this-&gt;get_default_heading(),
				'default'     =&gt; ''
			),
			'email_type' =&gt; array(
				'title'			=&gt; __( 'Email type', 'woocommerce' ),
				'type'			=&gt; 'select',
				'description'	=&gt; __( 'Choose which format of email to send.', 'woocommerce' ),
				'default'		=&gt; 'html',
				'class'			=&gt; 'email_type wc-enhanced-select',
				'options'		=&gt; $this-&gt;get_email_type_options(),
				'desc_tip'		=&gt; true,
			)
		);
	}
		
}
endif;</pre>

Viewing custom email settings

The code mentioned above will help us to create custom class with all settings and triggers. However, to be able to see the custom email settings that we created along with the default emails on WooCommerce Emails screen under WooCommerce > Settings > Emails, weā€™ll need to add this class to the default email classes in WooCommerce. In order to do that, weā€™ll make use of the woocommerce_email_classes filter to include custom email class to the default classes.

Add the following code to crwc-email-functions.php file (inside crwc-custom-emails directory).

<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">add_filter( 'woocommerce_email_classes', 'crwc_custom_woocommerce_emails' );
function crwc_custom_woocommerce_emails( $email_classes ) {
	//* Custom welcome email to customer when purchasing online training program
	$upload_dir = wp_upload_dir();
	
	include_once( $upload_dir['basedir'] . '/crwc-custom-emails/class-crwc-welcome-email.php' );
	
	$email_classes['CRWC_Welcome_Email'] = new CRWC_Welcome_Email(); // add to the list of email classes that WooCommerce loads
	return $email_classes;
	
}</pre>

Now, when you navigate to WooCommerce > Settings > Emails, you should be able to see the custom email Welcome Email that we added to the list of emails on that page. If you click on the Configure button, you will find settings screen that allows you to enable/disable the email, edit/update the email subject and heading and choose the email content type since we added these settings in the custom class we created above.

Creating custom email template

Until this point, we have been able to create email class that helps create email trigger and set-up email content and we have also been able to add our custom email to the WooCommerce Emails screen. We still need to define the email template that will be used for the email content. The paths to the email content templates have already been defined in the custom email class we created above. Letā€™s add the actual content that will be used by the welcome email we send out to customers.

Add the following code to crwc-welcome-email.php file (inside emails directory).

<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;?php
/**
 *
 * Welcome email content template
 *
 * The file is prone to modifications after plugin upgrade or alike; customizations are advised via hooks/filters
 *
 */
 
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?&gt;
&lt;p&gt;&lt;?php _e( 'Thank you for your purchase of Online training course. Your account has been successfully created over the Online Training Program portal.', 'woocommerce' ); ?&gt;&lt;/p&gt;
&lt;p&gt;&lt;?php _e( 'Use the following credentials to login to the portal:', 'woocommerce' ); ?&gt;&lt;/p&gt;
&lt;p&gt;
	&lt;strong&gt;&lt;?php __( 'Login URL: ', 'woocommerce' ) ?&gt;&lt;/strong&gt;&lt;?php _e( 'https://example.com' ); ?&gt;&lt;br /&gt;
	&lt;strong&gt;&lt;?php __( 'Username: ', 'woocommerce' ) ?&gt;&lt;/strong&gt;&lt;?php echo make_clickable( esc_attr( $order-&gt;get_billing_email() ) ); ?&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;?php _e( 'Below are the order details for your reference.' ) ?&gt;&lt;/p&gt;
&lt;?php
/**
* @hooked WC_Emails::order_details() Shows the order details table.
* @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
* @since 2.5.0
*/
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::order_meta() Shows order meta data.
*/
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::customer_details() Shows customer details
* @hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
/**
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );</pre>

You can modify the email content template as required based on your specific requirements and accordingly, the details that youā€™d need to send out to your customers.

Start making Custom WooCommerce email work

Weā€™re almost there with starting to send custom WooCommerce emails to the customers. All we need to do is to trigger our code. The filter we added to include our custom email class to list of default email classes is placed in crwc-email-functions.php, but hey!, wait a sec.. did we actually include it so that it is executed by WordPress? No, not yet. Letā€™s do that.

In order to do so, you can just add the following code to your themeā€™s functions.php:

<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$upload_dir = wp_upload_dir();
include_once( $upload_dir['basedir'] . '/crwc-custom-emails/crwc-email-functions.php' );</pre>

Thatā€™s it! Now on, when a customer purchases an online training product from your store, he would receive a welcome email with his credentials. Cheers!

Categories
Business

Online Business Failure: 6 things you are doing wrong and how to do it right?

We know reading this title will ā€œBreak Your Heartā€ and maybe you will have that strange and daunting feeling to increase the possibility of your success. Starting an online business has no guarantee of success, period! But thatā€™s how running an online business is like, right? You have read all the success stories of entrepreneurs and it felt so great that you took action to set-up your own Online Business. Woohoo!! And then, there you are reading this piece ā€“ it means you are missing that kink in your master plan or maybe you want to identify the main reasons of online business failure before starting your business.

According to research conducted by Bloomberg after the failure post-mortem of the companies, it states that 8 out of 10 companies fail within the first 18 months. Thatā€™s a whopping burn rate of 80 percent or simply we can say that a new business has 1 in 5 chances to survive in less than two years. Thatā€™s pretty depressing! While as an entrepreneur when you study how businesses succeed, you should also learn about the darker sides of online businesses failure. Surely, you donā€™t fail until you totally give up. Remember Henry Ford? His first two automotive efforts turned out to be a failure. We see him as an innovator who knew what might look like failure to some is a real innovation. But then you have to hit the road just one time. Thatā€™s it!

Why most of the Businesses Fail?

Business failure is a harsh reality. You could fail 10 times and reinitiate your business 11 times. If at any of the next attempt you made it happen, you didn’t actually fail because you didn’t give up. There are some specific reasons why businesses are failing. You build successful business strategies, statistics but if you fail to realize some crucial things or just overlook or push aside certain things, YOUā€™RE GONNA FAIL. Letā€™s put together a summary of mistakes entrepreneurs or business owners typically make in running an online business; where do they go wrong and most importantly, how can YOU avoid making these fatal mistakes? So if you donā€™t want to be a part of the 80 percent category there are some ways to combat it.

  1. Reason #1 – You have no Customers because there is no market need

    According to CB Insights, tackling problems that are interesting to solve rather than those that serve a market need was cited as the No. 1 reason for business failure, noted in 42% of cases. It is far simpler: the companies didn’t solve a big enough problem.

    This is like self-evident. Letā€™s get to the basics. Even though it feels obvious, it is not! And, let me warn you this is HUGE. Businesses fail all the time because they are trying to solve a problem that nobody really cares about. If you put your product or service out there and nobody buys it, thereā€™s a good chance you should look for a more important problem to solve. If no one wants your product or service your company isnā€™t going to succeed. Simple, right! Also, a lot of people, go into business with a different or a wrong perception, they see a business and they are like, “Oh, this is awesome, I can do it too.” Seriously! Remember, for every $137 billion company like Amazon, there are countless number of frivolous online businesses that never make it.

    The Fix – Just think about this, you receive a service or product that totally blows your mind. And, what you are going to do next is to recommend the product to your network, ā€œword of mouthā€, you see. Why? Because you found it useful, something that is delivering value. Itā€™s all about VALUE.

    First, find a Market. What is your market? Donā€™t say, ā€œUm, everyone.ā€ Thatā€™s not your market. You need to identify the group, the cluster of people whom you will be helping. The second thing is Need. What do people need? What are people looking for? Whether it is a market of recruiters searching for a perfect candidate or a super easy tool for accountants, your product or service should be able to universally serve with a scalable solution. Remember, you must be having great technology, data, expertise or reputation but your technology should solve the pain points of your target market; ultimately making their lives easier. It is always about delivering VALUE to market that will eventually pay you like spades in future.

  2. Reason #2 – You are not listening to your Customers

    An amazing thing happens when an entrepreneur sees a potential opportunity in the market and addresses the need with a new idea of a product or a service. But things donā€™t go well when you donā€™t have a complete understanding of your customer which is actually crucial to your product and companyā€™s success. Businesses fail when they neglect to stay in touch with their target audience, their customers and donā€™t understand what they need and the feedback they offer. How do you know if the problem you solve is important enough? Have you been listening?

    The Fix – Customers are the final arbiters and will tell you what they really think about your product or service. Remember, thereā€™s a reason why ā€œthe customer is always right,ā€ because without customers you donā€™t have a business. Listen to your customers, like for real. Walk 1,000 miles in the shoes of your customer. Your customer is the key. Donā€™t just pay lip service and even 280 characters of your tweet wonā€™t count. Make real conversation with real customers. This is one of the most important ways to avoid online business failure.

  3. Reason #3 – You are not able to compete in the market

    Your competition is not always startups; there are large companies too that are incubating ideas. In fact, you need to look out more on the giant ones. When the competition is fierce especially in lucrative markets where the stakes are high, companies get out-competed in the race. Sure, you may have the first-mover advantage but second-mover advantage can allow companies to quickly incorporate what you have validated and sink your ship in a blink.

    The Fix – Letā€™s take an example of Nokia, there was a time when the company ruled. Nokia failed when the smartphones took over the market. The company was much behind in terms of functionalities and innovation and was the one to enter late in the market. Whether a giant company or small startup, you have a competitor for your business to watch out. You need to be different, innovative and ahead of your competition in every aspect. You need to find ways and stay in business.

  4. Reason #4 – You have no Marketing Strategy

    It is vital that a business puts ample efforts into marketing at the bootstrapping stage. No matter how great and useful your product or service is, it will gracefully fail if no one knows about it or is not able to find the customers. Poor and inefficient marketing has always been one of the major causes of online business failure.

    The Fix – While you donā€™t always need a fully dedicated professional PR team to market your offerings but you need to make the target audience aware of the product or service existence in one or the other way. The goal of marketing is to connect your businessā€™ value to the right customer. Start marketing and advertising your products or services online with social media marketing, content writing & marketing, email marketing campaigns or print media whatever suits your business well.

  5. Reason #5 – You are not being able to decide on Product Pricing

    Finding a balance between the selling price and cost of the product is a real challenge and tipping to either of the sides can be disastrous for a company. Businesses always suffer between pricing good enough to maintain positive margins and covering all the operating costs, while also to price low enough to lure customers.

    The Fix – You need to find out that sweet spot of not too expensive and not too cheap price for your product while simultaneously maintaining the healthy margins. How do you do this? First, know your customers, figure out the segment you are targeting. Second, know your costs, your revenue target, your competition most importantly. Do keep track of outside factors that will impact the demand for your product in the future.

  6. Reason #6 – You are not optimizing your conversions

    Optimizing conversions is not only about more clicks, more money, more growth. It is so much more than that. Most of the entrepreneurs and business owners forget to address this important aspect of business success. With the implementation of several other strategies and techniques to target and drive customers optimizing your web pages for conversions can impact so many other areas of your marketing. Entrepreneurs and business owners should understand that you can always get more traffic but you can thrive only when you are able to capitalize on the existing traffic. And, this is where most businesses fail.

    The Fix – For a sustainable business and positive ROI ensure that you start optimizing conversions at early stages of business. Remember the reason you are optimizing conversion rates is to provide a better experience to your users who will ultimately be your customers. Ensure that you follow fundamentals to optimize your conversion rate with creating a powerful lead magnet, by increasing organic traffic with search engine optimization, A/B testing for your web pages according to demographics, conversion funnel, and other digital marketing activities. The better you do it, the more potential you have at churning a profit. Now is the time to get your website conversion rate optimized!

The Final Fix to avoid Online Business Failure

While there can be several other reasons for business failures like no business plan or model, losing the focus, product misfit, not having the right team and resources however according to industry experts and entrepreneurs the above-mentioned remains to be the main reasons for a business exiting the market.

No matter what, donā€™t let the fear of failure stop you from trying anything. Despite talking about reasons of failure we will leave you with the words of Thomas J. Watson – ā€œIf you want to increase your success rate, double your failure rate.ā€, a planned and continually improved approach will help you stay afloat in the competition.

Categories
WooCommerce WordPress

Adding and Sending Custom WooCommerce Email (without a plugin)

This tut has been updated to work with WooCommerce 3.0+. Read how can you add and send custom WooCommerce email for WooCommerce version 3.0 and higher.

Emails are pretty important when you have customers purchasing products from your online store. Customers buying your products (even us, when we make an online purchase), be it physical or virtual, expect to receive some sort of emails about the confirmation of payment, the processing of order and so on. If your store fails to do so, you’re probably doing it wrong and making your business suffer. Because, the customer has just sent you his money and they’ve not yet heard back from you, they’ve not received a payment confirmation. Get the problem?

If you’re selling with WordPress & WooCommerce, things are quite easy for you as a store owner/manager. WooCommerce, by default, sends out some emails to let your customers know that their order has been placed, processed and/or is complete. However, sometimes it may happen that based on the products you’re selling, you may need to send out custom emails to the customers once they’ve placed an order on your site.

Practical Example

For instance, let’s say, you have a WordPress & WooCommerce powered online store that allows customers to purchase a course on your website and in-turn grants them access to your online training program.

In such a case, you may want to send out a Welcome Email to the customers informing them about the purchase and sharing access details for the online training program. In order to be able to do so, we’ll need to add a custom WooCommerce email that triggers every time a new order is placed on the site. WooCommerce 2.0 introduced a whole bunch of new features, including the ability to add a new class-based implementation for emails. In this article, we’ll use the WooCommerce email class implementation to add a custom email which is triggered on every new order once the payment has been received.

Side Note

The example cited above may also require custom implementation that allows interaction between WooCommerce and (possibly the API to connect to) your online training program to allow adding new user accounts when a customer makes a purchase at your online store. This article does not cover the integration to a third-party service part, and is strictly intended to guide you on how can a custom email be added and sent through your WooCommerce store.

Implementation

Duh.. Enough Talk! Let’s Implement That

Implementation of custom email is divided into three phases:

  1. Extending WC_Email class to define the email header, subject, email template for content, etc.
  2. Adding our custom email class to the default WooCommerce email classes using woocommerce_email_classes filter
  3. Creating our own email template to be used to generate email content for our custom email.

Let’s get started.

First things first!

It is highly recommended that any customization be kept separate from the theme. A plugin like WP Designer could come in handy if you want to add such a customization. This example requires you to FTP into your website and create custom directories and files inside wp-content > uploads directory. Following is a list of directories and files that need to be created:

  1. Create directory crwc-custom-emails inside wp-content > uploads.
  2. Create file crwc-email-functions.php in the root of crwc-custom-emails directory (crwc-custom-emails > crwc-email-functions.php).
  3. Create file class-crwc-welcome-email.php in the root of crwc-custom-emails directory (crwc-custom-emails > class-crwc-welcome-email.php).
  4. Create a sub-directory emails inside crwc-custom-emails directory.
  5. Create a new file crwc-welcome-email.php inside the emails directory (crwc-custom-emails > emails > crwc-welcome-email.php).
  6. You can also choose to create a sub-directory plain inside emails directory and then create crwc-welcome-email.php file inside plain directory (crwc-custom-emails > emails > plain > crwc-welcome-email.php). This will be used in case emails use plain content-type.

Building custom email class

The custom email class that we create would actually define the email trigger plus the email content. We can extend the default WC_Email class and hence make use of all of the parent email class methods & members that are available. This makes life really easy šŸ˜‰

Add the following code to class-crwc-welcome-email.php file.

<?php

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

/**
 * Welcome Email class used to send out welcome emails to customers purchasing a course
 *
 * @extends \WC_Email
 */

class CRWC_Welcome_Email extends WC_Email {
	
	/**
	 * Set email defaults
	 */
	public function __construct() {

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

		// Is a customer email
		$this->customer_email = true;
		
		// Title field in WooCommerce Email settings
		$this->title = __( 'Welcome Email', 'woocommerce' );

		// Description field in WooCommerce email settings
		$this->description = __( 'Welcome email is sent when an online training program account is created for the customer after the purchase of the online course.', 'woocommerce' );

		// Default heading and subject lines in WooCommerce email settings
		$this->subject = apply_filters( 'crwc_welcome_email_default_subject', __( 'XYZ Online Training Program', 'woocommerce' ) );
		$this->heading = apply_filters( 'crwc_welcome_email_default_heading', __( 'Welcome to Online Training Program', 'woocommerce' ) );
		
		// these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
		$upload_dir = wp_upload_dir();
		
		$this->template_base  = $upload_dir['basedir'] . '/crwc-custom-emails/';	// Fix the template base lookup for use on admin screen template path display
		$this->template_html  = 'emails/crwc-welcome-email.php';
		$this->template_plain = 'emails/plain/crwc-welcome-email.php';

		// Trigger email when payment is complete
		add_action( 'woocommerce_payment_complete', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_on-hold_to_completed', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_failed_to_processing', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_failed_to_completed', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_pending_to_processing', array( $this, 'trigger' ) );
		
		// Call parent constructor to load any other defaults not explicity defined here
		parent::__construct();

	}


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

		// Bail if no order ID is present
		if ( ! $order_id )
			return;
		
		// Send welcome email only once and not on every order status change		
		if ( ! get_post_meta( $order_id, '_crwc_welcome_email_sent', true ) ) {
			
			// setup order object
			$this->object = new WC_Order( $order_id );
			
			// get order items as array
			$order_items = $this->object->get_items();

			//* Maybe include an additional check to make sure that the online training program account was created
			/* Uncomment and add your own conditional check
			$online_training_account_created = get_post_meta( $this->object->id, '_crwc_user_account_created', 1 );
			
			if ( ! empty( $online_training_account_created ) && false === $online_training_account_created ) {
				return;
			}
			*/

			/* Proceed with sending email */
			
			$this->recipient = $this->object->billing_email;

			// replace variables in the subject/headings
			$this->find[] = '{order_date}';
			$this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );

			$this->find[] = '{order_number}';
			$this->replace[] = $this->object->get_order_number();

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

			// All well, send the email
			$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->title ) );

			// Set order meta to indicate that the welcome email was sent
			update_post_meta( $this->object->id, '_crwc_welcome_email_sent', 1 );
			
		}
		
	}
	
	/**
	 * 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->email_heading( $this->course_info['program'] ),
			'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->email_heading( $this->course_info['program'] ),
			'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',
				'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
				'placeholder' => '',
				'default'     => ''
			),
			'heading'    => array(
				'title'       => __( 'Email Heading', 'woocommerce' ),
				'type'        => 'text',
				'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
				'placeholder' => '',
				'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'     => array(
					'plain'	    => __( 'Plain text', 'woocommerce' ),
					'html' 	    => __( 'HTML', 'woocommerce' ),
					'multipart' => __( 'Multipart', 'woocommerce' ),
				)
			)
		);
	}
		
}

Viewing custom email settings

The code mentioned above will help us to create custom class with all settings and triggers. However, to be able to see the custom email settings that we created along with the default emails on WooCommerce Emails screen under WooCommerce > Settings > Emails, weā€™ll need to add this class to the default email classes in WooCommerce. In order to do that, weā€™ll make use of the woocommerce_email_classes filter to include custom email class to the default classes.

Add the following code to crwc-email-functions.php file (inside crwc-custom-emails directory).

<?php

add_filter( 'woocommerce_email_classes', 'crwc_custom_woocommerce_emails' );

function crwc_custom_woocommerce_emails( $email_classes ) {

	//* Custom welcome email to customer when purchasing online training program

	$upload_dir = wp_upload_dir();
	
	require_once( $upload_dir['basedir'] . '/crwc-custom-emails/class-crwc-welcome-email.php' );
	$email_classes['CRWC_Welcome_Email'] = new CRWC_Welcome_Email(); // add to the list of email classes that WooCommerce loads


	return $email_classes;
	
}

Now, when you navigate to WooCommerce > Settings > Emails, you should be able to see the custom email Welcome Email that we added to the list of emails on that page. If you click on the Configure button, you will find settings screen that allows you to enable/disable the email, edit/update the email subject and heading and choose the email content type since we added these settings in the custom class we created above.

Creating custom email template

Until this point, we have been able to create email class that helps create email trigger and set-up email content and we have also been able to add our custom email to the WooCommerce Emails screen. We still need to define the email template that will be used for the email content. The paths to the email content templates have already been defined in the custom email class we created above. Letā€™s add the actual content that will be used by the welcome email we send out to customers.

Add the following code to crwc-welcome-email.php file (inside emails directory).

<?php
/**
 *
 * Welcome email content template
 *
 * The file is prone to modifications after plugin upgrade or alike; customizations are advised via hooks/filters
 *
 */
 
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>

<p><?php _e( 'Thank you for your purchase of Online training course. Your account has been successfully created over the Online Training Program portal.', 'woocommerce' ); ?></p>

<p><?php _e( 'Use the following credentials to login to the portal:', 'woocommerce' ); ?></p>

<p>
	<strong><?php __( 'Login URL: ', 'woocommerce' ) ?></strong><?php _e( 'https://example.com' ); ?><br />
	<strong><?php __( 'Username: ', 'woocommerce' ) ?></strong><?php echo make_clickable( esc_attr( $order->billing_email ) ); ?><br />
</p>

<p><?php _e( 'Below are the order details for your reference.' ) ?></p>

<?php
/**
* @hooked WC_Emails::order_details() Shows the order details table.
* @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
* @since 2.5.0
*/
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

/**
* @hooked WC_Emails::order_meta() Shows order meta data.
*/
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

/**
* @hooked WC_Emails::customer_details() Shows customer details
* @hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );

You can modify the email content template as required based on your specific requirements and accordingly, the details that you’d need to send out to your customers.

Start making Custom WooCommerce email work

We’re almost there with starting to send custom WooCommerce emails to the customers. All we need to do is to trigger our code. The filter we added to include our custom email class to list of default email classes is placed in crwc-email-functions.php, but hey!, wait a sec.. did we actually include it so that it is executed by WordPress? No, not yet. Let’s do that.

In order to do so, you can just add the following code to your theme’s functions.php:

$upload_dir = wp_upload_dir();

include_once( $upload_dir['basedir'] . '/crwc-custom-emails/crwc-email-functions.php' );

That’s it! Now on, when a customer purchases an online training product from your store, he would receive a welcome email with his credentials. Sounds good, right? Happy customers, happy you!

This tut has been updated to work with WooCommerce 3.0+. Read how can you add and send custom WooCommerce email for WooCommerce version 3.0 and higher.

Categories
WordPress

Category Specific Search on Category Archives in WordPress

Search form in WordPress comes in real handy when youā€™d like to allow users to navigate through your website content. If the site structure is not so intuitive or even otherwise, when a user wants to quickly look for something specific on your website, the search form is really helpful.

For developers, thereā€™s whole bunch of awesomeness with the default search form because it has plenty of scope for customization via hooks and filters.

In this tutorial, we will tweak the default search form in WordPress to fetch search results specific to the category on a category archives page. This way, the visitors on your site will be able to make a category specific search on a category archive page such that the results are displayed from within that particular category.

Customizing the default search behavior

We will make use of the get_search_form filter to achieve the desired results. Tweaking the search form to restrict the results specific to a particular category involves passing additional parameters to the search form. Add the following code to your functions.php to implement the category specific search through search form.

<?php
add_filter( 'get_search_form', 'cr_category_specific_search', 10, 4 );
function cr_category_specific_search( $form, $text, $button, $label ) {
	// Only run on category archives
	if ( ! is_category() )
		return $form;

	// Get the current category from query variable
	$category_id = get_query_var( 'cat' );
	$category_data = get_category( $category_id );
	$category = $category_data->slug;

	// Get search query; allow users to filter the placeholder text when idle
	$text = get_search_query() ? apply_filters( 'the_search_query', get_search_query() ) : apply_filters( 'cr_search_text', __( 'Search this website', 'cloudredux' ) . ' &#x02026;' );

	// 'Submit' button label
	$button = apply_filters( 'cr_search_button_text', esc_attr__( 'Search', 'cloudredux' ) );

	// Input label
	$label = apply_filters( 'cr_search_input_label', '' );    
	$value_or_placeholder = ( get_search_query() == '' ) ? 'placeholder' : 'value';

	// Default behaviour for form inputs
	$onfocus = "if ('" . esc_js( $text ) . "' === this.value) {this.value = '';}";
	$onblur  = "if ('' === this.value) {this.value = '" . esc_js( $text ) . "';}";

	// Search form
	$form  = sprintf( '<form class="search-form" itemprop="potentialAction" itemscope="" itemtype="http://schema.org/SearchAction" method="get" action="%s" role="search">', home_url( '/' ) );

	if ( '' == $label )  {
		$label = apply_filters( 'cr_search_text', __( 'Search this website', 'cloudredux' ) );
	}    

	$form_id = uniqid( 'searchform-' );

	// Add category slug as a hidden field to implement category specific search
	$form .= sprintf(
		'<meta itemprop="target" content="%s"/><label class="search-form-label screen-reader-text" for="%s">%s</label><input itemprop="query-input" type="search" name="s" id="%s" %s="%s" /><input type="hidden" name="category_name" id="category_name" value="%s" /><input type="submit" value="%s" /></form>',
		home_url( '/?s={s}' ),
		esc_attr( $form_id ),
		esc_html( $label ),
		esc_attr( $form_id ),
		$value_or_placeholder,
		esc_attr( $text ),
		esc_attr( $category ),
		esc_attr( $button )
	);

	return $form;
}

Displaying the category specific search form to visitors

We have already configured our search form to display category specific search results. Just to let the users know that they have the ninja ability to search within a category on our site, we may want to add a search form to category archive pages and indicate by modifying the placeholder text to guide the users. Add the following code to your functions.php to display a search form on category archive pages.

add_filter( 'cr_search_text', 'cr_category_archive_search_form_text', 20 );
function cr_category_archive_search_form_text( $search_text ) {
	if ( ! is_category() ) {
		return $search_text;
	}

	return __( 'Search this Category', 'cloudredux' );
}