Developer reference

Hooks, filters, custom rule types and conditions, admin extension points, REST API and data storage.

Updated 2 min read

Kayce Discount Rules is built to be extended. Pro itself uses only the hooks on this page.

Actions

HookWhen
kayce_dr_loadedThe plugin has booted (on plugins_loaded). Add-ons start here.
kayce_dr_registerRegister custom rule types and conditions (on init).
kayce_dr_rules_savedAfter rules are saved. Receives the saved rules.
kayce_dr_after_calculateAfter rules are applied to the cart. Receives the cart and engine.

Filters

FilterUse
kayce_dr_rule_matches_productChange whether a rule applies to a product.
kayce_dr_skip_cart_itemLeave a cart line untouched (bundles, gifts).
kayce_dr_resolve_priceResolve competing rules with your own strategy.
kayce_dr_strategiesAdd options to “If several rules match one item”.
kayce_dr_catalog_priceChange the price shown in the shop.
kayce_dr_display_product_typeShow discounted prices for other product types.
kayce_dr_cart_savingsChange the “You save” amount.

A custom rule type

Extend Kayce\DiscountRules\Rule_Type and register it:

use Kayce\DiscountRules\Rule_Type;
use Kayce\DiscountRules\Rule_Types;

class My_Members_Price extends Rule_Type {
    public function id()    { return 'members'; }
    public function label() { return 'Members price'; }

    // Unit price for a cart line, or null to leave it alone.
    public function item_price( $price, array $rule, array $context ) {
        return is_user_logged_in() ? $price * 0.9 : null;
    }
}

add_action( 'kayce_dr_register', function () {
    Rule_Types::register( new My_Members_Price() );
} );

Types that work on the whole cart implement apply_to_cart( $rule, $cart, $matching_keys ) and set line prices with kayce_dr_engine()->set_line_price( $cart, $key, $price, $rule ), so repeated calculations never discount twice.

A custom condition

use Kayce\DiscountRules\Condition;
use Kayce\DiscountRules\Conditions;

class Customer_In_Nepal extends Condition {
    public function id()    { return 'country_np'; }
    public function label() { return 'Customer in Nepal'; }
    public function matches( array $config, array $context ) {
        return WC()->customer && 'NP' === WC()->customer->get_billing_country();
    }
}

add_action( 'kayce_dr_register', function () {
    Conditions::register( new Customer_In_Nepal() );
} );

Fail-safe: A rule whose type or condition isn’t registered is kept when saving but never applied.

Admin extension points

The admin app is React. Add-ons enqueue a script that depends on kayce-dr-admin and use wp.hooks:

JavaScript filterUse
kayceDR.typeEditorsEditor component per rule type ({ config, onChange, rule }).
kayceDR.conditionsPanelComponent for step 3.
kayceDR.blankRuleDefault settings for a new rule of a type.
kayceDR.ruleChipsSummary chips on rule cards.
kayceDR.validateRuleAdd errors and warnings.
kayceDR.templatesAdd templates to the New rule window.
kayceDR.previewReplace the live preview for a rule type.

Shared components (number fields, segmented controls, option cards, product pickers) are available on window.kayceDRAdmin.

REST API

All routes need the manage_woocommerce capability.

RouteMethods
/wp-json/kayce-dr/v1/rulesGET, PUT (whole ordered list)
/wp-json/kayce-dr/v1/settingsGET, PUT
/wp-json/kayce-dr/v1/statsGET (30-day stats)
/wp-json/kayce-dr/v1/searchGET (products or categories)

Data storage

  • Rules: option kayce_dr_rules (ordered list). Settings: kayce_dr_settings. No custom tables.
  • Order line meta: _kayce_dr_rule_id, _kayce_dr_original_price, _kayce_dr_price; Pro gifts add _kayce_dr_gift.