WP Manifestindependent plugin directory
manifest / ecommerce / woocommerce-shop-kit

WooCommerce Shop Kit

WooCommerce storefront customisations on PHP 8.2: cart fragments, configurable product tabs, checkout field control and rate-limited AJAX authentication

by Alex Mochulskyi · github.com/alexskybrain/woocommerce-shop-kit

★ 0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/alexskybrain/woocommerce-shop-kit/archive/refs/heads/main.zip

The customisations almost every WooCommerce shop ends up asking for, written once and properly: a live cart counter, product tabs driven by configuration instead of hardcoded IDs, a trimmed checkout, and login and registration over AJAX without sending the customer to wp-login.php.

I have built these same four things on client shops more than once, each time as scattered functions in a theme's functions.php. This repository is that work rewritten as a single plugin on PHP 8.2, with the mistakes taken out.

Requirements

  • WordPress 6.4+
  • WooCommerce 8.0+
  • PHP 8.2+

Installation

Copy the folder into wp-content/plugins/ and activate it. There is nothing to configure: every behaviour has a sensible default and a filter to change it.

The plugin has no runtime dependencies and ships no vendor directory. Composer is used for the coding standard only.

What it does

Live cart counter. Registers a WooCommerce cart fragment, so the header count updates on add-to-cart without a page reload. The selector is filterable, so it fits whatever markup the theme uses.

Product tabs from configuration. Renames the description tab per product category and removes unwanted tabs. Categories are matched by slug through woo_shop_kit_description_tab_titles.

Shorter checkout. Removes or makes optional any checkout field, addressed as section.field, through woo_shop_kit_remove_checkout_fields and woo_shop_kit_optional_checkout_fields.

Variation layout. Moves the variation price block next to the quantity field and hides the "Choose an option" placeholder for attributes that do not need it.

Cart quantity sync. Submits the cart form shortly after a quantity settles, debounced, so nobody has to find the "Update cart" button.

AJAX login and registration. Two admin-ajax endpoints for a single-page account form, with the security details handled rather than assumed.

Template overrides. The plugin can supply WooCommerce templates, and the active theme still wins. Lookup order is theme, then plugin, then WooCommerce.

Notes on the authentication endpoints

This is the part that is easy to get wrong, so it is worth being explicit about what the code does:

  • The nonce is verified before any field is read out of the request, not after.
  • Input is unslashed and sanitised. The password is the deliberate exception: it is unslashed but never sanitised, because stripping characters would silently change what the customer typed.
  • Failed attempts are counted per client address in a transient, five within five minutes, because an unauthenticated AJAX endpoint is the cheapest brute-force target on a WordPress site. The address is hashed, so the options table does not become a visitor log.
  • Failures return one generic message. Distinguishing "no such user" from "wrong password" turns a login form into an account oracle, and registering an address that already exists returns the same response as a successful signup, with the account owner notified by email instead.
  • Usernames are derived from the email address and de-duplicated, so customers never have to invent one.

Filters

Filter Default Purpose
woo_shop_kit_cart_counter_selector .wsk-cart-counter Element replaced by the cart fragment
woo_shop_kit_description_tab_titles [] Category slug to description tab title
woo_shop_kit_default_description_tab_title Product information Title when no category matches
woo_shop_kit_remove_product_tabs ['additional_information'] Tabs to drop
woo_shop_kit_remove_checkout_fields ['order.order_comments'] Checkout fields to drop
woo_shop_kit_optional_checkout_fields [] Checkout fields to make optional
woo_shop_kit_move_variation_price true Move the variation block
woo_shop_kit_attributes_keeping_placeholder [] Attributes that keep "Choose an option"
woo_shop_kit_enable_quantity_sync true Auto-update the cart on quantity change
woo_shop_kit_registration_open users_can_register Allow registration
woo_shop_kit_new_customer_role customer Role given to new accounts
woo_shop_kit_minimum_password_length 8 Minimum password length
woo_shop_kit_login_after_registration true Sign the customer in after signup
woo_shop_kit_auth_redirect My account Where to send the customer afterwards

There is also an action, woo_shop_kit_customer_registered, passing the new user ID.

Front-end contract

The scripts bind to markup, not to a shortcode, so the forms can live anywhere in the theme:

<form data-wsk-form="login">
  <input type="email" name="log" required>
  <input type="password" name="password" required>
  <p data-wsk-message></p>
  <button type="submit">Sign in</button>
</form>

Use data-wsk-form="register" for the signup form, with email, password and optionally first_name, last_name and phone.

Architecture

Every feature is a small class implementing Hookable, and Plugin is the only place that knows the full list. Reading src/Plugin.php tells you everything the plugin touches, which is the property a theme's functions.php loses about six months into a project.

src/
  Plugin.php              composition root
  Contracts/Hookable.php  register(): void
  Support/Assets.php      script registration and versioning
  Support/RateLimiter.php transient-backed attempt counter
  Auth/                   AJAX login and registration
  Cart/                   fragments, quantity sync
  Checkout/               field configuration
  Product/                tabs, variation layout
  Templates/              WooCommerce template resolution

Scripts are registered up front and enqueued only on the pages that need them, are plain JavaScript with no jQuery, and are versioned by file modification time in debug and by plugin version in production.

The plugin declares High-Performance Order Storage compatibility, and refuses to boot with an admin notice when WooCommerce is missing or older than 8.0, rather than fataling.

Development

composer install
composer lint

The ruleset is WordPress Coding Standards plus PHPCompatibilityWP pinned at PHP 8.2, with file naming relaxed because the source follows PSR-4.

License

GPL-2.0-or-later — see LICENSE.