Appearance
Plus / Audience Management REST
Flow ID: AD-46 | Module(s): Plus (domain layer) | Complexity: Medium Last Updated: 2026-04-04
Business Context
The Plus module provides customer audience segmentation through a modern REST API. Audiences are named segments of customers defined by tag-based criteria. Each audience can contain multiple criteria rules that reference customer tags and tag groups, with a configurable matching logic (AND/OR).
Audiences are used by the marketing system for targeted campaigns, email lists, and personalized promotions. The criteria system allows building dynamic audience definitions like "customers tagged with 'VIP' AND 'Athens'" or "customers tagged with 'Newsletter' OR 'Active buyer'".
The audience-to-customer relationship is maintained via a many-to-many junction table (shop_customer_audience), populated by the AddCustomersToAudience scheduled job based on the audience's criteria.
API Reference
REST Endpoints -- Audience
| Method | Path | Action | Description |
|---|---|---|---|
| GET | /rest/plus/audience | index | List audiences (paginated) |
| GET | /rest/plus/audience/item | item | Get single audience by filter |
| GET | /rest/plus/audience/{id} | show | Get audience by ID |
| POST | /rest/plus/audience | store | Create an audience |
| POST | /rest/plus/audience/{id} | update | Update an audience |
| DELETE | /rest/plus/audience/{id} | destroy | Delete an audience |
Filters: id (exact), name (partial), criteriaType (exact) Sorts: id, name, creationDatetimeRelations: criteria (one_to_many), customers (many_to_many)
REST Endpoints -- AudienceCriteria
| Method | Path | Action | Description |
|---|---|---|---|
| GET | /rest/plus/audience-criteria | index | List criteria entries (paginated) |
| GET | /rest/plus/audience-criteria/item | item | Get single criteria by filter |
| GET | /rest/plus/audience-criteria/{id} | show | Get criteria by ID |
| POST | /rest/plus/audience-criteria | store | Create a criteria entry |
| POST | /rest/plus/audience-criteria/{id} | update | Update a criteria entry |
| DELETE | /rest/plus/audience-criteria/{id} | destroy | Delete a criteria entry |
Filters: id (exact), audienceId (exact), tagId (exact), groupId (exact) Sorts: id, audienceIdRelations: audience (belongs_to)
Legacy Admin Routes
No dedicated legacy admin routes for audience REST management. The legacy audience admin is in ecommercen/audience/controllers/Adv_audience_admin.php but manages audiences through a different interface.
Code Flow
Creating an Audience with Criteria
POST
/rest/plus/audiencewith:json{ "name": "VIP Athens Customers", "criteriaType": 2, "creationDatetime": "2026-04-04T10:00:00" }Controllers\Audience::store()->doStore()->WriteService::create().WriteData::fromArray()maps input toname,criteria_type,creation_datetime, etc.Validator::validateForCreate()runs (currently stub).WriteRepository::insert()inserts intoplus_audience.Returns the created audience via
Resource.POST
/rest/plus/audience-criteriafor each criteria rule:json{ "audienceId": 1, "tagId": 42, "groupId": 5, "customValue": null }Controllers\AudienceCriteria::store()inserts intoplus_audience_criteria.
Querying an Audience with Nested Data
- GET
/rest/plus/audience/1?with=criteria,customers Controllers\Audience::show(1)delegates to service.Service::get(1, ['criteria', 'customers'])fetches the audience and loads relations:criteria: ONE_TO_MANY fromplus_audience_criteriaviaaudience_idcustomers: MANY_TO_MANY fromshop_customerviashop_customer_audiencejunction table
Resourcereturns:json{ "id": 1, "name": "VIP Athens Customers", "criteriaType": 2, "creationDatetime": "2026-04-04T10:00:00", "updateDatetime": null, "userId": 1, "criteria": [...], "customers": [...] }
Domain Layer
Audience (src/Domains/Plus/Audience/)
| Component | Class | Description |
|---|---|---|
| Entity | Repository\Entity | id, name, criteria_type, creation_datetime, update_datetime, user_id |
| Repository | Repository\Repository | Table plus_audience |
| RepositoryConfigurator | Repository\RepositoryConfigurator | criteria -> AudienceCriteriaRepository (ONE_TO_MANY on audience_id), customers -> CustomerRepository (MANY_TO_MANY via shop_customer_audience) |
| Service | Service | Read service with filter/sort/pagination |
| WriteService | WriteService | Full CRUD |
| WriteData | WriteData | name, criteriaType, creationDatetime, updateDatetime, userId |
| Validator | Validator | Stub validator |
| WriteRepository | Repository\WriteRepository | Insert/update/delete |
AudienceCriteria (src/Domains/Plus/AudienceCriteria/)
| Component | Class | Description |
|---|---|---|
| Entity | Repository\Entity | id, audience_id, tag_id, group_id, custom_value |
| Repository | Repository\Repository | Table plus_audience_criteria |
| RepositoryConfigurator | Repository\RepositoryConfigurator | audience -> AudienceRepository (BELONGS_TO on audience_id) |
| Service | Service | Read service |
| WriteService | WriteService | Full CRUD |
| WriteData | WriteData | audienceId, tagId, groupId, customValue |
| Validator | Validator | Stub validator |
REST Layer (src/Rest/Plus/)
| Component | Class | Description |
|---|---|---|
| Controller | Controllers\Audience | Full CRUD with HandlesWriteActions |
| Controller | Controllers\AudienceCriteria | Full CRUD with HandlesWriteActions |
| Resource | Resources\Audience\Resource | Includes criteria (collection) and customers (collection) relations |
| Resource | Resources\AudienceCriteria\Resource | Includes audience (resource) relation |
| Collection | Resources\Audience\Collection | Paginated audience list |
| Collection | Resources\AudienceCriteria\Collection | Paginated criteria list |
| DI Container | container.php | REST controller registrations |
DI Container (src/Domains/Plus/container.php)
Registers all Audience and AudienceCriteria domain services, repositories, write services, validators, and write repositories.
Architecture
| Component | Path | Purpose |
|---|---|---|
| Domain container | src/Domains/Plus/container.php | DI registration for all Plus domain services |
| REST container | src/Rest/Plus/container.php | DI registration for REST controllers |
| REST routes | application/config/rest_routes.php:1073-1102 | Audience and AudienceCriteria routes |
| Legacy audience admin | ecommercen/audience/controllers/Adv_audience_admin.php | Legacy admin UI (separate from REST) |
| Job: populate audiences | ecommercen/job/libraries/AdvAddCustomersToAudience.php | Scheduled job to evaluate criteria and populate shop_customer_audience |
Data Model
plus_audience
| Column | Type | Description |
|---|---|---|
id | int (PK) | Auto-increment primary key |
name | varchar | Audience segment name |
criteria_type | int (nullable) | Criteria matching logic: null=ALL, 1=OR, 2=AND |
creation_datetime | datetime | When the audience was created |
update_datetime | datetime (nullable) | When the audience was last updated |
user_id | int (nullable) | Admin user who created the audience |
plus_audience_criteria
| Column | Type | Description |
|---|---|---|
id | int (PK) | Auto-increment primary key |
audience_id | int (FK) | Parent audience ID |
tag_id | int (FK) | Customer tag ID for matching |
group_id | int (FK) | Tag group ID for categorization |
custom_value | varchar (nullable) | Optional custom matching value |
shop_customer_audience (Junction Table)
| Column | Type | Description |
|---|---|---|
audience_id | int (FK) | Audience ID |
customer_id | int (FK) | Customer ID |
Configuration
No registry keys specific to audience REST. The personalization job queue must be enabled in application/config/jobs.php for the AddCustomersToAudience job to run.
| Source | Key | Description |
|---|---|---|
| Job config | jobs.personalization.enabled | Must be true for audience population jobs |
| Job config | AddCustomersToAudience | Schedule 30 3 * * * (daily at 03:30) |
Client Extension Points
- Override RepositoryConfigurator: Add custom relations (e.g., to custom tag systems).
- Override WriteService: Add custom validation or post-save hooks (e.g., trigger immediate audience population after criteria change).
- Override Resource: Add computed fields to the API response (e.g., customer count).
- Custom criteria evaluation: Override
AddCustomersToAudiencejob to add custom matching logic beyond tag-based criteria.
Business Rules
- Criteria type semantics:
null= match all criteria,1= OR logic (match any),2= AND logic (match all). - Deferred population: The
shop_customer_audiencejunction table is populated by theAddCustomersToAudiencescheduled job, not in real-time when criteria are created. - Tag-based criteria: Each criteria entry references a
tag_idandgroup_idfrom the customer tagging system. - Custom value: The
custom_valuefield allows criteria with custom matching logic beyond simple tag presence. - Many-to-many customers: The audience-customer relationship is a many-to-many -- a customer can belong to multiple audiences.
Related Flows
- AD-42 Marketing Admin -- Marketing tools that export customer segments
- AD-04 Customer Management Admin -- Customer detail shows audience memberships
- AD-15 Attributes & Tags -- Customer tag definitions used as criteria
- SY-01 Cron Framework --
AddCustomersToAudienceruns as a scheduled job