CMS Framework - v2.3.0
CMS Framework Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Added
Changed
Deprecated
Removed
Fixed
Security
[2.3.0] - 2026-07-09
Added
-
AI content-authoring agents (#170, #171, #172, #173, #174, #175) — Five new agents built on the
artisanpack-ui/aiv1.0 foundation:PostTitleSuggestionAgent(cms.post_title) — generate 3–5 title variants from a draft body.ExcerptGenerationAgent(cms.excerpt) — generate a natural excerpt (default ≤200 chars) from full post content.TagSuggestionAgent(cms.suggest_tags) — pick tags from an existing taxonomy, optionally propose new ones.CategorySuggestionAgent(cms.suggest_category) — pick one category (slash-delimited path) from a hierarchical tree.SlugSuggestionAgent(cms.suggest_slug) — produce an SEO-friendly kebab-case slug from a title, delegating ASCII folding toStr::slug().
Every agent honors the
artisanpack.ai.features.<key>.enabledtoggle and is auto-discovered viaCMSFrameworkServiceProvider::aiFeatures(). -
AI trigger surfaces — two consumer surfaces expose the same five agents:
- Livewire component
ap-cms-ai-tools(ArtisanPackUI\CMSFramework\Livewire\Ai\AiTools) — dispatchap-cms-ai:{action}browser events, receive results onap-cms-ai:{featureKey}:{status}. - REST controller mounted at
/api/v1/cms/ai/*(ArtisanPackUI\CMSFramework\Http\Controllers\Ai\AiController) — framework-agnostic path for React, Vue, or any HTTP client. Endpoints are guarded byauth:sanctumso bearer-token SPAs can authenticate. Adding a new CMS AI feature never requires touching the@artisanpack-ui/reactor@artisanpack-ui/vuepackages.
- Livewire component
-
AI_FEATURE_KEYSconstant onCMSFrameworkServiceProvider— canonical list of the fivecms.*feature keys, consumed by both trigger surfaces.
Changed
- Minimum PHP raised to 8.3 (#175) — the
artisanpack-ui/aifoundation this release depends on requires PHP 8.3+, and running a Composer resolution across the two constraints is not possible on PHP 8.2. Hosts still on PHP 8.2 should stay on the 2.2.x line until they can upgrade the runtime. No API changes; the codebase itself does not yet require 8.3-only syntax. - Dependencies —
artisanpack-ui/ai ^1.0added assuggest+require-dev. Without it the AI Livewire component and REST routes stay unregistered and the framework boots normally.
[2.2.3] - 2026-06-14
Changed
- Widened
laravel/tinkerconstraint to allow v3 (#167, #168) —composer.jsonrequire.laravel/tinkeris now^2.10.1|^3.0.laravel/tinkerv2 caps atilluminate/* ^12.0, so Laravel 13 consumer apps requirelaravel/tinker ^3.0; the previous pin blocked the upgrade even though the framework constraint already permitted Laravel 13. No code changes —tinkeris not referenced insrc/ortests/. Existing Laravel 12 users onlaravel/tinker ^2.10.1are unaffected.
[2.2.2] - 2026-06-09
Added
- Laravel 13 support (#161) — Widened the
illuminate/supportandlaravel/frameworkconstraints to additionally allow^13.0. Existing users on Laravel 12 are unaffected; Laravel 13 is only selectable on PHP 8.3+ because Laravel 13's ownphpconstraint enforces it, so no PHP-floor bump is required for users staying on Laravel 12.
[2.2.1] - 2026-06-07
Fixed
update:performcommand--versionflag collision (#162, #163) — Symfony Console reserves--version/-Vas a global flag on everyApplication, so declaring--versiononPerformUpdateCommandthrew "An option named version already exists" at command-registration time, breaking everyphp artisan ...invocation in host apps as soon as the command was discoverable. Renamed the custom option to--target-version(and updated the corresponding$this->option()lookup). Added a regression test that verifies the command exposes--target-versionand does not redeclare--versionon its own definition.
[2.2.0] - 2026-06-04
Added
Post::previous_postandPost::next_postaccessors (#154, #157) — published-adjacent post lookups so theartisanpack-ui/visual-editorPostResolvercan stamp navigation block payloads. Lookup is ordered bypublished_at, withidas a deterministic tie-breaker when timestamps collide.HasRenderedBlockContentconcern onPostandPage(#155, #156) — exposes arendered_contentaccessor soPostResolverinartisanpack-ui/visual-editorcan stamp the_resolvedContentHTML payload directly from the model.- "Using with the visual editor" README section (#150, #159) — documents the opt-in bridge to the
artisanpack-ui/visual-editorpackage, including theblock_contentcolumn,HasBlockContentpolyfill,_resolved*attribute flow, and the newprevious_post/next_post/rendered_contentaccessors.
Security
- Hardened CI and release GitHub Actions workflows (#140, #158) — added least-privilege
permissions:blocks to.github/workflows/ci.ymland.github/workflows/release.ymlso workflow tokens no longer inherit broad write scopes by default.
[2.1.0] - 2026-06-02
Added
- Comments submodule for the Blog module (#151):
Commentmodel withpost_id,parent_idthreading, optionaluser_id, guest author fields (author_name,author_email,author_url),content,status(pending/approved/spam/trash), andapproved_attimestamp; soft-deletablepost_commentsmigration with indexes for post, parent, status, and approved-at lookupsPostmodel gainscomments()(approved-only, newest-first) andcommentsIncludingUnapproved()relations, pluscomments_countandcomments_urlaccessors for visual-editor integration- REST endpoints under
/api/v1/comments— publicGET(index,show) returns the approved set, publicPOSTcreates apendingcomment for guests, andPUT/PATCH/DELETEare auth-gated CommentRequestform request with separatestore/updaterule sets and guest-vs-authenticated branchingCommentResourceAPI resource shaping the response payload — mirrors the shapeCommentResolverreads inartisanpack-ui/visual-editorto stamp_resolved*attributes onartisanpack/comment-*blocksCommentPolicywith hookable abilities and acomments.create.publicfilter that defaults to allowCommentFactorywithpending/approved/spam/trash/guest/forPost/replyTostates
- Public
POST /api/v1/commentsrate limiting —BlogServiceProvider::registerCommentsRateLimiter()registers athrottle:commentsnamed limiter that defaults to 10/min for guests (keyed by IP) and 60/min for authenticated users (keyed by user id). Both buckets are overridable via thecomments.rate-limit.guestandcomments.rate-limit.authenticatedhooks filters.
Security
- Public, unauthenticated
POST /api/v1/commentsis rate-limited by default (see Added) to keep guest commenters from bulk-inserting againstpost_comments.
[2.0.0] - 2026-05-26
Added
- SiteEditor module — entirely new module providing the back-end for a WordPress-style site editor experience:
- H0 — extended
theme.jsonschema covering settings, styles, templates, parts, patterns, andmenus.locations - H1 — Templates + template-parts:
TemplateandTemplatePartmodels,TemplateResolver/TemplatePartResolvermerging theme-shipped files with DB user customizations, REST endpoints returning WP/wp/v2/templatesand/wp/v2/template-partsshape, withap.visual-editor.templatesandap.visual-editor.template-partsfilter registration behindclass_existsguards - H2 — Patterns:
BlockPatternmodel +block_patternstable,PatternResolvermerging theme.phppattern files with user-source DB rows, REST endpoints under/api/v1/blocks(synced) and/api/v1/block-patterns/patterns(unsynced) returning WP-shape payloads, andap.visual-editor.patternsfilter registration behind aclass_existsguard PatternFileParserfor theme-shipped pattern files with WP-style header doc-comments (Title:,Slug:,Categories:,Description:,Block Types:)- H3 — Global styles:
GlobalStylesmodel +global_stylestable (singleton-per-theme),GlobalStylesResolverdeep-mergingtheme.jsondefaults with theme-shipped variation files (themes/{active}/styles/{slug}.json) and DB user customization,GlobalStylesEmittertranslating the resolved tree into--wp--preset--*custom properties + per-element CSS rules with content-hash cache invalidation on model save/delete, REST endpoints under/api/v1/global-styles(GET / PUT / DELETE / variations / css) returning WP/wp/v2/global-stylesshape,@cmsGlobalStylesBlade directive for front-end head injection, andap.visual-editor.global-stylessingleton filter registration behind aclass_existsguard - H4 — Menus:
Menu,MenuItem, andMenuLocationAssignmentmodels with REST endpoints for menus, menu items, and theme-declared menu locations
- H0 — extended
- Visual editor integration — opt-in bridge to the optional
artisanpack-ui/visual-editorpackage:block_contentJSON column onpostsandpagestables for visual editor block trees, alongside the existingcontentlongText columnPostandPagemodels adoptArtisanPackUI\VisualEditor\Concerns\HasBlockContentwith a polyfill stub so visual-editor remains an optional integration rather than a hard composer dependency- Auto-registration of
HasBlockContentcontent types into theap.visual-editor.resourcesfilter, plus explicit registration ofPostandPage - Registration of
visual_editor.*permissions when visual-editor is installed
- QueryRuntime service (G4c-1) for resolving
core/queryblock loops at render time - Site settings —
site.*settings registered with a WP-shape/api/v1/settings/siteendpoint and a by-key save path that applies sanitizers and types - Themes lifecycle:
installFromZip()API andPOST /v1/themesupload route for installing themes from a ZIP archive- Strict manifest schema enforcement for theme installs (
WpThemeJsonValidator+WpThemeJsonValidationResult) - Theme lifecycle hooks fired on install and activate
- Updates:
GitLabUpdateSourcenow supports release-asset download URLs in addition to tarball URLs
Changed
- RBAC migration (Wave 4) — the Users module's bundled
Role,Permission,HasRolesAndPermissions, and RBAC migrations have been removed and replaced by composition over the sharedartisanpack-ui/rbacpackage. The cms-framework classes remain at the same paths and subclass the rbac base, so existing imports keep working. See UPGRADE-RBAC.md for migration details. - Relaxed
artisanpack-ui/securityconstraint to allow^2.0in addition to^1.0.3 RolesTableSeederandPermissionsTableSeederare now opt-in; the defaultDatabaseSeederonly runsSettingsTableSeederrolesandpermissionsschemas now expose adescriptioncolumn (via the rbac base schema)- New
role:route middleware alias pairs with rbac'spermission:alias
Fixed
HasFeaturedImagecontent-type trait rewritten to use thefeatureablespivot table (replacing the legacy direct column reference)- Site editor REST routes now use
auth:sanctumso REST clients can pass Bearer tokens - Template parts now accept
navigation-overlayas a valid area; the legacygeneralarea was renamed touncategorizedto match WP core (Keystone #55) UpdateInfo->sha256is now populated from GitLab releasesUsersAPI routes (users,roles,permissions,users/bulk) are now gated behind theauthmiddleware (bug fix #129)PermissionControllernow callsauthorizeResource()so it consultsPermissionPolicylike every other controller in the framework (bug fix #127)PermissionPolicymethods now takeAuthenticatable $user(Laravel's standard signature) instead ofstring|int $id(bug fix #128)- Bulk settings updates wrapped in a DB transaction
- Schema-guarded
ap.visual-editor.*filter callbacks against missing tables PostandPage$fillableno longer includeblock_content(block trees flow through the visual-editor pipeline, not mass assignment)PatternFileParserregexes are now anchored
Removed
- Bundled
Rolemodel,Permissionmodel,HasRolesAndPermissionstrait implementation, and the three RBAC migrations (create_roles_table,create_permissions_table,create_user_role_permission_pivots) — superseded byartisanpack-ui/rbac. The class/trait names are preserved as subclasses for backward compatibility.
Migration / Upgrade
See UPGRADE-RBAC.md for the full upgrade guide. For most apps, the upgrade is composer require artisanpack-ui/rbac:^0.1 && php artisan migrate.
[1.1.0] - 2026-04-06
Added
- Bulk action API endpoints for posts, pages, and users (publish, unpublish, trash, restore, delete)
- OpenAPI specification generation for all API endpoints via Scramble
includequery parameter for on-demand relationship loading across API endpoints- TypeScript type definitions for all API responses and models
- GitHub Actions CI workflow with lint and test jobs
- GitHub Actions release workflow with changelog-based release notes and Packagist integration
- Claude Code and Claude Code Review GitHub Actions workflows
- Auto-assign milestone workflow for new issues
- GitHub issue and pull request templates
Changed
- Standardized JSON error response format across all API endpoints
- Extracted shared manifest parsing and discovery logic into
HasManifestParsingtrait - Extracted shared content query and filter logic into reusable traits
- Converted
UpdateInfo::hasUpdatefrom stored state to a computed method - Replaced magic strings with enums:
ContentStatus,SettingType,FieldType,ColumnType,UpdateType - Hoisted policy and permission resolution before loops in bulk actions
- Added php-cs-fixer and ran code style formatting across the package
- Updated PHP version requirement to 8.4 for CI
- Migrated repository from GitLab to GitHub
Fixed
- Sanitized error responses and normalized
published_atin bulk actions - Corrected LIKE wildcard escaping order and added ESCAPE clause
- Hardened URL parsing and cache serialization in update sources
- Fixed incorrect
@since 2.0.0tags to@since 1.0.0in update test files
[1.0.1] - 2026-01-09
Added
- Support for the core ArtisanPack UI package in the service provider
Changed
- Updated config settings names across controllers, models, policies, and tests for consistency
[1.0.0] - 2026-01-02
Added
- Configuration publishing for module-specific configs
- Plugins config:
php artisan vendor:publish --tag=cms-plugins-config - Themes config:
php artisan vendor:publish --tag=cms-themes-config - Updates config:
php artisan vendor:publish --tag=cms-updates-config
- Plugins config:
Changed
- Moved developer documentation to
docs/developer/directorySKIPPED_TESTS.md→docs/developer/Skipped-Tests.mdCOVERAGE.md→docs/developer/Test-Coverage.md
- Updated documentation to reflect PHP 8.2 and Laravel 12 requirements
Fixed
- Replaced deprecated
mime_content_type()withfinfo_file()in PluginManager - Fixed code style inconsistency in PluginManager exception handling
- Documented all skipped tests with explanations
Removed
V1_RELEASE_CHECKLIST.md- internal development tracking file
[1.0.0-beta1] - 2024-12-21
Added
- Core Updates Module with automatic update checking and management
- GitHub, GitLab, and Custom JSON update source support
- Version-specific update downloads with prerelease filtering
- Automatic backup creation before updates with rollback capability
- ZIP extraction with nested directory handling
- Path validation and security checks in backup operations
- Comprehensive error logging during update operations
- Artisan commands:
check-for-update,perform-update,rollback-update
- Plugin System foundation (experimental)
- Plugin model with activation/deactivation tracking
- Plugin manager for lifecycle management
- Plugin update manager integration
- Plugin validation and installation exceptions
- Theme System foundation (experimental)
- Theme manager with theme discovery
- Theme activation mechanism
- JSON manifest validation
- Comprehensive input sanitization throughout codebase
- Applied
sanitizeText()andsanitizeInt()to all user inputs - Protected database queries from SQL injection
- Validated and sanitized all controller inputs
- Applied
- Type declarations for improved IDE support
- Added
Buildertype hints to all Eloquent scope methods - Added return type declarations across models
- Improved parameter type hints in managers and services
- Added
- Database seeders for default data
- RolesTableSeeder (Admin, Editor, User roles)
- PermissionsTableSeeder (content, user, settings, system permissions)
- SettingsTableSeeder (site configuration defaults)
- Exception hierarchy with base
CMSFrameworkException- ValidationException for validation errors
- NotFoundException for missing resources
- UnauthorizedException for authorization failures
- All module exceptions now extend CMSFrameworkException
- Comprehensive documentation
- API documentation structure (
docs/api/README.md) - Route registry (
docs/routes.md) - Relationship documentation (
docs/relationships.md) - Helper functions reference (
docs/helpers.md) - Exception handling guide (
docs/exceptions.md) - Skipped tests documentation (now at
docs/developer/Skipped-Tests.md)
- API documentation structure (
- Improved
.gitattributesfor cleaner package distribution
Changed
- License changed from GPL-3.0-or-later to MIT for better framework compatibility
- Standardized all
@sinceannotations to 1.0.0 (removed premature 2.0.0 references) - Configuration system improvements
- Fixed publish tag from
artisanpack-package-configtocms-framework-config - Corrected config validation to use
artisanpack.cms-framework.user_model - Updated error messages to reflect actual file paths
- Fixed publish tag from
- Code style improvements (74% PHPCS error reduction)
- Fixed spacing issues in
declare(strict_types = 1)statements - Fixed reference operator spacing in closures
- Improved array alignment and formatting
- Fixed Yoda conditions for comparison safety
- Fixed spacing issues in
Fixed
- Configuration validation mismatch between publish tag, file path, and config key
- Test configuration (fixed config key from
cms-frameworktoartisanpack.cms-framework) - Progress bar in update command (removed misleading fake progress)
glob()error handling for backup operations- Path traversal security issues in backup ZIP creation
- JSON parsing errors in UpdateCheckerFactory
- Doctrine/DBAL deprecation warnings in migrations
- 706 code style violations (reduced from 941 to 235 errors)
- Input sanitization security vulnerabilities across multiple modules
- Unskipped 2 notification tests (role-based notification functionality now fully tested)
Security
- Added comprehensive input sanitization using ArtisanPackUI Security package
- Sanitized all user inputs before database operations
- Protected against XSS attacks with proper output escaping
- Validated file paths to prevent directory traversal
- Enhanced authorization with proper policy enforcement
- Improved error handling to prevent information disclosure
Breaking Changes
- Configuration file publish tag changed to
cms-framework-config - Configuration structure now uses
artisanpack.cms-frameworkinstead ofcms-framework - All
@since 2.0.0annotations changed to@since 1.0.0
Known Limitations
- Plugin system is experimental - full lifecycle hooks not yet implemented
- Theme system is experimental - asset compilation and child themes pending
- 4 plugin-related tests remain skipped (documented in
docs/developer/Skipped-Tests.md) - Test coverage report requires Xdebug/PCOV (recommended for CI/CD)
- 235 PHPCS code style warnings remain (mostly spacing and false positives)
[0.2.4] - 2025-09-02
Added
- Enhanced user migration with password reset tokens and sessions table support
- Password reset tokens table with email primary key, token storage, and timestamp tracking
- Sessions table with comprehensive session management including user ID foreign key, IP address tracking, user agent storage, and activity indexing
- Table existence checks to prevent conflicts during migration execution
[0.2.3] - 2025-09-02
Removed
- Complete removal of all media library references from CMS framework core
- Removed media-related API routes and controller imports from api.php
- Removed MediaLibraryServiceProvider registration from CMSFrameworkServiceProvider
- Removed media library integration documentation
- Removed media-related admin page references from development guide
- Cleaned up media library package discovery ignoring in test configuration
Changed
- Updated comprehensive CMS development guide to remove media library integration examples
- Restructured package ecosystem documentation to reflect media library as separate package
[0.2.2] - 2025-09-02
Added
- Complete media library decoupling and cleanup functionality
[0.2.1] - 2025-09-02
Added
- Comprehensive media library integration documentation
- Integration guide for external
artisanpack-ui/media-librarypackage - Migration instructions for transitioning from integrated media system
Changed
- Decoupled media library functionality from CMS framework core
- Updated service provider to remove media manager bindings
- Refactored CMS configuration schema to support external media library integration
Removed
- Built-in media management system (models, controllers, policies, tests)
- Internal media database migrations and factories
- MediaManager, MediaServiceProvider, and related media classes
- Media-related HTTP controllers, requests, and resources
- All media-related unit and feature tests
- Legacy media documentation
Breaking Changes
- Media functionality now requires separate
artisanpack-ui/media-librarypackage installation### Added - Comprehensive CMS development guide and API documentation
- Analytics system with page views, user sessions, and performance tracking
- Search functionality with full-text search and analytics
- Internationalization support with multi-language capabilities
- Health monitoring and system diagnostics
- Application Performance Monitoring (APM) with metrics collection
- Docker deployment setup with multi-service containers
- Performance testing suite with benchmarking tools
- Security testing suite including penetration testing
- Console commands for content, user, and system management
- Configuration validation and documentation generation
- Caching implementation with Redis support
- Structured logging and audit trail capabilities
- Rate limiting middleware for API protection
- Input sanitization utilities
Changed
- Updated content management system with enhanced controllers
- Improved user management with additional authentication features
- Enhanced media management with better error handling
- Refined plugin and theme management systems
- Updated all policy classes with improved authorization logic
- Modernized database models with better relationships
- Enhanced API routes with comprehensive endpoints
Fixed
- Critical security vulnerabilities with input validation
- Error handling and exception management
- Cache implementation and performance issues
- Authorization policy implementations
- Database query optimization
- API response formatting and error codes
- User authentication and session management
Removed
- Temporary documentation files and test scripts
- Legacy configuration files
- Unused development artifacts
Security
- Implemented comprehensive input sanitization
- Added CSRF protection across all forms
- Enhanced rate limiting for API endpoints
- Improved authorization checks in all policies
- Added security testing suite for vulnerability detection
- Implemented audit logging for security events
- MediaManagerInterface moved to external package namespace
- Media-related routes and API endpoints moved to external package
[0.2.0] - 2025-09-01
[0.1.0] - 2025-07-13
Added
- Initial test release
- Core CMS framework functionality
- Content management system
- User management with authentication
- Plugin and theme support
- Admin interface and dashboard widgets
- Settings management
- Media management integration
- Two-factor authentication
- Progressive Web App (PWA) support
- Audit logging capabilities