Files
2026-04-28 15:13:50 +02:00

336 lines
16 KiB
HTML

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><link rel="canonical" href="https://www.soft79.nl/development/" />
<link rel="shortcut icon" href="../img/favicon.ico" />
<title>Development - Soft79 Documentation</title>
<link rel="stylesheet" href="../css/theme.css" />
<link rel="stylesheet" href="../css/theme_extra.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github.min.css" />
<link href="../css/jos.css" rel="stylesheet" />
<script>
// Current page data
var mkdocs_page_name = "Development";
var mkdocs_page_input_path = "development.md";
var mkdocs_page_url = "/development/";
</script>
<!--[if lt IE 9]>
<script src="../js/html5shiv.min.js"></script>
<![endif]-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body class="wy-body-for-nav" role="document">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href=".." class="icon icon-home"> Soft79 Documentation
</a><div role="search">
<form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" title="Type search term here" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Extended Coupon Features for WooCommerce</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="..">About</a>
</li>
<li class="toctree-l1"><a class="reference internal" >Edit coupons</a>
<ul>
<li class="toctree-l2"><a class="reference internal" href="../usage-restrictions/">Additional usage restrictions</a>
</li>
<li class="toctree-l2"><a class="reference internal" href="../usage-limits/">Additional usage limits</a>
</li>
<li class="toctree-l2"><a class="reference internal" href="../usage-free-products/">Free products</a>
</li>
<li class="toctree-l2"><a class="reference internal" href="../usage-checkout/">Checkout</a>
</li>
<li class="toctree-l2"><a class="reference internal" href="../usage-misc/">Miscellaneous</a>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../auto-updates/">Automatic updates (PRO)</a>
</li>
<li class="toctree-l1 current"><a class="reference internal current" href="#">Development</a>
<ul class="current">
<li class="toctree-l2"><a class="reference internal" href="#filters-and-actions">Filters and Actions</a>
<ul>
<li class="toctree-l3"><a class="reference internal" href="#programming-additional-rules-for-limit-discount-to">Programming additional rules for 'Limit discount to'</a>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#create-mini-plugins-for-extended-coupon-features">Create mini-plugins for Extended Coupon Features</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="Mobile navigation menu">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="..">Soft79 Documentation</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content"><div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href=".." class="icon icon-home" aria-label="Docs"></a></li>
<li class="breadcrumb-item">Extended Coupon Features for WooCommerce</li>
<li class="breadcrumb-item active">Development</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div class="section" itemprop="articleBody">
<h1 id="development">Development</h1>
<h2 id="filters-and-actions">Filters and Actions</h2>
<p>These filters are called by Extended Coupon Features for WooCommerce:</p>
<pre><code class="language-php">apply_filters( 'wjecf_apply_with_other_coupons', true, $the_coupon, $applied_coupon_codes ) );
apply_filters( 'wjecf_bogo_product_amount_for_coupon', $qty, $coupon );
apply_filters( 'wjecf_bogo_products_to_apply_for_coupon', $bogos, $coupon );
apply_filters( 'wjecf_coupon_can_be_applied', $can_be_applied, $coupon );
apply_filters( 'wjecf_coupon_has_a_value', $has_a_value, $coupon );
apply_filters( 'wjecf_coupon_item_quantity', $item_quantity, $coupon, $item, $wc_discounts );
apply_filters( 'wjecf_coupon_multiplier_value', $coupon_multiplier_values, $coupon, $wc_discounts );
apply_filters( 'wjecf_first_order_statuses_to_check', $order_statuses );
apply_filters( 'wjecf_free_cart_item_price', __('Free!', 'woocommerce'), $price_html, $cart_item, $cart_item_key );
apply_filters( 'wjecf_free_cart_item_subtotal', __('Free!', 'woocommerce'), $price_html, $cart_item, $cart_item_key );
apply_filters( 'wjecf_free_product_amount_for_coupon', $coupon_qty, $coupon );
apply_filters( 'wjecf_free_products_to_apply_for_coupon', $free_product_quantities, $coupon )
apply_filters( 'wjecf_get_limit_to_options', $options );
apply_filters( 'wjecf_is_first_purchase', $is_first_purchase );
apply_filters( 'wjecf_set_free_product_amount_in_cart', $quantity, $product );
apply_filters( 'wjecf_set_free_product_amount_in_cart', $quantity, $product, $variation )
</code></pre>
<p>These actions are called by Extended Coupon Features for WooCommerce:</p>
<pre><code class="language-php">do_action( 'wjecf_admin_after_settings' );
do_action( 'wjecf_admin_before_settings' );
do_action( 'wjecf_after_update_matched_autocoupons' );
do_action( 'wjecf_assert_coupon_is_valid', $coupon );
do_action( 'wjecf_before_update_matched_autocoupons' );
do_action( 'wjecf_coupon_metabox_checkout', $thepostid, $post );
do_action( 'wjecf_coupon_metabox_customer', $thepostid, $post );
do_action( 'wjecf_coupon_metabox_free_products', $thepostid, $post );
do_action( 'wjecf_coupon_metabox_misc', $thepostid, $post );
do_action( 'wjecf_coupon_metabox_products', $thepostid, $post );
do_action( 'wjecf_init_plugins');
do_action( 'wjecf_woocommerce_coupon_options_extended_features', $thepostid, $post );
</code></pre>
<h3 id="programming-additional-rules-for-limit-discount-to">Programming additional rules for 'Limit discount to'</h3>
<p>apply_filters( 'wjecf_get_limit_to_options', $options )` filter allows developers to append rules for 'Limit to:'.</p>
<p>Rules can be added to the <code>$options</code>-array with these properties:</p>
<p><code>$key =&gt; [ 'function' =&gt; $callback_function, 'title' =&gt; $title ]</code></p>
<ul>
<li><code>$key</code> = The key that identifies the 'Limit to'-rule.</li>
<li><code>$title</code> = The title of the 'Limit to'-rule.</li>
<li><code>$function</code> = The callback with functionality of the rule. Callback must have this signature:
<code>function callback_function( $coupon, $discountable_items )</code>
<code>$discountable_items</code> are stdClass objects as generated by WC_Discounts.
The callback must return an array with the maximum amount of items to be discounted.
<code>[ $item_key =&gt; $discount_limit, ... ]</code>
Discount-quantity of cart_items that are not in the array will not be limited.</li>
</ul>
<h2 id="create-mini-plugins-for-extended-coupon-features">Create mini-plugins for Extended Coupon Features</h2>
<p>You can further extend functionality of Extended Coupon Features for WooCommerce by creating your own mini-plugins.</p>
<ol>
<li>Hook into the <code>wjecf_init_plugins</code>-action. (Using this hook guarantees that the WooCommerce and Extended Coupon Features for WooCommerce plugins are loaded)</li>
<li>Here, create a class that extends <code>Abstract_WJECF_Plugin</code>.</li>
<li>Create a constructor <code>__construct()</code>, where you setup the plugin data by calling <code>$this-&gt;set_plugin_data</code></li>
<li>Create a function <code>init_hook()</code>, where you setup your plugin and define frontend hooks.</li>
<li>Create a function <code>init_admin_hook()</code>, where you setup your plugin for admin usage and define admin hooks.</li>
<li>
<p>(Version 2.5.1+ only) If your plugin need to handle custom meta fields, use the WooCommerce meta box functions (e.g. <code>woocommerce_wp_select</code>).</p>
<p>To handle the sanitization of these fields, create a function <code>admin_coupon_meta_fields( $coupon )</code>
and have it return an array <code>[ 'field_name' =&gt; 'sanitization', ... ]</code> .</p>
<p>Upon saving a coupon, these fields will be automatically read from <code>$_POST</code> and sanitized with the given sanitization method,
e.g. <code>'int'</code>, <code>'int[]'</code>, <code>'yesno'</code>, <code>'decimal'</code>, <code>'clean'</code> or even a callback: <code>[ 'callback' =&gt; callback ]</code> and saved to the current coupon. </p>
<p>For versions prior to 2.5.1, you need to handle process_shop_coupon_meta yourself.</p>
</li>
<li>
<p>Load the class by calling <code>WJECF()-&gt;add_plugin( 'NameOfYourClass')</code></p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="language-php">&lt;?php
/**
Plugin Name: WJECF Example plugin - Allow a coupon on certain weekdays only
Description: An example on how to extend Extended Coupon Features for WooCommerce
Author: Soft79
Version: 1.0
Author URI: http://www.soft79.nl/
*/
add_action( 'wjecf_init_plugins', 'setup_my_wjecf_example_plugin' );
function setup_my_wjecf_example_plugin() {
class WJECF_Plugin_Example extends Abstract_WJECF_Plugin {
//This is the meta-key where the weekday will be saved
//HINT: Prepend it with _wjecf_&lt;your plugin name&gt; to avoid naming conflicts
const META_KEY_WEEKDAY = '_wjecf_example_plugin_weekday';
/**
* In the constructor you can supply general information about your WJECF-plugin.
*/
public function __construct() {
$this-&gt;set_plugin_data( array(
'description' =&gt; __( 'WJECF Example plugin - Accept a coupon on certain weekdays only.', 'your-text-domain' ),
'dependencies' =&gt; array(),
'minimal_wjecf_version' =&gt; '2.5.1',
'can_be_disabled' =&gt; true
) );
}
//FRONTEND
/**
* This function is called when WooCommerce and all other plugins are loaded.
* Here you can setup frontend hooks.
*/
public function init_hook() {
add_action( 'woocommerce_coupon_is_valid', array( $this, 'filter_woocommerce_coupon_is_valid' ), 10, 2 );
}
/**
* Invalidates the coupon if the weekday is not ok
* @param bool $valid
* @param WC_Coupon $coupon
* @return bool False if invalid
*/
public function filter_woocommerce_coupon_is_valid( $valid, $coupon ) {
if ( is_callable( array( $coupon, 'get_meta' ) ) ) {
//WC3.0+
$coupon_weekday = $coupon-&gt;get_meta( self::META_KEY_WEEKDAY );
} else {
//Older WC versions
$coupon_weekday = get_post_meta( $coupon-&gt;id, self::META_KEY_WEEKDAY, true );
}
//Not valid if the weekday differs
if ( is_numeric( $coupon_weekday ) &amp;&amp; date('w') != $coupon_weekday ) {
return false;
}
return $valid;
}
//ADMIN
/**
* This function is called when WooCommerce and all other plugins are loaded and we are on the admin section of WordPress.
* Here you can setup admin hooks.
*/
public function init_admin_hook() {
add_action( 'woocommerce_coupon_options_usage_restriction', array( $this, 'action_woocommerce_coupon_options_usage_restriction' ), 9999 ); //9999 is at the bottom of the tab
}
/**
* Automatically called at the process_shop_coupon_meta action (WJECF 2.5.1+ only).
*
* Returns an array [ meta_key =&gt; sanitizion_rule, ... ] with the meta fields that must be saved if the user clicks 'Update' on the coupon admin page. *
* Valid sanitizion rules are: 'html', 'clean', 'yesno', 'decimal', 'int', 'int[]' (array of ints), 'int,' (comma separated ints)
*
* $_POST[meta_key] will be sanitized and automatically saved.
*
* @since 2.5.1
* @param WC_Coupon $coupon The coupon that will be saved
* @return array An array with [ key =&gt; sanitizion_rule, ... ]
*/
public function admin_coupon_meta_fields( $coupon ) {
return array( self::META_KEY_WEEKDAY =&gt; 'int' );
}
/**
* This is called when the usage restrictions tab is rendered.
*/
public function action_woocommerce_coupon_options_usage_restriction() {
woocommerce_wp_select(
array(
'id' =&gt; self::META_KEY_WEEKDAY,
'label' =&gt; __( 'Weekday', 'woocommerce-jos-autocoupon' ),
'options' =&gt; array(
'' =&gt; '(Always valid)',
0 =&gt; 'Sunday',
1 =&gt; 'Monday',
2 =&gt; 'Tuesday',
3 =&gt; 'Wednesday',
4 =&gt; 'Thursday',
5 =&gt; 'Friday',
6 =&gt; 'Saturday'
),
'description' =&gt; __( 'Coupon is only valid on this weekday.', 'your-text-domain' ),
'desc_tip' =&gt; true
)
);
}
}
//Loads the plugin!
WJECF()-&gt;add_plugin( 'WJECF_Plugin_Example' );
}
</code></pre>
</div>
</div><footer>
<div class="rst-footer-buttons" role="navigation" aria-label="Footer Navigation">
<a href="../auto-updates/" class="btn btn-neutral float-left" title="Automatic updates (PRO)"><span class="icon icon-circle-arrow-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<!-- Copyright etc -->
</div>
Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<div class="rst-versions" role="note" aria-label="Versions">
<span class="rst-current-version" data-toggle="rst-current-version">
<span><a href="../auto-updates/" style="color: #fcfcfc">&laquo; Previous</a></span>
</span>
</div>
<script src="../js/jquery-3.6.0.min.js"></script>
<script>var base_url = "..";</script>
<script src="../js/theme_extra.js"></script>
<script src="../js/theme.js"></script>
<script src="../search/main.js"></script>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>