v2.1.3 Latest
October 15, 2026
Fix 1
Fix
- Sites with a Learnomy Pro licence activated on the License tab are offered Pro updates again. Learnomy copies the key to where the update checker reads it.
New 6 Improve 12 Fix 32 Security 9 Dev 6 Compat 1
New
- Incoming sales: one signed endpoint records a sale made in another system and grants access through the same checks as checkout.
- Checkout offers every registered payment gateway, and a guest can pay with PayPal.
- A saved grade can be corrected with Edit grade on the instructor grading screen and in wp-admin.
- The site owner is told when an instructor asks to be paid, and instructors see their recent payout requests with the outcome.
- Instructors are told when a course is approved or rejected, with the reason, and the owner is told about submissions and new reports.
- Filter learnomy_display_timezone lets a site show each member their own timezone.
Improve
- Every date and time is stored in UTC and shown in the site's timezone, the same way on admin screens, member pages, emails and PDFs.
- Plugin pages show the block theme's own header and footer on Twenty Twenty-Three, Twenty-Four and Twenty-Five.
- Text meets AA contrast in light mode, in a bridged theme's dark mode and in wp-admin.
- A membership, Space, cohort or learning path sale sends each instructor one notice per new member instead of one per course.
- Admin lists keep the search and filters on every page, and a page past the end shows the last page.
- Admin screens show the field-level reason when a request is refused instead of a generic error.
- Refund buttons appear only where a refund can go through, and the refund dialog shows the amount in the site currency.
- A locked lesson says how it opens, and the lock icon sits on the current row of the outline.
- The quiz player saves conversational answers as you go, accepts number keys and shows honest category scores.
- The certificate designer previews the canvas without saving, and its tools are reachable on every screen size.
- Re-running the setup wizard keeps the site's preset, modules, currency and enrollment mode.
- Recurring jobs run through one scheduler, and the Payment Log prunes itself.
Fix
- A quiz result waits for the instructor before giving a verdict, on the quiz page, in the account, in the review PDF and in wp-admin.
- Coupon start and expiry dates apply in the site's timezone, so a coupon no longer expires the evening before its date on sites west of UTC.
- Course sale windows open and close at the local time the owner set.
- Pausing a membership takes its course access away until it resumes, and resuming does not announce a new student to instructors.
- Deleting a user cancels their live subscriptions at the payment provider first.
- Saving settings no longer wipes other settings or stores the admin email as the sender.
- The Stripe sweep no longer re-grants a refunded or cancelled sale, and membership refunds work on Stripe.
- A WooCommerce refund returns the money through the order's own gateway.
- The certificate expiry sweep leaves a revoked certificate revoked, and Bulk Revoke asks before it acts.
- Resetting a student's course progress no longer restores access that was cancelled or expired.
- Students can start an access-code quiz after entering the correct code.
- The instructor who imports or creates a quiz without a course can edit, publish and delete it.
- A refused payout request leaves the saved payout email alone, and payouts are recorded in the site currency.
- Answers and questions saved over the REST API keep their backslashes, so math notation survives a save.
- The Course Search block and the search shortcode submit again.
- Long unbroken words wrap instead of breaking course cards and admin tables.
- Email Log Resend sends the email as it was sent and asks before overriding an opt-out.
- Joining a cohort sends the course welcome again.
- Deleting a just-sent announcement also cancels its queued deliveries.
- Tab-switch tracking stays off until the owner turns it on.
- CSV exports no longer log a warning on PHP 8.5.
- The monthly membership revenue share runs once for each month, and no longer runs again right after the update.
- Recurring jobs keep the time they were due when they move to the shared scheduler.
- The one-time date conversions cannot run twice when two visitors arrive during the update.
- A WooCommerce refund for another product, shipping or a fee on the same order no longer refunds the course.
- Admin tables scroll sideways on phones instead of breaking short words across lines.
- Warnings inside forms and settings cards show as a padded notice with the icon beside the text.
- Saving Data Retention on an updated site no longer switches on Email Log clean-up.
- The Resume button on a subscription appears only where it can work.
- The order of lessons in no section can be saved in the course builder.
- In the course builder a sub-lesson follows its lesson when the lesson is moved, and sits indented under it.
- The setup wizard's Get Started, Continue and Finish setup buttons are visible again, and its confirm dialog has its background.
Security
- An email verification link signs in only with its own valid token.
- With Require login for all course content on, another plugin can no longer switch the gate off, and public instructor profiles close with the catalogue.
- A draft quiz cannot be started by a student over the REST API or the abilities API.
- An instructor can no longer attach another instructor's question to their own quiz and read it.
- A free-preview lesson with a future Available date stays locked in the REST API, attachments and media, not only on its page.
- The public course catalogue no longer returns a course's raw settings, and a course embed shows nothing for a course the visitor may not see.
- Course reviews and member course panels follow the course's visibility and Require login for all course content.
- The wishlist no longer returns a course's raw settings.
- Unsigned calls to the incoming sales endpoint are logged at most once a minute.
Dev
- REST date fields are sent as ISO 8601 with the offset, for example 2026-10-20T08:30:00+00:00, so integrations that match the old text should parse it as a date.
- Filter learnomy_require_login_for_content can require login when the setting is off, and a false return no longer opens an academy the owner closed.
- Action learnomy_student_enrolled carries a fifth argument that is true when an enrollment the student already held was switched back on.
- Template_Loader::theme_header() and theme_footer() open the site chrome for classic and block themes.
- The command wp learnomy test all runs every suite to the end and reports one total.
- Developer guide covers payment gateways, product types and incoming purchase sources.
Compat
- Aligned with Learnomy Pro 2.1.2. Install both updates together.
New 9 Improve 8 Fix 9 Security 3 Dev 2 Compat 1
New
- One site currency is used for every course, plan and report, and price fields name it.
- Fixed-term access ends for every learner, and renewing keeps the progress and completion already earned.
- A course can set a minimum time per lesson, and a lesson can override it.
- Every block has a matching shortcode that draws the same output, with new My Courses and Course Search blocks.
- One Course complete screen covers every way a course ends, and a Manual course says it is waiting for its instructor.
- Quiz results show one result block after submit, on a return visit and in the account.
- A refused sale can tell the buyer why, and the wishlist heart confirms a save and links to saved courses.
- An admin notice says when a webhook has been paused, on the dashboard and Settings.
- Duplicating a course copies its sections, lessons, sub-lessons, quizzes and unlock rules.
Improve
- Blocks look the same in the block editor as on the site, and Learnomy stylesheets load only on pages that use them.
- The membership plans layout is shared by the pricing page, the block and the shortcode, and fits a page column on any theme.
- A course whose term ended stays in My Courses with a Renew link, and the lesson page says Renew too.
- Next and Previous follow the course outline, and section counters agree with the course percentage.
- The wp-admin Grading inbox and its badge count every submission.
- Admin buttons, filters and dropdowns share one height and spacing, and a missing user reads Deleted user on every screen.
- Lesson and quiz pickers name each item's course and follow one rule for instructors and page editors.
- Keyboard focus uses one visible ring on every front-end control.
Fix
- Lesson time counts only time that really passed, so a time rule cannot be met by repeated requests.
- A new or copied lesson, and a quiz, keep the place they are given in a section.
- A draft quiz no longer shows through the Quiz block, shortcode or widget.
- Course Grid set to a category with All selected shows courses instead of an empty grid.
- The student count no longer rises each time a fixed term is renewed.
- Deleting your account asks for your password and works, and removes notification and email-log rows.
- Checkout names a missing billing field and keeps the reason in view.
- One active certificate is kept per learner and course.
- Plugin pages print a single main landmark inside themes that already have one.
Security
- The lesson, quiz and section lists over the REST API are limited to authors and enrolled learners, and instructors see only their own.
- An instructor's question bank over the REST API holds their own questions and those used in courses they teach.
- App tokens carry a type, so only a refresh token can request a new pair.
Dev
- New filters learnomy_email_merge_tags and learnomy_is_editor_preview, and a docblock on every hook.
- Translation template regenerated for 2.1.1.
Compat
- Aligned with Learnomy Pro 2.1.1. Install both updates together.
v2.1.0
September 30, 2026
New 6 Improve 7 Fix 22 Security 3 Dev 2 Compat 1
New
- Guest checkout: a visitor can buy or enroll with only an email address, and their account is created once the payment succeeds.
- Learnomy notifications reach a community notification centre such as BuddyNext, each type with its own on/off switch.
- The purchase confirmation email and the owner's New purchase email carry a receipt with order number, amount, date and method.
- Lesson pages list their attached files.
- Certificates print the course instructor's name.
- Registration Fields can be reordered by drag and drop, or with Move up and Move down buttons for keyboard and touch.
Improve
- One grading inbox serves the front-end Grading page, the dashboard card and the mobile app.
- Catalog and course cards share one filter design, a linked External badge and a readable progress footer, and My Courses gains a grid and list switch.
- Membership Courses included cards match the catalog course card.
- Admin status tabs show counts, and an empty tab says what is empty instead of offering to clear filters.
- Toasts and confirm dialogs follow the theme's font, and use BuddyNext's shared popups when BuddyNext is active.
- Course hero badges get a subtle frosted background so they stay readable over any cover image.
- Admin fields, question editor answers and picker filters have accessible names for screen readers.
Fix
- The WooCommerce checkout page lays out its order summary and billing form as a normal form instead of centring every line.
- A WooCommerce guest order delivers the course instead of taking payment and granting nothing, and the guest sees their order confirmation instead of a login form.
- WooCommerce purchases grant access only once the order is completed, and a paid order holding only Learnomy items completes on its own.
- The WooCommerce thank-you page offers Start learning only after the order is completed.
- Guest checkout refuses an email that already has an account and asks the buyer to log in.
- A course taken off sale no longer shows Buy on the course page, the sticky bar or its catalog card.
- Learnomy pages no longer crash with ThinkRank, and with any supported SEO plugin they carry exactly one canonical, Open Graph title and meta description.
- Refunding a recurring course cancels its subscription.
- Stripe subscriptions recover a missed invoice webhook, book a missed renewal as a renewal, and never re-grant a payment whose buyer was deleted.
- An approved lesson comment is announced to the instructor, and an instructor's own reply is posted without waiting for moderation.
- Members cannot report their own course, review or comment, and a review's author sees its real status.
- My Courses and category archives honour the site-wide Catalog columns setting.
- A member's profile photo can no longer be attached to a lesson as a protected handout, which made it disappear everywhere else.
- The admin course roster lists removed and expired enrollments again, with Restore access.
- The admin course Instructors card shows no Save button when there is nothing to edit.
- Admin dropdown arrows, checkboxes and radios are visible again, and the Import CSV and Add Questions modals open centred over a backdrop.
- The lesson editor keeps the body editor for every content type and switches to edit mode after the first save.
- The course page clears the theme's sticky header and links only to sections that exist.
- The Transactions and Question Bank lists fit a laptop screen, so Status, Date and Refund are visible without scrolling sideways.
- Admin filter dropdowns leave room for their arrow instead of drawing it over the label.
- In solo mode the Modules page explains that Commissions is off and links to the setting, instead of a switch that did nothing.
- A guest whose email already has an account gets a Log in link, and the message is no longer hidden under a sticky header.
Security
- The order confirmation page shows a purchase only to the person who made it; a signed-in member could open another member's confirmation by changing the link.
- Per-IP limits on login, sign-up and guest checkout trust a forwarded address only from a known proxy, so a rotating header can no longer reset them.
- Guest checkout is rate-limited per IP and runs the registration CAPTCHA.
Dev
- New filters: learnomy_checkout_thank_you_url, learnomy_course_is_purchasable, learnomy_trusted_proxies, learnomy_guest_checkout_rate_limit and learnomy_seo_plugin_head_filters.
- External commission credits record their source and cannot be credited twice.
Compat
- Install alongside Learnomy Pro 2.1.0. Install both updates together.
v2.0.0
September 23, 2026
New 2 Improve 2 Fix 6 Dev 2 Compat 1
New
- Design the single course page in Elementor with Learnomy Pro: a Single Course template type in the Theme Builder, Learnomy widgets for every part of the page (curriculum, description, price and enroll box, outcomes, prerequisites, instructor), and display conditions for all courses, a category, or one course. If a template has no way to enroll, Learnomy adds the price and action bar so no course is left unbuyable.
- A single course can use a different layout from the rest of the site. Set Course template on the course itself; leave it on the site default and the course follows Settings > Layouts.
Improve
- Reviews and the Progressive Web App each have one switch now, on the Modules page, instead of a module and a separate setting that could disagree. An install that had either switched off keeps it switched off.
- Certificate Defaults renames Enable Certificates to Award by default, which is what it does: courses can still opt in individually when it is off.
Fix
- Renaming an entity in Settings > Labels no longer drops translations. Reworded strings had been orphaning their translations since 1.9.4, leaving parts of the interface in English on a translated site; 2,644 of them are restored across the nine locales, and the build now keeps every catalogue in step with the template.
- Unconfirmed machine-matched translations are no longer shipped as if a translator had approved them.
- A member with no profile photo now shows their initial on a branded tile everywhere their photo appears: course pages, instructor profiles, reviews, lesson comments, dashboards and the admin lists. WordPress's grey silhouette was still showing on most of them.
- The instructor photo on a course page renders as a cropped circle on sites that do not use Elementor. It had been an unstyled square with the initial stacked above the photo.
- Save Changes on Settings > URLs & Pages sits at the bottom of the panel, below the Frontend Pages list, rather than part way up the page.
- Approving an instructor application whose member account has since been deleted is refused with an explanation, instead of reporting success while granting nothing.
Dev
- Per-locale translation coverage is measured against the strings the code actually emits and gated, so a locale can no longer go backwards unnoticed.
- A layout variant may live outside the Free plugin and may be hidden from the owner-facing pickers when something else owns its on/off decision.
Compat
- Install alongside Learnomy Pro 2.0.0. Install both updates together.
v1.9.5
September 11, 2026
New 2 Improve 10 Fix 22 Dev 3 Compat 2
New
- The wp-admin Add New Course screen offers Create with AI, matching the frontend Course builder.
- The Students list gains a Current students filter, with past students one control away.
Improve
- Checkout no longer shows a billing error before the buyer has submitted anything, and the error names the fields that are missing.
- Every notification email is branded, including any type added later.
- The Email Log records the recipient address for every email it holds.
- A prospect browsing a paid Course now sees the full curriculum before buying.
- Maths assets load only on pages where maths can appear, instead of every Learnomy page.
- Account screens render their icons on the server, so the icon library no longer loads where nothing needs it.
- The Level, Rating, Duration and Instructor catalog filters are cached, and each caches as itself.
- Learnomy's own admin notices no longer stack above the settings you came to change.
- Every account screen uses the same page header.
- The withdrawal balance and minimum are available to the mobile app instead of being inferred.
Fix
- Removing a student from the Students list no longer strips their WordPress role or removes them from every Course.
- A Course that was completed stays completed after re-enrolment, so a retake cannot lock the next Course in a Learning Path.
- A refund sends one cancellation email instead of two.
- An expiry that has already happened is not announced again.
- The Students report counts the Course you filtered to rather than every Course a student holds.
- Switching a module off stops its API writes as well as its screens.
- Enabling a module that owns a page no longer leaves that page returning 404 until permalinks are saved.
- Declared limits on API fields are enforced again.
- A PATCH request no longer writes fields the request never mentioned.
- The Delete button on LTI Platforms works.
- A Course with no cover image shows nothing in a WooCommerce receipt instead of WooCommerce's placeholder.
- The Course cover in a WooCommerce receipt is no longer squashed in Outlook.
- Checkout still works when WooCommerce's product lookup table holds a stale row.
- WooCommerce buyers get the same billing field errors Stripe buyers get.
- An owner is no longer told they are in test mode while WooCommerce is taking the money.
- A lifetime plan's checkout no longer promises renewals it will never charge.
- Co-instructors are no longer shown a Duplicate button that always failed.
- Email Log and Gift Codes appear under their proper menu heading.
- The mobile app is told correctly whether student registration is open.
- Offline progress syncs, and the offline page can be reached.
- Gift, Learning Path and Space purchases go through WooCommerce when it is the chosen checkout, instead of charging through Stripe on the same site.
- Subscription renewal payments are linked to their subscription in the ledger, so per-subscription revenue stays complete on both Stripe and PayPal.
Dev
- Extensions can add a per-lesson panel to the Lesson editor through a supported hook.
- Pro extensions can register their own groups of email toggles.
- Design tokens are checked at release time, and a comment can no longer register as a token definition.
Compat
- Where BuddyNext is installed it owns the progressive web app and its service worker.
- Install alongside Learnomy Pro 1.9.5.
New 9 Improve 3 Fix 36 Security 6 Dev 12
New
- Student self-registration can be turned off from Settings > General > Academy Mode ("Allow students to sign up"), for a members-only academy or to drive signups through a third-party form (e.g. Gravity Forms): the register page 404s, the registration API rejects student signups, and every "Sign up to enroll" button retargets to the login page (or a URL from the learnomy_student_registration_url filter) so no link is left pointing at the disabled page. Instructor registration already had this switch; students now match.
- Students can leave a free course they joined themselves, right from the course page. Paid and membership enrolments are intentionally not self-removable there, since leaving would forfeit access with no refund, so the option shows only on free self-enrolments and the REST and ability routes enforce the same limit.
- Learnomy now emails students who stop studying, so they come back. A daily job sends a re-engagement reminder to anyone whose courses have gone quiet past a threshold you set (Settings > Emails, default 14 days), at most one per lapse. Instructors also get a Send reminder button beside each at-risk student on their dashboard, and the admin Students list gains an inactivity filter. The email is opt-out-able like any other.
- The course catalog can now be filtered by Price, Level, Rating, Duration and Instructor, alongside the existing category and tag filters. The filters appear in the sidebar catalog layout and each shows a live count. Site owners and extensions can add their own the same way, through the catalog facet registry.
- Coupons can be used on membership checkout. The discount applies to the first payment; renewals are charged at the plan's regular price, so an owner can run an early-adopter offer without discounting the membership forever.
- Membership plans can be sold as a one-time purchase with lifetime access. Pick "One-time (lifetime access)" as the billing interval: the buyer is charged once, no recurring payment is set up at the gateway, and the membership never expires. Pricing cards show the price as one-time and the button reads "Buy" instead of "Subscribe".
- A membership plan can be scoped to a Learning Space from the plan editor and the REST API. The column was already enforced when checking access but there was no way to set it except by editing the database.
- Instructors can duplicate a course from the "My Courses" list on their dashboard. wp-admin has had a Duplicate action for a while, but instructors who only ever see the frontend builder had no way to clone a course without an admin doing it for them. The copy is created as a draft.
- "Courses per page" is now a setting under Layouts. The catalog has always honoured this value but there was no field to set it, so it could only be changed with WP-CLI or code.
Improve
- A renamed entity label (Settings > Labels: Course, Lesson, Quiz, Section, Topic, Category, Student, Instructor) now follows through the whole product. Every owner- and member-facing surface reads the site's own words: the catalog, single course, lesson player and quiz screens, the student and instructor dashboards, the account and checkout pages, the block editor, emails and notifications, the browser title and SEO meta tags, and every wp-admin editor and list. JavaScript follows the rename too, so in-page toasts and inline labels match, and counted strings pick the singular or plural correctly. Whole surfaces stayed hardcoded before, so a site that called Courses "Programs" still read "Course" in dozens of places. Every string stays translation-ready.
- The browser now asks students to confirm before they reload or leave the page during a quiz that is in progress, so a stray refresh does not cost them exam time. It only appears while a quiz is being taken, not on the start or results screen.
- "Payment Webhook Log" is now "Payment Log", a pair with "Email Log" four rows above it and the last sidebar label that wrapped to two rows. The page address is unchanged, so bookmarks keep working.
Fix
- The setup wizard is no longer a dead screen on a fresh install. Its five steps all rendered hidden with no way to start, continue or skip, because the wizard runs as a standalone takeover before the admin script pipeline and its money-formatting dependency was never registered, so the whole wizard script was dropped and never printed. The dependency is now registered for the takeover, and step 1 loads with its Get Started button as intended.
- When a WooCommerce coupon discounts a Learnomy sale, the transaction now records what the customer actually paid, not the pre-discount list price. A $40 course bought with a 25% WooCommerce coupon for $30 was recorded as $40, and instructor commission was paid on the $40 the buyer never paid. The recorded amount now comes from the charged line total, and any tax baked into the price is scaled by the same discount.
- A one-time (lifetime) membership bought through PayPal now grants the membership. The buyer was charged and a transaction was recorded, but no membership was created, so they got no access. PayPal routes a lifetime plan through its order path, which recorded the sale but never subscribed the buyer; that path now grants access like every other gateway.
- A coupon used on the first payment of a Stripe subscription (Payment Element flow) is now marked redeemed, so its usage count and any redemption limit are accurate. Previously the coupon on a subscription's first invoice was recorded on the transaction but never counted, unlike every one-time purchase.
- When a recurring subscription or membership ends and revokes course access, the learnomy_student_unenrolled action now fires, so an integration that grants access on enrollment (a community, a companion product) revokes it too. Only a direct un-enrollment fired the hook before; subscription and membership expiry changed the enrollment silently and left those integrations granting access after it ended.
- The coupon field has been removed from the course page and the membership pricing page; coupons are now entered on the checkout page, the one surface that applies them for every payment method. On the WooCommerce gateway the course-page field promised a discount the WooCommerce checkout could not honour, so a buyer saw a discounted total and was charged full price. Buyers paying through WooCommerce use its own coupon box at the WooCommerce checkout.
- A quiz attempt where an essay question was left unanswered is no longer scored a silent zero and hidden from grading. It now waits in the instructor's grading queue showing "(no answer submitted)", so the instructor decides the mark. Previously such an attempt finalised itself, the essay was scored 0 with no trace, and it never appeared in Grading.
- Answers in the Classic quiz layout are now saved the moment you pick or type them, so an accidental reload or a closed tab resumes the attempt with your answers intact. Previously the Classic layout was the only one that did not save on change, and a reload restored nothing.
- Completing a lesson no longer auto-advances the student onto a lesson that is still locked by a drip schedule. When the next lesson has not unlocked yet, they stay on the lesson they just finished instead of landing on an "unlocks later" screen. Sequential courses are unaffected, since finishing a lesson unlocks the next one.
- Money is now written the same way everywhere. Some screens showed "US$627" where others showed "$627.00" for the same figure, and several screens printed a dollar sign whatever currency the site was set to. Every amount now uses the site's own currency symbol, its decimal count, and the side the symbol belongs on for the site language.
- The URLs & Pages settings tab showed two "Save Changes" buttons with nothing saying which fields each one governed. It now has one, like every other tab.
- A paused membership can now be cancelled. The button was already on the screen and the request was refused, so members had to resume - restarting billing - before they were allowed to stop it.
- A coupon that has used up its redemptions now reads "Exhausted" in the list and is switched off, instead of showing "Active" next to a spent count. Coupons already at their limit before this update are labelled correctly too.
- The Course Catalog block silently showed only its first page of courses. It now links to the full catalog when there are more, so nothing is unreachable.
- The transaction detail screen hid the Refund button as soon as any refund existed, so the rest of a partly-refunded sale could not be returned from that page. It now offers the remaining amount, matching the list view and the API, and shows "Partially refunded" instead of "Refunded".
- Setup wizard presets now switch OFF the features they do not include. Choosing "Simple courses" left quizzes, reviews, notifications and abilities running, so the site did not match the tile that was chosen.
- The QA seeding script left two courses with a stale student count, so a freshly seeded site failed its own integrity check every time. It now recomputes the counter for the courses it creates.
- A site set to live PayPal that still carried the old sandbox flag was calling the PayPal sandbox API with live credentials. The mode you selected now wins.
- The Categories admin listed every category on one page and put every one of them into the parent dropdown. It now pages 50 at a time with a search box, matching the Tags tab beside it. On a site with 2,000 categories the page went from 3.5 MB to 234 KB.
- The yearly billing badge on the pricing page said "Save up to 20%" whatever your plans cost. It now states the real best saving across your plans, and says nothing at all when a yearly price is not actually cheaper than paying monthly.
- Admin tables that are wider than the screen now show a soft shading at the edge that still has columns behind it, so it is clear the table scrolls sideways. Previously there was no indication at all, and on macOS the scrollbar stays hidden until you scroll.
- The membership plan editor offered 8 currencies while the product supports 163, so an owner could not price a plan in a currency the checkout would have accepted. Every currency picker now offers the full list, and a currency the product cannot charge in is refused on save instead of stored and quietly ignored later.
- The Dashboard system-health panel linked to "Webhook Events", a label removed in 1.9.3. It now matches the sidebar row it opens.
- Certificates no longer print the verification QR code over the certificate's own text or border. Two of the four supplied designs overlapped the QR with the course title or completion date, and a third placed it on the decorative frame; sites are corrected automatically on update, and a QR you positioned yourself is left exactly where you put it.
- The certificate heading and course title now use the full width of the page instead of folding into a narrow column with two thirds of the page empty. Existing sites are corrected on update.
- Lesson and quiz screens now use your theme's font. Those screens deliberately hide the theme's header and footer and were dropping its typeface as well, so the two screens students spend the most time in rendered in a different font from the rest of the site.
- Card, dropdown and dialog shadows are now visible in dark mode on Reign and BuddyX. Ten colours, including every shadow, kept their light-mode values because those themes signal dark mode their own way, which left a near-black shadow on a near-black surface.
- A quiz answer no longer shows the keyboard focus outline when it is clicked with a mouse. That outline exists to show keyboard users where they are and now appears only on keyboard focus.
- Previewing your own course no longer records lesson progress against you. An instructor or administrator clicking through a course they are not enrolled in was writing real completion rows, which inflated both their own progress and the course's activity figures.
- Turning a module off now disables the feature itself rather than only hiding its menu. Nine admin pages answered with a bare permission error instead of explaining that the module is switched off and how to turn it back on.
- The checkout no longer shows a red error box with nothing written in it. On the WooCommerce and PayPal routes the explanation was being written into an element those pages do not render, so a buyer was stopped with no reason given; and a completed form revealed an empty box instead of clearing the previous one.
- Placeholder text in Learnomy inputs is now readable. It failed the WCAG AA contrast minimum in both light and dark mode, most visibly in dark mode where the course search box read at roughly 2:1 against its own field.
- Extending a subscription from Learnomy now moves the WooCommerce next payment date with it. The extension was recorded on the Learnomy record only, so WooCommerce kept billing on its original date and the two screens disagreed about when the customer is charged. The date only ever moves later, so an extension can never bring a charge forward.
- A module that depends on another now shows the truth on the Modules screen. A dependent module could read as switched ON while its parent was off and the feature was doing nothing; the toggle now locks, names the module it needs, and keeps your choice for when you turn the parent back on.
- Email Log and Gift Codes now sit under a heading in the admin menu instead of being dropped, unlabelled, at the bottom of their menus.
- A one-time (lifetime) membership no longer tells the buyer at checkout that "renewals are billed at the regular price". There are no renewals on a lifetime plan, and the coupon applies to the whole purchase.
Security
- Closed a hole where a logged-in member could grant themselves a paid membership for free through the subscribe ability. The paid-plan guard that already protected the checkout API now lives in one place that every self-service subscribe path shares, so it can no longer be enforced on one surface and missed on another.
- The companion plugin installer now refuses any download that is not HTTPS from the Wbcom store. It previously installed whatever URL the store response contained, so a poisoned or intercepted response could have turned an admin clicking Install into installing someone else's zip.
- PayPal webhooks with no webhook ID configured are now always rejected. Previously verification was skipped in sandbox mode, and the sandbox flag defaulted to on and was never cleared when a site went live, so a live site that had not pasted a webhook ID would accept an unsigned request on a public URL.
- A PayPal subscription activation is now read back from PayPal before granting the membership, instead of trusting the identity in the webhook body.
- The Test payment gateway shipped switched ON by default. It completes a purchase and grants course access without charging a card, so on any site that never changed payment settings a buyer could take a paid course for nothing. It is now off by default, and updating switches it off on existing sites unless you deliberately chose sandbox mode. Your real payment settings are untouched, and the site tells you once that it changed.
- The setup wizard no longer badges sandbox mode "Recommended", and says plainly that anyone reaching your checkout can enrol without paying.
Dev
- All four payment gateways (Stripe, PayPal, WooCommerce, Test) now route through one shared Purchase_Provisioner: each parses its own payload and hands a normalized purchase to a single place that records it, enrols or subscribes, and handles the coupon. This retires the per-adapter branching where the gateways used to drift apart (the source of the charged-but-not-provisioned bugs), and the cross-adapter conformance suite proves all four reach identical outcomes, including new scenarios for Stripe's first-invoice subscription and WooCommerce's subscription path. WooCommerce keeps its own multi-item order loop, subscription mapping and renewal handling around the shared call, and continues to record which coupon paid without enforcing Learnomy redemption on a WooCommerce-managed coupon.
- The PayPal gateway now separates parsing an approved order from capturing it, and both PayPal paths (one-time purchase and membership activation) route through a shared Purchase_Provisioner that every adapter can use. This lets the cross-adapter payment conformance suite exercise PayPal offline, so the class of bug where a PayPal course sale charged the buyer but enrolled nobody is now caught automatically in CI rather than only by a live sandbox run.
- New Commission::earnings_summary_for_instructor_courses() and Commission::monthly_totals_for_instructor_courses() scope an instructor's earnings (lifetime, paid, pending, and the monthly trend) to a specific set of their courses, one aggregate query each, for surfaces that report earnings for some of an instructor's courses rather than all.
- New WP-CLI command "wp learnomy inspect quiz <id>" dumps a quiz's attempts, pass rate, average score, and per-question facility ordered hardest-first, so quiz analytics can be read from the terminal without a page or REST call.
- New Quiz::for_course() returns every quiz in a course, section-attached, lesson-attached, or loose, so analytics can list quizzes that have no attempts yet. The existing listers each returned only a partial set for the course builder.
- New GET /learnomy/v1/devices lists the caller's registered push devices (tokens returned as a hint only). POST and DELETE existed but there was no way to list what was registered.
- New GET /learnomy/v1/admin/commission-rules returns the current commission overrides. The write endpoints shipped without a read, so a client could set a rate and never confirm it.
- New GET /learnomy/v1/admin/reports returns the moderation queue (open reports by default). Resolving a report no longer requires knowing its ID from somewhere else.
- Checkout accepts a registered purchase_type and quantity, so an extension can sell through the one checkout path instead of building a parallel one. Pro's gift purchases now use it.
- New action learnomy_admin_subscription_detail_panels for content panels below the payments table on a subscription, distinct from the existing header-actions hook.
- Added Lesson::ids_by_course() and QuizAttempt::best_percentage_for_user_courses(), batch helpers that let Pro score one learner across many courses without a query per course.
- The REST catalogue in docs/api/openapi.json now refuses to generate when a route belonging to an optional integration is missing, instead of quietly publishing a spec with that route dropped.
New 11 Improve 8 Fix 24 Security 2 Dev 7
New
- Add your own fields to the student and instructor sign-up forms through three hooks, target one form or both, and mark a field required on the server and in the browser.
- A built-in anti-spam question for sign-up, off by default, with a seam any third-party CAPTCHA can plug into instead.
- Rename Student, Instructor and Space across the whole product, not just their content, from Settings or the learnomy_entity_labels filter.
- Every ISO 4217 currency is now offered, so a site can charge in Swiss francs, Kuwaiti dinars or anything else its gateway supports.
- Suspend and resume an instructor, instead of a Remove button that could not do what it said.
- Every curriculum row shows how long it takes, and a topic shows the total of what is inside it.
- The catalog tells a member which courses their membership already covers, before they reach checkout.
- A learner can list their own quiz attempts over the API, and the wishlist returns the courses rather than only their ids.
- Report state and announcement history are readable over the API.
- One instructor grading inbox, with a seam extensions can join rather than opening a second one.
- Extensions can contribute their own integrity repairs to the maintenance sweep.
Improve
- The curriculum locks to real access rather than a price check, and says which of the three reasons applies.
- A locked lesson remembers the course it sent you to, through logging in as well as signing up.
- The sidebar stops printing a section heading over nothing, and a protected video says when it cannot play instead of showing an empty frame.
- The instructor navigation hides the links a person would only 404 on.
- A long option list on sign-up becomes a pick-and-add control instead of a wall of tick boxes.
- Save confirmations use the real toast and survive the page reload that follows.
- Recommended course cards fit inside their card on a phone.
- The lesson drawer dims the page behind it, so it reads as a drawer.
Fix
- A currency code now has a space before its amount, so a price reads CHF 49.90 rather than CHF49.90.
- Bahraini, Iraqi, Jordanian, Kuwaiti, Libyan, Omani and Tunisian dinars are stored in thousandths, as their standard requires.
- A customer on a site with two-factor login is no longer told their password is wrong. The response now says a site login is required and why.
- The notification panel closes through its store rather than by writing to the page, so the bell and the panel stop disagreeing.
- The instructor roster stops counting courses that no longer exist.
- When a person has more than one enrollment row for a course, the row that got furthest represents the pair.
- A course with no sections renders through the same path as one with them, and a curriculum card no longer invents a title.
- The instructor suspension check tests the person acting, so an administrator is not blocked by somebody else's suspension.
- Certificate names stay on one line, and the font the instructor picked reaches the PDF.
- The lesson editor says when the fixed Available date is not the one actually in force.
- The instructor landing page explains itself again instead of returning 404.
- One resolver decides what the course call to action says, so the enrollment card and the button stop contradicting each other.
- The lesson-comments toggle renders on the course form again, and the form stops saving settings it does not show.
- An instructor's grade override now beats the auto-grader instead of being overwritten by it.
- Checkout prices come from one resolver, and the WooCommerce order summary shows the price it charged.
- The catalog Paid and Free filter asks what the learner actually pays.
- The grading API refuses a score above the question's maximum instead of echoing it back.
- A reported item keeps its Reported state across a reload, and the modules toggle stops reporting a network error over a save that succeeded.
- Money in templates and notifications carries its currency, formatted one way throughout.
- Commission rules can be deleted, as the documentation already promised, and a refunded commission stops counting as earned.
- Three controls that looked active and did nothing now do what they say.
- Instructor announcements report the real reason Send failed, in the three cases where it could.
- A learning path with an unavailable required step is no longer sold.
- Creating a course derives its slug, as creating a quiz already did.
Security
- The sign-up rate limiter now runs before the anti-spam challenge, so a flood cannot force repeated challenge work.
- The instructor status route is registered and permission-gated rather than reachable unannounced.
Dev
- New hooks: learnomy_account_fields, learnomy_account_fields_validate, learnomy_account_fields_save, learnomy_registration_challenge, learnomy_registration_challenge_verify, learnomy_entity_labels and learnomy_three_decimal_currencies.
- Entity relations are declared once, with cascade, detection and repair derived from that declaration.
- 140 lifecycle events are published, and publishing an event is now gated at zero tolerance rather than left to habit.
- The manifest lists the 37 REST routes it was missing, and a gate keeps it honest.
- Every functionality group shipped this release has a browser journey.
- Removed: Learnomy no longer edits your site's navigation menu. It used to hide menu items - instructor sections from students, "Become an Instructor" from instructors, student signup from anyone signed in - and it could remove the wrong item, including Home. Every one of those pages now explains itself instead, so nothing needs hiding. The `learnomy_hidden_nav_routes` filter added in 1.9.1 is gone with it; if you hooked it, your callback is simply no longer called and menu items you were hiding will reappear.
- New filter `learnomy_route_access_gates` (route name => template partial) so a route can answer a refused visitor with an explanation instead of a 404. The five instructor section routes now return 200 with an access gate rather than 404 for a signed-in non-instructor.
New 7 Improve 10 Fix 37 Dev 5 Compat 1
New
- Quiz start screens come in three layouts and you pick the one you want per quiz.
- The quiz attempt review exports as a printable PDF.
- A long review reads by section: 300 questions collapse into groups and filter down to just the mistakes.
- The quiz review shows which answer the student picked, beside the correct one.
- Instructors set how many questions a sectioned quiz draws from each section.
- Lessons can be detached to an orphan pool on purpose, and attaching a lesson that belongs elsewhere asks whether to Copy or Move it.
- The curriculum can return sub-lessons.
Improve
- Bulk actions sit above the list on every admin list screen, and row actions collapse into an overflow menu instead of crowding the table.
- The curriculum says WHY a lesson is locked, not only that it is.
- Settings are grouped by what they do rather than by which plugin adds them, and no settings row is left outside a group.
- Pro Tools groups its tools under Teaching, Skills and progress, and Standards and import instead of one flat list.
- The seat product is called Learning Spaces everywhere it is named, so it is not confused with the Spaces feature other plugins add to the same site.
- Switching a module off shows a screen naming the module to enable, instead of a permission error that reads like a fault.
- Learnomy routes present as pages, so theme builders render their headers and footers on them.
- Lesson comments go through normal WordPress moderation, and a comment made during a lesson can be deleted.
- "In progress" means enrolled and not finished, and one progress label is used across the screens.
- Certificate field labels say what each field actually takes.
Fix
- Outgoing email keeps the WordPress sender address when you have not set one. Learnomy replaced it with the site admin address, which is often on another domain and sent transactional mail to spam.
- "Show quiz answers: only after the student passes" now does exactly that. It was treated as "after each attempt", which handed the answer key to anyone who failed once.
- A course that requires a membership no longer offers a Join link when memberships are switched off, because that link led to a page which does not exist on those sites.
- A quiz that belongs to a course opens correctly from a learning path step instead of a Not Found page.
- A lesson quiz sends the student back to the lesson it belongs to.
- A quiz is only as open as the lesson it belongs to.
- Instructors can reach Assignments, Content Drip and Learning Paths from the admin menu again.
- White Label no longer renames all three Learnomy menus to the same word, which made Commerce and Settings impossible to tell apart.
- Reported Content opens a page headed Reported Content, and no page heading carries the pending count from its menu row.
- Analytics shows a dash where nothing has been graded yet and a real 0% where a group genuinely scored zero. The two were indistinguishable.
- A learner at zero percent reads as in progress, not as missing.
- A student who passed is no longer shown a cross on their result.
- Saving a course never changes its price.
- A zero-total order completes without a payment gateway configured.
- Subscription trials reach Stripe, and a trial checkout still mounts.
- A mistyped payout email is refused instead of silently paying the previous address.
- Dates the site does not have render as a dash, and are no longer written in the first place.
- Coupon and money-back wording appears only where a purchase can actually happen.
- Course pages no longer advertise "0 lessons" as a feature.
- An instructor sees their own course's content.
- A seeded membership plan opens the courses it advertises.
- Course payloads carry the price exactly as the site prints it.
- A member whose plan includes a course can open its lessons. The course page offered the course and the lesson then asked them to enrol.
- Instructor pages ask whether you may see them, not merely whether you are signed in. A student who typed the address was shown the instructor console.
- The Self-Publish Courses setting works in the course editor. Instructors it applied to were still offered Draft and Pending Review only.
- My Courses leaves out trashed courses, and its Next and Previous buttons work on the My Courses page.
- Review and Retake on the Quiz Scores panel open the quiz instead of a Not Found page, and a course quiz opened at its short address goes to the right place.
- Rejecting an instructor application asks for a reason, and the applicant reads it. Approve and Reject also work on the instructor's own page, where neither did anything.
- Applying to teach again after a rejection says what happened. The form also explains a missing field, an over-long answer and too many attempts, none of which reached the applicant before.
- A course page's breadcrumb leads back to Courses. Signing in re-pointed it at your account.
- The notifications panel closes. On some themes it painted over the page and stayed there.
- The account menu on a phone closes when you tap outside it or press Escape.
- Learnomy blocks appear under Learnomy in the block inserter instead of Uncategorized.
- Buttons that carry a course or space name wrap inside their border instead of running past it.
- The quiz buttons fit on a phone, at one height and one shape, and nothing floats over them.
- Previous and Next lesson cards line up when stacked on a phone, and a page heading's icon sits with its text at every size.
- A withdrawal of a single earning reads "1 earning".
Dev
- Right-to-left support: physical left/right CSS converted to logical properties, with a gate to keep it that way.
- Quiz URLs are built through one helper, so a course quiz and a standalone quiz always resolve to the route that serves them.
- New filters: learnomy_sender_email, learnomy_sender_name, learnomy_membership_on_offer, learnomy_admin_settings_nav_groups, learnomy_pro_tools_card_groups.
- A Pro content type can register what a client needs to play it, and content-type labels come from one place.
- Buttons whose label is content opt into wrapping with one modifier, and instructor routes gate on a named ability rather than a hardcoded capability.
Compat
- Requires Learnomy Pro 1.9.2. Install both updates together.
New 4 Improve 6 Fix 5 Dev 3 Compat 1
New
- The quiz result screen offers View Certificate when you hold one for that course, including the certificate that pass just earned.
- Catalog cards carry an Enroll or Buy action, so a course you have not bought invites you in like one you have.
- Instructor My Courses has a Create Course action on the list itself, not only on the dashboard.
- Members can edit their own billing address from the account area.
Improve
- Reports Completion counts everyone who finished the course, not only learners who enrolled inside the reporting window. This CHANGES figures you have seen: a course that read 0% may now read its real rate.
- Revenue totals count each refund once. Earnings and analytics figures will move, and the new numbers are the correct ones.
- Students list shows how many courses a learner is in; the student page still lists which.
- Instructor My Courses and Reports drop columns that duplicated the Earnings and reviews screens, so both tables fit without sideways scrolling.
- The account navigation is shorter, so pages are no longer as tall as the menu and the footer is easier to reach.
- Dashboard stat tiles share one baseline instead of sitting at four different heights.
Fix
- The quiz shortcode's Start Quiz button opens the quiz, instead of a missing page, when the quiz belongs to a course.
- A linear sectioned quiz opens on its first question instead of a second Start gate, so a timed exam no longer runs the clock on a screen you cannot answer.
- Registration links no longer appear to people who already hold the role, and an instructor can no longer take the student role by accident.
- Nav menu filtering and the registration security check now work on block themes, where neither applied before.
- The demo academy's fill-in-the-blank question can be answered.
Dev
- New filters learnomy_hidden_nav_routes and learnomy_instructor_routes; new helper \Learnomy\instructor_routes().
- Quiz submit responses carry a certificate object when the student holds one for that course.
- Documented the certificate visibility contract in docs/standards/certificate-visibility.md.
Compat
- Aligned with Learnomy Pro 1.9.1. Install both updates together.
New 5 Improve 4 Fix 13 Security 1 Dev 2 Compat 1
New
- Invite-only courses: you add the students, nothing is shown for sale, and checkout refuses the course.
- Per-course SEO overrides for title, meta description, social image and robots.
- Member billing address, kept on the account and frozen onto each order.
- Delayed payment methods (SEPA, Bacs, BECS, boleto, OXXO, Konbini) fulfil the enrolment when the funds clear.
- Filter learnomy_instructor_profile_url points an instructor's name at any page you choose, or none.
Improve
- Account and instructor navigation collapses to a labelled disclosure on phones instead of a clipped rail.
- Nav menus now offer nine account and instructor pages that could not be added before.
- One purchase recorder across every gateway, so tax, fees and idempotency behave the same everywhere.
- A refused action can explain itself instead of always reading as a permissions problem.
Fix
- PayPal one-time purchases redirect to checkout again; every one previously failed silently.
- Stripe subscriptions charge, enrol and record again after Stripe relocated three fields.
- Renewals extend to the next period instead of expiring the member on the day they paid.
- Refunding a membership updates the order instead of leaving it marked paid.
- Tax is recorded on Stripe orders instead of counting as zero.
- A private academy hides its categories and tags, not only its courses.
- Lessons and quizzes can no longer be created under a trashed course.
- The catalog search box keeps what you typed while suggestions load.
- Success messages appear fully on screen instead of clipped at the corner.
- Exported analytics reports no longer contain a Print button.
- Draft courses stay available in every content picker; only trashed ones are withheld.
- Sixteen style rules that silently rendered nothing now apply, including headings and a warning border.
- The thank-you page stops refreshing forever and states the position if fulfilment is slow.
Security
- Private-academy taxonomy endpoints no longer expose category and tag names to signed-out visitors.
Dev
- wp learnomy test no longer deletes the current month's commission rows while reporting success.
- New gates: undefined CSS tokens, unresolvable journey references and hedged test assertions now fail the build.
Compat
- Requires Learnomy Pro 1.9.0. Install both updates together.
New 2 Improve 7 Fix 20 Security 1 Dev 2 Compat 1
New
- Lessons can require a SCORM or standards package to report completion before the student can mark the lesson complete, so a "mark complete" trigger inside the package is what advances the course.
- Every course, catalog, lesson, membership and instructor page now writes its own meta description and social sharing tags, so a shared link shows a real title and summary instead of navigation text.
Improve
- The Learnomy admin menu fits on one screen: Pro tool pages moved into a single Pro Tools launcher, every row sits under a labelled section, and with all extensions enabled the menu dropped from 33 rows to 22 so nothing is cut off below the fold.
- Menu labels no longer collide: the moderation queue is "Reported Content", the payment log is "Payment Webhook Log" beside "Outgoing Webhooks", the companion installer is "Companion Plugins", the Pro catalog is "What's in Pro", and the top-level menus are "LMS Commerce" and "LMS Settings" so they fit one sidebar row. Every page address is unchanged, so existing bookmarks keep working.
- The Modules screen groups and explains each module instead of showing one long list, so a site owner can see what each one does before enabling it.
- A large course curriculum loads without a per-lesson query, so the page stays fast as the lesson count grows.
- "My Account" and "My Courses" can be added to any menu from Appearance, Menus, so members can reach their grades, notes, quiz attempts and billing without a hand-written link.
- Students no longer see the WordPress admin bar on the site; it stays for admins and instructors, and a filter turns it back on.
- On phones the account navigation labels are readable at 12px, and the floating notification bell reserves its own space so it never covers the last row of content.
Fix
- A draft lesson no longer counts toward course progress, so a student who finished every published lesson reaches 100% and receives their certificate instead of being stuck below the line.
- Draft lessons and topics are hidden from the curriculum, the lesson list API, resume links and next-lesson navigation for students, while instructors still preview them.
- Draft quizzes are hidden from the course curriculum and from the course content counts for students and visitors, matching the existing behaviour for draft lessons, while instructors still preview them.
- A quiz with no questions can no longer be started or submitted; students see a clear "check back later" notice and instructors are pointed to the quiz editor.
- A course whose date was never set no longer shows "Last updated November 30, -0001" on its page.
- Typing in the catalog search no longer wipes the box after two characters when the suggestion dropdown opens.
- The "Remove Demo Content" button in the dashboard alert bar works; it previously did nothing while the same button inside the onboarding card worked.
- The setup wizard launches on first activation instead of never appearing.
- The [learnomy_my_courses] shortcode shows the same enrolled courses as the account page; it previously claimed "no courses" for a student whose course was set back to draft.
- Publishing a course without publish permission now submits it for review instead of silently staying a draft nobody ever saw.
- The Enrollment Mode setting was removed until approval enrollment is actually built; it saved a choice that nothing enforced, so "Approval" behaved exactly like "Open".
- The course Q&A and course-comments toggles only appear when a feature is installed to power them, so enabling one can no longer produce an empty section on the course page.
- A quiz shown under a section now displays its pass percentage, matching quizzes outside sections.
- Instructor student and report lists could not reach page two; the page link led to a "not found". The pagination rule is now generated so every page is reachable.
- A shared breadcrumb was overwriting the row total on list pages, which silently hid the pager and left later pages unreachable on large rosters.
- Text, PDF and download lessons no longer load the video player, and a video URL removed from a lesson no longer stays in the page source.
- The "require login for all course content" setting now covers every public course surface, not only the lesson template.
- Currency symbols follow each locale's placement instead of a fixed prefix.
- Non-enrolled visitors no longer see the course intro video twice, tables no longer show a phantom scrollbar at tablet widths, and engagement alerts no longer wrap one word per line on narrow screens.
- Certificate PDF downloads open correctly. Warnings from the PDF library were being written into the file ahead of the document itself, which left it unreadable. The same fix covers the Pro analytics report exports.
Security
- Draft, pending and archived courses are hidden from the public: the course page returns not-found, enrollment is refused, and no search-engine data is emitted for them. Students already enrolled keep full access when a course is unpublished, and new enrollments require a published course.
Dev
- Quiz attempts can be read as one best-percentage-per-student map for a course in a single query, and front-end URLs go through one route-slug filter with a completeness gate that rejects hardcoded paths.
- Lesson model reads default to published status with an explicit every-status opt-in for editorial callers, and the hidden-submenu filter tolerates the value-append shape instead of emitting a broken selector.
Compat
- Pairs with Learnomy Pro 1.8.0, which adds the weighted gradebook, the SCORM completion gate answer, and assignment reporting. Install both updates together.
New 8 Improve 3 Fix 22 Security 2 Dev 11 Compat 1
New
- Live sessions have a Join link, a start time, and a duration. Students see a countdown before it starts, a Join button while it runs, and a clear "session has ended" afterwards.
- Images in lessons and course content can be set to a width (25%, 50%, 75%, 100%) and aligned left, center, or right, with text flowing around them. On phones they go full width automatically.
- Courses can be duplicated from the Courses list. The copy is created as a draft with the full curriculum.
- Refunds can be partial, and a sale stays refundable until it is refunded in full. Refund 25.00 of a 100.00 order today and the Refund button offers the remaining 75.00 later. Only a full refund revokes access and reverses commission.
- The grace period for a failed subscription payment is configurable under Settings, Payments (0 to 90 days, default 7). It was previously fixed at 7 days with nothing in the interface to show it.
- Mobile push notifications. Device tokens have been collected since 1.0 and nothing ever sent to them. Add your Firebase service account under Settings, Emails and members get the notifications they already receive in-app and by email on their phone as well. Off by default; a site without a mobile app needs nothing.
- Instructor withdrawals now capture where the payout should go. When an instructor requests a PayPal payout they enter the PayPal email, and the site owner sees it on the withdrawal so they know exactly where to send the money. An "arrange by email" option is available for any other method, and it stores no account details. No bank numbers are ever stored; those stay with your payment gateway.
- Members can block another member. The blocked member's comments and reviews no longer appear to them, and they can unblock anyone from a list on their account. Reporting content to a moderator was already available.
Improve
- The Analytics page now shows completion rate and average score for each course. The site owner previously saw less about their own academy than each instructor saw about their courses.
- Learnomy follows your theme's colour scheme instead of showing its own dark-mode switch on top of it. Site owners on a theme with no dark mode can turn the switch back on with the learnomy_standalone_dark_mode filter.
- Instructors can reach rubric grading from the grading queue when a quiz has a rubric. The screen existed but nothing linked to it.
Fix
- Pausing a subscription now records when it was paused, and resuming clears it. A resumed subscription used to look permanently paused to reports and exports.
- Scheduled live sessions were locked to students until the moment they began, so nobody could see the countdown or the join link. The start time is now stored separately from the drip schedule, and existing live lessons are unlocked automatically on update.
- Tax is applied to PayPal payments, not only Stripe.
- A course's price is charged in the currency set on its plan, instead of always using the site's default currency.
- Zero-decimal currencies such as Japanese Yen and Korean Won are charged the exact amount, not one hundred times too much, on both Stripe and PayPal.
- A failed subscription renewal now marks the subscription past due and begins the dunning emails on PayPal, and on Stripe for sites without Pro, matching what WooCommerce already did.
- A course a member joined through more than one route (for example free and then a membership) no longer appears twice in My Courses, and the "Courses Enrolled" total counts it once.
- Course prerequisites saved from the front-end course builder no longer lose the first prerequisite in the list.
- The editor's border, background, and stretch options for an image are now saved. They were previously discarded, so the toggle appeared to do nothing and reverted on reload.
- Certificates print correctly: the QR code no longer overlaps the signature, a long course title no longer prints through the completion date, the Modern design's signature is no longer cut off the edge of the page, and the Elegant designs now draw the border they are named for.
- Instructors no longer see the site owner's dashboard, or links to Certificates, Settings, Modules, Categories, and Earnings that answered "Sorry, you are not allowed to access this page". They now get their own dashboard, and are told plainly when an administrator has to do something for them.
- Licensing assets no longer fail to load on hosts where the document root does not match the plugin path (symlinked hosts, some managed hosts, local dev).
- Partial refunds are no longer double-counted when the payment gateway's confirmation webhook arrives after an admin refund. A 25.00 refund is recorded as 25.00, not 50.00, so revenue, access, and instructor commission stay correct.
- A sale can never be refunded past the amount charged, even if the Refund button is double-clicked or two refunds land at the same moment.
- Uninstalling Learnomy Free no longer deletes Learnomy Pro user data - the instructor's connected payout account, LTI identity, and saved notes and bookmarks are preserved.
- Mobile push notifications are delivered in the background instead of inside the payment webhook, so a member with several devices can no longer slow a checkout or cause a gateway to retry.
- Image width and alignment labels in the content editor are now translatable, and the front-end course builder's live-session fields no longer emit duplicate element ids.
- The Instructors admin page lists every instructor who teaches a course, including course authors and co-instructors. It used to show "No instructors yet" next to courses that had real instructors, because being assigned to a course did not create the instructor record the list is built from.
- Center-aligned certificate text placed near the left or right edge no longer clips off the page in the download. It stays within the certificate and wraps if needed.
- Right-aligned certificate text prints where it sits in the designer. It was placed from an estimate of the text width that drifted from the real width, more so for longer lines.
- Course-access-expiry and membership-renewal reminders are written in each member's own language, not the site's.
- With "Require login for all course content" turned on, the course grid and course catalog blocks and the XML sitemap no longer show the course list to logged-out visitors. Only the single-course pages and the REST API were covered before.
Security
- A course's title, full description, status, and price could be read by anyone, including for draft, pending, and private courses, through the Abilities REST surface. It now applies the same visibility rules as the rest of the API.
- A member's in-progress courses and completion percentages could be read by anyone. That data is now visible only to the member themselves and to staff.
Dev
- New Notification_Service::send_many() queues a large recipient fan-out (bulk enrolment, announcements) through Action Scheduler. Default async; filter learnomy_notifications_async to force inline.
- Member blocking stores a lrn_blocked_users table (database version 3.26.0) with routes POST and DELETE /users/{id}/block and GET /users/me/blocks; a blocked member is filtered from comment and review reads on every surface, and both directions are cleared on account erasure.
- wp learnomy repair student-count counts distinct people, so a course a member joined through more than one route is no longer reported as needing repair on every run.
- New shared gate \Learnomy\can_view_course( $course, $user_id ): every door that serves a course by ID applies the same two rules (unpublished is owner/admin only; private is owner/admin or enrolled).
- New lesson columns scheduled_start_at and live_duration_minutes (database version 3.18.0). A live session's start no longer shares the drip column. New filter: learnomy_live_session_duration.
- New withdrawal column destination (database version 3.19.0) holds the payout payee (the PayPal email), or stays empty for a manual arrangement. The POST /earnings/withdraw endpoint takes an optional payout_email, required when method is paypal. Readable, low-sensitivity; never a bank number.
- New single readers for values that were previously derived in several places: tax_rate(), tax_amount(), charge_currency(), subscription_grace_days(), Course::prerequisite_ids(), datetime_local_input().
- New filter learnomy_grading_row_actions on the grading queue, so an extension can add a grading route without forking the view.
- Image layout is stored on the block as { width, align } and rendered as classes on the figure. Both directions are enforced by the content round-trip gate, so a layout that cannot be read back fails the build instead of being silently erased.
- New action learnomy_webhook_deleted fires when a webhook is deleted, so an extension can clean up rows that hang off it. Learnomy Pro uses it to purge the deleted webhook's delivery log immediately instead of waiting for retention.
- Database version 3.20.0 backfills the instructor record for existing course assignments, so course authors and co-instructors appear in the Instructors list on upgrade.
Compat
- Requires Learnomy Pro 1.7.0 for the Pro modules. Install both updates together.
New 3 Improve 2 Fix 4 Dev 2 Compat 1
New
- Certificate library: four ready-made certificate designs (two Course Completion, two Quiz Completion) are seeded and available to every instructor out of the box, so a course can award a polished certificate with no design work.
- Instructor availability: admin-designed certificates stay private to admins by default, and you can share any template with all instructors or specific instructors from the certificate designer.
- Private academy: a "Require login for all course content" toggle under Settings, General puts every course, lesson, quiz, and the catalog itself behind a login.
Improve
- Instructors now pick a certificate from a clear, labeled list (Course Completion or Quiz Completion) scoped to what they are allowed to use, instead of a long list of unlabeled templates.
- Test payment mode is now clear and honest: one "test payment mode is on" notice instead of a misleading "customers cannot purchase" warning, and simulated Test-gateway orders are recorded at zero so they never inflate your revenue, earnings, or payouts.
Fix
- Deleting an instructor now reassigns their courses to the site admin with a confirmation notice, instead of leaving those courses showing "Unknown".
- The lessons list now labels standards content types correctly (SCORM, xAPI, LTI, QTI, H5P), while learners no longer see the underlying technical type on course cards.
- Member account pages (Certificates, Notes, Spaces, Learning Paths, Cohorts, Assignments, Billing, Details) now carry proper browser and search titles instead of just the site name.
- A certificate whose course was later deleted now verifies as "Course no longer available" and stays valid, instead of showing "Unknown Course".
Dev
- New extension point learnomy_route_title lets add-ons title their own front-end routes; new filters learnomy_unknown_instructor_label and learnomy_technical_content_types.
- Certificate library is an extensible registry: add designs on the learnomy_certificate_designs filter (seeded idempotently), and tune the specific-instructor picker cap with learnomy_certificate_instructor_choice_limit.
Compat
- Requires Learnomy Pro 1.6.0 for the Pro modules. Install both updates together.
New 4 Improve 6 Fix 6 Security 1 Dev 1 Compat 1
New
- Course-approval gate. Require admin approval before an instructor's course goes live, with a global toggle, a per-instructor override, and Approve or Reject actions on the Pending Review tab.
- Content moderation. Members can report a review, comment, or course, and admins action those reports from a new Reports queue.
- Per-template email editor. Edit the subject and body of any Learnomy notification from Settings using merge tags, with no code.
- SEO plugin handoff. When Yoast or Rank Math is active, Learnomy defers its canonical and Open Graph tags to that plugin while keeping its own Course structured data.
Improve
- The Email Log now records and shows the failure reason for a failed email, adds a one-click resend, and lets you search by recipient and date.
- Admin usability sweep: a single Learning Standards hub, a per-module surface map with Pro toggles locked when Pro is not installed, and clearer setup-wizard signposts.
- Coupons can be restricted to specific courses with a searchable picker, and the enrollment card now reprices live when a coupon is applied.
- The wp-admin course builder can now add a topic under a lesson without leaving the builder.
- The course builder and lesson drip scheduling batch their database work instead of running per-row queries, so large courses load and schedule faster.
- Removed two dead settings surfaces - the site-wide lesson-body search and the API Keys screen - that were wired to nothing.
Fix
- Catalog search is now fully keyboard-navigable and announces the active suggestion to screen readers.
- The instructor dashboard now shows the Awaiting Grading widget so essay and manual attempts are not missed.
- The data-integrity CLI check now flags only genuine orphaned progress rows instead of false positives.
- In the wp-admin course builder, a section's Rename, Move, and Delete now work the moment you add it, without reloading the page.
- Deleting a parent course category no longer hides its sub-categories; they move up to the parent's level instead of disappearing.
- Attempting to refund an already-refunded transaction now reports "already refunded" instead of a misleading "not completed" message.
Security
- Closed access-control gaps found in a security sweep: the public subscribe endpoint no longer lets a paid plan be joined for free, and REST API keys are accepted only in the request header, not the URL.
Dev
- New extension points: learnomy_lesson_unlock_date, learnomy_membership_plan_after_form, a course sidebar-card footer seam, and public per-member credential REST endpoints for certifications and teaching.
Compat
- Requires Learnomy Pro 1.5.0 for the Pro modules. Install both updates together.
New 12 Improve 8 Fix 5 Security 1 Dev 2 Compat 1
New
- Closed course pricing. Sell a course on any external platform (your own checkout, Gumroad, a CRM) and grant access here by email, CSV bulk upload, or an automatic signed webhook; refunds can auto-revoke access. Includes a copy-paste connection recipe on the Webhooks screen.
- Solo Academy mode. One switch turns Learnomy into a single-instructor academy, hiding every instructor-marketplace surface (instructor registration, commissions, earnings, become-instructor links) and forcing the monetization module off.
- Large-exam mode for the Focused and Review board layouts. A clickable question map, flag-for-review, per-answer autosave, and resume to the exact question and remaining time, verified at 150 questions.
- Five quiz layouts, each labelled with its best use case: Focused (timed exams), Classic (class quizzes), Sectioned (SAT/GRE-style), Conversational (knowledge checks), and Review board (long certification exams).
- Group questions by subject or category across all five quiz layouts, with a per-category score breakdown in the results so a raw percentage becomes a subject-wise diagnostic.
- Free section navigation for the Sectioned layout. Candidates choose which section to attempt first and switch between sections until they submit.
- Rich question stems. Author a formatted passage or scenario above a question's answers, stored round-trip-safe and rendered across every quiz layout.
- Quiz proctoring. Track when a student switches browser tabs, flag it for graders, and optionally auto-submit the quiz after a configurable number of switches; a monitored notice on the start screen tells candidates the rules before they begin.
- Native Fediverse video. Embed PeerTube and other Fediverse videos through SSRF-guarded oEmbed discovery, with no per-domain allowlist to maintain.
- Course search autocomplete. A typeahead dropdown of matching course names appears as you type on the catalog.
- Content-standard foundation. New lesson content-type, first-login provisioning, and quiz hooks let the Pro SCORM, xAPI, LTI, QTI and H5P modules plug straight into Learnomy's own progress, grading and reporting.
- The demo installer now seeds a categorized certification exam so a fresh install showcases grouped display, one-click navigation, and subject-wise scoring out of the box.
Improve
- Add questions from the Question Bank while creating a quiz, without having to save and reopen it first.
- The per-attempt exam-integrity report for graders now shows the submission IP address alongside the tab-switch count and late-submission signals.
- Every front-end and admin string is translatable, including the Interactivity-API quiz, catalog and membership modules, with professional copy and refreshed language templates.
- The quiz layout picker in the editor now describes the best use case for each of the five formats, so instructors choose the right one without guidance.
- The membership FAQ editor is now an add/remove repeater instead of a fixed grid of blank rows.
- Admin polish sweep: uniform on/off toggles, consistent status badges and action buttons, clearer Email Log and Settings, a shared CSV-import component, and self-contained settings cards across screens.
- The demo installer seeds a complete, non-empty dataset on every screen (real courses, lessons, reviews, webhooks, cohorts, spaces, and a categorized certification exam) so the product demonstrates fully out of the box.
- AI-assisted translations were extended across 9 Free locales (German, French, Spanish, Italian, Dutch, Brazilian Portuguese, Polish, Swedish, Russian). This entry originally said "full coverage", which was not accurate: the tooling of the time reported a catalogue as complete when a changed string had left it entirely. Real per-locale coverage is published from 2.0.0 onward.
Fix
- Multiple-choice answer options no longer re-shuffle when a student resumes an in-progress quiz.
- Flag-for-review marks on the Review board layout now survive a mid-exam refresh.
- The lesson-player sidebar now shows lessons that are not inside a section.
- Shortcodes in lesson content and course descriptions (contact forms, WP Fusion, galleries, or any third-party shortcode) now save as the shortcode and render on the front end. They previously corrupted the saved content and could show raw data on the page. The shortcode stays visible as a shortcode in the editor and renders only in the view, exactly like a WordPress post.
- Removed orphaned enrollment, progress and commission rows left by earlier deletes, and routed demo-data teardown through the full delete cascade.
Security
- The incoming enrollment webhook now requires a valid HMAC signature. It grants paid access, so an unsigned or unverifiable request is rejected instead of processed.
Dev
- New extension points: learnomy_closed_cta, learnomy_incoming_webhook_payload, learnomy_bulk_enroll_max, learnomy_section_navigation, learnomy_lesson_content_types, learnomy_provision_role, plus single-source Course pricing constants and question-type/stem seams.
- cmi5 support is planned with a code-verified implementation plan and will land in a later release.
Compat
- Aligned with Learnomy Pro 1.4.0. Install both updates together.
New 3 Improve 2 Security 1 Dev 1
New
- Uniform embeds. The lesson Embed type, embeds inside lesson and course content, and migrated content all render through one WordPress oEmbed pipeline as a premium responsive player, with a clean link-card fallback for anything WordPress cannot embed. Covers all built-in oEmbed providers (YouTube, Vimeo, TikTok, Spotify and ~40 more).
- Author embed preview now matches the student view in the lesson editor and the front-end course builder, via a new REST endpoint GET /learnomy/v1/oembed-preview.
- Translation ready. Every front-end string is translatable, and the plugin ships AI-assisted translations for 12 locales (German, French, Spanish, Italian, Brazilian Portuguese, Dutch, Polish, Swedish, Russian, Japanese, Korean, Simplified Chinese).
Improve
- Classic-layout quizzes now reliably record short-answer, fill-in-the-blank and essay responses.
- The lesson progress bar is calculated live from completed lessons so it always matches the X of N count.
Security
- Embeds resolve only through WordPress's built-in oEmbed provider list, closing a server-side request risk on the author preview endpoint.
Dev
- New filters learnomy_embed_html and learnomy_embed_oembed_args, and a new Learnomy\Content\Embed engine. Front-end account, registration and progress scripts are now i18n-wired.
New 1 Fix 1
New
- Course visibility is now a three-way choice - Public, Unlisted (hidden from the catalog but open to anyone with the direct link), or Private (enrolled students and admins only) - replacing the single Private hide-from-catalog checkbox so a course can be shared by link without being public.
Fix
- Restored the Payment Provider Mapping fields on the membership plan editor (Stripe Test/Live Price ID, PayPal Sandbox/Live Plan ID) so plans can be mapped to provider price IDs again.
New 6 Improve 2 Fix 3 Dev 4 Compat 1
New
- Import courses, lessons, quizzes, and questions from LearnDash, Tutor LMS, and LifterLMS through a guided wizard, with an optional people tier that brings across enrollments and progress.
- Migrations run in resumable background batches with a dry-run preview, and state up front which data is not migrated (certificates, grades, and payments).
- Build custom account fields for registration and the account profile from a no-code builder, managed entirely by the site owner.
- Set per-lesson access requirements through a filterable access gate, including lessons embedded outside the course player.
- Sections are now optional in the course builder, so lessons and quizzes can sit directly under a course.
- Reassign a course's lead author and add co-instructors from the course editor.
Improve
- Instructor roster data can now be anonymized through dedicated privacy hooks for export and erasure requests.
- Promoted the Abilities API from a single modules-table row to a linked, first-class integrations doc.
Fix
- Removed per-row queries in the instructor Q&A inbox, students-at-risk, and recent-transactions widgets so large dashboards load in a constant query count.
- The grading detail screen no longer fatals on a malformed format string, and editing a lesson no longer mangles its media IDs.
- Corrected a malformed placeholder in the revenue-trend widget that could fatal on PHP 8.
Dev
- Added a wp learnomy migrate WP-CLI command and REST endpoints that drive the import wizard.
- Added editor-field and integration hook seams so third-party fields round-trip through the course and account editors.
- Added an AI Agents and Abilities API integration guide covering the 34 AI-discoverable LMS actions across 6 categories.
- Added a Dutch (nl_NL) translation and regenerated the .pot.
Compat
- Aligned with Learnomy Pro 1.2.0. Install both updates together.
Improve 1 Fix 9 Dev 1 Compat 1
Improve
- Reworded user-facing strings to plain English across admin and front-end (replaced stylistic dashes with natural punctuation).
Fix
- Deleting a course category that still has courses now moves them to Uncategorized and removes the category, instead of appearing to do nothing; the confirm explains the move and the result reports how many courses moved.
- Checkout could subscribe a member to the same membership plan twice and double-bill; a second active subscription to the same plan is now rejected, and a different plan is directed to billing to change plans.
- All 12 Gutenberg blocks now load their styles on any page, not only on Learnomy routes; they previously rendered unstyled elsewhere.
- The membership pricing block now ships its own styles and shows the currency symbol on the amount.
- The become-an-instructor page now sends anonymous visitors to the public registration form instead of bouncing them to wp-login and losing the applicant.
- An unknown course URL now renders the theme 404 page and title instead of a "Course" title on a not-found body.
- Course and catalog grids no longer leave blank trailing columns when there are fewer cards than columns.
- The PWA manifest is now served dynamically with valid icons and a non-redirecting start URL, fixing manifest and icon 404s.
- Documentation and marketing copy corrected against the shipped product: REST auth endpoint (/auth/token) and endpoint count (166), the five Pro quiz question types, the Pro module count (15), lesson content types, settings navigation, and analytics docs.
Dev
- Full translation readiness: regenerated the .pot, added translator comments to every placeholder string, and registered front-end script strings (modals, course builder, quiz editor, toasts) for translation. The WordPress.WP.I18n check is clean.
Compat
- Aligned with Learnomy Pro 1.1.1. Install both updates together.
New 2 Fix 3 Compat 1
New
- Action Scheduler is now bundled, so recurring jobs (membership renewals, reminders, dunning, webhook delivery, large broadcasts) run on a standalone install with no WooCommerce required.
- BuddyX and BuddyX Pro theme bridge: Learnomy adopts the theme palette and follows its dark mode automatically.
Fix
- Bearer token authentication now works for REST and mobile clients; tokens were issued but never read, returning 401.
- The certificate designer pre-loads the Classic template when creating a new certificate instead of opening to a blank canvas.
- Cancelling a membership now unenrolls the member from the courses that membership granted, even on enrollments created without a stored plan id.
Compat
- Aligned with Learnomy Pro 1.1.0. Install both updates together.
v1.0.0
Note 19
Note
- Initial release.
- 37 custom MySQL tables: courses, quizzes, certificates, memberships, revenue, and more.
- Course builder with sections, lessons, and topics.
- 6 quiz question types with auto-grading and manual essay grading.
- 5 quiz display templates: Focused, Classic, Sectioned, Conversational, Review Board.
- Certificate generation with UUID verification, QR codes, and Ed25519 signatures.
- in membership plans with Stripe and PayPal recurring billing.
- 2-party commission system with instructor payout tracking.
- Coupon system with percentage and fixed discounts.
- 145 REST API endpoints under `learnomy/v1` with JWT auth and batch support.
- 12 Gutenberg blocks, 6 sidebar widgets, 10 shortcodes.
- 5 WP-CLI top-level commands with sub-commands for inspect, test, and selfcheck.
- no React, no jQuery, no build step.
- 34 AI-discoverable LMS actions across 6 categories.
- FULLTEXT search, JSON-LD schema markup, and XML sitemap.
- 8 HTML email templates.
- GDPR data export and erase compliance.
- Follows your theme's light or dark colour scheme.
- BuddyNext and Jetonomy ecosystem hooks.