v2.0.0 Latest
October 12, 2026
New 12 Improve 22 Fix 75 Security 18 Dev 29 Compat 2
New
- Every message sent through a listing's contact form is saved as a lead: owners read theirs under My Dashboard > Leads, site owners under Listora > Listings > Leads, and apps through the listora/v1/leads REST routes.
- The contact form asks for an optional phone number, and the owner's email is branded, editable under Email Templates and replies go straight to the sender.
- Leads are kept 12 months by default (Listings > Leads sets it) and are included in WordPress personal data export and erase requests.
- Listing types have their own Moderation (use the site setting, manual or auto-approve) and Reviews (use the site setting, on or off) choices, and both now take effect; existing sites behave as before until a type is changed.
- Category, location, tag and feature pages show the Directory filtered to that term, with the term title, breadcrumb and description, and the plain listings archive redirects to the Directory.
- Near me carries the visitor position through the search and filters results by a radius of 1, 5, 10, 25 or 50, with the start value set in Settings > General.
- Listing Types editor fields have "Show on listing page" and "Show in API" switches, and hidden fields stay out of listing pages, cards, the gallery, the public API and structured data.
- Events demo pack adds eight events dated relative to the import day, so the Events Calendar and event pages are no longer empty.
- Number fields can be shown as money in the site currency, and a min / max pair shows as one range: job cards, the listing page and Compare read "$140K - $185K", announced as "Salary $140K to $185K".
- The Directory can be filtered to featured listings, and the Featured block "See all" lists every featured listing.
- Settings > General has Country and City for where the directory is based; the setup wizard fills them in and the app configuration returns them.
- Listing tags have their own screen under Listora > Categories, like categories, locations and features.
Improve
- Browse by category hides empty categories by default, names the listing type on every unpinned tile (the type that uses the category most when no type lists it), keeps two columns on phones and spaces the "View all" link from the next block.
- The Directory Features filter lists every feature in use, most used first, with the rest under "Show all features (N)", and a chosen type lists only the features its listings use (or its "Selected only" list).
- Photo uploads follow the server limit, refuse oversized files by name before uploading, keep the photos that fit and show progress.
- Add Listing shows "This field is required." under empty required fields, clears the featured-photo error once a photo is set, and gives a submitted draft the right confirmation.
- The Education type has Phone, Email and Website fields for the provider on new installs.
- Demo import spreads publish dates over 60 days, offers each type its own features, and no longer emails an approval for every sample listing; the setup wizard hides other plugins' notices and Skip on the last step.
- Settings > Re-run Demo Import offers every demo pack, matching the setup wizard and WP-CLI.
- Listora stylesheets load as linked layered files instead of an inline @import, so cache plugins can combine and defer them.
- Listora follows the brand colour of Astra, Kadence, Blocksy, BuddyBoss and Elementor kits, and button hover darkens that colour.
- Every admin screen shares one page header with notices below it, and dashboard empty states and star ratings share one component, with stars announced as "Rated N out of 5".
- Listing expiry is off on a free directory and on while a paid add-on sells listing time, with a note on the setting saying why; events and job deadlines end on their own date either way, and new types default to no expiry in the editor and the REST API.
- Structured data uses option labels for choice fields and image URLs for file and gallery fields.
- Dashboard filter, services, blocked members, credits and calendar empty states use the shared empty-state card, so they match in spacing, icon and dark mode.
- Credit checkout shows Listora's own messages for every payment error, and the billing country list is in the site's language, sorted by name.
- Listing page tabs wrap onto a second row when they do not fit, so every tab stays visible at any screen width.
- On phones the listing page keeps its content clear of the bottom action bar, and the sidebar scrolls with the page.
- Prices members pay, such as credit packs and services, print in full instead of "1.2K", and three-decimal currencies such as KWD show all three decimals.
- Directory search ignores common words, so "the pizza" finds what "pizza" finds, and a cleared filter no longer returns no results.
- A review can be a star rating alone when the minimum review length is 0.
- File and image fields, such as Company Logo, show on the listing page and as a file name on cards.
- Accessibility: the Filters badge hides at 0, phone tap targets are 44px, card ratings read "Rated N out of 5", Reply moves focus to the reply box and the report dialog keeps keyboard focus inside.
- Scheduled jobs are checked once a day in wp-admin, or right after an update or feature change, instead of on every admin page: about 45 fewer database queries per admin page.
Fix
- Site Additional CSS and child-theme CSS apply to Listora blocks again; child themes wrap Listora rules in `@layer listora-overrides`.
- Add Listing shows a reason and a link to My Dashboard for a member whose role cannot submit, instead of a blank page, and the dashboard stops offering Add Listing to them.
- Directory search runs on Enter or the Search button, so the grid no longer stays unfiltered while the count changes, and Enter works in the Location field.
- "Listed by" no longer shows a private first and last name when the member has no public display name.
- Review criteria with the same key no longer share one star group, and picking an address without a street keeps the place name and adds the country.
- Services get their categories in the demo import, and the Services box lists categories as checkboxes.
- An admin saving a member's listing from the frontend edits it instead of hitting a duplicate warning, and a listing the user cannot edit returns 403.
- A rejected listing can no longer be published straight from Quick Edit, Bulk Edit, the block editor, the API or WP-CLI without an expiry; every path asks for Pending Review first and says so, and approving a pending listing sets its expiry and sends the approval email.
- Updating one setting of a listing type through the API no longer resets its other settings, and saving a built-in type in the editor keeps it built in (an update restores types already affected).
- The listing page "Open now" badge agrees with the Open now search for split hours, closing time and overnight spans.
- Competitor migrations started from WB Listora Pro run again, in the background one batch at a time.
- Owners can open their own rejected, deactivated and awaiting-payment listings from the dashboard, and visitors to an expired listing see a short notice.
- Event and listing dates and times show as entered in every timezone instead of shifting by the site offset, and event structured data carries the site's time zone offset for Google.
- A review posted a minute ago no longer reads "4 hours ago", and the aspect stars in the review form are thumb-sized.
- A Directory page past the last page shows the last page instead of "Showing 1,961-127 of 127".
- The map popup works on phones: it pans clear of the controls, shows the type name, uses translated labels and has a 40px close button.
- The map says "zoom in to see more" only when the marker limit hides results, and the dashboard no longer opens tabs for features that are off.
- JobPosting structured data includes the required title and datePosted, puts the location in jobLocation, gives the salary its currency and unit, and uses Google's employment type and remote values.
- Saving the Job, Classified, Education, Healthcare or Real Estate type no longer changes its Schema.org type to LocalBusiness, and an update restores types this already changed.
- A listing's rating is one public average and count, rounded to one decimal, on the page, cards, REST API and structured data; blocking a reviewer hides their review from you without changing the total.
- Demo jobs store their company and salary period in the Job type's own fields, and an update repairs demo content imported earlier: company, salary period, spread publish dates and image authors.
- The Listing Types editor no longer resets field settings it has no control for on save, and "Show in API" now saves.
- The listing form accepts a pin dropped on the map without a street address, and filling city and region from the pin no longer overwrites what the owner typed.
- Editing a listing as an admin or editor no longer asks to accept the terms again.
- Owners with the Subscriber role can open their own pending, rejected, paused or unpaid listings from the dashboard; everyone else still gets a 404.
- Submitting a saved draft from the dashboard says "Submit Listing" and shows "Listing Submitted!" with the real outcome (live, waiting for review or waiting for credits) instead of "Listing Updated!".
- Sites that imported the demo before 2.0.0 offer each listing type its own features instead of every demo feature.
- Updating no longer logs a "translation loading was triggered too early" notice: database upgrades now run at the start of init.
- Near me results show how far each listing is on its card, in the site's distance unit.
- A customised email body keeps the branded header, the "sent by" footer and the preferences link, and the editor lists every variable each email can use.
- With Pro's White Label on, admin notices, the setup wizard, settings, Site Health checks, uninstall and privacy texts use the custom brand name instead of "WB Listora".
- Every stylesheet reads design tokens Listora declares, so text sizes, spacing, soft status colours and the My Responses line height follow the theme and dark mode instead of fixed fallbacks.
- Category, location, tag and type pages use the term name as the page heading and breadcrumb on themes that read the title outside the loop, such as BuddyX Pro.
- Service categories in the dashboard are a checkbox list, so several can be chosen without Ctrl or Cmd.
- The Claims tile on the admin dashboard gets its icon tint like the other tiles.
- The dashboard Buy Credits link opens in the same tab.
- Notification emails: demo import stays quiet, "1 helpful vote" reads correctly, and the plain-text part no longer shows " or &.
- The Business Claims modal no longer promises a Verified badge, and its upload hint lists every accepted file type.
- "Delete data on uninstall" removes every listing with its images, every category, location, tag and type, and the Credits SDK data, whichever of WB Listora or Pro is deleted first, and touches no other plugin's rows.
- Undeclared v1 design tokens in empty states and labels now point at current tokens, so their spacing and colours apply.
- Editing a review checks the same minimum length as writing one, counted in characters.
- Editing a listing writes only its own type's fields, even when another type is submitted.
- A rate-limited request says when to retry (Retry-After), and the wait no longer grows while a client keeps trying.
- Services added in the wp-admin Services box are no longer saved a second time by the next Save, and a refused service says why.
- Phone and email fields with their own key, such as a seller email, show on the listing page instead of being hidden as part of the Contact card.
- Renewal is offered only for listings that expire after a set time, so free directories, events and jobs are not renewable, and a reinstated listing gets a fresh expiry date.
- Expiry emails show no Renew button for a listing that cannot be renewed, and the one-day reminder says "expires tomorrow".
- Members can change their email in the Profile tab with their current password and see the confirmation notice, and a display name can no longer be cleared.
- Opening the edit link of a listing you cannot edit shows a notice with a link to My Listings instead of an empty Add Listing form.
- Saving a listing with an empty title, or a contact message with no name or message, is refused with a clear message.
- Featuring or unfeaturing a listing updates the Featured block and filter at once, and a deleted featured listing leaves search immediately.
- Imported listings and their images belong to the member who ran the import, including batches after the first.
- Every admin list and the Leads tab show the last page for an out-of-range page number instead of an empty list.
- The Leads tab stays available to owners whose listings are all paused, expired or drafts.
- Credit history shows a translated line for every entry, including purchases and gateway refunds.
- Direct credit pack prices use each currency's own decimals, so a JPY pack of 2,500 no longer shows as 25.
- Remote job structured data names the country applicants must live in, as Google requires.
- Space submissions, migrated reviews and renewal times are stored in UTC like the rest of Listora's data.
- Demo content imported by older versions gets future job deadlines and event dates, and leftover demo images get an owner.
- The unsubscribe page shows as a page instead of plain text, and Health Check lists every Listora table.
- Grid, Categories and Featured blocks accept up to 12 columns, and an unknown card layout falls back to Standard.
- On multisite, uninstall erases each site with its own listing types, and keeps member data shared across the network unless every site chose to delete it.
- CSV exports and imports no longer log deprecation notices on PHP 8.4 and later.
- Search suggestions show "&" instead of "&" in listing, category and location names.
- Listing pages no longer scroll sideways on phones in right-to-left languages.
- On phones, "Search this area" steps aside while a map popup is open, so it never covers the popup.
- Previewing or test-sending the email verification template no longer logs PHP warnings.
- The CSV export writes "&" in titles, descriptions and category names instead of "&".
- Currencies shown by their code get a space, such as "CHF 12.50" and "KWD 1.234".
- A listing with one review reads "based on 1 review".
- Reinstalling after an older uninstall that left the credits version marker behind rebuilds the credit tables instead of leaving credits broken.
- Deactivating WB Listora clears every scheduled job, including review reminders, the email log prune, the search reindex and Pro's jobs, so none is left to fail.
- A search reindex after an update also finishes on hosts with WP-Cron turned off.
- Search suggestions on the Directory page open above the listing type tabs instead of behind them.
- The verify-email status on the dashboard and Add Listing, the low credit balance card and the map border follow dark mode.
Security
- Leads follow a listing to its new owner after a claim or author change, and a personal data export or erase also covers messages a member sent under another email address.
- The listing API no longer shows an owner's login as their name to visitors, leaves internal fields (plan, expiry, demo and consent state) out of public responses, and limits logged-out reads to 120 a minute per IP.
- Reviewers who never chose a display name show as "Member" instead of their login.
- Demo accounts get random passwords, and a migration locks existing demo accounts still using the old shared password.
- Block spacing, radius and shadow settings accept only numbers, known units and colours, so a block attribute cannot add CSS rules or load outside URLs.
- Members who never chose a display name get no profile link (profile addresses use the login), and listing embeds and feeds name the listing's public owner instead of the account.
- Helpful votes, reports and owner replies are refused on a review that is not published yet, and on a review that no longer exists.
- A submitted listing type must be a real type slug, and a per-type "reviews off" setting also blocks review edits, owner replies, helpful votes and reports.
- Block style output strips `<` so block attributes cannot close the style tag and inject markup.
- A listing title could carry script into the map popup that ran for anyone who opened its marker; popup text and links are now fully escaped.
- Unpublished listings stay hidden from visitors and other members in the listing and related-listings API, the duplicate check and the contact form.
- Reviews, review edits, owner replies and claims run the same spam checks as submissions: the keyword list, the link limit and Akismet.
- Claim proof documents are deleted with their claim, their listing, a privacy erase and on uninstall, and review photos are deleted with their review, listing or member data.
- Account deletion also erases the contact messages a member sent, and deleting a listing deletes the messages sent to it.
- The Listing Map height accepts a CSS length only, so the block cannot add other styles.
- Listing excerpts in the API are plain text, so encoded markup cannot become a tag in an app.
- The Email Log CSV export neutralises spreadsheet formulas.
- Business hours are cleaned of markup when saved, and listing structured data can no longer close its script tag.
Dev
- The code-standard ratchet counts hand-built empty states in templates and blocks; use wb_listora_render_empty_state().
- bin/token-parity-check.py fails the build when a stylesheet reads an undeclared --listora-* token; the optional knobs are listed in the styling guide.
- The dead-end crawl accepts empty states that are correct on real data: a member with no listings, the compare page before a pick, and a month with no events.
- wb_listora_before_contact_form_submit lets a site or add-on refuse a contact message; wb_listora_after_contact_form_submit now carries the phone number and lead ID.
- Uses only the Credits SDK 1.10 headless API (Billing::schema, Countries::display_name); nothing on screen comes from the SDK's text domain.
- Removed deprecated code: Listing_Type::is_default() and its interface method (use is_builtin()), the WBListora\Search\Facets class, the importers' set_taxonomy_terms() shims (use Term_Helper::set_terms()), Notifications::LOG_MAX_ENTRIES and its html_to_text() shim, and the submission block's termsPageId attribute.
- Removed unused settings default_type, max_upload_size, facet_cache_ttl, enable_guest_submission, guest_email_verification and reviews.require_login; an update clears them and moves a submission block's Terms page into Settings when none is set.
- wb_listora_most_favorited() returns the listings favourited most since a date, from one grouped count; the favorites table gains a date index.
- wb_listora_review_gate() and wb_listora_rate_limit() let add-ons apply the review rules and rate limits Free uses.
- New filters `wb_listora_theme_isolation`, `wb_listora_css_variables` and `wb_listora_owner_name_use_real_name`, and the JS hook `wbListora.formatAddress`.
- New filters `wb_listora_type_moderation` and `wb_listora_type_reviews_enabled`; listing-types REST accepts `moderation` (global, manual, auto) and `reviews` (global, on, off), and `wb_listora_user_can_edit_listing()` is the one edit-permission check.
- New filters `wb_listora_term_archive_filters`, `wb_listora_term_archive_intro`, `wb_listora_categories_show_type_label`, `wb_listora_categories_hide_empty` and `wb_listora_search_features_visible`.
- New filters `wb_listora_near_me_radius_options`, `wb_listora_visible_meta`, `wb_listora_submission_no_permission_message` and `wb_listora_expired_listing_notice`, plus `wb_listora_can_offer_submission()`.
- New `wb_listora_brand_name()` (filter `wb_listora_brand_name`) gives notices one product name for white label, and `wb_listora_get_dashboard_tab_labels()` lists dashboard tabs.
- `Status_Manager::transition_allowed()` is the one status-move rule (filter `wb_listora_allow_status_transition`), applied to `wp_insert_post` saves and the core REST route as well as `change_status()`.
- Field props `range_end`, `range_start` and `range_label`, and `wb_listora_field_display()`, which every field list uses to show a range once.
- New `wb_listora_term_type_usage( $taxonomy )` (cached listing counts per term and type) and `wb_listora_get_feature_filter_map()`.
- New `wb_listora_site_date( $days_ago )` returns the site-calendar date that analytics day buckets are cut with; no query uses the database server's clock (SQL NOW()) any more.
- New `wb_listora_user_public_name()` (filter `wb_listora_user_public_name`), filter `wb_listora_public_meta_keys`, and the `public_read` rate-limit action tunable through `wb_listora_rate_limit_config`.
- New `wb_listora_display_amount` filter in `wb_listora_format_currency()` lets a currency converter change what is shown, and the new `$exact` argument leaves charged amounts as recorded.
- New filter `wb_listora_should_send_notification` (a skipped email fires `wb_listora_notification_skipped`), `wb_listora_log()` for debug logging, and `wb_listora_queue_migration_import()`.
- New `DELETE /claims/{id}` and `Claims_Model::delete()` with `wb_listora_before_delete_claim` and `wb_listora_after_delete_claim`, used by wp-admin and REST.
- Shared UI helpers: `wb_listora_render_admin_header()` (prints the wp-header-end marker), `wb_listora_render_stars()`, `wb_listora_render_empty_state()`, `wb_listora_render_admin_empty_state()`, a `wb_listora_render_pagination()` that takes a base URL, and one `review-form.php` for the Reviews block and listing page.
- New `wb_listora_get_demo_packs()`, a public `Rate_Limiter::client_ip()`, `Dashboard_Data` for the member dashboard block and REST, and `wb_listora_local_timestamp()` for stored wall-time dates.
- The `directory_slug`, `submission_slug` and `dashboard_slug` settings are no longer read; URL helpers use `wb_listora_default_page_url()` and the `wb_listora_*_url` filters still override.
- New wb_listora_csv_cell() for formula-safe CSV text, and the meta service's get_visible_values() applies the page and API field visibility rule.
- New wb_listora_clamp_paged(), wb_listora_query_total() and wb_listora_window_counter(); author is a search filter.
- The hooks reference is generated from the source with a Deprecated table and removal versions, and local CI fails when it drifts.
- Recurring jobs are declared in one list, Cron_Scheduler::jobs(), extended with the wb_listora_cron_jobs filter, and one-off jobs use Cron_Scheduler::schedule_single(); the wb_listora_dedupe_recurring_hooks filter is removed.
Compat
- Requires WB Listora Pro 2.0.0 or later when Pro is active; install both updates together.
- Requires PHP 8.1 or later, the oldest version the code runs on.
v1.9.0
September 30, 2026
New 19 Improve 14 Fix 50 Security 1 Dev 14
New
- The admin menu is nine hub items (Dashboard, Listings, Listing Types, Categories, Moderation, Monetization, Analytics, Tools, Settings), each with a tab row; old links keep working and moderators see only their tabs.
- One shared admin table for Claims, Reviews, Email Log and every Pro list: status views, search, filters, a member search instead of raw user IDs, sortable columns, bulk actions, a detail drawer, numbered pages, and rows that stack on small screens.
- Listing types can be Draft (hidden from members) or Active, and deleting a type moves its listings to another type first.
- Listing Types editor: field actions always visible, one searchable picker for categories and features, and a page a third of its former height.
- Categories and Features show which listing types use each term, with a filter by type.
- Email Log has its own table with the full email, Sent and Failed views, filters, search, Resend, and a retention setting (90 days by default).
- Settings > Notifications lists every email, Free and Pro, as one row with an on/off switch, recipients, Edit template and Preview.
- Settings > Credits is split into Pricing, Limits and Payments sub-tabs, and Listing Limits per Role lists only roles that can submit.
- Settings > Maps offers one-click tile sources (OpenStreetMap, MapTiler, Stadia) and a map picker with place search for where maps start.
- Settings > Integrations shows the plugins Listora is connected to right now.
- Admin Dashboard leads with Needs attention (every queue), links each card to what it counts, and shows the last 30 days and a real activity feed.
- Directory: the type chips are the type picker and scroll with arrows; the map fits the listing cluster and says "Showing 500 of N on the map, zoom in to see more" when the marker cap hides results.
- Single listing: a Location card in the sidebar with the map, address and Get directions, and a gallery lightbox with View all photos.
- Browse Categories has "View all N categories" grouped by type; the Featured carousel has prev/next arrows and moves by whole pages.
- Member dashboard: linked and grouped navigation, Next steps on Overview, search, status filter and numbered pages on My Listings, a profile photo control, and grouped notification toggles.
- Add Listing: tags are chips, Business Hours has "Copy Monday to all days / weekdays", the featured image has Replace and Remove, gallery photos reorder, and the preview shows the listing card and every section with Edit links.
- Events calendar shows multi-day events on every day they cover, links each event to its listing, and lists a month agenda on phones.
- Reviewers are told when their review is awaiting moderation.
- Demo content ships curated photos per listing, category icons and colours, 30 days of views and clicks, and demo remove also removes the terms, users and analytics it added.
Improve
- One title per admin screen, and admin buttons keep their 13px size; the member button styles no longer override them.
- Destructive admin actions sit in a row menu behind a confirm instead of a red button on every row; one stat-card style and one Export CSV style across screens.
- Settings nav is grouped by task with a top tab bar below 1200px, one switch per behaviour, and "Reset this tab" instead of a red Reset to Defaults.
- Edit Listing opens with the fields drawer open and Listing Type first; All Listings fits an iPad, hides Views by default and shows Reports only while something is reported.
- Locations use one term per country, and the 1.9.0 update merges duplicate country trees.
- Only the chosen listing type's fields are on the Add Listing page, checkbox fields show one label, and addresses are stored as a street address instead of the geocoder's full line.
- Listing pages stack the sidebar below the content at 900px or less, use one heading scale, and show the phone once.
- Grid cards read Free for a price of 0, keep the favourite count in its pill, align their footers, and leave tags to the single listing.
- Credit history reads On hold, Hold released and Spent instead of Hold, Refund and Deduction.
- Listing Details shows free-text fields in full.
- Demo listings use photos chosen for each listing, with no photo repeated within a listing type; demo reviews are written by demo member accounts with different names.
- The Restaurant type offers Vietnamese, Korean, Seafood, Latin American and Cafe & Coffee cuisines.
- The Credits tab on the member dashboard pages through the full transaction history instead of stopping at the latest 20.
- Each settings tab has one Save Changes that saves everything on the tab, including email templates, and warns before you leave with unsaved changes.
Fix
- Update Listing on a draft with no plan chosen did nothing; the form now says which choice is missing.
- The Reviews tab on a listing could not be reached on an iPad; the tab bar now scrolls inside its column.
- Related listings showed Featured twice and left an empty column.
- The admin Dashboard's "Unique Users" and "Pending Items" counted the wrong things.
- A claim or review already decided by another moderator is reported, not applied twice, and a page refresh never repeats an action.
- The Events calendar showed the previous month's name for sites west of UTC.
- The Featured block with Sort by Featured showed non-featured listings.
- The Reply button and Write a Review follow the Reviews settings, and both review forms send the CAPTCHA token.
- Demo content created duplicate categories, left expired demo listings behind on remove, stored empty galleries when seeded from WP-CLI, and wrote reviews under authors that never existed.
- A listing type re-created without fields (the "business" and empty Job types) is repaired with its default setup on update and when demo content is added.
- Healthcare Specialty showed a raw slug on cards.
- Directory search filters no longer lead to "page not found" on sites where another plugin or the theme uses the same address words; filter links now use listora_ names such as ?listora_category=, and older links keep working.
- The Reviews tab on the member dashboard now counts the reviews it lists, labels the ones awaiting approval or not published, and no longer lists reviews marked as spam. The website and the app show the same number.
- Two paid actions by the same member at the same moment, such as a Featured upgrade or a renewal started in two tabs, can no longer both go through and push their credits below zero.
- A Featured upgrade or renewal that fails no longer gives back an earlier charge on the same listing, such as its plan.
- Refunding or cancelling a WooCommerce order for credits now removes the credits it added, including partial refunds.
- Stripe refunds now remove the refunded credits; they could not be matched to their purchase. A second partial Stripe refund no longer removes too many.
- A paid Stripe or PayPal credit purchase can no longer be lost when two members check out at the same moment, or when the first attempt to credit it fails.
- After buying credits with Stripe or PayPal from the Add Listing form, the Credits page again offers the way back to the saved listing.
- Stripe and PayPal credit packs keep their own id in the purchasable pack list; every one was reported as pack 0.
- The member dashboard shows credit balances as 10 or 12.5 instead of 10.00, and a member with a negative balance sees how many credits they owe.
- With credit sales switched off, the Buy Credits page says purchases are paused instead of showing a page-not-found error, and a link to the dashboard Credits tab opens Overview.
- On the BuddyX theme, Listora buttons that are links (such as Go to your dashboard) keep their button colours; BuddyX 5.1 had turned them into underlined link text.
- A renewal lasts your standard expiration period when Renewal duration is 0, instead of a full year; a listing never expires when that period is 0 too.
- New listings follow Settings > Default expiration; it was only used for renewals.
- A renewal that fails no longer counts as a renewal, keeps the old expiry date, and tells the member plainly that they weren't charged.
- Renewed listings expire at the right time; the new date was stored in site time and expired hours late.
- The listing submission cost is charged: members without enough credits are asked to buy credits instead of listing for free, and auto-approved listings are charged too.
- Saving a draft no longer holds the submission cost; it is charged when the draft is submitted.
- Deactivating a live listing no longer refunds its submission cost.
- Two paid submissions sent at the same moment can no longer both be charged against credits for one.
- A settings save that a section refuses now says so instead of reporting Settings saved.
- Claiming or reporting a listing confirms once, in the dialog, instead of also popping up a second notice.
- Long notices wrap inside their box instead of running past it.
- Editing a listing from the frontend no longer strips images, video and formatting from its description, and the CSV, JSON and GeoJSON importers keep description HTML.
- A listing on a paid plan is charged once; the plan was taken at publish, the listing was then parked awaiting credits and the next top-up charged the plan again.
- Two listings submitted at the same moment no longer leave a response pointing at a listing that was never saved; the member is asked to submit again.
- Text typed into frontend forms keeps its quotes and dashes on save.
- Search suggestions wait for a pause in typing before asking the server.
- Unsaving a listing on the dashboard Favorites tab removes its card and updates the count.
- Accepting the Terms of Service on a frontend edit is remembered; owners of listings made in wp-admin or imported were asked again on every edit.
- The Add Listing success message says the listing is live when it published at once, not that it is pending review.
- Per-criterion review ratings are saved on every site; without Pro's multi-criteria reviews they were collected and then dropped.
- Ticking Selected only in the Listing Types Features or Categories picker no longer makes Save fail.
- Buying credits by Stripe or PayPal works for members with no billing details on file; the first Buy click asks for name and country once, then checkout opens.
- Form rows built on the shared form-field styles stack label above field again; those styles had been switched off by mistake.
- The dashboard services window no longer slides under the WordPress admin bar.
- Block styles are served under the plugin version, so style changes reach returning visitors after an update instead of waiting on the browser cache.
- Share on a listing no longer locks page scroll on browsers without a share sheet; it copies the link and says so.
- On phones the theme's back-to-top button no longer covers the Save button in the listing action bar (Reign, BuddyX).
Security
- Submitting a saved draft always charges the listing submission cost; a made-up plan id no longer lets a member list for free.
Dev
- New hooks: wb_listora_dashboard_nav_group, wb_listora_member_notification_events, wb_listora_dashboard_attention, wb_listora_dashboard_activity, wb_listora_dashboard_period_cards, wb_listora_active_integrations, wb_listora_credit_entry_types, wb_listora_event_labels, wb_listora_notification_events, wb_listora_notification_preview, wb_listora_credits_subtabs, wb_listora_settings_general_rows, wb_listora_reset_field_aliases, wb_listora_show_basic_csv_import, wb_listora_featured_backfill, wb_listora_import_location_as_place, wb_listora_layered_style_bases, wb_listora_show_credit_record and wb_listora_demo_gallery_max. See the hooks reference.
- Admin_Table service (wb_listora_service( 'admin_table' ), contract Admin_Table_Interface) and Admin_Table::stat_cards(); Listing_Type_Registry gains get_active(), reassign_listings() and install_default(); listing type REST routes take status and reassign_to and answer 409 listora_type_has_listings.
- New helpers wb_listora_directions_url(), wb_listora_event_label(), wb_listora_notification_enabled(), wb_listora_credit_entry_types(); GET /settings/notifications/preview; wb_listora_log_email() takes the body and headers.
- DB 1.9.0: email_log table (the email log option is imported and deleted), location repair, hold-release ledger retype. New meta _listora_pre_claim_author, _listora_status on types, term meta _listora_country_code; admin URL params renamed claim_action and review_action.
- Submission templates: step-details.php renders each type inside a <template> that view.js mounts; the form is novalidate; a required radio group may carry data-listora-required-message. Frontend CSS loads in @layer listora with an isolation reset.
- Removed the wb_listora_skip_admin_header filter with the injected title bar.
- Directory filter URLs are now listora_-prefixed (listora_keyword, listora_type, listora_category, listora_location, listora_page and every field filter). Read them with wb_listora_url_arg() and build links with wb_listora_url_args(); REST parameters are unchanged.
- New wb_listora_with_credits_lock( $user_id, $callback ) runs a credit spend so no other spend by the same member can run at the same time. Wrap any balance check and hold in it.
- Bundled Wbcom Credits SDK updated to 1.7.2. New wbcom_credits_checkout_enabled filter decides whether a credit checkout may start.
- New wb_listora_format_credits() formats a credit amount as 10 or 12.5, never 10.00.
- wb_listora_log_email() records an email in Listora > Email Log, for add-ons that send their own mail.
- wb_listora_dashboard_tab_available() says whether a dashboard tab is switched on for the site; wb_listora_hide_unavailable_pages now also passes the page and its registry key.
- wb_listora_listing_duration_days() returns how long a listing runs: plan, then listing type, then Default expiration.
- wb_listora_listing_submission_cost() and the wb_listora_listing_submission_charge action; the credits SDK's listing_submission consumer holds on that action.
v1.8.0
September 23, 2026
New 9 Improve 5 Fix 47 Security 2 Dev 16 Compat 1
New
- The setup wizard offers pages for the Categories, Featured Listings and Events Calendar blocks, which previously had nowhere to live. Existing pages built around those blocks are adopted rather than duplicated.
- Turn Services off for a listing type that does not need them, such as Jobs or Classifieds. Existing services are hidden rather than deleted, so switching it back on restores them.
- Features > Contact Owner Form turns the listing contact form off, on the website and in the app.
- Type an address on the Add Listing form and press Enter to pick it from a list of matches, which fills the town, region, country and postcode and places the map pin. It used to guess from what you had typed so far and silently take the first result, so the pin often landed on the wrong street.
- Reporting a listing now emails administrators and moderators, so a report reaches a person instead of sitting unread. Repeat reports on the same listing are throttled. The listing owner is deliberately not told. Switch it off in Settings > Notifications > Listing reported.
- Listing pages show who listed the business, the way Google Maps and Yelp do. Uses the listing's Contact Name, or the account display name when there is none, and never a login or an email address. Turn it off in Features > Show Who Listed It.
- A dashboard page can belong to one listing type, so a site running Jobs, Classifieds and Real Estate on separate pages gives each page its own dashboard. The listing counts on that page follow the same type.
- Video URL is now a field on every listing type, so the listing editor in wp-admin can show and change a video a member submitted. The submission form has always asked for one, but nothing in the admin could display it.
- The Media box in the listing editor now has a working photo gallery - add images, remove them, and see what is already attached. It previously rendered with no gallery control at all.
Improve
- The plan picker no longer offers plans restricted to other listing types.
- The Reports column on the listings screen is visible by default, so a report is visible without opening Screen Options.
- Listing type is now picked from a list in the block editor instead of typed as a slug, on every block that filters by type. A grid pinned to a type with no listings now says which type is empty instead of asking the visitor to adjust filters they never set.
- Stripe and PayPal settings are now shown on the Credits tab by default. Setting up direct credit purchases previously required hand-written PHP, so the Credits tab offered to add packs while giving you nowhere to enter the keys they need.
- Settings > Submissions now explains how listing limits work for a member with more than one role: the most generous limit wins, and 0 does not block someone who also holds another listed role. The Administrator row shows as always unlimited instead of looking editable.
Fix
- The message shown after paying for credits can now be closed. It had no close button and came back on every page reload.
- Choosing a plan that is not available for the listing type you are submitting is now refused with a clear message, instead of saving the listing as "Awaiting credits" for a plan no top-up could ever activate. Listings already stuck that way are released for review when you update.
- The Credit Balance on your dashboard no longer jumps to a figure around a hundred times too high after paying with Stripe or PayPal. It was showing the stored value rather than the amount, and reloading did not clear it.
- The "nothing links to these pages" notice now appears only on Listora Settings, where you can act on it. It was repeating on the listings screen and every listing taxonomy screen.
- The Blocked Members section on your dashboard Profile tab is styled to match the rest of the tab. It was rendering as unstyled text with list bullets.
- A directory whose only credit pack is a Direct (Stripe or PayPal) pack no longer says "No credit packs yet" on the Credits tab and the setup checklist.
- Credit receipts now open from the link in your dashboard or confirmation screen even if you are signed out or open them in a new window. They used to show a technical error instead of the receipt.
- Two listing grids on one page now page independently. Clicking Load More under one grid appended the other grid's listings, so a "Top restaurants" section filled up with hotels.
- Enquiries sent through a listing contact form are now counted whether or not the Analytics feature is switched on, and on sites running the free plugin alone. The Leads figure stayed at zero while the messages arrived.
- Deactivating your account twice now answers normally instead of an error saying you cannot post. A double tap, a stale tab or a retry no longer looks like a failure.
- A listing paused awaiting credits now shows in the app's dashboard, not just on the website. The app also reported a listing count that agreed with the omission.
- Credits no longer take the site down when another Wbcom plugin loads an older copy of the shared credits library. Every credits check now confirms the loaded library can actually service a balance, hold or purchase, so a mismatched site shows credits as unavailable with a notice naming the plugin to update.
- Logged-out visitors can see the "Claim" button on a listing again, and clicking it prompts them to log in. It was only shown to signed-in users, so the owners it exists for never saw it.
- Pressing Enter in the directory search box now filters the listings. It updated the address bar but left the results untouched, so the keyword had to be submitted again with the Search button.
- Upload buttons in the listing editor now open the media library. Any file field, such as a Job listing's Company Logo, printed an upload area that did nothing when clicked.
- Selecting gallery images in the listing editor now survives saving. The choice appeared to work and was silently discarded, including when only one image was chosen.
- A toggle field, such as a Job listing's Position Filled, now renders as a checkbox instead of a text box.
- Job listings now have a Media section. They were the only listing type without one, even though the submission form offers photos and video for every type.
- A configured payment gateway now reaches the Buy Credits page. With Stripe enabled and keyed, every pack still showed "Checkout unavailable" and no buy button was ever drawn.
- The Marker clustering setting now applies to map blocks that have not set their own clustering. It only reached the mobile app, so turning it off changed nothing on the website.
- Settings > General shows "Page selected but not published" for a draft privacy policy or terms page instead of "Not set", and saving Settings no longer drops a selected draft terms page.
- A business claim with a proof file attached is saved again. Attaching a file made the request run out of memory, so the claim was never recorded.
- With Google Maps as the provider, the directory map block now draws with Google alone. Leaflet also started on the same map, which left it broken.
- Reviews in wp-admin have a Read full review link showing the whole text and the stars given per criterion, so a review is no longer approved from a 15-word excerpt.
- Reply is offered only on approved reviews, in wp-admin and through the REST API. A reply to a pending or rejected review answered something visitors could not see.
- Each review on a listing now shows the stars the reviewer gave per criterion, such as Food or Service, not only the overall rating.
- With two listing grids on one page, each "Showing X-Y of Z" now counts its own grid. Both showed the last grid's numbers and neither moved with Load More.
- Approving, rejecting or deleting a review in Listora > Reviews now updates the listing's star rating and review count. Existing counts are corrected by Rebuild Search Index in Listora settings.
- Bulk Apply on the Reviews and Claims screens and the Claims Filter button work again. They showed Processing... and did nothing.
- A logged-out visitor who clicks Claim or Report now sees a log-in prompt that says so. It always read "Log in to save listings", the favorites wording.
- Unticking a toggle such as Position Filled on the frontend edit form now saves; it came back ticked after every update.
- Listing Types: switching Services off now saves, and the member dashboard hides the services count and Manage Services button for that type.
- A Listora Moderator saving a listing in wp-admin no longer empties its photo gallery and file fields, and a member editing their listing no longer loses photos an admin added.
- A listing submitted from the website now gets its Country, State and City locations, so the Locations panel in wp-admin and the location filter show it.
- "Listed by" no longer shows an account's login name; it uses the real name, or is hidden when there is none.
- Save Draft no longer runs into the new-listing limit; only creating a listing counts, and a draft that cannot be saved now says why.
- Save Draft is no longer shown on the Type step of Add Listing, where there is nothing to save yet.
- Pending listings on the dashboard no longer show an empty More menu.
- Admin notices no longer appear twice on the Listings and Categories screens.
- The Business Hours time picker no longer shows a second box inside the field on some themes, and matches dark themes.
- Members behind one shared network (an office, a campus) no longer run into each other's limits; each account has its own.
- A listing's Country, State and City now follow its address when it is changed in wp-admin or the block editor, not only on the website.
- A member editing a service no longer loses a photo an admin added to it.
- The Services box in the wp-admin listing editor is hidden for listing types with services switched off.
- When the bundled Credits SDK is missing, the admin no longer also claims another plugin is loading an older copy of it; one notice explains the fix.
- The directory search bar no longer makes the page scroll sideways on phones with themes such as Twenty Twenty-Five; the Location field now fits its column.
- The Add Listing step bar now shows every step on phones. The first and last steps were cut off at 390px on every theme.
Security
- On a directory that charges credits, a listing can no longer be published without a plan. Submitting without choosing one, or publishing a plan-less draft, is now refused instead of going live free of charge.
- A space curator can no longer add a non-listing or unpublished post to a BuddyNext space showcase, and the showcase total no longer counts rows it does not show.
Dev
- wb_listora_pro_show_gateway_settings still hides those settings for a site that wants them hidden; pass __return_false.
- Field::show_in_admin is now honoured, on render and on save, so a field can be kept off the listing editor. The property existed and defaulted to true but was never read.
- wb_listora_get_template() now defines $view_data in template scope, so a template can read either $view_data['key'] or the extracted variable.
- window.wbListoraGeocoder replaces the address lookup on the location picker. Return a promise for an array of { lat, lon, display_name, address }. Pro registers a Google-backed one when Google is the live map provider.
- The search engine has extension seams: wb_listora_search_parse_args (covers search, the map clusters and the grid, map and featured block renders in one listener, and runs before the cache key is built), wb_listora_search_where_clauses and wb_listora_search_where_params, wb_listora_search_orderby, and wb_listora_search_result. The existing wb_listora_search_args stays REST-only.
- wb_listora_listing_removed_from_space now carries the prior status and a context of reject, takedown or withdraw, and wb_listora_listing_rejected_in_space fires for a declined submission. The first three arguments are unchanged.
- GET /spaces/{id}/listings/pending takes page and per_page and sends X-WP-Total and X-WP-TotalPages.
- wb_listora_listing_report_recipients filters who is emailed about a reported listing, wb_listora_listing_report_notify_interval how often repeat reports notify, and wb_listora_max_stored_listing_reports caps what is stored per listing.
- wb_listora_listing_owner_name and wb_listora_listing_owner_url filter the public owner name and the page it links to; return an empty URL to render the name unlinked, or a member-profile URL to point it at a community profile.
- wb_listora_member_listing_statuses filters the post statuses a member sees on their own dashboard, on the website and in the app together.
- GET /listings/{id}/detail carries owner: { name, url }; the key is absent when Show Who Listed It is off. GET /dashboard/listings accepts listing_type.
- Map blocks gain a Use site setting / On / Off clustering choice. Return true from wb_listora_map_block_clustering to cluster every map that has not chosen, as before.
- wb_listora_rest_prepare_dashboard_stats now also runs on cached responses, so fields a listener adds are not lost on repeat requests. Moderating a review in wp-admin now fires the same review hooks as the REST API.
- wb_listora_submission_steps and wb_listora_submission_plan_step now receive the ID of the listing being edited (0 for a new one).
- wb_listora_rate_limit_ip_counts_members restores per-IP limits for signed-in members; return true.
- Any form with data-listora-confirm-form and a data-confirm-message now asks for confirmation with the Listora modal before it submits, when the listora-confirm script is loaded.
Compat
- Aligned with WB Listora Pro 1.8.0. Install both updates together.
New 6 Improve 13 Fix 45 Security 8 Dev 14 Compat 1
New
- Site Health warns you when WooCommerce is set to a different currency from Listora, since a member would then see one currency and be charged in another. Listora shows one currency everywhere rather than mixing them, so this is the place it can be spotted.
- Site Health tells you when your maps have no tile source and will therefore draw on a blank background, with a link to the setting. It stays quiet on a site whose listings have no locations, since there is nothing to draw.
- Listora now tells you when a page it created is not linked from any menu, and offers to add it. A page can be published, mapped and working while no visitor can reach it, and every admin screen reported success - so the one thing missing was the one thing nobody was told about.
- Settings > General > Pages offers Create page on any row reading Missing, so a deleted page can be brought back without hand-building one with the right block in it.
- Listings on a plan that renews itself now do so from the member's credit balance instead of expiring. If the balance will not cover it the listing pauses rather than expiring, and comes back on its own the moment they top up.
- Going to buy credits from the listing form no longer loses the listing. It is saved as a draft first, and the credits screen offers a link straight back to it, opened on the plan you were choosing.
Improve
- The Submission form style setting now says that adding or editing from inside the member dashboard always uses the single page form. The setting only governs the standalone Add Listing page, and nothing said so - so it looked broken to anyone testing it from the dashboard.
- It offers only pages people navigate to. Compare Listings and Buy Credits are reached from a button on a listing or a plan, so they are never suggested for a menu.
- It adds to the menus you already use for Listora pages, which on themes with separate logged-in and logged-out menus means both - not just the one members see. A page you have deliberately placed in only one menu is left alone.
- Listora admin screens now have a proper page heading, so screen readers announce where you are.
- A Compare page built with the old [listora_compare] shortcode is recognised as your Compare page, so the plugin does not offer to create a second one beside it.
- A Listora page is created once per site and never re-created behind your back, so a page you delete stays deleted.
- A web address on its own is no longer accepted as a listing title. It became the business name on the card, the page and the permalink, which is what automated spam posting looks like. Names that contain a domain, such as Booking.com, are unaffected.
- The Buy Credits link on a plan you cannot afford is a full-size tap target on phones, rather than a line of text under half the usual size.
- Service prices follow the site currency everywhere they appear, so a directory trading in yen or euro no longer shows dollar amounts on listing pages and the member dashboard.
- Zero-decimal currencies such as JPY render without decimal places, and whole amounts drop the trailing zeros.
- The submission map picker draws the tile source configured in Settings > Maps, matching the directory map instead of always loading OpenStreetMap.
- A directory with no tile source configured shows an unstyled picker rather than quietly loading a third party's tiles; panning, zooming and dropping a pin still work.
- Photos uploaded through the submission form are now attached to the listing they belong to, so they appear under it in the Media Library instead of the Unattached pile.
Fix
- The Upgrade and account links in the admin now point at pages that exist. Three of them led to 404s on the store.
- Changing the listing type in search now narrows the Features checkboxes to the ones that type allows, instead of leaving the previous type's list on screen. Any feature that no longer applies is unticked rather than left filtering results down to nothing.
- Submitting a listing with a feature its listing type does not allow is now refused with a clear error, naming the field. It used to return success while quietly discarding those features, so a member could not tell that part of what they chose had been thrown away.
- Turning off Listing Submission now hides every invitation to submit, not just the dashboard button. The empty state still offered Add Your First Listing, and the form it led to then explained submissions were closed.
- The dashboard header no longer leaves an empty bar when there is nothing to put in it.
- Credit pack prices now show in your currency like every other price. The credits screen could show one currency while the rest of the site showed another.
- Your currency setting is now used everywhere a price appears. Prices entered before you changed currency kept showing the old symbol, because the code stored on the row outranked your setting - so a site switched to yen still showed dollars on older listings.
- Search engines are told the same currency your visitors see. The structured data read WooCommerce's currency instead of yours, so a site set to yen displayed one currency and reported another - and invented one entirely on sites with no WooCommerce.
- The map on a listing now uses the map tile source you set in Settings. It ignored that setting entirely and always drew OpenStreetMap tiles, so a site that had configured its own tile server saw its choice applied to the submission map picker and nowhere else.
- A page whose feature is switched off no longer serves visitors a blank page. It returns a proper 404 instead, and Settings > Pages marks the row Feature off with what to do about it. Turning the feature back on restores the page exactly as it was.
- Admin notices on Listora screens are visible again. The pages had no heading for WordPress to place notices after, so they were being dropped into a hidden tab panel - present on the page, readable by nobody.
- The Settings screen no longer draws its header twice.
- Links to a Listora page are no longer dropped because the page was edited. Whether a link could be shown was worked out in four different places, and one of them required the page to still contain the original block - so rebuilding your Compare page with your own layout removed the Compare link from the site.
- No Listora link now points at a draft page a visitor cannot open.
- Editing one of the plugin's pages no longer creates a duplicate. Replacing the block on the Buy Credits page with your own layout made the plugin decide the page was not its own, create a second one at buy-credits-2, and point every Buy Credits link at the empty new page while the page you wrote sat orphaned.
- Deleting one of the plugin's own pages no longer breaks the links that pointed at it. The page mapping kept the deleted page's identifier, so links to it rendered empty and buttons quietly fell back to whatever other address they knew. The mapping now re-attaches to a page carrying the same block, exactly as it already did when the mapping was missing altogether.
- After paying for credits, the order confirmation now links straight back to the listing you were part-way through. The link was lost in the checkout redirect, so members finished paying and were left on a receipt whose only listing link started a new one.
- The Add Listing block now has a Form Layout control in the editor. The setting existed and was honoured, but was never shown, so a block saved as a wizard or single form could not be changed back and a site owner who altered Settings > Submissions saw nothing happen with no way to find out why.
- A listing type restricted to certain Features & Amenities now shows only those on the Add Listing form. Every feature on the site was offered whatever the type, so the setting had no visible effect.
- Validating a Pro licence from the upgrade screen works again. It was checking a licence server on a retired domain, so every key came back as "could not be validated" - which reads as a bad key rather than a broken check. It now asks the Wbcom store, where the licence actually lives.
- Plugin links, documentation links and the author link point at wbcomdesigns.com. Several went to a domain that no longer resolves, and a few others to store pages that had moved.
- Autosave and Save Draft work throughout the form. Both were rejected until the Terms of Service box on the final step was ticked, and the failure was never shown, so nothing was saved while you were still typing.
- Every autosave now updates the same draft. Only the first one was stored; later ones were turned away as duplicates while the form still reported "Draft saved".
- Editing a listing no longer demands the Terms of Service box be ticked again. A saved draft still requires acceptance before it goes live, and that acceptance is now recorded against the listing.
- A draft saved before the Terms of Service step no longer records an acceptance that was never given, which had pre-ticked the box on the way to publishing.
- Members who buy credits through a mapped WooCommerce, MemberPress or Paid Memberships Pro product can see their Credits tab and balance again.
- A directory selling credits only through a mapped product no longer tells members that credits are not on sale.
- The Credit Transactions screen shows credit counts, so a 50-credit purchase reads as 50 rather than 5000.
- The Credits Issued and Credits Used totals report credits instead of raw ledger values.
- The Item ID column shows a dash on top-up rows instead of a meaningless zero; the purchase reference remains in the Note column.
- The refund dialog lays out as a centred panel with its fields stacked and aligned.
- Total Revenue follows the site currency instead of always showing a dollar sign.
- Turning the Listing Submission feature off hides the dashboard Add Listing button, and the Add Listing page explains that new listings are closed rather than rendering an empty screen.
- The directory's no-results empty state could still offer an Add a listing button after submissions were turned off, leading to a page that said new listings were closed. It is now hidden along with every other submission invitation.
- Turning off new submissions no longer blocks editing an existing listing. The page used to show "New listings are closed" before checking whether you were editing, so an owner following an Edit link on their own listing saw that message instead of their listing.
- Uploading photos in the submission form works again on WooCommerce sites. WooCommerce redirects members without publishing rights away from wp-admin, and the wizard's photo picker posted through wp-admin, so gallery and custom-image uploads had no working path for exactly the members submitting listings.
- Permanently deleting a listing now deletes its featured image and gallery photos with it, instead of leaving every uploaded file behind on disk. An image still used by another listing is left alone.
- Uninstalling the plugin now removes listing images along with everything else, instead of leaving gallery photos behind on any listing created before 1.7.0.
- Buying credits directly with Stripe or PayPal (outside a WooCommerce, MemberPress, or Paid Memberships Pro product) now completes. Direct checkout was missing a required pricing configuration, so every attempt failed before reaching the payment gateway.
- If the payment confirmation from the gateway is slow or does not arrive, credits now still land when you return to the site after paying, instead of never being added.
- The credits screen no longer tells you credits have been added before they actually have. It now says payment was received while crediting is in progress, and confirms once your balance updates.
- Settings and Credits screens no longer show misaligned field columns, labels sitting flush against the card edge, or fields spilling outside the card padding, wherever in the page a section renders.
- Currency and product dropdowns in the admin no longer clip the bottom of their text.
- The Save/Reset bar on long settings screens, such as Credits, now stays visible as you scroll instead of being left far up the page.
- Admin buttons and links share one consistent style across the whole plugin section, instead of some picking up the active theme's button styling.
Security
- Features outside a listing type's allowlist are refused when a listing is saved. Only the form limited the choice, so a direct API call could attach any feature to any type.
- Files uploaded to prove a business claim are stored under an unguessable name, and the claimant is no longer handed a direct link to their own upload. The file kept the name it was given, so an address like /uploads/2026/08/drivers-licence-scan.png could simply be guessed.
- The companion-plugin installer only downloads from the Wbcom store over HTTPS. It previously installed whatever download address the store replied with, so a spoofed or compromised reply could have installed other code.
- Changing the email address on an account now needs the current password, and the new address has to confirm before anything moves. It used to change immediately, so a stolen session or an application password was enough to take the address and then reset the password.
- A member without publishing rights can no longer put a listing live by asking for the expired status. It skipped moderation, the terms gate and the duplicate check, and the page was readable by anyone with the link.
- Photos and files can only be attached to a listing or service by the member who uploaded them. Media IDs were accepted on trust, so any file in the library could be attached to someone else's listing and its address published.
- Services switched off by their owner are no longer readable by the public. Asking for them by status, or by their own address, returned the title and price of a service the owner had deliberately hidden.
- Credits are no longer granted for an order nobody has paid for. Cash on Delivery, cheque and bank-transfer orders move to processing while still unpaid, and the mapped credit pack was credited at that moment - a buyer could order, receive credits, spend them and never pay. Credits now wait until the payment is recorded, including when a shop marks a cash order completed later.
Dev
- Added wb_listora_get_feature_allowlist_map(), used by both the submission form and the search filters.
- wb_listora_refuse_disallowed_features restores the previous drop-and-accept behaviour for a site that prefers it.
- Guardrail G18 fails the build on a frontend submission CTA that does not check the feature toggle.
- Guardrail G16 fails the build on a hardcoded map tile URL, G17 on a price rendered with a per-row or hardcoded currency.
- Documented what contract_version promises: it versions the shape of /settings/app-config and nothing else, not the values a field returns. See docs/REST-API.md.
- Added the is_available page-registration key, wb_listora_hide_unavailable_pages, and Page_Registry::key_for_page().
- Added wb_listora_get_public_page_url() and the default_shortcode registration key.
- Added wb_listora_ensure_page() and wb_listora_create_page() as the single page-creation path, and the wb_listora_page_created action.
- New `wb_listora_should_expire_listing` filter lets an extension keep a listing alive at the moment the expiry sweep would retire it, and `wb_listora_renew_listing()` runs the ordinary renewal from code that has no REST request to hand.
- New `wb_listora_credit_purchase_paths()` reports which credit purchase routes are live, replacing three separate answers that could disagree with each other.
- New `wb_listora_credit_purchase_paths` filter lets an extension declare its own purchase route.
- New `wb_listora_delete_listing_media` filter turns off the image cleanup above for an owner who wants images kept; `wb_listora_listing_media_deleted` action fires with what was removed.
- Admin RTL stylesheets are now generated at build time from their LTR source instead of hand-maintained, so they can no longer drift out of sync.
- Deleting one of the plugin's pages now clears its page-mapping option immediately rather than leaving it pointing at a deleted page until next read. New `wb_listora_page_mapping_forgotten` action.
Compat
- The bundled Wbcom Credits SDK is updated to 1.6.0, bringing gateway and adapter fixes that a forked copy had been holding back.
New 9 Improve 9 Fix 25 Security 2 Dev 6
New
- Listing photos display as a carousel, so every image stays reachable without scrolling back to the thumbnails.
- The featured image box accepts a dragged file, which its label has always offered.
- Members can set amenities when submitting or editing a listing, instead of only administrators from wp-admin.
- Tags are a discovery dimension: they filter search, appear as a facet, and render as clickable chips on cards and listing pages.
- A listing's video is rendered on the listing page rather than only stored.
- Services can be added, edited and deleted from the member dashboard.
- Automation and webhook subscribers can discover every available trigger from a published registry, with a JSON schema per event.
- The submission API accepts a complete `categories` list for clients that manage the full set.
- Features can be limited to specific listing types, so a Jobs page stops offering classified-ad amenities.
Improve
- An icon chosen in the admin picker is always one the front end can draw, so a selected icon can no longer vanish.
- Search filters and the submission form offer only the categories and features the selected listing type allows.
- Every endpoint returns the same `featured_image` shape, so a client no longer has to handle three variants.
- Every human-facing string leaves the API decoded, so ampersands and apostrophes render as typed.
- Review criteria saved against a listing type are the criteria the review form and averages use.
- Related Listings can be extended from a child theme through dedicated hooks.
- Health Check reports whether the search index is actually populated and indexed, not merely that its table exists.
- The dashboard checklist now guides owners through monetization setup in the order it has to happen.
- Terms of service is mapped once, by choosing the page your site already has, and every surface links to it.
Fix
- Editing a listing no longer deletes the categories the single-select form cannot display.
- Saving a new listing type, and resetting settings, now confirm they worked instead of reloading silently.
- Each member dashboard tab now titles the page after itself, instead of every tab reading "My Listings".
- Upgrading records the map tile source it was already using, so existing maps keep rendering and the source is now visible and editable.
- A map tile URL keeps its {z}/{x}/{y} placeholders when saved, so tiles load instead of every request returning 404.
- The setup wizard asks for a map tile server, so a fresh install is not left with a map it cannot draw.
- A site using Google Maps shows the map again, instead of an "unavailable" notice asking for a tile source Google never uses.
- The "Open Map settings" link, and the dashboard checklist's map item, land on the Map tab instead of falling back to General.
- Editing a service shows the category it is filed under, instead of an empty dropdown.
- Preview Your Listing lists the features you ticked by name, instead of their numeric term IDs.
- Service Categories has an admin screen, so the category dropdown on the member service form can actually be filled.
- Preview Your Listing groups the features you ticked into one row, instead of repeating the heading for each one.
- The listing header address no longer repeats the city and state, and no longer drops the postal code.
- Brand-coloured text meets AA contrast whatever accent colour the site or its theme uses.
- Credits status now reads the same on every screen, so members are no longer told to contact an administrator on a site that can take their payment.
- A listing whose category sits outside its type's allowed list can be edited and saved again.
- A search cache lifetime of 0 disables caching, rather than caching permanently.
- Rebuild Search Index now rebuilds the index instead of reloading the page.
- The map picker renders and accepts a dragged marker on the wp-admin listing editor.
- The favourite heart on the dashboard sits over the card image and responds to clicks.
- Approving or rejecting a claim from wp-admin now notifies the same listeners the API path does.
- Category names containing an ampersand display correctly in the submission form.
- A site missing a canonical page no longer white-screens after an update.
- A review held for approval now says so and keeps saying so, instead of the confirmation being wiped by a page reload that had nothing to show.
- Automation trigger labels translate again, and no longer fill the debug log with a notice on every page load.
Security
- Submitting a listing now requires a valid listing type, so listings can no longer be created without one.
- Terms of Service acceptance is enforced on `POST /submit`, which previously accepted a submission with no consent recorded. Clients that cannot send `agree_terms`, including sites that hide the checkbox, opt out with `add_filter( 'wb_listora_require_terms_acceptance', '__return_false' )`.
Dev
- New helper `wb_listora_directory_is_operational()` reports whether an install is a working directory, wizard walked or not.
- New public helpers: `wb_listora_render_icon()`, `wb_listora_get_icon_choices()`, `wb_listora_get_review_criteria()` and `wb_listora_decode_text()`.
- New public helper `wb_listora_sanitize_tile_url()` sanitizes a tile template without stripping the placeholders Leaflet substitutes.
- New hooks: `wb_listora_before_related_listings`, `wb_listora_after_related_listings` and `wb_listora_require_terms_acceptance`.
- `/search` accepts a `tags` argument; `/settings/app-config` publishes `contact_path`.
- Database version moves to 1.6.0; the migration clears cache entries written without an expiry and runs on activation.
New 8 Improve 8 Fix 22 Security 1 Dev 6 Compat 1
New
- A day in Business Hours can now hold up to three time ranges, so a split shift such as 08:00-12:00 and 17:00-22:00 is finally expressible.
- Members can block a reviewer from the review card and unblock from their dashboard, so blocking is no longer one-way.
- Bulk Edit and Quick Edit can set the listing type, so retyping a batch of listings no longer means opening each one.
- Administrators can change a listing's type directly from the listing screen.
- Site owners choose which platforms the Social Links field offers, in Settings, rather than taking the full built-in list.
- Site currency symbol, position, and decimal precision are now published to connected apps, so prices display the way the site formats them instead of falling back to a generic currency code.
- Map tile source and attribution are published to connected apps, so native maps render the same tiles as the website.
- Two repair commands, wp listora repair-locations and wp listora repair-credit-ledger, report what they would change and only act when asked; the credit repair adds a correcting entry and never removes credits already granted.
Improve
- The plugin is fully translatable for the first time: 284 previously untranslatable strings were exposed, the JavaScript layer is translated, and ten locales ship complete.
- The setup checklist no longer asks owners to configure settings that do not exist, so it can actually reach complete.
- Owners are warned when a listing type is open for submission but has no categories, instead of members meeting an unusable form.
- A review left by a since-deleted account reads as Former member, and one anonymized under a privacy request reads as Anonymous, rather than showing nothing.
- Abbreviated and zero-decimal currencies render correctly, and a new filter allows a custom symbol, suffix position, or precision.
- Records left behind by listings deleted on earlier versions are now cleared automatically by the daily cleanup, instead of only when the cleanup command was run by hand.
- Filtering reviews or claims by status is substantially faster on large directories, and sorting listings by Views no longer scans the whole analytics history.
- The admin Reviews screen loads author names and listing links in one batch instead of one lookup per row.
Fix
- Right-to-left sites no longer request a stylesheet that does not exist on every page load.
- A listing paused for credits can now be activated by a member who already has enough, instead of being told to buy credits they do not need.
- A listing whose plan was deleted now says so, rather than promising it will activate on its own and sending the member to an empty credits store.
- The listing header no longer shows Verified twice, and no longer repeats the city and state that are already part of the address.
- The Reviews screen in wp-admin now distinguishes a review left by a deleted account from one anonymized under a privacy request, matching what the listing page shows.
- Photos attached to a review now appear on the listing page; they uploaded correctly and were never shown back.
- The My Listings counter now includes listings awaiting credits, and every other status the list shows; it could read zero above a listing you could see.
- Keyboard focus stays inside an open dialog instead of moving to the page behind it.
- The map now plots the search that is actually running: filtering the directory left the map showing pins for listings the results had excluded.
- The saved-count beside a listing's Save button updates when you save, instead of waiting for a page reload.
- Credits are awarded and spent as credits rather than the ledger's internal units, so buying a 50-credit pack adds 50 and the transaction history reads in credits.
- The dashboard Favorites tab listed nothing for every member while the tab counter still showed the real number.
- Opening hours were missing from the search-engine markup of every member-submitted listing, and a split shift showed as closed on the listing page.
- Saving a listing in wp-admin no longer erases its location.
- A directory with a single listing type has a working Add Listing form again.
- The plugin's own admin notices no longer hide themselves.
- Turning the sitemap setting off now drops every Listora post type rather than only listings.
- A review count shown above a list now matches the reviews the reader can actually see, once blocking is taken into account.
- The plain-text part of a notification email no longer carries the previous email's listing.
- Business hours a competitor importer cannot interpret are preserved and reported instead of being discarded while the import reports success.
- Deleted listings no longer count toward search result totals or page counts.
- Translations are no longer shadowed by a stale compiled catalogue, which could serve older wording while every completeness check reported the language as fully translated.
Security
- Service names, descriptions, and prices belonging to a draft, pending, or rejected listing are no longer readable by visitors; they now follow the listing's own visibility.
Dev
- New wb_listora_search_args_from_url() builds search arguments from the URL for every surface that renders a filtered set, and a new wb_listora_map_query_args filter matches the grid's. Search accepts has_geo to page over mappable listings only.
- New wb_listora_normalize_hours() and wb_listora_max_hours_slots() helpers: any reader of business hours must normalize through the former, and any writer must cap through the latter.
- The credit balance REST response now states its units and adds the human-readable figure and currency alongside the existing field, which keeps its previous meaning.
- New wb_listora_get_currency_format() and wb_listora_get_map_tiles() helpers, with wb_listora_currency_format and wb_listora_map_tiles filters, are shared by the website and the app payloads so the two cannot drift.
- New wb_listora_social_platforms and wb_listora_credit_pack_sizes filters, and a new wb_listora_migrated_hours_unreadable action fired when an import cannot read a source's hours.
- Database indexes added to reviews, claims, and analytics. The upgrade runs automatically on activation.
Compat
- Aligned with WB Listora Pro 1.5.0. Install both updates together.
Improve 1 Fix 3 Dev 2 Compat 1
Improve
- The wp listora cleanup command now removes records orphaned by listings deleted on earlier versions.
Fix
- The submission form no longer shows an error page when select, radio, or multiselect options were added through the listing type editor; stored options are normalized to a canonical shape on read and on save.
- Permanently deleting a listing now also removes its reviews, review votes, favorites, claims, services, and analytics records. Trashing a listing keeps everything so restore is lossless.
- Corrupted or legacy-shaped stored data (dashboard statistics cache, gallery, social links, review reports, and data supplied by extensions to the calendar, categories, and review criteria hooks) renders safely instead of producing an error page.
Dev
- New wb_listora_listing_data_deleted and wb_listora_purge_orphaned_listing_data actions let extensions clean their own listing-scoped data alongside the core cleanup.
- Field options and review criteria are normalized on save, and render-time hook returns are shape-checked before use.
Compat
- Aligned with WB Listora Pro 1.4.1. Install both updates together.
New 3 Improve 4 Fix 5 Dev 3 Compat 1
New
- Members can sign in to the mobile app by typing the WordPress password they already have, instead of walking the browser approval screen.
- Settings > Advanced carries an App sign-in switch so the site owner decides whether password sign-in is offered. Turning it off leaves the browser flow and does not sign out members who already use the app.
- Signing in again from the same install replaces that install's credential instead of adding another, so a member's app-password list stops growing on every reconnect.
Improve
- The app is told which sign-in doors this site offers before it draws the screen, so it never presents a path the site will refuse.
- Sign-in failures answer identically whether the username or the password was wrong, so the endpoint cannot be used to discover which accounts exist.
- Repeated failed sign-ins are throttled per address and per account, and only wrong passwords count toward the limit.
- Sites running two-factor authentication are never bypassed; the app is handed back to the browser flow so the second factor can complete.
Fix
- Members can delete their own listings again. The permission check refused the owner and allowed only administrators.
- Custom badges now appear on directory cards and in Quick View, and a featured listing no longer shows the Featured label twice.
- The single-form submission layout no longer hides its own steps.
- Status colours now meet contrast requirements in dark mode.
- The owner contact form and the Pro lead form share one submit path, so a listing shows one working form rather than two competing ones.
Dev
- The server advertises its own contact and lead-form routes; clients no longer hardcode them.
- Card view data now carries through anything added by the wb_listora_card_view_data filter, so an extension's additions reach the card templates.
- New filters: wb_listora_app_scheme, wb_listora_app_connect_schemes, wb_listora_app_connect_bridge and wb_listora_app_password_login_enabled, plus the wb_listora_app_credential_issued action.
Compat
- Ships in lockstep with WB Listora Pro 1.4.0. Install both updates together.
Fix 7 Dev 3 Compat 1
Fix
- Submitting a listing now requires an account. Anonymous guest submission (and its email-verification step) has been removed: guests could never upload media, so the flow always dead-ended. The former block "Require Login" control was removed to match, and the inert enable_guest_submission flag no longer appears in the app-config REST response.
- The listing submission form and dashboard no longer show credit pricing or a Buy Credits link on installs that have no configured way to buy credits.
- Per-listing credit fees are now charged at the correct amount; a money-unit mismatch could charge a fraction of the configured fee.
- A custom Buy Credits URL set by the site owner is now honored on every credit call-to-action, including paused-listing emails.
- Listings awaiting email verification now carry a proper status label and valid status transitions instead of appearing unlabeled.
- Updating settings through the REST API now uses the same validation as the admin screen, so a headless client can no longer corrupt list-limit or notification settings.
- Activation reliably records the Directory page in settings, and a redundant page-creation routine was removed.
Dev
- The shared payments table definition is kept byte-identical across Free and Pro so a version upgrade never rewrites it.
- Custom capabilities and their uninstall cleanup derive from a single list; uninstall removes them without stripping WordPress core capabilities.
- Added internal-audit guardrails (rating source, Free-Pro option boundary, payments schema, credit-surface gating) to the local-CI gate.
Compat
- Ships in lockstep with WB Listora Pro 1.3.0. Install both updates together.
Improve 1 Fix 2
Improve
- A missing or incomplete bundled library now shows a soft admin notice and disables only the dependent features, instead of risking a fatal error.
Fix
- The bundled Credits SDK and license/update SDK sources were stripped from the 1.2.1 package, disabling credit-based features and auto-updates on fresh installs. Both now ship complete.
- Distribution excludes are now anchored to the plugin root so bundled libraries under libs/ are never stripped, and the release build fails fast if any SDK source is missing from the zip.
New 2 Improve 2 Fix 4
New
- Integrations page showcasing the Wbcom plugin family with product logos, store links, and one-click companion install.
- wb_listora_notification_created action so suite-wide tools can aggregate Listora notifications.
Improve
- Color and elevation tokens aligned to the Wbcom Community-OS design system.
- Demo seeder is now autoloadable everywhere, with an autoload-resolution gate to prevent activation errors.
Fix
- Activation redirect to the setup wizard no longer gets lost, and the setup notice is scoped and persists correctly.
- Suppressed the duplicate setup wizard so Free and Pro no longer launch two wizards.
- Analytics, media privacy, submission preview, and carousel QA fixes.
- Card and comparison field values truncate with a real ellipsis instead of a literal HTML entity.
New 10 Improve 4 Fix 16 Dev 3 Compat 1
New
- Demo packs and large CSV imports run as resumable background jobs with a live progress widget and a per-column field-mapping UI.
- Analytics-lite view tracking: per-listing view counts on the dashboard, an admin Views column, and a REST field. Defers to Pro analytics when active.
- Email template editor under Settings - Notifications: override any notification subject and body per event, honored on every send path.
- Bulk actions on the listings table: approve, reject, feature, unfeature, and assign category. Invalid status transitions are reported, never silently applied.
- One-click unsubscribe links (RFC 8058 signed tokens) in marketing email footers, plus a review-reminder opt-out on the profile tab and admin toggles.
- WordPress privacy-tools integration: personal-data exporter and eraser cover claims, reviews, and favorites.
- Review-reminder notification event, and an Open now / Closed badge on listing detail computed from business hours.
- HivePress migrator joins the competitor migration set.
- Inline add and edit listing forms inside the dashboard, so owners never leave My Listings.
- Submission form style setting: choose the step-by-step wizard or a single page form site-wide; a block whose author picked a layout in the editor keeps that choice.
Improve
- The Media step now says "Add a featured photo to continue" instead of a generic required-field error, and validation messages are translatable and filterable per field.
- Dashboard sidebar restyled as an elevated card panel; tab navigation gains a scroll affordance on small screens.
- Hours builder gives live Open-24h and Closed feedback; small buttons meet the 40px tap-target floor; featured images get an alt-text fallback.
- Database migrations run automatically after a plugin update, no manual trigger needed.
Fix
- Background import no longer sticks at Running after an error: failed chunks retry up to 3 times from the saved cursor, then the run is marked Failed with a clear message.
- Featured Listings block renders a proper empty state instead of silently vanishing when its listing type has no listings.
- Manage Services on My Listings opens in a modal dialog next to the listing instead of a panel at the bottom of the page.
- My Listings Active filter no longer shows deactivated, draft, pending, or rejected listings.
- Favorites dashboard tab moved to an overridable template file (tab-favorites.php), matching every other tab.
- Settings Documentation buttons deep-link to the live docs site sections instead of 404 pages.
- Submission map picker keeps Leaflet controls below fixed theme headers while scrolling.
- Keyword search shows a single clear icon: the native browser cancel control no longer stacks under the plugin's clear button.
- Post-submission success message is centered as a unit on every theme width, with stacked full-width buttons on mobile.
- Map picker now loads on the dashboard inline Add Listing form (single-form layout); it previously initialized only when stepping through the wizard.
- Single-form submission shows the Submit button directly and hides the redundant Back/Continue navigation, with full field validation run on submit.
- Onboarding dismissal is stored under the wb_listora_onboarding_dismissed key (auto-migrated from the legacy unprefixed key).
- Removed a "translation loading triggered too early" notice (WordPress 6.7+) by deferring email-template filter registration to the init hook.
- Featured Listings block no longer crashes the page (division by zero) when its columns value reaches the server as 0 via the editor preview API or saved content; columns now floor at 1.
- Listing Grid and Categories blocks also clamp a 0 columns value, which previously collapsed the layout to zero columns.
- Featured count and Grid per-page values of 0 no longer crash search pagination; the search engine floors page and per_page at 1.
Dev
- New hooks: wb_listora_search_resolved, wb_listora_dashboard_credit_row_actions, wb_listora_before/after_dashboard_favorites, wb_listora_show_credits (lets Pro's new Monetization toggle hide credit surfaces), and a reusable rating-recompute entry point. Removed the dead listing-detail view.js.
- Relocated QA artifacts from tests/qa to docs/qa and adopted the portfolio-standard pre-release smoke model.
- New release gates against the fatal class above: PHPStan now analyzes blocks/, a block-attribute guard detector runs in coding-rules (Rule 7), and an adversarial block-attribute journey fuzzes every block via the preview REST API.
Compat
- Aligned with WB Listora Pro 1.2.0. Install both updates together.
New 2 Improve 7 Fix 18 Dev 4 Compat 1
New
- Pro feature toggles now register into the Features screen, so all features are managed in one place when WB Listora Pro is active.
- WP-CLI gains wp listora test-email and cleanup subcommands.
Improve
- Demo import is faster and more resilient: per-image timeout reduced from 30s to 10s, gallery images capped, repeated image URLs downloaded once, and a failed image is skipped instead of stalling.
- CSV import and export now support the Location taxonomy and offer a per-column field-mapping UI, so listings round-trip without data loss.
- Listing-grid ratings are batch-prefetched, the admin Reviews and Claims tables and the dashboard Claims tab are paginated, and the calendar recurring-events query is bounded.
- The settings option no longer autoloads on every request, and a composite index speeds per-user review pagination.
- The Write a Review form is fully styled and responsive (criteria stack on mobile, full-width submit, clearer spacing and star states).
- Reporting a review now uses an accessible modal instead of the native browser prompt.
- Submission preview and the location map are hardened so a single failing section cannot blank the preview and the map recalculates as soon as it is visible.
Fix
- A build missing a bundled SDK no longer white-screens the site; the license and credits SDKs ship composer-free and load defensively.
- Credit purchases are idempotent: webhook replays cannot double-credit, refunds carry the real amount, and PayPal refunds link back to the original transaction.
- Schema.org JSON-LD and canonical tags no longer duplicate when Yoast SEO or Rank Math is active, and og:locale is emitted in Open Graph output.
- Breadcrumbs and BreadcrumbList schema now come from one canonical trail, and the listing-detail REST schema field respects the Schema.org toggle.
- Admin script no longer 404s during demo import; it now loads from the packaged build path.
- Documentation buttons now open the correct docs host instead of an unreachable domain.
- Search field clear and near-me icons no longer touch the field edges.
- The /search REST endpoint no longer returns a zero rating average for rated listings.
- Business hours now appear in the listing submission preview, the Business Hours builder is aligned, and the submission map stays contained in its step.
- Selecting a listing-type tab no longer increments the filter count, and the active type tab is now highlighted.
- Listing dashboard service and more-actions controls now open as expected, and the submission success card resolves the Dashboard link reliably.
- Map no longer errors when marker clustering is disabled.
- The Listings per page setting is now respected by the grid on first load.
- The Required Skills field on Job listings is now usable instead of showing only a label.
- The review form respects the configured minimum review length, and report reasons validate against a fixed vocabulary.
- Pagination active-page text stays visible under aggressive theme link styles, and dark-mode contrast is corrected on BuddyX.
- Renewal modal errors are announced to screen readers, and small buttons meet the tap-target floor.
- Settings REST endpoints return structured listora_unauthorized (401) / listora_forbidden (403) codes on denial.
Dev
- Wbcom Credits SDK re-homed from a git submodule to a committed composer-free libs/ copy that loads defensively when absent.
- CSV importer and migrator base consolidated onto the shared Term_Helper; claims queries consolidated into a canonical Claims_Model.
- wb_listora_send_notification filter now receives the recipient address as its 4th argument.
- Off-canon CSS breakpoints consolidated, and the WP-CLI table-status query is prepared.
Compat
- Aligned with WB Listora Pro 1.1.0. Install both updates together.
New 3 Improve 2 Fix 5 Dev 1 Compat 1
New
- Public Page Registry helper and new block render hooks for theme and Pro extensions.
- All 6 scheduled jobs migrated to Action Scheduler for reliable background processing at scale.
- Network timeout handling with a clear retry message on slow connections.
Improve
- Consistent page shells, cards, badges, and empty states across all 11 blocks.
- REST listing queries prefetch caches, saving about 100 queries per request on large directories.
Fix
- Setup wizard no longer renders a blank page after completing on restricted accounts.
- Approve, reject, and expiry notification emails reach listing owners again.
- Map popups show the listing featured image, and a map fatal on activation is resolved.
- Business Hours time picker works in Firefox.
- Services photo upload, helpful votes, owner reply form, and filter-count badge restored.
Dev
- Architecture invariants enforced between Free and Pro; WPCS and PHPStan baselines green.
Compat
- Aligned with WB Listora Pro 1.0.4. Install both updates together.
New 8
New
- 11 Gutenberg blocks: grid, search, map, detail, reviews, submission, categories, featured, calendar, card, and user dashboard.
- Dynamic listing types with 22 custom field types.
- Frontend submission wizard with guest registration and spam protection.
- Review system with star ratings, helpful votes, owner replies, and reporting.
- Business claims, favorites, business hours, services, and recurring events.
- Import and export for JSON, GeoJSON, and CSV plus 4 competitor migration tools.
- Full-text search with facets and geo-distance queries on dedicated database tables.
- REST API, extensive hooks, WP-CLI commands, and 14 email notification templates.