Skip to content

Slider / Slideshow Management

Flow ID: AD-21 Module(s): sliders, Slider (domain) Complexity: Medium Last Updated: 2026-04-04

Business Overview

Three-level hierarchy: Slideshow Groups -> Sliders (Slideshows) -> Slides. Supports date-based display filtering (auto-cleanup of expired slides), audience targeting for personalized campaigns, YouTube video slides alongside images, per-language content (title, subtitle, discount text, button label, image, URL), and theme classes for visual styling. Both legacy admin controllers and a modern REST API with full CRUD operate on the same data model.

The slider system is used for homepage hero banners, category page promotions, and marketing campaigns. Slides can be time-boxed (scheduled start/end dates) and audience-targeted, making them a key tool for personalized merchandising.

API Reference

REST Endpoints (Modern Layer)

Group Endpoints:

MethodPathControllerDescription
GET/rest/slider/groupAdvisable\Rest\Slider\Controllers\Group::indexList all groups (paginated, filterable)
GET/rest/slider/group/itemGroup::itemGet single group by filter
GET/rest/slider/group/{id}Group::showSingle group
POST/rest/slider/groupGroup::storeCreate group
POST/rest/slider/group/{id}Group::updateUpdate group
DELETE/rest/slider/group/{id}Group::destroyDelete group

Slider (Slideshow) Endpoints:

MethodPathControllerDescription
GET/rest/slider/sliderAdvisable\Rest\Slider\Controllers\Slider::indexList all sliders (paginated, filterable)
GET/rest/slider/slider/itemSlider::itemGet single slider by filter
GET/rest/slider/slider/{id}Slider::showSingle slider with translations
POST/rest/slider/sliderSlider::storeCreate slider (with MUI translations)
POST/rest/slider/slider/{id}Slider::updateUpdate slider
DELETE/rest/slider/slider/{id}Slider::destroyDelete slider

Slide Endpoints:

MethodPathControllerDescription
GET/rest/slider/slideAdvisable\Rest\Slider\Controllers\Slide::indexList all slides (paginated, filterable)
GET/rest/slider/slide/itemSlide::itemGet single slide by filter
GET/rest/slider/slide/{id}Slide::showSingle slide with translations
POST/rest/slider/slideSlide::storeCreate slide (with MUI translations)
POST/rest/slider/slide/{id}Slide::updateUpdate slide
DELETE/rest/slider/slide/{id}Slide::destroyDelete slide

All endpoints also support language-prefixed routes: /{lang}/rest/slider/... (e.g., /el/rest/slider/slide).

Total: 18 REST endpoints (6 per entity x 3 entities), each duplicated with language prefix = 36 route entries.

Legacy Admin Routes

RouteControllerDescription
sliders/slide_adminAdv_slide_adminSlide CRUD, image upload, YouTube, ordering
sliders/sliders_adminAdv_sliders_adminSlider CRUD, slide assignment
sliders/slideshow_groups_adminAdv_slideshow_groups_adminMinimal UI shell for group management
sliders/slideshow_groups_admin/api/*AdvApiSlideshowGroupsEditorAdminREST-style API for group editor Vue component

Code Flow

Slide Creation via REST API

POST /rest/slider/slide
  |-- HandlesWriteActions::doStore()
  |     |-- Parse JSON body
  |     |-- WriteData::fromArray($data)
  |     |     |-- Map camelCase -> snake_case fields
  |     |     |-- audienceId, showButton, dateStart, dateEnd, themeClass, order
  |     |-- Validator::validateStore($writeData)
  |     |     \-- themeClass is required on create
  |     |-- WriteService::store($writeData)
  |     |     |-- WriteRepository::insert($writeData->toArray())
  |     |     |-- If translations provided:
  |     |     |     \-- MuiWriteRepository::insertMany($translations)
  |     |     \-- Return created entity
  |     \-- Return Resource with 201 status

Slide Display on Frontend (Date + Audience Filtering)

Adv_sliders_model::getSliderSlides($sliderId)
  |-- Query: slider_slides JOIN slide JOIN slide_mui
  |-- Date filter: NOW() BETWEEN date_start AND date_end (or dates are NULL)
  |-- Auto-cleanup: expired slides removed from slider_slides on fetch
  |-- Audience filter: slide.audience_id checked against customer audiences
  |     |-- EntityCustomerAudienceCheck::audiencesCheck($customerAudiences, $audienceId)
  |     |     |-- NULL audience_id -> show to all
  |     |     |-- criteria_type ALL (null) -> show to all
  |     |     |-- No criteria -> show to all
  |     |     \-- Check: in_array($audienceId, $customerAudiences)
  |-- Order: slide.order ASC
  \-- Limit: slider.slides_num (if set)

Group Management (Vue Component + API)

AdvApiSlideshowGroupsEditorAdmin
  |-- index(): GET all groups with slider count + view metrics
  |-- store(): POST create group (name + created_at)
  |-- update($id): POST update group name
  |-- destroy($id): DELETE group
  |     |-- Nullify slider.group_id and slider.group_order for orphaned sliders
  |     \-- Delete from slideshow_groups
  |-- updateOrder(): POST reorder sliders within a group
  |     \-- Batch update slider.group_order based on position array

YouTube Thumbnail Download

Adv_slide_admin::saveYoutubeThumbnail($youtubeId)
  |-- Try: download maxresdefault.jpg from YouTube
  |-- Fallback: download hqdefault.jpg if maxres not available
  |-- Save to files/sliders/ directory
  \-- Return filename for slide_mui.image field

Domain Layer

Modern Domain (src/Domains/Slider/)

Slide Entity:

FileDescription
Slide/Repository/Entity.phpProperties: id, audience_id, show_button, date_start, date_end, theme_class, order. Implements FilterTranslation.
Slide/Repository/MuiEntity.phpMUI properties: id, slide_id, url, title, subtitle, discount, button_label, color_inverse, image, lang, descr, media_type, youtube_id
Slide/Repository/Repository.phpBaseRepository with translation filtering
Slide/Repository/MuiRepository.phpBaseMuiRepository for slide_mui
Slide/Repository/WriteRepository.phpInsert/update for slide table
Slide/Repository/MuiWriteRepository.phpInsert/update for slide_mui table
Slide/Repository/RepositoryConfigurator.phpTable name, relations, default includes
Slide/Repository/Specification/FilterByTranslation.phpFilter slides by MUI fields
Slide/Repository/Specification/SortByTranslation.phpSort slides by MUI fields
Slide/Service.phpRead operations: match (paginated list), get (single)
Slide/WriteService.phpWrite operations: store, update, destroy
Slide/WriteData.phpValue object: audienceId, showButton, dateStart, dateEnd, themeClass, order. OpenAPI-annotated.
Slide/MuiWriteData.phpTranslation value object for slide_mui fields
Slide/Validator.phpValidates required fields (themeClass on create)
Slide/ListRequest.phpFilter/sort/pagination params

Slider Entity:

FileDescription
Slider/Repository/Entity.phpProperties: id, name, group_id, group_order, slides_num. Implements FilterTranslation.
Slider/Repository/MuiEntity.phpMUI properties: id, slider_id, url, title, image, descr, lang
Slider/Repository/Repository.phpBaseRepository with translation filtering
Slider/Repository/MuiRepository.phpBaseMuiRepository for slider_mui
Slider/Repository/WriteRepository.phpInsert/update for slider table
Slider/Repository/MuiWriteRepository.phpInsert/update for slider_mui table
Slider/Service.phpRead operations
Slider/WriteService.phpWrite operations
Slider/WriteData.phpValue object: name, groupId, groupOrder, slidesNum. OpenAPI-annotated.
Slider/MuiWriteData.phpTranslation value object for slider_mui fields
Slider/Validator.phpValidates required fields (name on create)

Group Entity:

FileDescription
Group/Repository/Entity.phpProperties: id, name, created_at
Group/Repository/Repository.phpBaseRepository
Group/Repository/WriteRepository.phpInsert/update for slideshow_groups
Group/Service.phpRead operations
Group/WriteService.phpWrite operations
Group/WriteData.phpValue object: name, createdAt. OpenAPI-annotated.
Group/Validator.phpValidates required fields

DI Container:

  • Domain: src/Domains/Slider/container.php
  • REST: src/Rest/Slider/container.php

REST Controllers (src/Rest/Slider/Controllers/)

FileDescription
Group.phpExtends HandlesRestfulActions + uses HandlesWriteActions. CRUD for slideshow groups.
Slider.phpExtends HandlesRestfulActions + uses HandlesWriteActions. CRUD for sliders with MUI.
Slide.phpExtends HandlesRestfulActions + uses HandlesWriteActions. CRUD for slides with MUI.

REST Resources (src/Rest/Slider/Resources/)

FileDescription
Group/Resource.php / Collection.phpGroup resource transformation
Slider/Resource.php / Collection.phpSlider resource
Slider/MuiResource.php / MuiCollection.phpSlider translations
Slide/Resource.php / Collection.phpSlide resource
Slide/MuiResource.php / MuiCollection.phpSlide translations

Legacy Admin Controllers (ecommercen/eshop/controllers/ or ecommercen/sliders/)

FileLinesDescription
Adv_slide_admin.php~516Slide CRUD: create/edit with image upload and YouTube support, ordering via drag-and-drop, audience targeting assignment
Adv_sliders_admin.php~277Slider CRUD: create/edit named slideshows, assign/remove slides, manage slide order within slider
AdvApiSlideshowGroupsEditorAdmin.php~240REST-style API for Vue-based group editor: CRUD + reorder, with view metrics integration
Adv_slideshow_groups_admin.php~18Minimal UI shell -- loads Vue component that calls the API controller

Architecture

Entity Hierarchy

Slideshow Group (slideshow_groups)
  |-- 1:N --> Slider (slider)  [via slider.group_id]
                |-- N:N --> Slide (slide)  [via slider_slides junction]
                |             |-- 1:N --> Slide MUI (slide_mui)  [per-language content]
                |-- 1:N --> Slider MUI (slider_mui)  [per-language metadata]

Key Features

  • Date filtering: Slides only display if NOW() >= date_start AND NOW() <= date_end (or dates are NULL). Expired slides are auto-removed from slider_slides junction table on fetch.
  • Audience targeting: Each slide has an optional audience_id FK. Frontend filtering uses EntityCustomerAudienceCheck trait to verify customer membership.
  • YouTube support: slide_mui.media_type (0=image, 1=youtube) + slide_mui.youtube_id. Thumbnail auto-downloaded from YouTube (tries maxresdefault, falls back to hqdefault). Added via migration 20251229133112.
  • Drag-and-drop ordering: Slides within sliders use slide.order field. Sliders within groups use slider.group_order field. Both support AJAX reorder.
  • Cache: PSCache invalidation on any modification (clearCache('sliders')).
  • Theme classes: slide.theme_class (0=default, 1=light, 2=dark) controls visual styling.
  • Blog integration: Blogs can reference a slider_id for embedded slideshows (added via migration 20260224114108).

Data Model

slide Table

ColumnTypeDescription
idINT(10) PK AISlide ID
audience_idINT(11) NULLFK to audience.id for targeting
show_buttonTINYINT(1) DEFAULT 1Whether to show CTA button
date_startDATETIME NULLScheduled start date
date_endDATETIME NULLScheduled end date
theme_classTINYINT(4)Theme: 0=default, 1=light, 2=dark
orderINT(10) NULLDisplay order within slider

Index: audience_id.

slide_mui Table

ColumnTypeDescription
idINT(10) PK AITranslation ID
slide_idINT(10)FK to slide.id
urlTEXTCTA link URL
titleVARCHAR(280) NULLSlide title
subtitleVARCHAR(255) NULLSlide subtitle
discountVARCHAR(255) NULLDiscount text overlay
button_labelVARCHAR(150) NULLCTA button label
color_inverseTINYINT(1) DEFAULT 0Invert text color
imageTEXTImage filename
media_typeINT DEFAULT 00=image, 1=youtube
youtube_idVARCHAR(20) NULLYouTube video ID
langVARCHAR(2)Language abbreviation
descrVARCHAR(400)Description text

Indexes: slide_id, lang, (slide_id, lang).

slider Table

ColumnTypeDescription
idINT(10) PK AISlider ID
nameVARCHAR(100)Internal name
slides_numINT(10) NULLMax slides to display
group_idINT(11) NULLFK to slideshow_groups.id
group_orderINT(11) NULLOrder within group

slider_mui Table

ColumnTypeDescription
idINT(10) PK AITranslation ID
slider_idINT(10)FK to slider.id
urlTEXT NULLSlider-level URL
titleVARCHAR(280) NULLSlider title
imageTEXT NULLSlider image
descrMEDIUMTEXT NULLSlider description (enlarged via migration 20241025134613)
langVARCHAR(2)Language abbreviation

Indexes: slider_id, lang, (slider_id, lang).

slider_slides Junction Table

ColumnTypeDescription
slider_idINT(10)FK to slider.id
slide_idINT(10)FK to slide.id

Indexes: slide_id, slider_id, (slider_id, slide_id).

slideshow_groups Table

ColumnTypeDescription
idINT(11) PK AIGroup ID
nameVARCHAR(255)Group name
created_atDATETIMECreation timestamp
MigrationDescription
20241025134613_change_slider_descr_type_medium_text.phpslider_mui.descr changed from VARCHAR(400) to MEDIUMTEXT
20251229133112_add_youtube_support_to_slide.phpAdded media_type (INT) and youtube_id (VARCHAR(20)) to slide_mui
20260224114108_blog_slider.phpAdded slider_id column to blog table for embedded slideshows

Configuration

  • Cache key: sliders -- invalidated via clearCache('sliders') on any slider/slide modification.
  • Image upload directory: files/sliders/ for uploaded slide images and YouTube thumbnails.
  • Audience targeting: Requires SMART_RECOMMENDATIONS.IS_ENABLED_CUSTOMER_TAG registry value to be enabled.
  • DI modules: Registered in application/config/container/modules.php.

Client Extension Points

  • Legacy controllers can be overridden in client repos by placing same-named files in application/controllers/.
  • REST controllers can be overridden via DI alias in custom/Rest/Slider/container.php.
  • Domain services can be extended via Custom\Domains\Slider\* with DI aliases.
  • Additional slide fields can be added via migrations + MuiEntity extension in client repos.

Business Rules

RuleImplementation
Slider deletion blocked if slides are linkedcan_delete_record() check in legacy model
Group deletion orphans slidersNullifies group_id and group_order on child sliders
Date auto-cleanupExpired slides removed from slider_slides junction on fetch
Audience + date combinedFrontend filters by both date range AND customer audience membership
YouTube thumbnail fallbackTries maxresdefault.jpg, falls back to hqdefault.jpg
Slides_num limitIf slider.slides_num is set, only the first N ordered slides are shown
Multi-language imagesEach language can have a different image via slide_mui.image
Order fieldslide.order for within-slider; slider.group_order for within-group