Dette er en demoshop til testformål. Ordrer vil ikke blive gennemført. Luk

Videre til indhold
  • Forside
  • Løsninger
    • Hjemmesider
    • Nyhedsbreve
    • Webshop
    • WordPress
  • Webalive plugin
    • WooCommerce produkt sortering
  • kontakt
  • Forside
  • Løsninger
    • Hjemmesider
    • Nyhedsbreve
    • Webshop
    • WordPress
  • Webalive plugin
    • WooCommerce produkt sortering
  • kontakt

© 2019

Webalive plugin

← Tilbage til alle plugins

Woo Webalive Smart Manager Premium

Af WebAlive

Version 1.5.26 WP 5.8+ Testet 7.0 PHP 7.4+ Opdateret 2026-07-16

Beskrivelse

Manage and bulk edit WooCommerce products, orders, coupons, posts, users, subscriptions; any WordPress post type and taxonomies (including custom) and custom fields using an Excel-like sheet editor.

Add products, update prices, edit SKUs, change order statuses, manage coupons, edit blog posts - perform hundreds of store operations from one place, instantly.

WebAlive-specific features

This build is the WebAlive fork of Smart Manager, with a large set of stock-management, UX and integration features layered on top of the upstream grid. All additions are scoped to #woo-wa-stock-manager-premium-app so nothing bleeds outside the plugin, and every DOM injection uses the safe appendChild-only overlay pattern so React re-renders never crash the grid.

Stock Manager grid — WebAlive columns & controls

  • Placering column (Row / Rack / Shelf) — per-product warehouse location shown as a compact badge between Product name and Price. Click a badge to open the inline edit modal (Row / Rack / Shelf + optional Stock qty). Values are stored in three plain post meta keys (_wwsmp_loc_row, _wwsmp_loc_rack, _wwsmp_loc_shelf) and are also editable from the WooCommerce product edit screen's Beholdning tab and from a dedicated sub-page (?page=stock-manager-locations) with search + pagination + AJAX save.
  • Stock qty in the Placering modal — entering a quantity here auto-enables Manage stock, persists the quantity, updates the stock status (instock / outofstock) and paints an overlay on the row's „Stockstatus & antal“ cells so the new value is visible immediately, even before React re-renders.
  • Auto-enable "Allow backorders, notify customer" — when Manage stock is turned on (via the grid checkbox or the Placering modal), the product's Backorders setting is automatically flipped from "Do not allow" to "Allow, but notify customer". Only fires on the transition, so an explicit backorders=no choice is never overridden retroactively.
  • Statusmærke badge column (WWSS integration) — when Woo Webalive Stock Status Premium is active, a badge column shows at-a-glance state: red UDGÅET for discontinued products, blue Tilbage DD-MM-YYYY when a restock date is set, purple Egen tekst when per-product WWSS text-overrides exist, or a subtle — for defaults. Clicking the badge opens a full editor modal for all WWSS fields (7 text overrides, Discontinued flag, hide-stock-status, expected restock date, alternative products picker) — no navigation to the product edit page required. Auto-detected: column only appears when WWSS_Plugin class exists.
  • Compact stock-status picker — the upstream Stock Status <select> has options with very long labels (fx Product has been discontinued by producer, Remote stock — 4-5 days) that ballooned the column width. WWSMP layers a small overlay showing only the current label + a chevron; clicking opens a compact modal picker that writes the choice back to the React-managed <select> via the native prototype value setter + bubbling change event (React-compatible pattern).
  • + Add product button — inline in the „Lager Administration“ heading row (pastel-purple ghost button style). Opens a modal with SKU / Title / Price / Manage stock / Stock qty / Row / Rack / Shelf and creates the product as a draft via a dedicated AJAX endpoint (wwsmp_sm_create_product). Location fields are written to the same meta keys as the Placering column so the new row shows its location immediately.
  • Ghost-draft filter — drafts left over from failed WooCommerce imports, discarded new-product wizards or plugins that spawn hidden drafts are hidden from the grid. Only drafts that WWSMP itself created via + Add product are shown (marked via _wwsmp_sm_draft = yes). Implemented as a posts_where clause on woocommerce_rest_product_object_query.
  • Orange draft IDs — draft products that WWSMP created (and are therefore still visible in the grid) render their ID cell in bold orange (#c2410c) so it is obvious the row is not yet live on the storefront.
  • Partial SKU-match — typing 531 in the SKU filter now finds 510-0531, 531-2000, 2015-0531-A and so on. Implemented on rest_request_before_callbacks: WWSMP intercepts the SKU parameter, runs a direct LIKE lookup against postmeta (unioned with parent IDs so variation matches surface the parent), and rewrites the parameter to a comma-separated list of exact SKUs that matched. WC's own strict IN-filter then runs unchanged, bulletproof against downstream sanitisation.
  • Wider SKU column — inputs in .stock-manager-field-sku widened to min-width: 25ch so SKUs like 510-50201081 and RD201-31032 are visible without truncation.
  • Compact number inputs & row spacing — Price / Sale price / Stock qty inputs constrained to 4.5 rem, cell padding tightened to 4 px, Placering + Statusmærke columns squeezed to 80/90 px minimum. Keeps the widened SKU column from pushing the table off-screen.
  • images payload hardening — the upstream WSM React bundle reads product.images.length without a nullish guard, so a single product without an images array crashes the entire Redux-driven grid. WWSMP adds a woocommerce_rest_prepare_product_object filter that guarantees $response->data['images'] is always an array.

Silent auto-save + toast feedback

  • Auto-save every edit — the WSM React "Save all changes" fixed-bottom bar is hidden by default (walked up from the Save button to the first position:fixed ancestor, then marked with a stable class — works despite webpack CSS Modules' hashed class names). A short debounce (~1.5 s) auto-clicks the invisible Save button after any edit.
  • Toast notifications — a small slide-in toast in the bottom-right corner confirms every save cycle: green Gemt on success, red Kunne ikke gemme with response detail on failure. Auto-dismisses after 3 s (6 s for errors). Implemented via a window.fetch interceptor scoped to actual save actions only (wwsmp_sm_save_location, wwsmp_sm_wwss_save, wwsmp_sm_create_product, POST /wp-json/wc/v3/products/batch, POST /wp-json/wc/v3/products/{id}/variations/batch) — batch-read endpoints, WP heartbeat and unrelated admin-ajax traffic are silently ignored.
  • Live status sync — after every successful save the wwsmp-sm-saved custom event fires, the WWSS labels cache is invalidated in place, every visible row is re-batched, and both the Statusmærke badge and the upstream Stock Status cell are repainted with fresh data.

Warehouse Locations sub-page (?page=stock-manager-locations)

  • PHP-rendered table with search + pagination.
  • Inline-edit Row / Rack / Shelf per product row, AJAX save on blur (no page reload).
  • Helper WWSMP_SM_Locations::get_for_product( $product_id ) returns the combined "A / 01 / 3" string — useful for packing slips, PoS displays and custom order views.

Access, branding & UX polish

  • Shop Manager role fixed — the webshop-manager role now sees the full set of Smart Manager dashboards by default (empty wwsmp_access_privilege_shop_manager option no longer resolves to "one dashboard whose key is the empty string"). Admins can still lock down individual roles via Settings → Access Privileges.
  • Auto-collapsed admin sidebar — Stock Manager sub-pages (?page=stock-manager, ?page=stock-manager-import-export, ?page=stock-manager-log) automatically collapse the WordPress admin sidebar to icons on load (matches the main WWSMP grid). Respects the existing wp_force_collapse_admin_menu setting; users can still un-collapse via WP's own toggle.
  • Modernised look — 12 px rounded cards with subtle shadow, WWSMP-purple primary buttons (#5850ec), striped tables with hover-highlight, WordPress-native underline tabs on .stock-manager-navigation, system-ui typography, warmer neutral palette (#f9fafb background, #e5e7eb borders).
  • Compact filter layout — Category / Type / Stock status dropdowns share a row with SKU / Search and are pushed to the right edge via :has() — no React bundle patch needed.
  • "Manage with Smart Manager" list-table button — the button injected next to WP list-tables' Add new title-action uses the WebAlive blueduck logo (18 px), reads simply "Smart Manager", and matches the WWSMP purple / border-radius: 6 px look.
  • Brand cleanup — upstream StoreApps testimonials and third-party brand assets (Acrom, Bryan Batcher, Jeff Smith, storeapps-logo.svg, etc.) removed from the pricing page and image folders.
  • Renamed to "Webalive Smart Manager Premium" — plugin header, admin menu title, header helper, all __()/_x() strings and readme content updated. Folder slug, text-domain, PHP constants, hook / option / transient prefixes and the update-server URI are unchanged so existing installs are not broken.
  • Danish translations wired up correctly — wp_set_script_translations now uses the 'woo-wa-stock-manager-premium' domain and the root languages/ folder, and a pre_load_script_translations filter merges every per-source Poedit JSON (Product.js, ProductFilter.js, …) into the single JSON WordPress serves for the compiled React bundle. Poedit's normal Save workflow "just works" — no wp i18n make-json step required.

Cron / scheduler stability

  • Action Scheduler PHP 8+ fix — string-keyed action args are normalised to positional args before hook dispatch, preventing fatal errors like Unknown named parameter $tasks_meta_id during cron queue execution.
Ændringslog

1.5.26 (2026-07-16)

  • Fix: Placering modal's stock-qty save no longer paints a WWSMP-owned green overlay on top of the WSM „Stockstatus & antal“ cells. That approach from 1.5.24 was wrong — it made the row look different from every other row in the grid and hid the real React-managed input beneath a custom badge. Removed paintStockCells, the .wwsmp-qty-overlay / .wwsmp-status-overlay--managed CSS, and the extra stock_status / stock_status_label fields on the save-response payload. Now the modal save simply writes to WSM's existing .stock-manager-field-stock-quantity input and .stock-manager-field-manage-stock input[type="checkbox"] via the same native-prototype _valueTracker trick already used for the stock-status <select> picker (reactSetInputValue, reactSetCheckboxValue) — React sees a real change event, its Redux store updates, and the row is re-rendered by the WSM app itself with its own styling. Nothing custom, nothing overwritten.
  • Fix: Placering modal now pre-populates the Stock qty field with the actual persisted WooCommerce value (from WC_Product::get_stock_quantity()), not by inspecting the row's DOM for a number input — the previous approach found the FIRST number input (regular-price) instead of the qty input, and returned empty on non-managed rows where the qty input doesn't render at all. Extended wwsmp_sm_get_locations_batch to return { combined, stock_qty, manage_stock } per product ID (was "combined" string only); the JS cache mirrors this shape, so opening the modal shows the true DB qty and correct manage_stock state without an extra round-trip.

1.5.25 (2026-07-16)

  • Docs: Expanded the Description section with a full WebAlive-feature index (Placering, Statusmærke, compact stock-status picker, + Add product, ghost-draft filter, orange draft IDs, partial SKU-match, wider SKU column, compact number inputs, images payload hardening, silent auto-save + toast, WWSS live status sync, Warehouse Locations sub-page, Shop Manager role fix, auto-collapsed sidebar, modernised look, brand cleanup, Danish translations, Action Scheduler PHP 8+ fix). Added a recommended installation path via WA Quick Installer at the top of the Installation section, with the manual /wp-content/plugins/ upload kept as a fallback. Readme-only release — no functional code changes over 1.5.24.

1.5.24 (2026-07-16)

  • Fix: Setting a stock quantity in the Placering modal did not visibly update the „Stockstatus & antal“ column afterwards. The AJAX save persisted the value correctly, but the JS then poked tr.querySelector('input[type="number"]') — which matches the FIRST number input in the row (the regular-price cell), not .stock-manager-field-stock-quantity. Even with the correct selector the input often didn't exist yet because manage_stock had just been flipped on and React had not re-rendered the row into number-input mode. Fixed on two ends: (1) wwsmp_sm_save_location now always returns stock_status, stock_status_label and manage_stock in the response so the client has authoritative post-save state; (2) wwsmp-sm-locations-grid.js now paints WWSMP-owned overlays on .stock-manager-field-stock-quantity (showing the qty as text) and .stock-manager-field-stock-status (showing the status label) using the same appendChild-only overlay pattern used for the stock-status picker, so the persisted values become visible immediately regardless of React's internal state. Overlays are kept in sync by an extension to paintStatusOverlays that reads back from the row's own inputs when React does eventually re-render.

1.5.23 (2026-07-16)

  • Fix: Infinite AJAX loop. wwsmp-sm-autosave.js's fetch interceptor treated EVERY POST to admin-ajax.php as a save („relevant=true“), which included the internal wwsmp_sm_wwss_batch, wwsmp_sm_get_locations_batch and wwsmp_sm_get_statuses_batch fetches. Those triggered the wwsmp-sm-saved event, which in turn called refetchAllVisible(), which fired another batch fetch, ad infinitum — hundreds of "Gemt" toasts stacking up on every page load. Narrowed the interceptor to only recognise actual save actions: wwsmp_sm_save_location, wwsmp_sm_wwss_save, wwsmp_sm_create_product, plus WC REST product/variation batch endpoints. Batch-read actions and unrelated admin-ajax traffic (klawoo subscribe, heartbeat, etc.) are silently ignored.

1.5.22 (2026-07-16)

  • Change: The upstream Stock Status <select> (visible on non-managed-stock products) contains options with very long labels (e.g. Product has been discontinued by producer, Remote stock - 4-5 days) that ballooned the column width and pushed the table off-screen. Constrained the cell to 140px via CSS and layered a WWSMP-owned overlay (<div>) on top that displays only the currently-selected label. Clicking the overlay opens a compact modal listing all available statuses; picking one writes the new value back to the underlying React-managed <select> via the native HTMLSelectElement.prototype value setter + a bubbling change event, which is the standard React-compatible pattern for driving controlled inputs from external JS. No <td> content is overwritten — the overlay is appendChilded once, and React continues managing its <select> child untouched.

1.5.21 (2026-07-16)

  • Fix: Ticking "Mark as discontinued" in the Stock Status modal appeared to wipe every text-override on the product. Root cause: the JS submitted every label field (including empty ones because most rows have no per-product custom text), and the PHP save handler treated an empty submitted value as delete_post_meta(...). The Discontinued flag saved correctly, but the seven label meta keys were nuked in the same request. Rewrote the save flow to only send labels the user actually changed (via data-original attributes on each <input>), and dropped the delete_post_meta call on the PHP side. Fields still get cleared by explicitly wiping them (they will now be recognised as "changed to empty" and sent as such).
  • New: When the WSM React grid's "Manage stock" checkbox is ticked (or Manage stock is enabled via the Placering modal's Stock qty input), the product's Backorders setting is automatically flipped from "Do not allow" to "Allow, but notify customer". Only fires on the transition, so a user's explicit backorders=no choice is never overridden retroactively. Hooked on woocommerce_before_product_object_save.

1.5.20 (2026-07-16)

  • Change: Compacted the Stock Manager grid so the wider SKU column from 1.5.17 does not push the table off-screen. Reduced number-input max-width for Price / Sale price / Stock qty (.numberControl input) from 6rem to 4.5rem, tightened cell horizontal padding to 4px, and squeezed the Placering + Statusmærke badge columns (padding-inline: 6px, min-width 80/90px). All rules scoped to #woo-wa-stock-manager-premium-app so nothing bleeds outside the WSM grid.

1.5.19 (2026-07-16)

  • New: Restock date is now surfaced in the WWSMP-owned "Statusmærke" badge column (rolled back from the React-managed "Stock status" cell in 1.5.18 for safety). When a product has _wwss_restock_date set and is not marked as discontinued, the blue "Restock / alt." badge is replaced with a formatted date badge („Tilbage 17-07-2026“ using the site's date_format when available, otherwise DD-MM-YYYY). Falls back to the plain "Restock / alt." label if only alternative products are set (no date). Zero DOM mutation of React-owned cells — date lives inside our own <td> that WWSMP fully owns.

1.5.18 (2026-07-16)

  • Fix: Grid rendered as empty after clicking the Manage-stock checkbox on any row, with DOMException: Node.removeChild: The node to be removed is not a child of this node in the console. Root cause was 1.5.6 / 1.5.7's rewriteStockStatusCell() which overwrote the WSM React app's <td> content directly with textContent = .... React's virtual DOM still expected its <Control> component in that cell; when the row re-rendered after the checkbox click, React tried to unmount the Control it thought was there and threw when the DOM node no longer existed. Rolled back the cell-rewrite entirely: the upstream Stock status column now shows whatever the WSM React bundle wants to show (typically WWSS's own re-labelled text via woocommerce_get_availability), and the WWSS Restock date / Discontinued state is surfaced exclusively through the WWSMP-owned "Statusmærke" badge column + modal.

1.5.17 (2026-07-16)

  • Change: Widened the SKU (varenummer) column input in the Stock Manager grid by ~5 characters (from the browser default ~20ch to min-width: 25ch). SKUs like 510-50201081 and RD201-31032 are now fully visible without horizontal truncation. Implemented as CSS injected by wwsmp-sm-locations-grid.js targeting the existing .stock-manager-field-sku input class WSM already sets, so no React bundle rebuild is needed.

1.5.16 (2026-07-16)

  • Fix: The Stock Manager grid table showed as empty (TypeError: can't access property "length", e.images is undefined at Products.js:196) on sites where a WooCommerce product had no images array on its REST payload. The upstream WSM React bundle reads product.images.length in Products.js line 20 without any nullish guard, so a single malformed product crashes the entire Redux-driven grid render. Added a defensive woocommerce_rest_prepare_product_object filter that ensures $response->data['images'] is always an array before the payload leaves the server — fixes the crash for all products, past and future, without needing to rebuild the React bundle.

1.5.15 (2026-07-16)

  • New: Stock quantity input added to the Placering modal. When the product's Manage stock flag is not already enabled, saving via this modal automatically enables it (set_manage_stock( true )) so the entered quantity actually takes effect. Modal now pre-populates the field with the current WC stock quantity, and any change is persisted alongside Row / Rack / Shelf in the same AJAX round-trip.
  • Change: Removed the auto-save-when-all-three-location-fields-are-filled debounce. The modal now only saves on explicit action — Enter key (from any input) OR click on Gem. Rationale: users typing a partial location + Tab-ing between fields sometimes triggered a premature save.

1.5.14 (2026-07-16)

  • New: The Stock Manager grid now filters out "ghost" draft products — drafts left over from failed WooCommerce imports, discarded new-product wizards, or plugins that spawn hidden drafts. Only drafts that WWSMP itself created via the "+ Add product" modal are shown; every other draft is invisible in the grid until it is published. Implemented via a marker post meta _wwsmp_sm_draft = yes set by WWSMP_SM_Locations::ajax_create() on creation, plus a posts_where clause hooked onto woocommerce_rest_product_object_query that requires either non-draft status or presence of the marker.
  • New: Draft products that DO appear (i.e. WWSMP-created drafts still awaiting publication) now render their ID cell in bold orange (#c2410c), making it obvious at a glance that the row is not yet live on the storefront. Batch-fetched via a new lightweight endpoint wwsmp_sm_get_statuses_batch and applied by wwsmp-sm-locations-grid.js on every column paint pass.

1.5.13 (2026-07-16)

  • Fix: The "Mark as discontinued" checkbox in the Stock Status modal was persisted server-side but appeared to "lose" its state on reopen. Root cause was 1.5.12's refetchAllVisible() reassigning cache = Object.create( null ) while saveModal()'s own success handler was still executing — both hold a lexical reference to the same cache variable, so the modal's cache[ pid ] = json.data sometimes landed on the freshly-emptied object before the batch refetch populated it, and the next modal open read data.discontinued === undefined (falsy → unchecked). Rewrote the invalidation to CLEAR entries in place (for ( var k in cache ) { delete cache[ k ]; }) so all writers see the same shared object identity throughout the save cycle.
  • Debug: Added console.debug( 'WWSMP save payload: {...}' ) and console.debug( 'WWSMP save response: {...}' ) inside saveModal() so it is trivial to confirm what value is being sent + received for every field.

1.5.12 (2026-07-16)

  • Fix: The "Stock status" grid column stayed on its old value (e.g. Ikke på lager) after the user changed the stock quantity and the auto-save persisted it. The WWSS labels grid cached each product's effective_label and re-used it forever; there was no invalidation path when a save happened. Added a decoupled wwsmp-sm-saved custom event: wwsmp-sm-autosave.js dispatches it after every successful save-fetch, and wwsmp-sm-wwss-labels-grid.js listens for it, clears its per-product cache, re-batches every visible row, and repaints both the Statusmærke badge and the upstream "Stock status" cell. 500 ms delay before the refetch so WooCommerce has time to persist meta changes before we ask for the resolved label.

1.5.11 (2026-07-16)

  • Fix: Save toast rendered to the DOM in 1.5.10 but was never visible on the user's site. The opacity: 0 → opacity: 1 fade-in relied on a setTimeout( ..., 10 ) adding a .visible class, and a race with browser paint frames occasionally landed the toast in the removed state before the .visible class was applied. Replaced the two-step fade-in with immediate visibility (opacity 1 by default) — the toast now appears the frame it is appended. Also added a console.debug( 'WWSMP toast: ...' ) log at every render so it is trivial to verify the DOM insertion in DevTools.

1.5.10 (2026-07-16)

  • Change: Removed the immediate "Saving…" toast on the debounced auto-save button click. All feedback now comes strictly from the window.fetch interceptor — green "Saved" on 2xx, red "Save failed" on non-2xx or network error. Rationale: the click-based fallback fired even when the underlying WC REST batch call was already in flight from a previous edit, causing double-toasts and false-positive feedback.
  • Debug: The fetch interceptor now emits console.debug on every intercepted call (WWSMP fetch: <method> <url> → relevant=<bool>) so it is trivial to diagnose why a save is not surfacing a toast. Filter the DevTools Console by WWSMP to see the full trace.

1.5.9 (2026-07-16)

  • Fix: 1.5.8's "hide the Save all changes bar" CSS never matched anything because the WSM React app uses webpack CSS Modules (SaveChanges.scss) that emit hashed runtime class names (SaveChanges_wrapper__<hash>). Replaced the static selector list with a JS walk: wwsmp-sm-autosave.js now locates the Save button (which we already find for auto-save), walks up until it hits an element with position: fixed in its computed style, and adds a stable marker class wwsmp-sm-save-bar-hidden on that wrapper. A MutationObserver re-runs the walk on every React re-render so the bar cannot come back. The invisible Save button remains in the DOM so the debounced auto-save can still click it.
  • New: Immediate "Saving…" toast on every debounced auto-save so the user sees feedback even before the WooCommerce REST batch call resolves. Final "Saved" / "Save failed" toast still fires from the window.fetch interceptor when the response returns. Added a console.info( 'WWSMP autosave: fetch interceptor active' ) log so it is trivial to verify the interceptor is installed via DevTools.

1.5.8 (2026-07-16)

  • Fix: stock_status was called incorrectly _doing_it_wrong notice spammed the debug log every time the WWSS labels batch endpoint fired. Root cause was WC_Product::get_availability() running the woocommerce_get_availability filter chain, which on this site includes a third-party function (woocommerce_get_custom_availability) that still uses direct property access $product->stock_status. Rewrote WWSMP_SM_WWSS_Labels::get_for_product() to bypass get_availability() entirely and call Woo_Stock_Base::woo_rename_stock_status() directly — same result (per-product override → category meta → global setting → default) but without invoking unrelated third-party filters.
  • Fix: include_once ... class-wwsmp-manager-pro-base.php warning on every admin page load. The upstream WWSMP layout had a pro/common-pro/ folder that our fork never shipped, but the WWSMP_Controller bootstrap tried to include one specific file inside it during the scheduled-tasks setup. Wrapped the include in file_exists(), matching the existing file_exists() guards on the sibling includes in the same block.
  • Change: The upstream React "Save all changes" fixed-bottom bar is now hidden by default (display:none !important). Edits are auto-saved silently by the existing wwsmp-sm-autosave.js debouncer (unchanged behaviour, just no visible bar). Instead, a small slide-in toast appears in the bottom-right corner after each save cycle: green with a checkmark on success, red with an X and the response message on failure. The toast auto-dismisses after 3 s; failures stay visible for 6 s. Implemented via a window.fetch interceptor scoped to the WSM REST endpoints (/wp-json/wc/v3/products* and wp-admin/admin-ajax.php?action=wwsmp*) so it does not touch unrelated network activity.

1.5.8 (2026-07-15)

  • Fix: Action Scheduler compatibility on PHP 8+ — normalized string-keyed action args to positional args before hook dispatch to prevent fatal errors like Unknown named parameter $tasks_meta_id during cron queue execution.

1.5.7 (2026-07-14)

  • Fix: The Stock Status grid column now appends the WWSS restock date when set, e.g. Ikke på lager (tilbage 17. juli 2026). Server-side format uses WordPress's date_i18n() with the site's date_format option, so the date honours the current locale automatically.
  • Fix: Modal layout — the two flag rows Marker som udgået and Skjul lagerstatus were moved to the BOTTOM of the modal (just above the Save/Cancel bar). The modal now flows top-to-bottom in order of increasing rarity: restock date + alternatives (most-edited) → text overrides → flags (edge cases).
  • Fix: WSM React grid headers ("SKU", "Product name", "Stock status", filter labels, etc.) stayed in English despite Poedit having translated them. Root cause: Poedit generates one script-translations JSON per source file (Product.js, ProductFilter.js, …), but WordPress's wp_set_script_translations only serves the ONE JSON whose filename is md5(enqueued_script_src).json — which for the compiled React bundle only contained 12 internal property strings, not the UI text. Registered a pre_load_script_translations filter that, on the WSM React handle, discovers all per-source JSONs in languages/ and merges their locale_data.messages into a single response. Poedit's normal Save workflow now "just works" — no wp i18n make-json step required.

1.5.6 (2026-07-14)

  • Change: Text-overrides section in the Stock Status modal is now laid out in two columns instead of a single stacked list, roughly halving the modal's vertical footprint. The two flag rows (Discontinued / Hide status) and the restock date + alternatives row are unaffected.
  • New: "Udfyld fra standard" button in the text-overrides section. Fills every EMPTY override input with the current WWSS global setting (wc_slr_<status>). Non-empty inputs are left alone so an existing per-product customisation is never overwritten by accident. Global values are shown as greyed-out placeholders even before the button is pressed, so it is always clear what each empty field will fall back to on the frontend.
  • New: The grid's built-in "Stock status" column (rendered by the upstream WSM React bundle) is now rewritten to show the effective WWSS availability label — i.e. the same text a shopper would see on the product page after WWSS resolves per-product override → category meta → global setting → hardcoded default. Implemented via a batch fetch that calls WC_Product::get_availability() server-side (fires WWSS's own woocommerce_get_availability filter chain), then overwrites the cell content in the same MutationObserver pass that paints the Status label badge. Falls back silently to whatever WSM originally rendered if WWSS is not active or get_availability() returns empty (e.g. variable-parent with mixed variation states).

1.5.5 (2026-07-13)

  • New: Full WWSS Stock Status modal editor in the Stock Manager grid — clicking the "Status label" badge now opens an in-grid modal that reads and writes every relevant WWSS post meta directly (no edit-page navigation, no data duplication). Editable fields:
    • Marker som udgået (checkbox, _wwss_discontinued) — forces Discontinued display, blocks add-to-cart, reports schema.org/Discontinued.
    • Skjul lagerstatus (checkbox, hide_stock_status) — suppresses the stock status message entirely.
    • Forventet genopfyldnings-dato (date, _wwss_restock_date) — drives the restock notice module (auto-hides after date passes).
    • Alternativer (WC product multi-picker, _wwss_alternative_products) — uses the same wc-product-search Select2 the WWSS product page does; suggested replacements always show alongside the restock notice / discontinued badge on frontend.
    • 7 tekst-overrides (in_stock, only_s_left_in_stock, can_be_backordered, s_in_stock, available_on_backorder, out_of_stock, discontinued) — per-product custom labels, blank = fall through to the WWSS global setting.
  • New: wwsmp_sm_wwss_save AJAX endpoint (edit_products cap, dedicated nonce) validates all inputs (date must match YYYY-MM-DD, alternatives must be existing product post IDs) and writes them via update_post_meta / delete_post_meta so an empty value cleans up the DB row rather than storing ''.
  • Change: The badge column's batch endpoint (wwsmp_sm_wwss_batch) now returns the full state so the modal can pre-populate without a second round-trip, and so the badge can distinguish "has custom text" from "has restock date / alternatives".

1.5.4 (2026-07-11)

  • Change: Replaced 1.5.3's custom in-grid modal for editing WWSS stock-status labels with a plain hyperlink on the badge that opens the product's WooCommerce edit screen scoped to the existing WWSS "Custom Stock Status" tab (post.php?post=<pid>&action=edit#custom_stock_status_data). Rationale: WWSS already owns the fully-fledged editing UI on the product page (all 7 label fields, colors, per-variation overrides, Discontinued checkbox, hide-status option), so a second parallel modal in the grid duplicated logic and diverged in features. The badge column still gives the at-a-glance status (red UDGÅET / purple Egen tekst / gray dash), fetched via the existing wwsmp_sm_wwss_batch endpoint, and clicking it now takes you straight to the canonical editor.
  • Cleanup: Removed the wwsmp_sm_wwss_save AJAX endpoint, the client-side save/cancel/keyboard-modal logic, and 8 modal-only localized strings that were never rendered again — shrinks the JS bundle from ~14 KB to ~5 KB and removes 8 English fallback strings that were dependent on translation timing.

1.5.3 (2026-07-11)

  • New: WWSS (Woo Webalive Stock Status Premium) custom stock-status labels are now surfaced and editable directly from the Stock Manager grid (?page=stock-manager). A new "Status label" column is injected next to Placering; each row shows an at-a-glance badge — red UDGÅET if the product is flagged Discontinued (via WWSS 1.0.6's _wwss_discontinued meta), purple Egen tekst if any of the 6 built-in per-product WWSS text overrides is set, or a subtle — if the product uses the WWSS global defaults. Clicking the badge opens a modal with all 7 text override fields (in_stock, only_s_left_in_stock, can_be_backordered, s_in_stock, available_on_backorder, out_of_stock, discontinued) plus a Mark as discontinued checkbox. Saves via a new AJAX endpoint (wwsmp_sm_wwss_save, edit_products capability, dedicated nonce) that writes directly to WWSS's existing post meta keys — no data duplication, no sync layer, so WWSS and WWSMP stay in perfect agreement.
  • Auto-detection: the column + modal only enqueue when WWSS is active (class_exists( 'WWSS_Plugin' ) at admin_enqueue_scripts time). Sites without WWSS see no change.

1.5.2 (2026-07-11)

  • Fix: "+ Add product" button in 1.5.1 landed above the React grid instead of next to the "Lager Administration" heading. Root cause: the assistant had assumed the <h2> lived INSIDE #woo-wa-stock-manager-premium-app, so ensureAddButton() searched the app container for h1, h2, found none, and fell back to pinning the button at the top of the React app. In reality the heading is rendered server-side by stock-manager/admin/views/admin.php as a sibling of the app container (<div class="wrap"> → <h2>Lager Administration</h2> → <div id="woo-wa-stock-manager-premium-app">). Moved the button injection out of JS entirely: the PHP template now wraps the heading in a flex row (.wwsmp-sm-page-heading) with the button rendered inline as a sibling of the <h2>. The button is server-rendered, so it survives React re-renders without a MutationObserver. Same pastel ghost-button styling from 1.5.1 preserved.

1.5.1 (2026-07-09)

  • UI: "+ Add product" button restyled to match the pastel-purple ghost-button look used on ?page=wwsmp ("+ Ny Min Max Rule") — light lavender background (#eeecff), dark purple text (#4b44d9), 6 px radius, subtle 1 px border, no drop-shadow. Repositioned to sit on the same visual line as the <h2> "Lager Administration" heading (auto-detects the first h1 / h2 inside #woo-wa-stock-manager-premium-app, wraps its parent in a positioned container, and pins the button top-right of that container). Previously the button was pinned to the app container's top-right corner and landed on top of the filter row instead of the heading row.

1.5.0 (2026-07-09)

  • Fix: "+ Add product" button from 1.4.9 never appeared because the grid JS bundle was truncated mid-boot() (missing MutationObserver, missing IIFE close), and the AJAX action name in submitAddModal was hard-coded to a non-existent handler (wwsmp_sm_add_product) instead of the registered cfg.createAction (wwsmp_sm_create_product). Rewrote the tail of wwsmp-sm-locations-grid.js: boot() now waits for the app root, injects the button, calls schedule(), and starts a MutationObserver that re-injects both the Placering column and the Add-product button on every React re-render. Also switched the button from a position:fixed floating action button (which floated over the WordPress admin bar) to position:absolute; top:12px; right:20px; inside the app container, so it sits in the top-right corner of the Stock Manager card as requested. Verified with node --check.

1.4.9 (2026-07-09)

  • New: “+ Add product” floating action button injected top-right on the Stock Manager grid (?page=stock-manager). Clicking opens a modal with the essential fields — SKU, Title, Price, Manage stock, Stock qty, Row / Rack / Shelf — and creates the product as a draft via a new wwsmp_sm_create_product AJAX endpoint (reuses the existing wwsmp_sm_locations nonce and edit_products capability). Location fields are written to the same _wwsmp_loc_row / _wwsmp_loc_rack / _wwsmp_loc_shelf meta keys as the Placering column so the new row shows the location immediately after save. WooCommerce’s REST products endpoint returns draft products with context=edit, so the newly created draft appears in the grid after the automatic page-reload following save.

1.4.8 (2026-07-09)

  • UX: Placering inline modal auto-saves when all three fields (Row / Rack / Shelf) have non-empty trimmed content. A 500 ms debounce absorbs mid-typing pauses, and the existing Save button + Enter-to-save + Cancel/Esc all remain functional. Added a double-save guard (saveBtn.disabled) so the debounce firing near-simultaneously with a manual click cannot dispatch two POSTs.

1.4.7 (2026-07-09)

  • Fix: Shop Manager (webshop-manager) role saw an empty Stock Manager dashboard instead of the full set of Smart Manager panels. Root cause: WWSMP_Pro_Access_Privilege::get_current_user_access_privilege_settings() runs explode( ",", get_option( 'wwsmp_access_privilege_shop_manager', '' ) ) when the option is not configured — explode of an empty string returns array('') (a truthy 1-element array), which the downstream unset-loop then treats as "the user is only allowed one dashboard whose key is the empty string", removing every real dashboard. Rewrote the resolver so an empty option is coerced to an empty array, i.e. "no restriction configured → keep every dashboard". Admins can still lock down individual roles via the existing Settings → Access Privileges UI; only the default (unconfigured) behavior changed. Menu registration in WWSMP::add_menu() was already using manage_woocommerce (which shop_manager has) so no menu change was needed.

1.4.6 (2026-07-09)

  • Fix: Partial SKU-match — rewritten from scratch on a different hook that cannot be undone by WooCommerce's REST controller. Uses rest_request_before_callbacks on the /wc/v3/products endpoint: the SKU parameter is intercepted BEFORE WC builds its query, we run our own LIKE-lookup against postmeta, and rewrite the parameter to a comma-separated list of the exact SKUs that matched (or a sentinel value if nothing matched). WC then runs its normal IN-based SKU filter with a pre-computed match set, so we don't fight the WC sanitisation pipeline at all.

1.4.5 (2026-07-09)

  • Fix: 1.4.3 / 1.4.4's partial SKU-match still didn't work in practice. Root cause: WC_REST_Products_Controller::prepare_objects_query() adds SKU as meta_query with compare = 'IN' (an array of SKUs, exploded on comma), not a single-value exact match. Simply flipping the compare to LIKE breaks because LIKE doesn't accept an array value, and the strict WC sanitizer runs after our filter and can re-normalise. Switched to a pre-computed post__in approach: our filter runs a direct SELECT post_id FROM postmeta WHERE meta_key='_sku' AND meta_value LIKE '%xxx%', unions with parent-IDs so variation matches surface the parent product too, strips WC's own _sku meta_query, and sets post__in on the query. Bulletproof against any downstream sanitisation.

1.4.4 (2026-07-09)

  • Fix: 1.4.3's partial SKU-match filter never fired in practice because the wwsmp_sm_filter gate parameter is not reliably present as the string "true" in $request->get_query_params() — the React app passes a JavaScript boolean, WooCommerce's REST controller strips it during sanitisation, and the strict 'true' !== ... check always short-circuited. Removed the gate; partial SKU-match now runs on any WooCommerce REST product query that includes a sku parameter. This makes ?page=stock-manager finally find 510-0531 when typing 531, 0531, 510, or 510-05. External integrations that rely on exact-SKU lookup can opt-out via the wwsmp_sm_sku_like filter (return false to disable).

1.4.3 (2026-07-09)

  • Change: The SKU field in the Stock Manager grid filter (#woocommerce-product-manager-filter-sku) now performs a partial (substring) match instead of exact-match only. Typing 15 will now find 15-1600, 15-2000, 2015-1600, and so on. Implemented via a woocommerce_rest_product_object_query filter at priority 100 that rewrites the _sku meta_query clause added by WC_REST_Products_Controller from compare = '=' to compare = 'LIKE'. Only affects REST requests that come from the Stock Manager grid (identified by the wwsmp_sm_filter=true parameter that the React app already sends).

1.4.2 (2026-07-08)

  • New: Placering badge in the Stock Manager grid now opens an inline edit modal instead of navigating to the product-edit page. Clicking any location cell shows a lightweight modal with Row / Rack / Shelf inputs (same three fields as the Locations sub-page). Saving uses the existing wwsmp_sm_save_location AJAX endpoint and updates the badge in place without a page reload.

1.4.1 (2026-07-08)

  • New: Warehouse Location fields (Row / Rack / Shelf) are now surfaced in two more places:
    • WooCommerce product edit → Varedata → Beholdning tab. Three inline inputs shown right after the existing stock/inventory fields, saved via the standard woocommerce_process_product_meta hook. This is the natural place to enter location while editing a product's stock data, so the previously-added side metabox has been removed to avoid duplication.
    • Stock Manager grid (?page=stock-manager). A read-only "Placering" badge column is injected between "Product name" and "Price" via a DOM helper (MutationObserver-based, so it survives grid re-renders on filter/pagination). Product IDs are extracted from the existing #XXX cell, then a single batched AJAX call fetches all locations for the visible rows and paints the values. Editing is done via the Beholdning tab or the dedicated Locations sub-page — keeps the grid injection minimal and robust to upstream React changes.
    • New batched AJAX endpoint wwsmp_sm_get_locations_batch that returns location strings for an array of product IDs in one round-trip.

1.4.0 (2026-07-07)

  • New: Warehouse Locations — track physical storage location (row / rack / shelf) per WooCommerce product. Adds:
    • A new sub-page under the Stock Manager menu: Lokationer (?page=stock-manager-locations). PHP-rendered table with search + pagination, inline-edit Row / Rack / Shelf per product row, AJAX save on blur (no page reload).
    • A Warehouse Location panel on the single WooCommerce product edit screen (edit.php?post=X) with three inputs and combined display "A / 01 / 3".
    • Three new product meta keys: _wwsmp_loc_row, _wwsmp_loc_rack, _wwsmp_loc_shelf (string values — free text for now, can be constrained to enumerated values in a future release).
    • A helper WWSMP_SM_Locations::get_for_product( $product_id ) that returns the combined location string; useful for packing slips, PoS displays, or custom order views.

1.3.10 (2026-07-07)

  • Change: The "Manage with ..." button that WWSMP injects next to the "Add new" title action on WooCommerce/WP list-tables (Products, Orders, Coupons, Users, custom post types) has been redesigned:
    • Icon: replaced the tiny 16px WSM icon with the webalive_blueduck.svg logo at 18px.
    • Text: shortened from "Manage with Webalive Smart Manager Premium" to just "Smart Manager".
    • Colours: switched from the arbitrary green accent (#0e9f6e) to the WWSMP purple (#5850ec), consistent with the rest of the plugin.
    • Padding + rounded corners aligned with the modernised WWSMP look (border-radius: 6px).

1.3.9 (2026-07-07)

  • Change: Renamed the plugin display-name from "Webalive Smart Manager Premium" to "Webalive Smart Manager Premium" across the codebase (plugin header, admin menu title, header helper, all __() / _x() strings, readme title & description). The renaming removes the naming clash between the parent plugin and its folded-in stock-manager/ sub-module: the parent is now "Smart Manager" (the spreadsheet grid that edits ALL post types, orders, coupons, users, custom fields), and the sub-menu entry "Stock Manager" is the focused stock/log/import view.
  • Not changed (intentional, would break existing installs): folder slug woo-wa-stock-manager-premium, text-domain woo-wa-stock-manager-premium, all WWSMP_* PHP constants, all hook / action / filter / option / transient prefixes, the update-server URI. Only user-visible strings are affected.

1.3.8 (2026-07-07)

  • Fix: The React app on the Stock Manager sub-pages was calling wp_set_script_translations( ..., 'stock-manager', WWSMP_SM_DIR . 'languages' ), so it looked for a woo-wa-stock-manager-premium-admin-script-react-stock-manager-<locale>.json file in the wrong directory. Wave A already renamed the PHP text-domain from woocommerce-stock-manager to woo-wa-stock-manager-premium, so all the __() / _x() calls resolve against the main WWSMP .mo file — the JS was the last piece not wired up. Now uses 'woo-wa-stock-manager-premium' domain and the root WWSMP_PATH . 'languages/' folder so React strings resolve against the same translation files as the rest of WWSMP.

1.3.7 (2026-07-07)

  • Change: Stock Manager sub-pages (?page=stock-manager, ?page=stock-manager-import-export, ?page=stock-manager-log) now automatically collapse the WordPress admin sidebar to icons on load, matching the behaviour of the main WWSMP grid. Implemented server-side via admin_body_class (adds the WP-native folded class) so it takes effect before render, no flash of expanded menu. Respects the same wp_force_collapse_admin_menu setting used by the grid; users can still un-collapse via WP's own #collapse-menu toggle.

1.3.6 (2026-07-07)

  • Change: Stock Manager grid page (?page=stock-manager) filter layout — Category / Type / Stock status dropdowns are now on the same row as SKU / Search, pushed to the right edge (via margin-left: auto on the second .row). Uses :has() to target the React-rendered filter without patching the bundled JS.
  • Change: All input, select and textarea fields inside the Stock Manager pages get 6px rounded corners, 1px #d1d5db border and consistent padding to match the modernised WWSMP look.
  • New: Auto-save on the Stock Manager grid. Instead of waiting for the upstream React "Save all changes" bar (which is a position: fixed bottom-bar with low z-index that often ends up hidden behind WooCommerce/theme footers), a small helper script now listens for edits inside #woo-wa-stock-manager-premium-app and clicks the primary save button automatically after a short debounce (1500 ms). Also raises the z-index of the fallback save-bar to 999999 so it stays visible if it ever renders.

1.3.5 (2026-07-07)

  • Change: Modernised the visual look of the Stock Manager sub-pages (?page=stock-manager, ?page=stock-manager-import-export, ?page=stock-manager-log) so they align with the main WWSMP dashboard aesthetic. Added an overlay stylesheet (stock-manager/admin/assets/css/wwsmp-sm-modern.css) enqueued after the upstream admin.css:
    • Rounded corners (12px) and subtle shadow on .toret-box cards.
    • Modern flat buttons with WWSMP purple (#5850ec) for primary actions and consistent hover states.
    • Cleaner tables: no heavy #ddd borders, striped rows, hover-highlight.
    • System-ui typography, warmer neutral palette (#f9fafb background, #e5e7eb borders).
    • WordPress-native .stock-manager-navigation tabs (underline style) instead of the boxed classic look.
    • Filter blocks and pagination redesigned as inline cards.

1.3.4 (2026-07-07)

  • Change: Removed upstream Smart Manager brand assets and testimonials that referred to third-party customers of the original StoreApps product:
    • Deleted image assets: acrom.png, bryan-batcher.jpeg, jeff-smith.png, sm-in-app-promo.png, dirty.gif, logo-32x32.png, storeapps-logo.svg, sa-onboarding-connect-account.png, sa-onboarding-success.png.
    • Removed the three testimonial blocks on the Pricing page (Jeff Smith, Acrom, Brian Batcher).
    • Replaced the StoreApps privacy-policy link in the Stock Manager subscribe form with the Webalive equivalent.
    • Removed dead-code class-wwsmp-in-app-offer.php (BFCM 2025 promo banner) and its bootstrapping in class-wwsmp.php.
  • New: Added a shared admin header (WWSMP::render_admin_header()) with the webalive_blueduck.svg logo + "Webalive Smart Manager Premium" title. Rendered on: Pricing (?page=wwsmp-pricing), Welcome/FAQs (?page=wwsmp&landing-page=wwsmp-faqs), Settings (?page=wwsmp-settings), and the three Stock Manager sub-pages (stock-manager, stock-manager-import-export, stock-manager-log). The main grid dashboard is intentionally unchanged — it has its own navbar.

1.3.3 (2026-07-07)

  • Fix: WP admin plugins list showed "Auto-updates are not available for this plugin" instead of the normal "Enable auto-updates" link. Upstream Smart Manager registered a plugin_auto_update_setting_html filter that unconditionally overrode the auto-update column text when Pro was installed (originally meant to steer Smart Manager Pro users toward StoreApps' own update flow). WWSMP has its own PUC-based auto-update endpoint at updates.webalive.dk, so the filter is no longer needed. Removed both the add_filter hook and the auto_update_setting_html() callback; WordPress' default auto-update UI is now visible again.

1.3.2 (2026-07-07)

  • Change: Removed the "Docs & Support" submenu (page=wwsmp&landing-page=wwsmp-about) and the "WebAlive Plugins" submenu (page=wwsmp-webalive-plugins). Both were legacy landing pages that added noise to the admin menu without providing plugin functionality. The activation redirect that used to land users on the Docs & Support page has been changed to the main dashboard. All page-slug checks (in_array filters for footer text, admin notices, feature notices, footer CSS enqueue, in-app offer plugin-page detection) have been updated so these two slugs are no longer accepted. The WebAlive_Marketplace::init() call — which was the entire body of the WebAlive Plugins page — is no longer wired up. The about_screen() renderer in WWSMP_Admin_Welcome is retained (unused) but its switch-case entry is removed; the nav-tab that pointed to it has also been removed.

1.3.1 (2026-07-07)

  • Fix: stock-manager/loader.php now checks with is_file() that each sub-module class file exists before calling require_once. Prevents a fatal error on partial deploys where the new stock-manager/ directory has not been fully uploaded yet.

1.3.0 (2026-07-07)

  • New: Stock Manager for WooCommerce (StoreApps 3.7.0) folded into WWSMP as a stock-manager/ sub-module. Provides a dedicated stock/price editor dashboard, quick filters, stock log history, and CSV import/export as a sub-page under the WWSMP admin menu. The standalone woocommerce-stock-manager plugin is no longer required and can be deactivated — its features are now built-in.
    • Renamed the entire WSM namespace to avoid collision if the standalone plugin is still installed:
    • PHP classes: Stock_Manager → WWSMP_SM_Manager, Stock_Manager_Admin → WWSMP_SM_Admin, WSM_Save → WWSMP_SM_Save, WSM_Stock → WWSMP_SM_Stock.
    • Constants: STOCKDIR → WWSMP_SM_DIR, WSM_PLUGIN_URL → WWSMP_SM_URL, WSM_PLUGIN_FILE → WWSMP_SM_FILE, WSM_PLUGIN_VERSION → WWSMP_SM_VERSION.
    • Hook/CSS prefixes: wsm_ → wwsmp_sm_, wsm- → wwsmp-sm-, sa_ → wwsmp_sm_, sa- → wwsmp-sm-, SA_ → WWSMP_SM_.
    • Text domain: woocommerce-stock-manager → woo-wa-stock-manager-premium (translations merged into the existing WWSMP domain).
    • The DB table name {$wpdb->prefix}stock_log is kept unchanged to preserve any existing stock log data from prior WSM installs.
    • WSM's standalone add_menu_page( 'Stock' ) replaced by add_submenu_page under WWSMP's own menu slug.
    • Removed upstream StoreApps in-app pricing/promo dead code (class-wsm-in-app-pricing.php), matching the same policy applied to WWSMP itself.
    • Removed register_activation_hook / register_deactivation_hook; the stock-log DB table is now created on demand via WWSMP's install flow.

1.2.7 (2026-07-07)

  • Fix (fatal error Class "WWSMP_Manager_Base" not found): WWSMP_Manager_Controller::request_handler() used a whitelist regex /^class-wa-manager(-pro)?(-[a-z0-9_]+)?\.php$/i to decide which files were safe to include_once. When Wave E renamed the physical files from class-wa-manager-*.php to class-wwsmp-manager-*.php this regex stopped matching — so the base class was never loaded, and the wwsmp_manager_handler filter callback (WWSMP_Controller::req_handler → include_once class-wwsmp-base.php) hit class WWSMP_Base extends WWSMP_Manager_Base before WWSMP_Manager_Base was defined. Updated the whitelist regex to match the new class-wwsmp-manager-*.php naming.

1.2.6 (2026-07-06)

  • Fix (systematic audit — the whole reason nothing worked after Wave E). All rename-induced problems fixed in one pass:
    • Double-prefix in filter/action/option/transient names. After Wave E, WWSMP_SKU = 'wwsmp' was concatenated with a 'wwsmp_' prefix in ~30 places producing hooks like wwsmp_wwsmp_dashboard_model, wwsmp_wwsmp_data_model, wwsmp_wwsmp_manager_handler, wwsmp_wwsmp_validate_current_page, wwsmp_wwsmp_check_dashboard_access, wwsmp_wwsmp_manager_common_core_path, wwsmp_wwsmp_manager_func_handler, wwsmp_wwsmp_manager_request_handler_allowed_dir_path, plus option/transient/user-meta keys wwsmp_wwsmp_<dashboard_key>, wwsmp_wwsmp_feedback_done, wwsmp_wwsmp_feedback_start_date, wwsmp_wwsmp_feedback_close_date, wwsmp_wwsmp_feedback_action_counts, wwsmp_wwsmp_dashboard_load_count. Meanwhile the pro layer registered add_filter('wwsmp_dashboard_model', ...), add_filter('wwsmp_data_model', ...) etc. — the two sides never met, so every pro column, data-model transform, and dashboard access check was silently dead. All 'wwsmp_' . $plugin_sku . '_...' collapsed to 'wwsmp_...'.
    • Double-prefix in AJAX action URLs. The background-updater JS was building ?action=wwsmp_wwsmp_manager_include_file, again never matching any handler. Collapsed to ?action=wwsmp_manager_include_file.
    • Dead JS action wwsmp_beta_include_file in pro/class-wwsmp-pro-background-updater.php — no PHP handler ever registered under that name (this was a legacy sm_beta_include_file from upstream that was renamed but never wired up). Routed to the actual handler wwsmp_manager_include_file.
    • *`add_filter('wwsmpbeta_include_file', ...)**-style hooks inclass-wwsmp-pro-user.phpverified consistent withapply_filters('wwsmpbeta*', ...)sites inclass-wwsmp-pro-base.php`.
  • This release is the result of a top-down audit (AJAX action registrations vs JS action calls, wp_create_nonce vs check_ajax_referer, filter callers vs listeners, script handle registrations, dashboard-property bridge between base and pro) rather than reacting to one browser console error at a time.

1.2.5 (2026-07-06)

  • Fix (root cause of the empty dashboard / empty AJAX response in 1.2.4): two rename escapees from Wave E broke the entire AJAX layer.
    1. wp_ajax_sa_ prefix survived the regex rename (word-boundary did not match after _). PHP was still registering the handler as wp_ajax_sa_wwsmp_manager_include_file while JS was calling wwsmp_manager_include_file — WordPress never routed the request to any callback so the response was empty. Same issue for wp_ajax_sa_stop_background_process and wp_ajax_sa_wwsmp_stop_background_process. All three sa_ prefixes removed from add_action calls.
    2. Nonce mismatch. wp_create_nonce() produced 'wwsmp-manager-security' (one prefix) but check_ajax_referer() verified 'wwsmp-' . $plugin_sku . '-manager-security' = 'wwsmp-wwsmp-manager-security' (double prefix). Every AJAX call failed the nonce check. Aligned both sides to 'wwsmp-manager-security'.

1.2.4 (2026-07-06)

  • Fix (root cause of the empty dashboard / JSON parse error): the pro JS layer read window.wwsmp.wwsmp_nonce and window.wwsmp.wwsmp_ajax_url, but the base only set this.saCommonNonce / this.commonManagerAjaxUrl. Every pro-side AJAX request went out with security=undefined and the WordPress ajax handler exited silently on check_ajax_referer — producing an empty response and a JSON parse error in the browser. Renamed saCommonNonce → wwsmp_nonce and commonManagerAjaxUrl → wwsmp_ajax_url in both base and pro so the two sides finally agree.
  • Breaking: Continued the decoupling from the upstream StoreApps identity. All remaining sa_ / sa- / SA_ prefixes (StoreApps namespace) and wa_manager_ / WA_Manager_ library-wrapper prefixes have been renamed to wwsmp_ / wwsmp- / WWSMP_ / WWSMP_Manager_.
    • AJAX action sa_wwsmp_manager_include_file → wwsmp_manager_include_file.
    • Nonce key sa-wwsmp-manager-security → wwsmp-manager-security.
    • Class names SA_WWSMP_In_App_Offer → WWSMP_In_App_Offer, SA_WWSMP_Deactivation → WWSMP_Deactivation, WA_Manager_Controller / WA_Manager_Base / WA_Manager_Product / WA_Manager_Feedback / WA_Manager_Background_Updater → WWSMP_Manager_*.
    • Folder sa-includes/ → includes/ (both classes/ and pro/). Files class-sa-wwsmp-*.php → class-wwsmp-*.php.
    • Fixed pluginSlug = 'sm' in the JS constructor → 'wwsmp' (previously produced dead CSS classes like sm-select2 after the sm-→wwsmp- CSS rename in 1.2.1).
    • Removed dead-code SA_In_App_Offer base class (defined twice, referenced nowhere) and pro/sa-includes/class-storeapps-cache.php (unused StoreApps cache wrapper).
  • Note: This continues the breaking-change behaviour from 1.2.0-1.2.3. Options, transients and user-metas keyed on the old prefixes will be re-initialised on first load. No functional change beyond identity renaming.

1.2.3 (2026-07-06)

  • Fix: Dashboard crashed on load with You declared cell type "wwsmp.image" as a string that is not mapped to a known object from Handsontable. Root cause of the mismatch introduced in 1.2.1: common-core/class-wa-manager-product.php builds column type strings dynamically as $this->plugin_sku . '.image' — after the SKU rename in 1.2.0 that produces wwsmp.image — while assets/js/wwsmp.js was still calling Handsontable.cellTypes.registerCellType('sm.image', ...) and several pro/classes/*.php files still hardcoded 'sm.datetime', 'sm.date', 'sm.time', 'sm.multilist', 'sm.multipleImage', 'sm.longstring', 'sm.serialized', 'sm.action' as column types. All Handsontable cell-type registrations (9 in wwsmp.js) and all hardcoded 'sm.<celltype>' type strings in the pro PHP layer have been aligned to the wwsmp.<celltype> namespace produced by plugin_sku.

1.2.2 (2026-07-06)

  • Fix: Dashboard rendered as an empty grid (no columns, no rows) with TypeError: window.wwsmp.column_names_batch_update is undefined thrown from pro/wwsmp-product.js:122 during setDashboardModel. Root cause: the upstream refactor renamed the state property from column_names_batch_update (snake_case) to columnNamesBatchUpdate (camelCase) in core-base.js (assignment site), but left the legacy snake_case reads in the pro layer (pro/wwsmp.js and pro/wwsmp-product.js). The very first read threw before the grid could paint. All ~20 snake_case reads in the pro JS layer have been aligned with the actual camelCase property.

1.2.1 (2026-06-14)

  • Breaking: Continuation of the Smart Manager decoupling started in 1.2.0. All remaining sm_/sm- prefixes have been renamed to wwsmp_/wwsmp-.
    • CSS class names (sm-header, sm-base-*, sm-loader, .sm-marketplace, .sm_button, etc.) and CSS custom properties (--color-sm-base-*) renamed to wwsmp-* / --color-wwsmp-base-*.
    • DOM IDs (#sm_editor_grid, #sm_simple_search_box, #sm_nav_bar, etc.) renamed to #wwsmp_*.
    • Script/style handles (sm_custom_*, sm_pro_*, sm_beta_*) renamed to wwsmp_*.
    • PHP variables and properties starting with $sm_ / ->sm_ renamed to $wwsmp_ / ->wwsmp_.
    • JS bridge properties (window.wwsmp.sm_beta_pro, .sm_views, .sm_dashboards, .sm_nonce, etc.) renamed to .wwsmp_* on both the PHP localize side and the JS reader side.
    • Database keys (transient names, option names, custom SQL table suffixes like sm_advanced_search_temp) renamed to wwsmp_*. Existing rows keyed on the old prefix will be re-initialised on first load.
  • Note: This release continues the breaking-change behaviour from 1.2.0. After upgrading, all saved per-user state, transient caches, and the wp_sm_advanced_search_temp table contents will be re-built on first dashboard load.

1.2.0 (2026-06-14)

  • Breaking: Complete decoupling from the upstream Smart Manager identity. All runtime relations to WWSMP have been removed.
    • JS globals: window.wwsmp → window.wwsmp.
    • JS classes: WWSMP → WWSMP, WWSMPPro → WWSMPPro.
    • PHP localize variable: wwsmp_params → wwsmp_params.
    • Library classes: SaCommonManager → WWSMPCommonManager, SaErrorHandler → WWSMPErrorHandler.
    • Plugin SKU: WWSMP_SKU = 'sm' → 'wwsmp'. Plugin object key: 'wwsmp' → 'wwsmp'.
    • Hook/filter/action prefix: sa_sm_ → sa_wwsmp_. Hardcoded AJAX actions wp_ajax_sm_* and wp_ajax_wwsmp_* renamed accordingly.
  • Note: This is a breaking change. Saved per-user dashboard views, column states, transients and any other data keyed on the old sm / wwsmp prefixes will be re-initialised on first load after upgrade. CSS class names (sm-, sm_) and internal script handles (sm_custom_*) are intentionally left unchanged in this release.

1.1.6 (2026-06-11)

  • Fix: Removed two dead wp_register_script calls for pro/assets/js/wwsmp-nl-converter.js and pro/assets/js/wwsmp-url-parser.js. Those files do not exist in the package (and never existed in the upstream Smart Manager 8.87.0 source either) - the registrations only produced 404s in the browser console.
  • Fix: Auto-CSS loader was including pro/assets/css/wwsmp.css via the /pro/assets/css/*.css glob and then mangling the URL into pro/assets/css/css/wwsmp.css (the folder-path logic only handles CSS files in subfolders). Removed the top-level glob entry; wwsmp.css was already enqueued explicitly as sm_pro_main_style immediately afterwards.

1.1.5 (2026-06-11)

  • Fix: pro/assets/js/wwsmp.js referenced a non-existent global class WWSMP (left over from the initial Smart Manager → WWSMP rename pass). The actual lite base class is WWSMP, so the pro file threw ReferenceError: WWSMP is not defined at parse time and aborted before installing any Pro overrides. Renamed all references: WWSMP_Pro → WWSMPPro and WWSMP → WWSMP. This restores window.wwsmp as a proper WWSMPPro instance and fixes the cascade errors setSaveButtonState is not a function and showVariationsHtml is not a function on the products dashboard.

1.1.4 (2026-06-11)

  • Compat (PHP 8.x): Fixed Optional parameter $update_flag declared before required parameter $args is implicitly treated as a required parameter deprecation in WWSMP_Pro_Product::products_post_batch_update_db_updates(). Removed the default value on $update_flag (the method is only used as a sm_post_batch_update_db_updates filter callback, which always passes both arguments).

1.1.3 (2026-06-11)

  • Updates: Removed the manual update-checker bootstrap from the main plugin file. The proper fix lives in public/build-packages.php (findMainPluginFile() now scans only the plugin root, so it can no longer accidentally inject into bundled libraries that also carry a Plugin Name: header, such as pro/libraries/action-scheduler/action-scheduler.php). The standard auto-injection now lands in the correct file again.

1.1.2 (2026-06-11)

  • Updates: Explicitly bootstrap the WebAlive update checker (yahnis-elsts PUC + includes/UpdateChecker.php) from the main plugin file so the standard "Undersøg for opdateringer" link shows up on the Plugins screen and updates are pulled from https://updates.webalive.dk. The build pipeline's auto-injection picked the wrong header file (pro/libraries/action-scheduler/action-scheduler.php also contains a Plugin Name: header), which is why the link was missing in 1.1.1.
  • UI: Removed the legacy "Boost us with ⭐⭐⭐⭐⭐" wordpress.org review link and the obsolete "Go Pro" entry from the plugin row meta on the Plugins screen. This plugin is not listed on wordpress.org and ships as Premium (= Pro), so neither entry was meaningful.

1.1.1 (2026-06-11)

  • Compat (PHP 8.x): Silenced deprecation notices from the bundled Action Scheduler library:
    • Added #[\ReturnTypeWillChange] to ActionScheduler_DateTime::getTimestamp(), getOffset() and setTimezone() so they no longer trigger PHP 8.1+ "Return type ... should either be compatible" warnings.
    • Removed the redundant $this->scheduled_date = null; assignments in ActionScheduler_NullSchedule::__construct() / __wakeup() that triggered "Creation of dynamic property" deprecations on PHP 8.2+ (parent's private $scheduled_date already defaults to NULL).
    • as_get_datetime_object() now coalesces a null date string to 'now' before calling new DateTime(), fixing the "Passing null to parameter #1 ($datetime) of type string is deprecated" notice on PHP 8.1+.
  • Compat (PHP 8.2): Declared public $req_params = array(); on WWSMP_Pro_Views to remove the "Creation of dynamic property WWSMP_Pro_Views::$req_params is deprecated" notice.

1.1.0 (2026-06-10)

  • Fix: Fatal error Declaration of WWSMP_Pro_Base::get_export_csv() must be compatible with WWSMP_Base::get_export_csv($params = []) that crashed all admin-ajax responses for the dashboard. The Pro override now matches the base signature. This was the root cause of the dashboard hanging on the rotating loading messages ("Almost there...", "Warming things up...", "Putting everything in its right place..."): the AJAX call to sa_sm_manager_include_file returned a fatal-error 500, the JS setDashboardModel short-circuited on the empty response, and hideDashboardLoadingMessage() was never called.
  • Note: Version aligned to 1.1.0 to resolve a previous header/readme mismatch (header was 1.0.7, readme was 1.0.9).

1.0.9 (2026-05-23)

  • Compatibility: Declare support for WooCommerce High-Performance Order Storage (HPOS) and Cart/Checkout Blocks in the main bootstrap file to remove the "incompatible plugin" notice in WooCommerce 10.7+.

1.0.8 (2026-05-22)

  • Compatibility: Tested with WordPress 7.0 and WooCommerce 10.7.

1.0.7

  • Compat: Tested with WordPress 7.0 and WooCommerce 10.7.

1.0.6

  • Cleanup: Removed dead-code file pro/sa-includes/class-storeapps-upgrade-3-9.php (legacy StoreApps OAuth connector / WebAlive_Upgrade_3_9). The class was never loaded by the current bootstrap and contained an unused OAuth flow POSTing to webalive.dk/oauth/token. No functional change.

1.0.5

  • Privacy/Offline: Removed the outbound deactivation-survey HTTP call to webalive.dk in sa_submit_deactivation_reason_action(). The deactivation modal still shows and the AJAX handler still validates nonce + manage_options, but no data (domain, activation dates, reason, etc.) is sent anywhere. The handler now returns success immediately.

1.0.4

  • Updates: Plugin updates are now delivered through the WebAlive update server at https://updates.webalive.dk via the standard WebAlive update checker (yahnis-elsts PUC, auto-injected by the build pipeline). Added Update URI: header pointing at the metadata endpoint.
  • Privacy/Offline: Removed the legacy one-time wp_remote_get to webalive.dk/wp-admin/admin-ajax.php?action=check_update in pro_activated() (that endpoint was unrelated to the actual update server). The option WWSMP_PREFIX._check_update is still written/read so the call stays disabled across upgrades.

1.0.3

  • Privacy/Offline: Removed the outbound license-validation HTTP call to webalive.dk in show_upgrade_to_pro(). Since the plugin only ships as Premium (= Pro), the call served no purpose and leaked the license key + site URL on every WWSMP admin pageload. The Pro install marker is now always true and no network request is made. The behavior can be re-enabled via the wwsmp_enable_remote_license_check filter if license management is added later.

1.0.2

  • Fix: Fatal error "Class 'WebAlive_Upgrade_4_0' not found" on wp_loaded when the ported StoreApps upgrader class file is not shipped. on_wp_loaded() now verifies that the resolved upgrade class actually exists before instantiating it.

1.0.1

  • Security: AJAX request handler in WA_Manager_Controller now enforces a current_user_can('manage_woocommerce') capability check (filter wa_manager_required_capability) in addition to the existing nonce and admin-page checks.
  • Security: Top-level admin menu (add_menu_page) capability raised from read to manage_woocommerce (filter wwsmp_menu_capability).
  • Change: Pro Access Privilege option prefix renamed from legacy sm_beta_ to wwsmp_ (option name pattern is now wwsmp_{role}_accessible_dashboards). Existing per-role dashboard assignments will need to be re-saved once after upgrade.

1.0.0

  • Initial WebAlive release. Ported Smart Manager 8.87.0 codebase into a Webalive-branded plugin with PSR-4 bootstrap (WebAlive\WWSMP), webalive text domain woo-wa-stock-manager-premium, and renamed constants/classes (WWSMP_*, WWSMP). All Lite + Pro feature modules included.
© 2026 Webalive - live website