Skip to content

MelisSmallBusiness

Editorial-team add-on for the CMS — user roles, a validation workflow, page versioning, comments and page locking, plus a TinyMCE media library, surfaced through the React back-office. Package melisplatform/melis-small-business.

Purpose

MelisSmallBusiness layers small-team collaboration tooling on top of the CMS page editor. It keeps versions of published pages (restore/preview an earlier state), drives a content workflow where an editor asks for validation and a reviewer validates or refuses it, attaches comments to pages, prevents two users from editing the same page at once through a page lock, manages a custom user role tool, and ships a TinyMCE-based media library (MoxieManager). Business logic stays server-side (Laminas services, CMS-editor events); in v6 the whole user-facing surface is a set of React bricks and modular contributions.

Enable it

This is a standard Laminas module. Add it to config/melis.module.load.php:

php
return [
    // …
    'MelisSmallBusiness',
];

It depends on melis-core, melis-engine, melis-front and melis-cms, and its tables are created via dbdeploy (extra.dbdeploy = true). Each React surface below appears only when the module is active (brick discovery via GET /melis/react-api/react-modules).

React surfaces

In the React back-office (/melis-react) the module ships two bricks and two modular contributions that have no route of their own.

SurfaceKindRoute / host
User Roles (smallbusiness)native full-React (New/Old toggle)/melis-core/user-roles
Media library (smallbusiness-medialib)iframe brick (MoxieManager)/melis-cms/media-library
Workflow modalshared modal (window.__melisWorkflowModal)rendered by News / Blog / CMS page editor / Newsletter + Dashboard widget
Versioning / Comments / Locktabs + banner in the CMS page editorcontributed to the meliscms_page capability node
Role in UsersRole column/filter/selectorhost Users tool, gated by useModuleActive('MelisSmallBusiness')

public/ui-react/brick.manifest.json declares both bricks; ui-react/src/brick.tsx registers them and publishes the Workflow modal as a window global so other bricks can render a single shared implementation.

User Roles tool

Where: sidebar → MelisCore → User Roles (/melis-core/user-roles).

A role is a named rights profile stored once (melis_core_user_role) and assigned to many users. The list shows every role with KPI cards (Roles / Assigned), search, a Columns manager, Export and a New / Old toggle (Old = the classic tool in an iframe). Each row (ID, Name, Created, Users count) has edit/delete actions; a role assigned to users cannot be deleted.

Roles list in the React back-office

Editing a role opens a sub-tab with a Role name field and an Access rights tree that mirrors the Users rights tree (TOOLS grouped by section, per-tool List/Create/Edit/Delete/Export, plus the Pages and Dashboard-plugins sections). Save persists the name and the urole_rights XML.

Role editor and its rights tree

WARNING

Writing a role's rights XML requires a platform administrator (usr_admin); a non-admin editing a role gets a 403 on the rights write. This blocks a privilege-escalation path (forging an all-rights role, then self-assigning it). The role name can be changed by anyone with the tool's edit right.

Role in the Users tool

When the module is active, the MelisCore Users tool gains a Role column + filter in the list and a Role selector in the user form (alongside Status and Rights). The dropdown is fed by GET /melis/react-api/roles (the MelisCore selector list); on save, a listener re-injects the role's capabilities so they are not lost.

User form with the Role selector

Media library

Where: sidebar → MelisCms → Media library (/melis-cms/media-library).

The advanced TinyMCE / MoxieManager file browser: folders on the left, files on the right (name, size, type, date), with Create, Upload, list/grid view, Sort, Filter and Favorites/History/ Uploaded shortcuts. The React page is a thin wrapper rendering a full-tab iframe to the legacy moxiemanager (/melis/MelisSmallBusiness/js/tinyMCE/moxiemanager/index.php?lang=xx), so behaviour is identical to the classic tool — no react-api of its own.

Media library — MoxieManager browser in a React tab

Workflow (page validation)

The Workflow lets an editor ask for validation and a validator answer. The same modal opens from the CMS page editor (Workflow button), the News and Blog editors, and the Dashboard widget. It is generic over the item type — PAGE, NEWS, BLOG.

Under Ask for validation, pick a Role to notify everyone with that role, or "1 person only" to reveal a User dropdown and target a single person, then Send request.

Workflow modal — ask a single person

The modal's History lists every demand and answer (Date, Status, To/Role, From, Action). A recipient of an open demand gets Validate / Refuse buttons and may attach a note.

Workflow modal — history with Validate/Refuse

The back-office Dashboard shows a Workflow widget listing demands, split into Users' demands / My demands with PAGE / NEWS sub-tabs; each row shows a status pill (VALIDATED / REFUSED / Demand) and offers inline validate (✓) / refuse (✗) and preview actions on demands addressed to you.

Dashboard Workflow widget

Versioning & Comments (CMS page editor)

Opening a page in the CMS editor adds two SmallBusiness tabs after the native ones:

  • Versioning — a paged list of the page's snapshots (No., Name, Modified on, By) with per-row View / Restore / Rename. A snapshot is taken on each publish.

    Page editor — Versioning tab

  • Comments — the page's activity timeline mixing user comments and workflow events (newest first), with an "Add a comment" box.

    Page editor — Comments tab

A page lock banner + Unlock button appear when another user holds the lock on the page.

react-api endpoints

All under /melis/react-api/…, contract { success, data, error }. The controllers live in this module (config/react-api.php + src/Controller/MelisReactApi*Controller.php).

ControllerBase routesGuard
MelisReactApiRoleControllerGET /user-roles, /user-roles/stats, /user-roles/:id; POST /user-roles/save; DELETE /user-roles/delete/:idmelissb_tool_userrole access + capability (rights XML write = admin-only)
MelisReactApiWorkflowControllerGET /workflow/roles, /workflow/users, /workflow/history; POST /workflow/askauth-only
MelisReactApiPageVersioningControllerGET /cms-page/versioningauth-only
MelisReactApiPageCommentsControllerGET /cms-page/comments, /cms-page/timeline; POST /cms-page/comments/saveauth-only
MelisReactApiPageLockControllerGET /cms-page/lock; POST /cms-page/unlockauth-only

Workflow mutations reuse the proven legacy endpoints rather than react-api: GET /melis/MelisSmallBusiness/MelisWorkflow/saveWorkflowActions (validate / refuse) and POST /melis/MelisSmallBusiness/MelisWorkflow/addWorkflowComments (add a note). Comment text is HTMLPurifier-sanitised on save.

Capabilities

config/react.capabilities.php contributes the page-editor button + tabs under the shared meliscms_page key owned by MelisCms (merged, so MelisCms need not know about SB):

KindKeyLabel
actionworkflowWorkflow button
actionunlockUnlock button
tabmelissb_page_versioningVersioning tab
tabmelissb_page_commentsComments tab

CmsPage.tsx filters those tabs / hides those buttons via useCaps('meliscms_page').can(cap). The Roles tool itself is keyed under melissb_tool_userrole and the Media library under melissb_medialib.

Database tables

Created by install/dbdeploy/126618_melis_sb_install.sql.

TableRole
melis_sb_page_versioningArchived copies of published pages (backs the Versioning tab).
melis_sb_workflowWorkflow records per item.
melis_sb_workflow_eventsWorkflow events (ask / validate / refuse).
melis_sb_page_commentComments attached to a page (comment type 1 = PAGE, 2 = WORKFLOW).
melis_sb_page_comment_typeComment types.
melis_sb_page_lockedActive page locks (which user is editing which page).
melis_core_user_roleNamed roles (urole_id, urole_name, urole_creation_date, urole_rights XML).

Key services

Service aliasRole
MelisEnginePageThe module overrides the engine's page service with MelisSBPageService; on the version-preview route it returns the versioned tree from melis_sb_page_versioning, otherwise it behaves like the parent.
MelisSBPageCommentServicePage comments: getPageComments() / setPageComments().

WARNING

By aliasing MelisEnginePage to its own class, this module replaces the core page service for the whole application while it is enabled. Keep that in mind when ordering modules.

The workflow sends three back-office emails (app.emails.php): WF_DEMAND, WF_VALIDATED, WF_REFUSED (tags USER_TO, USER_FROM, TYPE, DETAILS).

Key files

ConcernPath
Module bootstrap & listenerssrc/Module.php, src/Listener/
react-api routes + invokablesconfig/react-api.php
react-api controllerssrc/Controller/MelisReactApi{Role,Workflow,PageVersioning,PageComments,PageLock}Controller.php
Capabilities contributionconfig/react.capabilities.php
Page service (engine override)src/Service/MelisSBPageService.php
Comment servicesrc/Service/MelisSBPageCommentService.php
React bricks (source)ui-react/src/ (brick.tsx, UserRolePage.tsx, MediaLibraryPage.tsx, WorkflowModal.tsx, RolesRightsTree.tsx)
Built bundlepublic/ui-react/brick.js + brick.manifest.json
Install SQLinstall/dbdeploy/126618_melis_sb_install.sql