Skip to content

Releases: jwincek/producerkit

ProducerKit 2.9.1

Choose a tag to compare

@jwincek jwincek released this 02 Oct 16:37
6f2a6e5

Fixes only, two of them for security. Recommended for every site.

Nothing new to learn and nothing to set up: update, and everything you've built stays as it was.

Security

Unpublished products no longer give away their sources. Anyone could ask ProducerKit's public API for the sources behind a product by its number, including products that were still drafts, private, scheduled or password-protected. Counting through the numbers was enough to find what a product you hadn't announced yet was made from, and where it came from. Now only published products answer, and every other number gets the same empty reply, so it doesn't reveal which products exist either.

The product spreadsheet export can no longer carry a formula. It copied product names and notes straight into the file, so a product named starting with = would run as a formula when someone opened the export in Excel or Google Sheets. Such cells are now marked as plain text. Importing the file undoes exactly that, so a real product called "-40° Frozen Berries" comes back unchanged.

Fixed

An old PHP version now explains itself instead of taking your site down. WordPress only checks a plugin's PHP requirement when you activate it. If files are replaced in place, as an FTP upload or a host's sync does, and the server runs an older PHP than ProducerKit needs, the next page load was a blank white screen. ProducerKit now stops before loading anything and tells you which version it needs, which one your site has, and that your content is safe.

Marking something sold out takes effect straight away. If a product was "abundant" last week and you marked it sold out today, the availability board kept showing it as abundant, because it picked the most optimistic status rather than the most recent. Today's update now wins everywhere.

A shop's board lists only what that shop carries. Products marked "available everywhere I sell" belong on your own stand's board, not on a retailer's.

Statuses are translated. "Sold out", "Abundant" and the rest stayed in English on sites in other languages. The help text in a location's Payment Options is now translatable too.

Deleting the plugin cleans up properly. If you've asked for your data to go when ProducerKit is deleted (under ProducerKit → Producer Profile), it now removes everything, including your product types, seasons and event types, which every version since 2.2.0 left behind. If you haven't asked, your products, events and settings are kept as before, and only ProducerKit's internal records go.


Full changelog: https://github.com/jwincek/producerkit/blob/v2.9.1/CHANGELOG.md

ProducerKit 2.9.0

Choose a tag to compare

@jwincek jwincek released this 14 Sep 00:59
b02e981

Turn off the parts you don't use.

ProducerKit arrives with everything switched on — pre-orders, made-to-order requests, customer emails, WooCommerce settlement — whether or not you take any of them. If you sell at a stand and nothing else, four screens you'll never open have been sitting in your menu since the day you installed it. Now they don't have to.

Added

Switch off what you don't use. Under ProducerKit on the dashboard, each optional part of the plugin can be turned off: Pre-Orders, Made-to-order requests, Customer emails, and WooCommerce settlement.

Before it switches anything off, it tells you what that part is currently holding — "3 orders, 2 still to collect", "1 published page uses its block, and would render nothing there" — so you find out before rather than afterwards. It only asks you to confirm when something would actually be affected.

Nothing is deleted, ever. Switching a part back on restores everything exactly as it was, orders and all. That is worth saying plainly, because it's the question the button raises.

The parts you can't turn off are the ones the rest of the plugin is built on — your catalog, your locations, your availability board, your events, and the trade you chose. Turning those off wouldn't tidy your site so much as take it apart.

Copy payment options between locations. If you sell in more than one place, the second location can copy its payment options from one you've already set up instead of your typing the same list again. It's a copy, not a link — the two don't stay in step afterwards, because what you take at your own stand and what you take at a market genuinely differ. That's why these live per location in the first place.

Changed

Under the hood, the plugin's admin code now loads on every request instead of only in the admin. Nothing behaves differently — none of it ever ran on the front end and none of it does now. What changes is that the automated tests can finally see it. Two bugs had shipped in that blind spot: a dashboard page you couldn't reach by clicking, and a "remove sample data" button that removed slightly more than sample data.


Full changelog: https://github.com/jwincek/producerkit/blob/v2.9.0/CHANGELOG.md

ProducerKit 2.8.0

Choose a tag to compare

@jwincek jwincek released this 12 Sep 01:28
a628997

If your site doesn't have another block plugin installed, ProducerKit's blocks have never appeared in the editor. This release fixes that.

Nothing in your site was broken by it — pages you already built kept working, and still do. What didn't work was adding a new one: the blocks were simply missing from the inserter, with nothing to say why. Update and they're there.

Fixed

The blocks appear in the editor. All eleven of them. They were being loaded before the part of WordPress they depend on, so they gave up silently. On a site running Gutenberg or WooCommerce something else happened to load that part first and the blocks worked, which is why this took so long to find — it only happens on a site that has nothing else.

The same problem meant the blocks' own labels could never be translated, whatever language pack was installed. They can now.

Added

A Getting Started guide, inside the dashboard. Under ProducerKit → Getting Started. Until now the guide existed only in the plugin's source repository, which is not a place a person setting up a farm stand is going to look.

It's written in your trade's words. A beekeeper is told to set up their home yard and fill in an Apiary; a potter, their studio and a Clay Supplier; a baker reads about their bakehouse. Change your trade under Producer Profile and the guide changes with it.

Changed

The availability board's filters say what they do. The statuses across the top are a set you're including — they show a tick when on, and the name is crossed out when off. Product types and trade fields are a choose-one, and look like it.

Before this, both were the same kind of button sitting next to each other, and clicking Abundant hid the abundant things, which is the opposite of what anyone expects.

The board now opens with a plain sentence — "Showing 6 of 8 items, hiding Sold out" — where each thing being hidden can be put back with one click, and the filter controls fold away until you want them. Each status also shows how many items it holds, so you can see what a filter is worth before pressing it.

The count under the board also stayed in English on translated sites once you touched a filter. Fixed.


Full changelog: https://github.com/jwincek/producerkit/blob/v2.8.0/CHANGELOG.md

ProducerKit 2.7.0

Choose a tag to compare

@jwincek jwincek released this 11 Sep 17:31
b174494

The QR code on your stand sign works now. It never has.

If you have printed the Fresh Sheet — the one-page list of what's available, meant to be taped to the stand each morning — the payment QR code on it has been blank in every released version since 2.4.0. The code that draws it was being left out of the plugin package, and the script that needed it gave up quietly rather than complaining, so nothing anywhere said it was broken. Update and it appears. There is nothing else to do.

This release also gives you a way to build your site's pages, and lets two producers who share a stall point at each other.

Fixed

The payment QR code never appeared. On the Fresh Sheet, and on the Location Info block with QR turned on. A packaging rule meant to exclude developer tooling was matching more than it meant to and taking the QR library with it. The build now checks that every file the plugin needs is actually in the package, so this particular silence cannot happen again.

Added

Generate Default Pages. ProducerKit deliberately has no automatic listing pages — the blocks are the listing, which is what lets you choose what they show. The cost is that a new site has nothing to navigate to and no hint that the pages are yours to build. This button builds them: a home starter, Visit, your events page, and pages for pre-orders and made-to-order requests, with the blocks already pointed at your own location.

Page names follow your trade, so a musician gets Shows and Bookings where a farm gets Calendar and Special Orders.

Everything is created as a draft for you to review, nothing you have already written is touched, and your menu and front page are left alone. Run it again later and it fills in what's missing. A page is only offered when it would actually show something — Visit waits until you have a location, and pre-orders until you have a product.

Changed

"Sharing the booth" can link. If another maker sells alongside you, put their web address after their name — Slowbird Bread Co. https://slowbird.example — and your event page shows their name as a link to their site. A name on its own still reads as plain text, and nothing you have already written changes.

This matters most for two producers who keep separate sites and occasionally share a stall: each site knows what its own producer is bringing and nothing about the other's, so the event is where a visitor finds out.


Full changelog: https://github.com/jwincek/producerkit/blob/v2.7.0/CHANGELOG.md

ProducerKit 2.6.0

Choose a tag to compare

@jwincek jwincek released this 10 Sep 18:23
eaec261

The plugin stops calling your work by somebody else's name.

A potter's process notes were stored as milling. A musician's release notes were stored as growing. You never saw those words — the screen has said "Preparation Notes" and "Release Notes" since 2.5.0 — but the database, the API and your spreadsheet exports all still said farm. This release corrects that everywhere, on update, with your data intact.

It is also the release where a farm and a bakery can share one site and a visitor can tell which is which.

Changed

Your fields are stored under names that fit your trade. Nineteen stored field names were corrected, along with the matching names in the API, the agent-facing schema, and the product CSV. If you have written a template, snippet or integration against a name like _pkit_em_ticket_url or _pkit_growing_notes, it is now _pkit_ticket_url and _pkit_production_notes. The spreadsheet column growing_notes is now production_notes, and older exports still import.

Loading sample data now says what it does. It publishes example content that visitors can see, which the button never mentioned.

Added

Say which business made this. When two producers share a site, products and events carry a byline — "Grown by Leftfield Urban Farm", "Baked by Slowbird Bread Co." The wording follows the trade of whoever published it, so a bakery's loaf is never "grown", and an event is always "Hosted by". Set the name you want shown on your own user profile. Nothing appears on a single-producer site.

Four things any event can have, named for your trade: who else is on it, when doors open, who can come, and where tickets are sold. A band's support act is a farm's shared booth is a workshop's co-teacher.

Sample data that matches your trade. A beekeeper gets Wildflower Honey at The Home Yard; a potter a Stoneware Mug at The Studio — rather than eight farm products whoever you are.

Fixed

Clicking "ProducerKit" opened an empty Sources list instead of the dashboard. The dashboard could only be reached by typing its address, which also meant the sample-data controls were effectively hidden.

Removing sample data deleted more than sample data. It also swept up leftover availability and RSVP records belonging to real products and events you had deleted yourself, and it stopped after 200 items per type.

Editor sidebar panels no longer call a React hook conditionally. Nine panels could break the editor sidebar depending on what a post had filled in.


Two things to know before updating.

Stored field names change automatically and your data comes with them — but custom code written against the old names needs updating. The full list is in the changelog.

If your products and events were published by more than one WordPress user, they will now carry a byline naming the producer. That is intended for two businesses sharing a site, but it triggers on any site with more than one author. Set each person's name on their profile, or turn bylines off with the pkit_show_producer_byline filter.

Full changelog: https://github.com/jwincek/producerkit/blob/v2.6.0/CHANGELOG.md

ProducerKit 2.5.0

Choose a tag to compare

@jwincek jwincek released this 06 Sep 17:27
dfea6e2

Recurring events, and the plugin finally asking what you make.

A weekly market used to be one event with one date, so it dropped out of the upcoming list the week after it started. It is now a series that creates a real event for every Saturday — and any single one can be cancelled for a holiday or moved, and stays that way when you change the series.

Added

Recurring events. Give an event a repeat — every week, every other week, the first Saturday of the month — and see the dates before you publish. Each one becomes a real event people can RSVP to individually, rather than everyone booking "the series". Dates are created about a year ahead and topped up daily, so a market never quietly runs out.

Cancel or change one date. Open that Saturday, toggle Event Cancelled, or change anything about it. From then on the series leaves it alone: change the series later and every untouched date follows, while your holiday closure stays put.

ProducerKit now asks what you make. Everything is named after your trade — the fields, the menus, the word for a made-to-order request — and until you choose, it uses a farm's words, because that is where the plugin started. A beekeeper was quietly getting "Growing / Baking Notes" where they meant hive notes. One dropdown, and it is easier now than after a season of typing.

Featured products on an event. Say what you are bringing to the festival. The field was already returned by the API and there was no way to set it, so it was always empty.

Fixed

A shop's page listed everything you make instead of what they carry. Products marked available everywhere now show at your own stand and market, not on a retailer's shelf — the one screen a customer might act on by driving there.

The availability board offered filters that showed nothing. Product-type buttons came from the whole catalogue rather than what was on the board, and counted products rather than items. They now also fade when the statuses you are showing leave them with nothing.

Also

The getting-started guide has been rewritten against a clean install — it never mentioned choosing a trade, and seven of its menu paths were out of date. Eight new screenshots, replacing five that predated the rename.


One thing to know if you set a recurrence rule by hand before this release, through WordPress's custom fields box: that event becomes a series the next time it is saved. It stops appearing on the site itself and the dated events it generates appear instead, reachable from the occurrences link on its row. Nothing is deleted. If you never touched that field — and there was no way to, until now — this does not affect you.

Full changelog: https://github.com/jwincek/producerkit/blob/v2.5.0/CHANGELOG.md

ProducerKit 2.4.0

Choose a tag to compare

@jwincek jwincek released this 04 Sep 22:14
2a7e60a

Three sales formats a beekeeper actually uses, and two features that turned out never to have worked.

Retailer stock answers the question a combined availability board cannot: someone in town wanting a jar today needs to know which of four shops to walk to. Deposits answer the one a nucleus colony raises — and building them uncovered that pre-orders could not be paid for through WooCommerce at all.

Added

Shops that carry your goods. Mark a location as a Retailer and record what they have. Their page gains an "Available here" list; every product page gains a "Where to find it" line naming the shops that currently stock it. Sold-out items drop off both, so nobody makes a wasted trip. Retailers need no accounts — you update it from your own delivery notes.

Per-product deposits on pre-orders. Take a fixed amount per item, a percentage, or the full price up front, and leave the rest for pickup. A $50 deposit on a nucleus colony takes $100 for two and leaves $300; jars in the same order ask for nothing. The balance is collected either way, chosen per pre-order: send a payment link, or take it at the table and mark it paid.

Made-to-order requests are called what your trade calls them. "Commission" is right for a potter and wrong for a beekeeper answering an enquiry about bulk honey, or a grower taking a special order.

Your profile now names the fields too, not just the categories. A beekeepers source is an Apiary with Forage Notes; a musicians is a Label with a Studio and Mastering Notes. The help text under each field follows the label.

An editor panel for sources. Their four fields were rendered on the front end and returned by the API with nowhere in the editor to enter them.

ProducerKit identifies itself to WooCommerce as an extension and declares compatibility with High-Performance Order Storage and the Cart & Checkout Blocks. Without this a store could be prevented from turning HPOS on.

A translation template ships with the plugin, so it can be translated without waiting for a WordPress.org listing.

Fixed

Pre-orders could never actually be paid for through WooCommerce. The pricing and the order-raising both existed but were never joined up, so the payment link the plugin promised for "a request" only ever appeared for commissions.

The editor is translatable throughout. The PHP was fully translated and the JavaScript beside it was hard-coded English — around 270 strings a translator could not reach.


Upgrading is safe: nothing here changes existing data or behaviour on its own. Pre-orders stay reservations until you mark a product as taking a deposit, and a site that never chose a producer profile sees the same labels it saw before.

Full changelog: https://github.com/jwincek/producerkit/blob/v2.4.0/CHANGELOG.md

ProducerKit 2.3.0

Choose a tag to compare

@jwincek jwincek released this 04 Sep 01:30

The trade fields a producer profile switches on now do something everywhere they appear — and the plugin stops looking like it is only for farms.

Filter the board by your own fields

A potter with a hundred pieces could not ask the obvious question: show me everything in stoneware. Now each field the active profile switches on gets its own filter row — Clay Body, Glaze, Firing Method for a potter; Substrate, Ink, Colours for a printer; Format, Edition, Packaging for a band.

The fields narrow together: Stoneware and Ash Glaze shows what is both, which is what someone picking through a shelf means by it.

Two things it deliberately will not do. Rows list only the terms actually on the board, because offering "Cone 10 Gas" when nothing on the board is fired that way is a dead end. And a field with a single value gets no row at all, because that is a control that cannot change what you see.

A farm profile uses none of these fields and sees no extra filters.

Trade Details in the editor

These fields were reaching the block editor through WordPress's own generic taxonomy panels, so a maker filled in price and unit in one place and Clay Body somewhere else entirely, further down the page. They are now in a single Trade Details panel beside the rest, labelled from the active profile, and the duplicate panels are gone.

Token fields rather than dropdowns, because these are open vocabularies you add to — a new glaze, a new wood — and the profile only seeds a starting set.

Twenty Abilities

Six added. Commissions had none at all, and RSVPs had only the visitor-facing create — so an assistant could answer "which pre-orders are due for pickup?" and not "which commissions are waiting on a quote?" or "who is coming on Saturday?"

list-commissions              count-commissions-by-status
send-commission-quote         update-commission-status
list-event-rsvps              cancel-rsvp

All six require the Editor role rather than Contributor, matching the screens that guard the same records — these hold customer names, email addresses, and prices the business is held to. None of them return a token: a quote token lets its holder accept a binding price and an RSVP token lets its holder cancel a booking, so both reach the person by email instead.

The icons stopped assuming you farm

A carrot sat on the product editor panel and in the block inserter. The commission form had a hammer, which a potter, an author, a beekeeper and a comics artist all do not do. The dashboard showed a leafy green and a sheaf of grain.

And a carrot sat at the top of every email the plugin sent — reaching a potter's customers, an author's readers and a band's mailing list, rather than only an admin who had learned to ignore it.

The catalogue is a tag everywhere it appears now, and there is a test that fails if any of them creep back.

Fixed

One of the optional taxonomies pluralised its REST base by appending "s", giving finishs. A REST base is a public route name, so it is now spelled out.

Upgrading

Safe from 2.2.0 and 2.1.0 — no data changes. If you are on 1.x, read the 2.0.0 notes first: there is no upgrade path from 1.x.

Requirements

WordPress 6.9+ · PHP 8.1+ · WooCommerce optional

24 unit and 317 integration tests, PHPCS clean, and Plugin Check run against the built package.

ProducerKit 2.2.0

Choose a tag to compare

@jwincek jwincek released this 03 Sep 21:13

Every request this plugin takes from a visitor can now be reached again by the person who made it.

Until this release, none of them could.

Request What happened before
Commission quote the emailed link returned a 404 for every customer
RSVP the guest got no email at all, and could not cancel once they closed the tab
Pre-order the form said "keep this cancellation code" and gave them nowhere to enter it

Each now opens from a link showing what was booked, with the one action that makes sense. Those actions are POSTs behind a confirmation, never plain links — a mail client prefetching a URL must not be able to cancel someone's booking or accept a quote on their behalf. The pages carry noindex and no-referrer, so a link cannot travel further than the person it was sent to.

RSVPs

Guests now get a confirmation email. Previously every notification in the plugin went to the site owner, so a visitor RSVP'd, saw a message on the page, and received nothing. It carries the event, the date, the party size and a link to the booking they can cancel themselves. On a capped event that matters: a guest who cannot cancel silently holds a seat nobody knows is free.

A guest list screen, which had never existed. The events list has shown an RSVP count since the feature was written, and there was no way to see who those people were. Now: headcount, spots remaining, one-click cancellation, and a CSV download to take to the door.

Cancelling frees the place whichever way it is done — the screen uses the same route the guest's own link does, so the count can't drift.

Pre-orders

The confirmation email now carries a link to view or cancel the order, and the form links to it instead of printing a code. The page shows the pickup date, the location, the items, and a status in ordinary words — "Collected", not picked_up. Cancelling is offered while the order is still pending or confirmed, and once it is packed or collected the page says so rather than pretending, because the produce is already picked.

Your data

Deleting an event or a pickup location now removes the bookings attached to it. Before, an event could be deleted and its attendees' names and email addresses stayed in the database indefinitely, pointing at a post that no longer existed and invisible in every screen. Trashing still keeps them, since a trashed event can be restored.

uninstall.php, which the plugin did not have. Deleting it used to leave four database tables, seven options, a scheduled job and every booking ever taken. Plugin bookkeeping now always goes; your products, locations, events and their bookings only if you have ticked the box under ProducerKit → Producer Profile. That is off by default, because deleting a plugin to troubleshoot something should not destroy a catalogue — and there is no undo.

Reading a guest list now requires the Editor role rather than Contributor. Names and email addresses are not a low bar.

Upgrading

Safe from 2.1.0 and 2.0.0 — no data changes, and the new cleanup only ever runs on a permanent delete you perform yourself. If you are on 1.x, read the 2.0.0 notes first: there is no upgrade path from 1.x.

Requirements

WordPress 6.9+ · PHP 8.1+ · WooCommerce optional

24 unit and 231 integration tests, PHPCS clean, and Plugin Check run against the built package.

ProducerKit 2.1.0

Choose a tag to compare

@jwincek jwincek released this 03 Sep 01:43
b789ddd

Recommended for anyone on 2.0.0. That release shipped a commission workflow that could not complete, and a checkout that could charge less than the listed price.

Commissions now work

In 2.0.0 a maker could send a quote and no customer could ever accept it. The accept/decline endpoint only answers POST — deliberately, so that a mail client prefetching a link cannot accept a quote on someone's behalf — but the email could only send a clickable link, and a click is a GET. Every customer who tried got a 404.

Quote links now open a confirmation page showing the price, the estimated date and what was asked for, with Accept and No thank you buttons. The page is noindex and sends no-referrer, so a quote link cannot travel further than the person it was sent to.

Quotes can also now be revised or reissued after the 30-day expiry. Previously the customer was told to ask for a new link and the maker had no way to send one.

Money

  • Pre-orders could be undercharged. The checkout read prices with a heuristic built for search-engine markup, which takes the first run of digits it finds: 2 for $5 was charged as $2.00, and $1,200.00 as $1.00. Any price that is not one unambiguous amount now stops the checkout and names the product so it can be fixed.
  • An accepted commission never produced a payment link — the code that raises the order had no caller at all.
  • Paying an order could settle nothing. The link between order and request was not checked before a payment URL was handed out, so the customer could pay and the request stay open.
  • Settlement ran twice per payment, overwriting the payment time with the fulfilment time.
  • Retrying a failed checkout created a duplicate hidden product each time.

Privacy

  • The hidden product raised for a commission was publicly readable. It was saved with WordPress's default published status, so the customer's name and their verbatim request were served to anyone who guessed its URL. It is now private, and no longer carries the customer's words at all.
  • The public commission endpoint returned database columns added by the WooCommerce module.
  • Reading customer records and issuing binding quotes required only the Contributor role. It now requires Editor, adjustable with the pkit_commission_manage_cap filter.
  • Rate limiting hashed visitor IP addresses without a salt.

Also fixed

One click on the commissions screen could put a request into a state it could not be recovered from. A commission's type and material displayed as raw slugs. Settlement columns could never be added on a site that enabled the commissions module second, and a failed table creation was never retried. Around twenty database queries were run to draw the commissions filter row, and four on every order status change store-wide.

Upgrading

Safe from 2.0.0 — no data changes. If you are on 1.x, read the 2.0.0 notes first: there is no upgrade path from 1.x and content saved by it is not read.

Requirements

WordPress 6.9+ · PHP 8.1+ · WooCommerce optional

24 unit and 197 integration tests, PHPCS clean, Plugin Check clean, PHPUnit passing on PHP 8.1.