Skip to content
CAI
Software that uses CAICheck a score

getgrav/grav

55.5

Adequate · 22 September 2026

102.8k

lines of production code

PHP

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the core engine of the Grav content management framework, providing a PHP-based architecture for managing static and dynamic content through a flexible, event-driven lifecycle. It features a modernized request handling pipeline using PSR-15 middleware, a robust Flex data system for structured content and user management, and comprehensive asset management for media and frontend resources. The platform supports extensibility via a plugin ecosystem, CLI tools for maintenance, and secure, standardized interfaces for caching, HTTP communication, and template rendering.

How it got here

2014–2016 — Grav 2.0 architecture and security overhaul

47 changes.

This period focused on the foundational development of Grav 2.0, characterized by a major architectural shift to PSR-15 middleware, PHP 8.3 compatibility, and a comprehensive security hardening of the codebase. Key features included the introduction of a SQLite-based page index for performance, native .env support, and a robust filesystem abstraction with secure ZIP handling. The work also established a rigorous testing infrastructure using Codeception and refactored core services and CLI tools to support the new Flex-based account system.

2017–2018 — Framework standardization and Flex introduction

43 changes.

This period focused on rebuilding Grav's core architecture around modern PHP standards, introducing PSR-7, PSR-11, and PSR-15 compliance for HTTP, dependency injection, and request handling. It established a new object and collection model with lazy loading and nested property support, while launching the Flex system for structured data management. Concurrently, the framework expanded its capabilities with a comprehensive caching layer, secure form handling, and enhanced asset and media interfaces.

2019–2021 — Framework modernization and Flex system expansion

40 changes.

This period focused on modernizing the Grav framework by introducing PSR-7 compliance, a new ACL system, and a robust HTTP client abstraction. It simultaneously expanded the Flex storage architecture to comprehensively manage Pages, Users, and User Groups with dedicated interfaces and traits. The work also included significant security hardening, static analysis integration, and infrastructure improvements for installation and CLI tools.

2022–2026 — Framework modernization and security hardening

25 changes.

This period focused on modernizing the Grav framework by replacing abandoned dependencies with maintained alternatives, such as migrating from Doctrine Cache to Symfony Cache and bringing Pimple in-house. Significant effort was dedicated to security hardening, including the introduction of a Twig content sandbox for editor-authored templates, strict media URL allowlisting, and comprehensive unit tests covering these fixes. The work also established foundational APIs for a new relationships system and added compatibility layers for Twig 3 and Monolog 3 to ensure smooth upgrades.

Features

Added Identifier class for object identification

A new Identifier class has been introduced in the Grav Framework to handle object identification. This class implements the IdentifierInterface and stores an object's unique ID and type. It provides methods to retrieve these values and supports JSON serialization and debug output, facilitating consistent identification of objects within the framework.

system/src/Grav/Framework/Object/Identifiers · high confidence

Added Phan static analysis configuration and internal stubs

The project now includes a \.phan/config.php\ file to configure the Phan static analysis tool, enabling strict method checking and several plugins (AlwaysReturn, UnreachableCode, etc.) while suppressing specific known issues. Additionally, internal stub files for the Redis, Memcache, and Memcached PHP extensions have been added to provide type definitions and autocomplete support for these libraries during static analysis.

.phan · high confidence

Added generic Flex type classes

Introduced three new classes—GenericObject, GenericCollection, and GenericIndex—in the Grav Common Flex namespace. These classes extend the abstract base types (FlexObject, FlexCollection, FlexIndex) to provide a generic implementation for handling flexible data structures without specific type constraints.

system/src/Grav/Common/Flex/Types/Generic · high confidence

Backwards-compatible serialization trait for PHP 7.3+

A new Serializable trait has been added to the framework to provide backwards compatibility for the PHP 7.3 Serializable interface. This trait allows classes to implement standard serialization methods while internally delegating to \_\serialize and \\_unserialize, ensuring consistent behavior across supported PHP versions.

system/src/Grav/Framework/Compat · high confidence

Deferred block rendering support in Twig templates

The system now supports the \deferred\ keyword within Twig block definitions (e.g., \{% block name deferred %}\), allowing template blocks to be rendered asynchronously or in a deferred manner. This is implemented via a new \DeferredExtension\ that includes custom node visitors and token parsers to handle the new syntax, ensuring compatibility with both Twig 1.x and Twig 2/3 environments.

system/src/Twig · high confidence

Hidden CLI command to list plugins with available commands

A new hidden console command, \plugins:list\, has been added to help users identify which enabled plugins expose CLI capabilities. When run, it scans the \plugins://\ directory for any plugin that contains a file matching the pattern \cli/\[Name\]Command.php\ and outputs a numbered list of those plugins along with the specific command syntax needed to invoke them (e.g., \bin/grav \[plugin\_name\] list\). This assists users in discovering and using plugin-specific terminal tools without needing to manually inspect plugin directories.

system/src/Grav/Console/Plugin · high confidence

Introduce ContentBlock framework for nested content and asset management

This change adds the \Grav\\Framework\\ContentBlock\ component, introducing \ContentBlock\ and \HtmlBlock\ classes along with their interfaces. \ContentBlock\ provides a structure for creating nested blocks of content with serialization support, including checksums and caching flags. \HtmlBlock\ extends this to manage web assets, allowing users to register and retrieve styles, scripts, links, and inline HTML with priority and location (head/bottom) sorting. This framework enables structured content composition and centralized asset handling within the Grav system.

system/src/Grav/Framework/ContentBlock · high confidence

Introduce modern, secure scheduler with job queuing, history, and webhook support

The scheduler in system/src/Grav/Common/Scheduler has been replaced with a modern implementation that adds a file-based job queue (JobQueue) with priority levels and HMAC-signed serialization to prevent tampering, a JobHistory manager for logging execution details and output, and a SchedulerController exposing health, statistics, and webhook endpoints. The webhook endpoint now fails closed when no token is configured, addressing a security vulnerability. Additionally, the scheduler initializes lazily instead of on every request, improving performance, and supports features like retry strategies, dependencies, and environment recording in cron lines.

system/src/Grav/Common/Scheduler · high confidence

Introduce per-page SQLite index store for lazy page hydration

Grav now supports a new page indexing engine that stores each page's metadata in a single-file SQLite database (backed by the \PageIndexStore\ class) instead of serializing the entire page tree into one cache blob. This allows the system to hydrate only the pages actually requested during a visit, significantly reducing memory usage and startup time on large sites. The feature is opt-in via the \GRAV\_PAGES\_INDEX\_ENGINE\ environment variable (supporting 'sqlite' or the pure-PHP 'yetisql' fallback) and integrates with the existing \Pages\ class to serve routes, children, and sort orders from the index when enabled.

system/src/Grav/Common/Page · high confidence

Introduction of Flex Pages framework components

This change introduces the core classes for the new Flex Pages system within the Grav Framework. It adds \FlexPageCollection\ to manage page listings with optimized filtering (published, visible, routable) and sibling navigation, \FlexPageIndex\ to handle page indexing and route normalization, and \FlexPageObject\ to represent individual pages with support for content, media, routing, and translation traits. These components provide the underlying data structure and behavior for managing pages via the Flex system.

system/src/Grav/Framework/Flex/Pages · high confidence

Introduction of FormTrait for Grav Framework Form handling

The \FormTrait\ class has been added to the Grav Framework, providing a comprehensive set of methods and properties for managing form state, validation, and file uploads. This trait introduces support for form enabling/disabling, unique ID generation, nonce handling for security, and integration with the Flex storage system. It also includes logic for handling form flashes (messages), file uploads with SVG XSS checks, and serialization compatibility, effectively centralizing core form behavior for Grav's form components.

system/src/Grav/Framework/Form/Traits · high confidence

Introduction of PSR-11 compliant DI Container

A new \Grav\\Framework\\DI\\Container\ class has been added, extending Pimple and implementing the PSR-11 \ContainerInterface\. This provides a standardized way to retrieve (\get\) and check for existence (\has\) of services within the dependency injection framework, ensuring compatibility with PSR-11 standards.

system/src/Grav/Framework/DI · high confidence

Introduction of PSR-15 RequestHandler class

A new RequestHandler class has been added to the system, implementing the PSR-15 RequestHandlerInterface. This component allows developers to register middleware and a default handler, supporting both callable and MiddlewareInterface-based middleware registration via the addCallable and addMiddleware methods. It integrates with a PSR-11 container when provided, enabling dependency injection for middleware instances.

system/src/Grav/Framework/RequestHandler · high confidence

Introduction of PageStorage for Flex Pages

A new PageStorage class has been added to handle the storage and retrieval of Flex Pages. This component extends FolderStorage to manage page-specific logic, including parsing keys with language variations, reading frontmatter and raw content from Markdown files, and building storage keys based on order, folder, and template parameters. It integrates with Grav's configuration to respect settings for ignoring hidden files, specific file/folder patterns, and default language extensions, providing the underlying storage mechanism for the Flex Pages system.

system/src/Grav/Common/Flex/Types/Pages/Storage · high confidence

Introduction of RequestHandlerTrait for middleware processing

A new RequestHandlerTrait has been added to the Grav Framework, providing a reusable implementation for processing HTTP requests through a chain of middleware. This trait manages the execution flow by iterating through registered middleware items—supporting both direct MiddlewareInterface instances and service container lookups—and falling back to a default handler when the chain is exhausted, thereby standardizing how request handling logic is composed and executed within the framework.

system/src/Grav/Framework/RequestHandler/Traits · high confidence

Introduction of new Asset and Browser classes for resource management and user-agent detection

The system now includes dedicated \Assets\ and \Browser\ classes in the \Grav\\Common\ namespace. The \Assets\ class centralizes the management of CSS, JavaScript, and module assets, introducing support for asset pipelining, timestamping, and collection-based loading to optimize frontend performance. The \Browser\ class provides structured user-agent detection by leveraging the \donatj/phpuseragentparser\ library, enabling more accurate identification of browsers and devices for conditional logic or analytics.

system/src/Grav/Common · high confidence

Introduction of the Grav Framework Flex system

The \system/src/Grav/Framework/Flex\ directory now contains the core implementation of the Flex system, introducing a new architecture for managing structured data. This includes the \Flex\ class as the central registry for directories, \FlexDirectory\ for type configuration and storage management, and \FlexObject\ for individual data entities. The system provides \FlexCollection\ and \FlexIndex\ for efficient querying and sorting, along with \FlexForm\ and \FlexDirectoryForm\ to handle data input and validation via blueprints. Additionally, \FlexFormFlash\ manages form state persistence, and \FlexIdentifier\ provides a standardized way to reference Flex objects within the application.

system/src/Grav/Framework/Flex · high confidence

New CLI entry points and local upgrade test harness

The \bin/\ directory now includes dedicated executable scripts for the Grav CLI (\bin/grav\), the Grav Package Manager (\bin/gpm\), and plugin-specific commands (\bin/plugin\), all of which automatically install vendor dependencies if missing. A new \bin/build-test-update.php\ script allows developers to generate local test update packages for validating the upgrade flow, accompanied by \bin/test-selfupgrade.sh\ to orchestrate end-to-end self-upgrade tests against a local fake CDN.

bin · high confidence

New ControllerResponseTrait for standardized HTTP responses

Introduced the ControllerResponseTrait class, which centralizes the creation of HTTP responses (HTML, JSON, redirects, downloads, and errors) within the Grav framework. This trait ensures consistent handling of response codes, headers, and content types, with specific improvements for JSON responses such as safe UTF-8 encoding and proper redirect behavior for .json extensions.

system/src/Grav/Framework/Controller · high confidence

New Filesystem abstraction for stream URL manipulation

Introduced the \Grav\\Framework\\Filesystem\\Filesystem\ class, providing a new API for manipulating stream URLs. This component includes methods for normalizing paths (handling dot-dot segments), extracting basenames and directory names, and parsing path information, with specific improvements to ensure UTF-8 safety and correct handling of URL-encoded characters in stream contexts.

system/src/Grav/Framework/Filesystem · high confidence

New FilesystemInterface for Unicode-safe path operations

A new \FilesystemInterface\ has been introduced in the Grav Framework, defining a contract for Unicode-safe and stream-safe filesystem operations. This interface standardizes path manipulation methods including \basename\, \dirname\, \pathinfo\, \normalize\, and \parent\, ensuring consistent behavior for file and directory path handling across the application.

system/src/Grav/Framework/Filesystem/Interfaces · high confidence

New Flex Page traits for authors, content, legacy, routing, and translation

The system now includes a set of new traits in the Flex Pages framework to handle specific page responsibilities. PageAuthorsTrait introduces author-based access control, allowing pages to define specific authors and inherit permissions from parent pages. PageContentTrait manages page content, summaries, and media routes. PageLegacyTrait provides backward compatibility methods for raw data, frontmatter, and HTTP headers. PageRoutableTrait handles URL generation, canonical links, and routability checks. PageTranslateTrait manages multi-language support, including translation lookups and language lists. These traits collectively enhance the Flex Pages system with more granular control over page metadata, access, and internationalization.

system/src/Grav/Framework/Flex/Pages/Traits · high confidence

New Flex Traits for Event Triggering and Container Access

Added new PHP traits in the Flex system to standardize event handling and container access for Flex collections and objects. FlexCollectionTrait and FlexObjectTrait now provide a triggerEvent() method that automatically prefixes event names with 'onFlexCollection' or 'onFlexObject' respectively, ensuring consistent event emission. FlexCommonTrait introduces a getTemplate() method for resolving Twig templates with error handling, while FlexGravTrait provides helper methods for accessing the Grav container, active user, and authorization scope.

system/src/Grav/Common/Flex/Traits · high confidence

New Flex interfaces define authorization, storage, and collection capabilities

The Grav Framework introduces a comprehensive set of new interfaces in the Flex system to standardize and extend object management. \FlexAuthorizeInterface\ adds granular authorization checks, allowing \isAuthorized\ to return \null\ for unmatched rules to support rule chaining. \FlexStorageInterface\ defines the data layer with methods for row CRUD operations, key existence checks (\hasKey\/\hasKeys\), and media path resolution. \FlexCollectionInterface\ and \FlexIndexInterface\ provide collection management features including search, sorting, filtering by key-value pairs, and index map retrieval. Additionally, \FlexDirectoryInterface\ manages directory configurations and object creation, while \FlexFormInterface\ supports file uploads and media tasks. These interfaces collectively establish the contract for Flex Objects, Collections, and Directories, enabling features like custom blueprints, media handling, and flexible indexing.

system/src/Grav/Framework/Flex/Interfaces · high confidence

The Flex framework now includes four new traits in the Traits namespace to enhance object capabilities. FlexAuthorizeTrait implements basic ACL checks, allowing users to verify authorization for specific actions and scopes against Flex directory configurations. FlexMediaTrait adds comprehensive media handling, including support for media fields, media pickers, and the ability to automatically update object media on save, with an event fired for plugins to modify media URLs. FlexRelationshipsTrait introduces logic for defining and managing relationships between Flex objects, enabling queries based on related data. FlexRelatedDirectoryTrait provides methods to retrieve collections of related objects by property, facilitating complex data associations within Flex directories.

system/src/Grav/Framework/Flex/Traits · high confidence

New Flex-based User Group objects and collections

The User Groups system now uses dedicated Flex types (UserGroupObject, UserGroupCollection, and UserGroupIndex) to manage group data. This introduces a new object model where each group is represented by a UserGroupObject that implements UserGroupInterface, handling access control via an embedded Access object. The collection class aggregates authorization checks across all groups, while the index class provides the standard Flex indexing structure. This change replaces or supplements the previous group handling mechanism with a more structured, Flex-native approach for user group management.

system/src/Grav/Common/Flex/Types/UserGroups · high confidence

New Grav Framework Pagination component

Grav now includes a new \Grav\\Framework\\Pagination\ component that provides a structured way to handle paginated content. This addition introduces \AbstractPagination\ and \Pagination\ classes to manage page logic, limits, and total counts, alongside \AbstractPaginationPage\ and \PaginationPage\ for representing individual page states. The component supports both standard URL parameters and query parameters for navigation, allowing developers to easily integrate pagination into their themes and plugins.

system/src/Grav/Framework/Pagination · high confidence

New Grav\\Framework\\File classes for structured data formats

The \system/src/Grav/Framework/File\ directory now includes a new set of classes (\YamlFile\, \JsonFile\, \IniFile\, \CsvFile\, \MarkdownFile\) that extend \DataFile\ to handle specific data formats. These classes rely on a formatter interface (\FileFormatterInterface\) to encode and decode data, providing a structured way to load and save configuration and content files compared to the previous generic file handling.

system/src/Grav/Framework/File · high confidence

New Markdown output format for AI agents and text clients

Grav now supports serving any routable page as Markdown (via \.md\ extension or \Accept: text/markdown\ header). This feature renders the page through the theme exactly as a browser would see it, then converts the main content region back to Markdown, including resolved image paths, page-relative links, and modular assembly. The output includes a YAML frontmatter block, the main content body, and a navigation section linking parent, neighboring, and child pages by their \.md\ URLs, enabling AI agents to traverse the site without leaving Markdown. The feature is controlled by \system.pages.markdown\_output.enabled\ and includes an optional \X-Markdown-Tokens\ response header.

system/src/Grav/Common/Page/Markdown · high confidence

New Media Interfaces for Audio, Video, and Image Manipulation

The system now exposes a set of new interfaces in the \Grav\\Common\\Media\\Interfaces\ namespace to define the contract for media objects. \AudioMediaInterface\ and \VideoMediaInterface\ extend \MediaPlayerInterface\ to support HTML5 player attributes (e.g., controls, loop, autoplay, muted, preload) and specific features like \controlsList\ for audio and \poster\/\playsinline\ for video. \ImageManipulateInterface\ provides methods for image processing, including generating responsive derivatives, setting quality/format, and managing alternative image sizes. \MediaUploadInterface\ formalizes upload, copy, delete, and rename operations, while \MediaCollectionInterface\ and \MediaObjectInterface\ define the core behaviors for managing media lists and individual media metadata/attributes.

system/src/Grav/Common/Media/Interfaces · high confidence

New PSR-16 Simple Cache framework implementation

Grav now includes a new \Grav\\Framework\\Cache\ component that provides a PSR-16 compatible "Simple Cache" implementation. This adds a new \CacheInterface\ and \AbstractCache\ base class, along with a \CacheTrait\ that handles key validation, namespace management, TTL conversion, and standard cache operations (get, set, delete, clear, and their multiple variants). The implementation also includes specific exception classes (\CacheException\, \InvalidArgumentException\) that adhere to the PSR-16 standard, allowing for consistent error handling in cache interactions.

system/src/Grav/Framework/Cache · high confidence

New PSR-16 cache adapters (Chain, File, Memory, Session, Doctrine)

The \Grav\\Framework\\Cache\\Adapter\ directory now includes five new cache backend implementations that conform to the PSR-16 Simple Cache interface. \ChainCache\ allows combining multiple adapters into a single hierarchical cache layer, while \FileCache\ provides persistent storage with HMAC-signed payloads to prevent tampering. \MemoryCache\ offers a fast, request-scoped in-memory store, \SessionCache\ persists cache data within the user's session, and \DoctrineCache\ bridges to existing Doctrine Cache providers. These adapters give users flexible options for caching strategies without relying on legacy implementations.

system/src/Grav/Framework/Cache/Adapter · high confidence

New PSR-7 HTTP message implementation using Nyholm/psr7 decorators

Grav now includes a new \Grav\\Framework\\Psr7\ namespace that implements PSR-7 interfaces (\Request\, \Response\, \ServerRequest\, \Stream\, \UploadedFile\, \Uri\) as decorators around the \Nyholm/psr7\ library. This provides a standardized HTTP message layer for the framework, with \Response\ adding convenience methods like \withJson\ and \withRedirect\, and \ServerRequest\ offering helpers for parsing parameters and content types. The previous \AbstractUri\ implementation is marked deprecated in favor of this new decorator-based approach.

system/src/Grav/Framework/Psr7 · high confidence

New PSR-7 compliant URI framework classes

Grav introduces a new \Grav\\Framework\\Uri\ namespace containing \Uri\, \UriFactory\, and \UriPartsFilter\ classes that implement the PSR-7 \UriInterface\. This provides a standardized way to parse, construct, and manipulate URIs, including support for UTF-8 aware URL parsing, query parameter handling, and strict validation of URI components like hostnames and ports.

system/src/Grav/Framework/Uri · high confidence

New PSR-7 compliant exception classes for request handling

The RequestHandler framework now includes a set of new exception classes (RequestException, NotFoundException, NotHandledException, PageExpiredException, and InvalidArgumentException) that extend standard PHP exceptions but integrate with PSR-7. These exceptions carry the original ServerRequestInterface, allowing the system to preserve request context and map specific HTTP status codes (e.g., 404, 405, 400) directly from the exception state, improving error reporting and middleware handling.

system/src/Grav/Framework/RequestHandler/Exception · high confidence

New PSR-7 decorator traits for HTTP message handling

Grav now includes a set of new PHP traits in the \Grav\\Framework\\Psr7\\Traits\ namespace to support PSR-7 HTTP message decoration. These traits—\MessageDecoratorTrait\, \RequestDecoratorTrait\, \ResponseDecoratorTrait\, \ServerRequestDecoratorTrait\, \StreamDecoratorTrait\, \UploadedFileDecoratorTrait\, and \UriDecorationTrait\—provide reusable implementations for wrapping and delegating PSR-7 interfaces. This change introduces new internal infrastructure for handling HTTP messages, requests, responses, streams, and URIs, enabling more modular and consistent PSR-7 compliance within the Grav framework.

system/src/Grav/Framework/Psr7/Traits · high confidence

New Relationships framework for managing object associations

The \system/src/Grav/Framework/Relationships\ directory now contains a new set of classes (\Relationships\, \ToOneRelationship\, \ToManyRelationship\, and \RelationshipTrait\) that provide a structured way to define and manage relationships between objects. This implementation introduces support for one-to-one and one-to-many associations, allowing users to add, remove, and query related identifiers while tracking modification states. The framework includes validation for relationship cardinality and handles specific identifier types like media and flex objects.

system/src/Grav/Framework/Relationships · high confidence

New Route and RouteFactory classes for URL manipulation

Added the \Grav\\Framework\\Route\\Route\ and \RouteFactory\ classes to the framework, providing a dedicated object-oriented interface for parsing, constructing, and manipulating URLs. The \Route\ class exposes methods to access route parts, query parameters, language prefixes, and Grav-specific parameters, while \RouteFactory\ offers static methods to create route instances from legacy URIs, strings, or structured parts, enabling more robust handling of routing logic within the application.

system/src/Grav/Framework/Route · high confidence

New Twig tags for caching, asset management, and control flow

This update introduces several new Twig tags to the template engine: \{% cache %}\ for caching rendered content with optional keys and lifetimes, \{% script %}\ and \{% style %}\ for registering JavaScript and CSS files or inline code into the asset pipeline, \{% link %}\ for adding link tags, \{% markdown %}\ for rendering markdown content, \{% render %}\ for rendering Flex objects, \{% switch %}\ for control flow, \{% throw %}\ for throwing exceptions with custom codes, and \{% try %}\ for error handling. These tags provide a more integrated way to manage assets, cache output, and handle logic directly within Twig templates.

system/src/Grav/Common/Twig/Node · high confidence

New Twig template tags for control flow, resource management, and error handling

This update introduces several new Twig token parsers in the Grav Common Twig component, expanding template capabilities. Users can now use \{% cache %}\ to cache template output with optional keys and lifetimes, \{% switch %}\ for cleaner conditional logic, and \{% try %}/{% catch %}\ for error handling. Resource management is enhanced with \{% script %}\ and \{% style %}\ tags that support file paths, inline content, priority, and placement (head/bottom), replacing the deprecated \in\ operator with \at\. Additionally, \{% link %}\ allows adding document links (e.g., icons, preloads), \{% render %}\ enables rendering objects with layouts, and \{% throw %}\ allows throwing specific HTTP errors directly from templates.

system/src/Grav/Common/Twig/TokenParser · high confidence

New and updated CLI commands for Grav 2.0 maintenance and setup

The \bin/grav\ console interface now includes a comprehensive set of commands for managing Grav 2.0 installations. A new \backup\ command creates zipped backups with progress tracking, while \cache-cleanup\ identifies and removes orphaned cache directories based on age (with \--force\ to delete). The \clean\ command has been updated to target Grav 2.0-specific scaffolding and vendor files. Setup workflows are streamlined with \sandbox\ (renamed from \setup\) for creating development environments, \install\ for dependency installation, and \new-project\ to combine both. Additional tools include \composer\ for vendor management, \logviewer\ for inspecting logs, \scheduler\ for managing cron jobs, \security\ for XSS detection, and \page-system-validator\ for testing Flex Page migrations.

system/src/Grav/Console/Cli · high confidence

New collection classes for filesystem and indexed data access

The \Grav\\Framework\\Collection\ namespace now includes \AbstractFileCollection\ and \FileCollection\ to lazily iterate over filesystem paths (supporting recursive traversal, filtering, and Doctrine Criteria matching), and \AbstractIndexCollection\ as a base for key-based collections. Additionally, \ArrayCollection\ and \AbstractLazyCollection\ provide new collection methods (\reverse\, \shuffle\, \chunk\, \select\, \unselect\) and JSON serialization, while \CollectionInterface\ and \FileCollectionInterface\ define the standard APIs for these behaviors.

system/src/Grav/Framework/Collection · high confidence

New contract interfaces for object identifiers and relationships

This change introduces a set of new interfaces in the Grav Framework Contracts layer to support a new relationships system. It adds \IdentifierInterface\ for standard object identification, \MediaObjectInterface\ for media-specific metadata and responses, and a hierarchy of relationship interfaces (\RelationshipInterface\, \RelationshipsInterface\, \ToOneRelationshipInterface\, \ToManyRelationshipInterface\, and \RelationshipIdentifierInterface\). These contracts define the structure for managing one-to-one and one-to-many relationships, including methods for adding, removing, and retrieving identifiers, checking modification status, and accessing nested objects. This provides the foundational API for the new relationship handling logic.

system/src/Grav/Framework/Contracts · high confidence

New file and formatter interfaces introduced in Grav Framework

The Grav Framework now exposes \FileInterface\ and \FileFormatterInterface\ in the \Grav\\Framework\\File\\Interfaces\ namespace, providing a standardized contract for file readers and formatters. \FileInterface\ defines core file operations such as reading, writing, locking, and metadata retrieval (path, extension, timestamps) for formats like CSV, JSON, Markdown, and YAML. \FileFormatterInterface\ extends \Serializable\ to handle encoding/decoding of data and exposes MIME type and file extension information, enabling formatters to self-identify their supported formats. These interfaces allow developers to interact with file handling components in a consistent, type-safe manner across the framework.

system/src/Grav/Framework/File/Interfaces · high confidence

New file formatter framework for YAML, JSON, CSV, Markdown, INI, and serialized data

Grav introduces a new \Grav\\Framework\\File\\Formatter\ component that provides a unified interface for encoding and decoding various file formats. This includes dedicated formatters for YAML (with native and fallback parsing), JSON, CSV (with configurable delimiters and null handling), Markdown (with YAML frontmatter support), INI, and PHP serialized data. The system uses an \AbstractFormatter\ base class and a \FileFormatterInterface\, allowing for consistent configuration of file extensions, MIME types, and format-specific options like JSON encoding flags or YAML indentation levels. A deprecated \FormatterInterface\ is provided for backward compatibility.

system/src/Grav/Framework/File/Formatter · high confidence

New filesystem abstraction with secure ZIP extraction and configurable file filtering

The \system/src/Grav/Common/Filesystem\ directory now contains a new set of classes (\Archiver\, \ZipArchiver\, \Folder\, and several iterator filters) that replace or supplement the previous file handling logic. For users, this introduces a more robust backup and archive system: ZIP extraction is now protected against decompression bombs (limiting uncompressed size, file count, and nesting depth) and Zip Slip attacks (preventing directory traversal). Additionally, the system now supports configurable ignore patterns for files and folders during backup and file change detection, allowing users to exclude specific paths or file types from operations like backups and cache clearing.

system/src/Grav/Common/Filesystem · high confidence

New formal extension API for Markdown blocks and inlines

The Markdown engine now supports a structured extension system, allowing custom block and inline syntax to be registered via dedicated interfaces (BlockHandlerInterface, InlineHandlerInterface, etc.) and a MarkdownExtensionRegistry. This replaces the legacy closure-injection and magic-method conventions, providing a cleaner way to extend parsing behavior. The change also introduces helper classes like Element and BlockResult to simplify building parsedown element arrays and managing block state, and adds support for fenced-code block attributes (e.g., \{\#id .class}\) and nested \markdown="1"\ content that correctly inherits page-level definitions.

system/src/Grav/Common/Markdown · high confidence

New helper classes for Base32 encoding, Exif metadata, file reading, log viewing, HTML truncation, and YAML linting

This change introduces several new helper classes in the Grav Common Helpers namespace. The Base32 class provides static methods for Base32 encoding and decoding. The Exif class handles EXIF data reading for images, with configuration support for auto-metadata generation. The FileReader class provides a secure, hardened method for reading files via Grav stream URIs, including validation of allowed streams, extensions, and path containment. The LogViewer class offers functionality to tail and parse log files, including trace parsing. The Truncator class provides safe HTML truncation by words or letters using DOM manipulation. The YamlLinter class adds capabilities to lint YAML and Markdown files across various Grav directories (config, pages, blueprints, environments) with optional strict parsing and progress callbacks.

system/src/Grav/Common/Helpers · high confidence

New language negotiation and code management classes

The system now includes dedicated \Language\ and \LanguageCodes\ classes to manage multilingual support. The \Language\ class handles initialization, default language selection, and active language resolution, while \LanguageCodes\ provides a comprehensive mapping of language codes to their display names, native names, and text orientation (including RTL support). This change introduces structured language code validation and standardizes how supported languages are defined and retrieved within the application.

system/src/Grav/Common/Language · high confidence

New lifecycle and registration events for plugins and system services

Grav now exposes four new event classes to allow plugins to hook into specific system phases: \BeforeSessionStartEvent\ and \SessionStartEvent\ trigger respectively before and after the session is started; \PluginsLoadedEvent\ fires after plugins are loaded but before initialization; and \FlexRegisterEvent\ allows registration of Flex directories when the Flex service is first accessed. These additions provide more granular control over initialization order and service registration.

system/src/Grav/Events · high confidence

New media framework interfaces introduced

The system now includes a new set of interfaces in the \Grav\\Framework\\Media\\Interfaces\ namespace to define the structure for media handling. \MediaInterface\ provides methods to retrieve associated media collections, filesystem paths, and display ordering. \MediaCollectionInterface\ defines the contract for collections of media objects, extending standard PHP array and iterator behaviors. \MediaObjectInterface\ specifies how individual media items expose metadata, URLs, and nested property access. Additionally, \MediaManipulationInterface\ is added to handle file uploads and deletions, though it is marked as deprecated in version 1.7 and is not currently used.

system/src/Grav/Framework/Media/Interfaces · high confidence

New object access and nested property traits

The framework now includes new traits in the \Grav\\Framework\\Object\\Access\ namespace to enhance object property handling. \ArrayAccessTrait\ and \NestedArrayAccessTrait\ allow objects to be accessed like arrays, with the nested variant supporting dot-notation paths. \NestedPropertyTrait\ provides methods to get, set, and unset properties across nested structures (objects, arrays, or \ArrayAccess\ instances) using a configurable separator (defaulting to \.\). \NestedPropertyCollectionTrait\ extends this capability to collections, allowing nested property operations on all contained elements. \OverloadedPropertyTrait\ enables magic method access (\\_\get\, \\\_set\, etc.) for object properties.

system/src/Grav/Framework/Object/Access · high confidence

Option to serve page media through the page route

A new configuration option, \system.pages.media\_route\_urls\, allows page media (including Markdown images, lightbox thumbnails, and retina files) to be served via the page's route rather than directly from the disk path. When enabled, media URLs are rewritten to pass through Grav's fallback URL handler, enabling access control listeners (such as those in the Login plugin) to intercept and validate requests. This feature requires corresponding web server configuration to block direct access to the \user/pages\ directory to ensure security.

system/src/Grav/Common/Media · high confidence

Support for multiple MIME types per file extension

The new MimeTypes class allows file extensions to map to multiple MIME types rather than a single one. Users can now retrieve all associated MIME types for an extension or all extensions for a MIME type, providing more flexibility in content-type handling.

system/src/Grav/Framework/Mime · high confidence

Security

Block direct web access to sensitive user/account data

Added an .htaccess file to the user/accounts directory to prevent direct browser access to sensitive files such as password hashes, databases, and tokens, while explicitly allowing access to avatar images (JPEG, PNG, GIF, WebP, AVIF, BMP, ICO) served by the application. This change implements a defense-in-depth security measure to ensure that private account data is not exposed via direct URL requests, addressing a potential security vulnerability.

user/accounts · high confidence

Block direct web access to sensitive user/data files

A new .htaccess file in the user/data directory now prevents direct browser access to sensitive data files (such as .yaml, .json, .md, databases, and keys) while explicitly allowing access to public media assets like images and videos. This change addresses a security vulnerability by ensuring that non-public content stored in this user-writable folder cannot be downloaded directly via a web request, using mod\_rewrite rules to enforce this restriction.

user/data · high confidence

Fix XSS vulnerability in Flex Pages content saving

The Flex Pages system now enforces a render-time XSS backstop when saving page content. Editor-authored Twig in page content is rendered in isolation to detect flagged markup, preventing potential cross-site scripting attacks during the save process. This security fix applies specifically to the content handling within the Flex Pages type.

system/src/Grav/Common/Flex/Types/Pages · high confidence

Introduces Twig content sandboxing to secure editor-authored templates

Grav now applies a strict security policy to templates authored in the page editor (content processed via Twig), preventing access to dangerous filters, functions, and internal configuration. This change introduces a new \GravSecurityPolicy\ that restricts allowed tags, filters, and methods, and a \SandboxConfig\ facade that redacts sensitive configuration paths (such as proxy credentials and security tokens) from editor content. Editor-authored templates are now isolated from the full Grav container, while trusted theme and plugin templates remain unsandboxed to preserve full functionality.

system/src/Grav/Common/Twig/Sandbox · high confidence

New Twig extensions for filesystem operations and security-hardened array filters

This change introduces two new Twig extensions: \FilesystemExtension\, which exposes standard PHP file functions (such as \file\_exists\, \filesize\, \exif\_read\_data\, and \pathinfo\) as Twig filters and functions with built-in filename validation, and \GravExtension\, which provides core Grav utilities including translation, formatting, and new array helpers like \array\_group\_by\ and \replace\_last\. Crucially, the \GravExtension\ hardens several existing array filters (\filter\, \map\, \reduce\, \find\, \sort\) against Server-Side Template Injection (SSTI) and code execution vulnerabilities by enforcing sandbox checks and restricting dangerous string callables, while also guarding JSON/YAML encoding against sandbox exfiltration.

system/src/Grav/Common/Twig/Extension · high confidence

New media object abstraction and security hardening for media URLs

This change introduces a new media handling layer in the framework, adding \MediaIdentifier\, \MediaObject\, and \UploadedMediaObject\ classes to manage media resolution for both Flex objects and uploaded files. As part of this refactor, media URL actions are now restricted to a documented allowlist, preventing the execution of undocumented or unsafe methods via request parameters (addressing [GHSA redacted]).

system/src/Grav/Framework/Media · high confidence

Secure, persistent form state and file uploads via FormFlash

The form framework now introduces \FormFlash\ and \FormFlashFile\ classes to persist form data and uploaded files across requests, enabling features like delayed uploads and state maintenance on page reloads. To prevent path traversal attacks, identifiers used for storage paths are strictly sanitized against an alphanumeric allowlist. Additionally, uploaded SVG files are scanned for XSS vulnerabilities based on their actual content rather than client-supplied MIME types before being stored.

system/src/Grav/Framework/Form · high confidence

Security hardening and self-healing for sensitive user folders

Upgrading Grav now automatically patches your site's .htaccess files to block direct web access to sensitive user folders (accounts, config, data, env), preventing exposure of password hashes, configuration, and other private files. The update intelligently allows public media assets (images, audio, video, PDFs, CSS, JS, fonts) to continue loading from user/data and user/accounts/avatars, while excluding SVG to mitigate stored-XSS risks. It also ensures these security rules are case-insensitive and inherited by subdirectories, fixing issues where plugins or themes could inadvertently bypass protections or cause 500 errors on servers with limited .htaccess override permissions.

system/src/Grav/Installer/updates · high confidence

Security hardening of media handling and image processing

This change introduces strict security controls to the media system to prevent code execution and injection attacks. It implements an allowlist of valid image manipulation actions (e.g., resize, crop, filter) that can be invoked via URL query strings, blocking arbitrary method calls on medium objects. It also adds protection against XML External Entity (XXE) attacks when reading SVG files by stripping DOCTYPE/ENTITY declarations and disabling entity loaders. Additionally, it restricts media URL actions to a documented allowlist and constrains image watermark paths to the media sandbox.

system/src/Grav/Common/Page/Medium · high confidence

Updated web server configuration samples with hardened security rules

The bundled configuration files for Caddy, Nginx, Apache (.htaccess), lighttpd, and IIS (web.config) have been updated to enforce stricter security policies. These changes block direct web access to sensitive directories (such as .git, cache, logs, backups, tests, and user/config) and prevent the execution of scripts in system and user folders. The rules also protect sensitive files like .env, composer.json, and LICENSE.txt. Additionally, the configurations now allow direct serving of avatar images and public media uploads while explicitly blocking SVG files to mitigate stored XSS risks. Nginx and lighttpd configs also include improved static asset caching and query string handling.

webserver-configs · high confidence

Architecture

Grav core services are now registered via dedicated ServiceProviders

The Grav application container is now initialized through a set of dedicated ServiceProviders (e.g., AccountsServiceProvider, ConfigServiceProvider, FlexServiceProvider, SessionServiceProvider) located in system/src/Grav/Common/Service. This change centralizes the wiring of core services—such as user accounts, configuration loading, Flex directories, and session management—into a structured, modular setup. For users, this ensures a more consistent and maintainable initialization process for the application's internal services without altering the public API.

system/src/Grav/Common/Service · high confidence

New Page and Collection Interfaces for Grav 1.7

The system now exposes a comprehensive set of interfaces in \Grav\\Common\\Page\\Interfaces\ to define the contract for page objects and collections. This includes \PageInterface\ (which aggregates content, form, routable, translation, and legacy capabilities), \PageCollectionInterface\ for managing page lists, and specialized interfaces like \PageContentInterface\, \PageFormInterface\, \PageRoutableInterface\, \PageTranslateInterface\, and \PagesSourceInterface\. This structural change standardizes how pages and their data are accessed, supporting features like Flex Pages and improved static analysis.

system/src/Grav/Common/Page/Interfaces · high confidence

Behavioural changes

Added Clockwork debugger UI assets and fixed phpdebugbar styling

This change introduces new CSS and JavaScript assets for the Clockwork debugger, adding a fixed-position badge with a hover tooltip that directs users to the Clockwork Web interface or browser extension. It also includes a CSS fix for phpdebugbar to correct the background image for the restore button, ensuring proper visual rendering of the debug bar controls.

system/assets/debugger · high confidence

Added Monolog 3 compatibility shim for legacy installations

Grav now includes a compatibility layer in the Framework/Compat/Monolog directory to support upgrades to Monolog 3. This shim provides a backport of the Monolog\\Utils class (including JSON encoding and path canonicalization utilities) for environments where the full Monolog 3 library is not yet present, ensuring that newer Grav code can run without fatal errors on older Monolog versions.

system/src/Grav/Framework/Compat/Monolog · high confidence

Added abstract Flex base classes and fixed MediaInterface implementation

The Flex component now provides abstract base classes (FlexObject, FlexCollection, FlexIndex) in the Grav namespace that extend the core framework equivalents and integrate Grav-specific traits. FlexObject now explicitly implements MediaInterface, ensuring Flex objects correctly expose media capabilities, and includes logic to handle media order fields and strip unnecessary URL data during storage preparation.

system/src/Grav/Common/Flex · high confidence

An empty assets folder has been introduced to the project structure, containing a .gitkeep file that includes a copyright notice for Trilby Media, LLC covering the years 2015 to 2023. This ensures the directory is tracked by version control and establishes the legal ownership header for any future assets added to this location.

assets · high confidence

Added default system templates for fallback rendering, markdown output, and metadata

The system now ships with a set of default Twig templates in \system/templates\ to handle core rendering scenarios when no theme is active or when specific formats are requested. This includes \default.html.twig\ and \modular/default.html.twig\ which provide a basic error-aware fallback for pages missing a theme template, and \default.md.twig\ which enables serving page content as raw Markdown (useful for AI agents or text clients) when the \markdown\_output\ configuration is enabled. Additionally, \partials/metadata.html.twig\ now handles page metadata tags and injects a \text/markdown\ alternate link when appropriate, while \partials/messages.html.twig\ provides a standard structure for displaying site notifications. Flex-related templates (\flex/404.html.twig\, \flex/\_default/collection/debug.html.twig\, \flex/\_default/object/debug.html.twig\) are also added to support debugging and error handling for Flex objects.

system/templates · high confidence

Added deprecated EventSubscriberInterface shim

A new \EventSubscriberInterface\ has been added to the RocketTheme Toolbox, extending Symfony's \EventSubscriberInterface\. This interface serves as a compatibility shim for existing event subscriber implementations but is marked as deprecated, indicating that users should migrate to the PSR-14 implementation in the future.

system/src/RocketTheme · high confidence

Added placeholder files for cache, images, and logs directories

Placeholder .gitkeep files have been added to the cache, images, and logs directories to ensure these folders are tracked by version control. This change ensures that the directory structure is preserved in the repository, which is important for maintaining the expected layout of application data and logs.

cache, images, logs, user/plugins, user/themes · high confidence

Added temporary directory placeholder

A new \tmp\ folder has been added to the project root, containing a \.gitkeep\ file with an updated copyright notice (2015–2023) to ensure the directory is tracked by version control.

tmp · high confidence

Automatic Twig 1/2 to Twig 3 template compatibility layer

Grav now includes a compatibility layer that automatically rewrites legacy Twig 1/2 template syntax to work with Twig 3. This change introduces a new loader and transformer in the system core that intercepts template source code and applies on-the-fly transformations, including converting \{% raw %}\ to \{% verbatim %}\, \{% spaceless %}\ to \{% apply spaceless %}\, \{% filter %}\ to \{% apply %}\, and updating \sameas\ tests to \same as\. It also handles legacy \for\ loop guard syntax, \divisibleby\ and \none\ tests, and updates the \replace\ filter signature. Additionally, the new loader proxies standard FilesystemLoader methods and supports the \addLoader()\ capability, ensuring plugins that dynamically register template paths continue to function correctly without modification.

system/src/Grav/Common/Twig/Compatibility · high confidence

Backup system initialization and scheduler integration

The backup system now initializes lazily via the \onSchedulerInitialized\ event rather than on every request, improving performance. Backup profiles are registered as scheduler jobs with support for environment-specific scheduling, explicit enable/disable toggles, and backlinks to the backups tool page. Download URLs are generated using sanitized filenames via \Utils::basename()\ to prevent path traversal issues.

system/src/Grav/Common/Backup · high confidence

Backward-compatible cache layer replaces abandoned Doctrine Cache

The system now uses Symfony Cache as the underlying storage engine, replacing the unmaintained Doctrine Cache package. To ensure existing extensions continue to function without modification, a compatibility layer has been added in \system/src/Doctrine/Common/Cache\ that re-implements the legacy \Doctrine\\Common\\Cache\ interfaces (such as \Cache\, \CacheProvider\, and various multi-operation interfaces) and delegates calls to the new Symfony adapters (e.g., \FilesystemCache\ now wraps \Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter\).

system/src/Doctrine · high confidence

Blueprint validation and filtering now report specific error causes

The blueprint validation system in system/src/Grav/Common/Data has been updated to provide more precise error messages for users. Instead of generic "Invalid input" errors, the system now explicitly names values that fail option-membership checks (such as invalid selections in checkboxes or arrays) and clearly distinguishes between malformed data and length violations (too short or too long). This change improves the debugging experience by pinpointing the exact cause of validation failures in form fields.

system/src/Grav/Common/Data · high confidence

Compiled file caching for YAML, JSON, and Markdown

Grav now compiles YAML, JSON, and Markdown files into cached PHP arrays to improve performance and ensure changes are detected reliably. The new \CompiledFile\ trait (used by \CompiledYamlFile\, \CompiledJsonFile\, and \CompiledMarkdownFile\) implements a fast-path cache that includes metadata (class, modification time, size) to avoid re-parsing unchanged files, while gracefully handling corrupt cache entries by regenerating them. This reduces memory usage and speeds up configuration and page loading, especially when OPcache is enabled.

system/src/Grav/Common/File · high confidence

Default configuration and security hardening for user/config

The default user configuration has been updated to ship with production-suitable settings, including enabling the cache and debugger provider (Clockwork) while keeping the debugger disabled by default. The default theme is set to 'quark2', and the GPM release channel is configured to 'stable' with peer verification enabled. Additionally, a new .htaccess file has been added to the user/config directory to block direct web access to sensitive configuration files, ensuring they are only read server-side.

user/config · high confidence

Deprecation of legacy User object methods

A new \UserObjectLegacyTrait\ has been introduced to handle backward compatibility for the User object in Grav's Flex system. This trait deprecates several older methods, including \merge()\, \getAvatarMedia()\, \avatarUrl()\, \authorise()\, and \count()\. Users relying on these methods will now receive deprecation warnings and are advised to migrate to the newer equivalents: \update()\, \getAvatarImage()\, \getAvatarUrl()\, \authorize()\, and standard PHP countable implementations respectively. This change ensures smoother transitions for existing code while encouraging the use of updated, validated APIs.

system/src/Grav/Common/Flex/Types/Users/Traits · high confidence

Deprecation of legacy User, Group, and Access classes in favor of Flex-based accounts

The \Grav\\Common\\User\ namespace has been refactored to deprecate the legacy \User\, \Group\, and \Access\ classes. Static methods such as \User::load()\, \User::find()\, and \User::remove()\ now emit deprecation warnings and redirect to the new \$grav\['accounts'\]\ Flex collection interface. Similarly, \Group\ methods are deprecated in favor of \$grav\['user\_groups'\]\. This change signals that the traditional YAML-based user/group management is being superseded by the Flex system, and users should migrate their code to use the new service-based account management APIs.

system/src/Grav/Common/User · high confidence

Enforce user/ folder security rules in subdirectories

A new .htaccess file in the user/ directory now enforces security restrictions on sensitive files (such as config, env, and source code) and public assets (avatars and data) within all subdirectories. This change prevents third-party plugins or themes from disabling these protections by using their own RewriteEngine rules, ensuring that dangerous file types are blocked and only allowed media assets are served, even in nested folders.

user · high confidence

Enhanced collection filtering and natural sorting

The collection framework now supports string manipulation functions (LENGTH, LOWER, UPPER, LTRIM, RTRIM, TRIM) within matching criteria, allowing users to filter objects based on transformed field values. Additionally, sorting by string fields has been improved to use natural, case-insensitive ordering, ensuring that items like 'Item 2' appear before 'Item 10' regardless of capitalization.

system/src/Grav/Framework/Object/Collection · high confidence

Form framework interfaces formalized with new contracts

The Form framework in \system/src/Grav/Framework/Form/Interfaces\ now exposes explicit contracts for its core components. \FormInterface\ defines the standard API for form handling, including methods for validation, submission, nonce management, and accessing blueprint data. \FormFlashInterface\ standardizes the persistence of form state (including file uploads) across requests, while \FormFactoryInterface\ provides the entry point for creating form instances from pages. These interfaces establish a clearer separation of concerns and stricter typing for form operations.

system/src/Grav/Framework/Form/Interfaces · high confidence

FormFlash legacy file handling methods deprecated

The \FormFlash\ class in \system/src/Grav/Common/Form\ now exposes \getLegacyFiles()\, \uploadFile()\, and \cropFile()\ methods that are explicitly marked as deprecated in version 1.6. These methods provide backwards compatibility for legacy file upload and cropping workflows but should not be used in new code, as the underlying framework implementation is preferred.

system/src/Grav/Common/Form · high confidence

GPM CLI commands refactored into dedicated command classes with new preflight and version capabilities

The GPM console commands have been restructured into individual classes (DirectInstallCommand, IndexCommand, InfoCommand, InstallCommand, PreflightCommand, SelfupgradeCommand, UninstallCommand, UpdateCommand, VersionCommand) to improve modularity and maintainability. The new PreflightCommand allows users to run upgrade checks without modifying the installation, while the VersionCommand provides detailed version and update status for Grav and installed packages. The IndexCommand now supports filtering by installed/updates-only and sorting options. The SelfupgradeCommand includes PHP version requirement checks and major version upgrade warnings. The InstallCommand now handles specific version installation via package:version syntax and dependency management. The UninstallCommand checks for dependent packages before removal. The UpdateCommand provides warnings about major/minor upgrades and recommends updating plugins/themes before core upgrades for major version changes.

system/src/Grav/Console/Gpm · high confidence

GPM now blocks cross-major upgrades and surfaces next-major migration hints

The Grav Package Manager (GPM) now prevents automatic self-upgrades that would jump across a major release boundary (e.g., 1.x to 2.x), ensuring users stay within their current release family. Additionally, the Upgrader component now exposes information about the next major version and a migration URL, allowing the system to display informational notices about upcoming major releases without triggering an automatic upgrade.

system/src/Grav/Common/GPM · high confidence

GPM remote package handling refactored with new repository logic and cross-major migration hints

The remote package management layer in system/src/Grav/Common/GPM/Remote has been restructured to improve reliability and provide better upgrade guidance. The new implementation uses HTTPS for all repository requests and includes the current Grav version and PHP version in index requests to ensure accurate package data. A new \next\_major\ hint is surfaced from the remote repository, allowing the Upgrader to display cross-major migration notices. Additionally, the \Package::jsonSerialize()\ method now correctly returns an array, and changelog retrieval has been added for both Grav core and individual packages.

system/src/Grav/Common/GPM/Remote · high confidence

Grav 2.1.9 core system files and configuration

This update introduces the core system files for Grav version 2.1.9, including a new \defines.php\ that establishes the application version, sets the minimum PHP requirement to 8.3.0, and implements native \.env\ support for environment variable loading. The release also includes a new \install.php\ to handle installer logic during upgrades, a \rector.php\ configuration for code modernization targeting PHP 8.4, and a \router.php\ script for the built-in PHP CLI server that enforces security rules by blocking direct access to sensitive directories and file types.

system · high confidence

Grav installer rewritten with new versioning and YAML update infrastructure

The core installer logic in system/src/Grav/Installer has been completely rewritten to support a more robust upgrade and installation process. This change introduces a new VersionUpdater and VersionUpdate system that manages extension version history and schema tracking via a dedicated Versions class, allowing for granular pre- and post-installation hooks. Additionally, a new YamlUpdater class has been added to handle configuration file updates while preserving hand-written comments and formatting where possible. The installer now enforces stricter minimum requirements, specifically PHP 7.3.6 and Grav 1.7.51, and includes updated recommended versions for core plugins like Admin, Email, Form, and Login. These changes improve the reliability of self-upgrades and new installations by providing better error handling and state management during the installation process.

system/src/Grav/Installer · high confidence

Improved exception handling and PUT/PATCH multipart support

The request handling middleware now provides two key improvements. First, the new Exceptions middleware ensures that error messages in JSON responses are properly escaped to prevent injection issues, while ValidationException messages are left unescaped to preserve their original content; detailed trace information (type, file, line, stack trace) is now included in the JSON error response only when the debugger is enabled. Second, the new MultipartRequestSupport middleware enables the server to correctly parse multipart/form-data requests sent via PUT and PATCH methods, allowing these HTTP verbs to handle file uploads and form fields just like POST requests.

system/src/Grav/Framework/RequestHandler/Middlewares · high confidence

Introduce dedicated storage classes for user accounts

Added \UserFileStorage\ and \UserFolderStorage\ classes to handle user account persistence. These classes extend the base file and folder storage implementations and override the \prepareRow\ method to ensure the \access\ data is correctly preserved during save operations, addressing issues where account data might be lost or corrupted.

system/src/Grav/Common/Flex/Types/Users/Storage · high confidence

Local package management and compatibility detection

The GPM now tracks locally installed plugins and themes via new Local package classes. Each local package exposes a safe HTML description (rendered with Parsedown in safe mode) and a plain-text version, and detects whether the package is a symbolic link. Compatibility metadata is resolved from the package blueprint or inferred from dependencies, with explicit support for Grav 2.0, 1.8, and 1.7 version gating.

system/src/Grav/Common/GPM/Local · high confidence

Media traits refactored and security hardening for image attributes and audio/video URLs

The media handling logic in system/src/Grav/Common/Media/Traits has been reorganized into specialized traits (AudioMediaTrait, ImageDecodingTrait, ImageFetchPriorityTrait, ImageLoadingTrait, ImageMediaTrait, MediaFileTrait, MediaObjectTrait, MediaPlayerTrait, MediaTrait, MediaUploadTrait, StaticResizeTrait, ThumbnailMediaTrait, VideoMediaTrait). This change introduces new image attributes (decoding, fetchpriority, loading) configurable via system settings, and hardens security by escaping media URLs in audio/video source tags and validating resize dimensions to prevent CSS injection. It also refactors media file operations, upload handling, and thumbnail management into modular traits for better maintainability.

system/src/Grav/Common/Media/Traits · high confidence

Native .env support and refactored configuration compilation

Grav now supports native .env files (via Symfony Dotenv) to configure environment variables early in the bootstrap process, allowing secrets to be kept outside the web root. The configuration loading system has been refactored to use new compiled classes (CompiledBase, CompiledConfig, CompiledBlueprints, CompiledLanguages) that cache and optimize the merging of YAML files, improving performance and reliability. Additionally, a new \user-data://\ stream has been added for writable user data, and the \media://\ stream is now environment-aware.

system/src/Grav/Common/Config · high confidence

New ACL framework with inheritance and custom permissions

The system introduces a new Access Control List (ACL) framework in the \Grav\\Framework\\Acl\ namespace, replacing the previous implementation. This update adds support for hierarchical permission inheritance, allowing child access rules to automatically inherit settings from parent scopes. It also enables the definition of custom permissions via configuration files, parsed by the new \PermissionsReader\ which supports YAML-based action and type definitions with dependency resolution. The \Access\ class now tracks inherited actions, and the \Permissions\ class provides a structured registry for action types and instances, improving how administrators define and manage granular access rights.

system/src/Grav/Framework/Acl · high confidence

New Flex Storage implementations with metadata and prefix support

The Flex storage layer has been refactored to introduce new storage classes (\AbstractFilesystemStorage\, \FolderStorage\, \FileStorage\, and \SimpleStorage\) that improve how data is persisted and retrieved. \SimpleStorage\ now supports a \prefix\ option to keep items under nested arrays and ensures the modified time is updated on save. \FolderStorage\ and \FileStorage\ provide more robust file-based storage with support for custom key lengths, partial deletes, and recursive filtering. All storage classes now implement \getMetaData()\ to return updated object meta information (such as timestamps) alongside the data, and \hasKeys()\ is available to check for the existence of multiple keys efficiently.

system/src/Grav/Framework/Flex/Storage · high confidence

New Grav Framework Session component replaces legacy implementation

The system now uses a new \Grav\\Framework\\Session\ component to manage user sessions, replacing the previous \RocketTheme\\Toolbox\\Session\ implementation. This change introduces a dedicated \Session\ class and \SessionInterface\ that allow administrators to configure all standard PHP session options (such as \cookie\_samesite\, \gc\_maxlifetime\, and \save\_handler\) via the \system.session.options\ configuration file. The new component also includes a \Messages\ class for handling scoped flash messages and a \SessionException\ for error handling, providing improved session fixation protection and better compatibility with modern PHP versions.

system/src/Grav/Framework/Session · high confidence

New HTTP client abstraction using Symfony HttpClient

Grav now provides a new \Grav\\Common\\HTTP\\Client\ and \Response\ class that wraps the Symfony HttpClient component, replacing the previous internal HTTP implementation. This change introduces a unified interface for making HTTP requests, supporting configurable transport methods (cURL, native, or auto-selected), proxy settings, peer/host verification, and progress callbacks. Users relying on the previous internal HTTP mechanisms will see a behavioral shift as the system now delegates to Symfony's robust HTTP client, ensuring better compatibility and performance for remote requests.

system/src/Grav/Common/HTTP · high confidence

New event classes and improved request handler event behavior

This change introduces new event classes (\RequestHandlerEvent\, \PageEvent\, \TypesEvent\) and refactors the base \Event\ class to support PSR-14 compatibility and better upgrade handling. Specifically, the \RequestHandlerEvent\ now allows setting a Response object, enabling early termination of the request handling process. The base \Event\ class includes logic to map to Symfony Contracts or legacy Symfony Event classes when available, falling back to a minimal implementation otherwise, which helps resolve event errors during upgrades.

getgrav/grav · high confidence

New user and authorization interfaces defined

The system introduces a set of new interfaces in the user component to standardize user data handling and access control. AuthorizeInterface defines the contract for checking user authorization against specific actions and scopes. UserInterface expands the user data model by extending DataInterface, MediaInterface, and other standard interfaces, adding methods for dot-notation data access, avatar image retrieval, and authentication. UserGroupInterface extends AuthorizeInterface to enforce authorization checks on groups. UserCollectionInterface extends Countable and defines methods for loading, finding, and deleting user accounts, enabling direct counting of existing users.

system/src/Grav/Common/User/Interfaces · high confidence

Pimple dependency container brought in-house

The Pimple dependency injection container has been copied directly into the application's source tree (system/src/Pimple) for continued internal development. This change includes the core Container class, PSR-11 compatibility wrappers, service iterators, and specific exception classes, replacing any previous external dependency with a local implementation.

system/src/Pimple · high confidence

Plugin CLI commands now support aliases

The PluginCommandLoader now registers command aliases alongside their primary names, allowing users to invoke plugin console commands using any defined alias. This change ensures that if a plugin command defines aliases, they are all available for lookup and execution via the CLI.

system/src/Grav/Console/Application/CommandLoader · high confidence

Re-added .gitkeep to preserve backup directory in version control

The .gitkeep file has been restored in the backup directory to ensure the folder is tracked by Git and persists in the repository structure. This change also updates the copyright notice within the file to reflect the 2015–2023 period for Trilby Media, LLC.

backup · high confidence

Redesigned error page with improved layout and Safari support

The system error page has been completely restyled to provide a cleaner, centered layout that renders correctly in Safari and other browsers. The new design uses Flexbox for vertical centering and includes updated typography and spacing, ensuring that error messages are displayed clearly to users when a server error occurs.

system/src/Grav/Common/Errors/Resources · high confidence

Refactored Asset Manager into reusable traits

The internal implementation of the Grav Asset Manager has been restructured by extracting its logic into three distinct traits: AssetUtilsTrait, LegacyAssetsTrait, and TestingAssetsTrait. This change introduces a new utility trait for handling asset pipeline operations, such as fetching remote/local files, rewriting CSS/JS paths, and managing HTML attributes. It also adds a legacy compatibility trait that normalizes argument formats for older API calls (e.g., converting positional arguments to options arrays) and deprecates specific methods like addAsyncJs and addDeferJs in favor of dynamic loading attributes. Finally, a testing trait is provided to expose internal asset collections and states for unit testing purposes.

system/src/Grav/Common/Assets/Traits · high confidence

Refactored CLI application structure and added blue output styling

The CLI console application has been restructured into a base Application class and specialized subclasses (GravApplication, GpmApplication, PluginApplication) to better organize command registration. This change fixes an issue where the --env and --lang options were ignored if they appeared after other arguments, ensuring environment and language settings are now correctly applied regardless of option order. Additionally, the console output formatter now supports a \<blue\> tag for styled text.

system/src/Grav/Console/Application · high confidence

Refactored CLI command execution with new base classes and trait

The CLI infrastructure in system/src/Grav/Console has been restructured by introducing three new base command classes—ConsoleCommand, GpmCommand, and GravCommand—that all utilize the ConsoleTrait. This change centralizes console setup, language handling, and Grav initialization logic into the trait, ensuring that plugins, themes, and pages are properly initialized during CLI operations. Users will benefit from more reliable command execution, particularly for GPM operations and cache clearing, as the new structure enforces consistent initialization sequences and resolves previous issues with early theme/plugin initialization and cache compatibility in CLI environments.

system/src/Grav/Console · high confidence

Refactored Flex Page traits to align with legacy Page behavior

The Flex Pages system now uses dedicated traits (PageContentTrait, PageLegacyTrait, PageRoutableTrait, PageTranslateTrait) to implement core page functionalities. This change ensures that Flex pages behave more consistently with traditional Grav pages by implementing methods for ID generation, date handling, parent/child navigation, active state detection, and multi-language translation lookups. Users will see improved compatibility with existing plugins and themes that rely on standard Page interface methods when working with Flex content.

system/src/Grav/Common/Flex/Types/Pages/Traits · high confidence

Refactored GPM package handling with new common classes

The GPM (Grav Package Manager) internals have been restructured to unify how installed and remote packages are managed. This change introduces three new classes in the \Grav\\Common\\GPM\\Common\ namespace: \AbstractPackageCollection\ provides a base for iterating and serializing package lists to JSON or arrays; \CachedCollection\ adds a static caching layer to speed up package retrieval; and \Package\ acts as a wrapper around blueprint data, implementing \Stringable\ and providing accessors for package properties. This refactoring aims to improve code readability and consistency across the GPM system.

system/src/Grav/Common/GPM/Common · high confidence

Refactored Object and Collection classes with new ArrayObject and LazyObject types

The Object framework in \system/src/Grav/Framework/Object\ has been significantly restructured. New concrete classes \ArrayObject\ and \LazyObject\ have been introduced to handle data storage via private arrays and lazy-loaded properties respectively, both implementing \NestedObjectInterface\ and \ArrayAccess\. The \ObjectCollection\ class now extends \ArrayCollection\ and utilizes \ObjectExpressionVisitor\ for filtering and sorting, while \ObjectIndex\ provides an abstract base for indexed object collections with lazy loading capabilities. These changes replace previous implementations, altering how objects and their collections are instantiated and accessed within the framework.

system/src/Grav/Framework/Object · high confidence

Refactored Object serialization and property handling into base traits

The \ObjectCollectionTrait\ and \ObjectTrait\ in the Grav Framework have been refactored to standardize how objects are serialized, deserialized, and accessed. Serialization now explicitly validates the object type during unserialization to prevent data corruption, and the \\_\unserialize\ method automatically triggers \initObjectProperties\ if available. Property access methods (\getProperty\, \setProperty\, etc.) now return \$this\ to support method chaining, and the \ObjectTrait\ adds a \\\_toString\ implementation that returns the object's key.

system/src/Grav/Framework/Object/Base · high confidence

Refactored asset management with per-file cache-busting and block support

The Assets component has been refactored to support granular cache-busting and content blocks. For local assets, the system now uses per-file modification times (mtime) for cache-busting tokens when the \enable\_asset\_timestamp\ config is active, ensuring that editing a single file invalidates only its own URL rather than the entire global cache key. Additionally, a new \BlockAssets\ class has been introduced to automatically register styles, scripts, links, and HTML from \HtmlBlock\ content, allowing content-defined assets to be managed alongside standard page assets.

system/src/Grav/Common/Assets · high confidence

Refactored error handling with lazy initialization and production-safe JSON responses

The error handling system in system/src/Grav/Common/Errors has been restructured to improve performance and security. The Whoops error handler stack is now built lazily only when an error actually occurs, rather than at every request bootstrap. A new BareHandler ensures HTTP status codes (400-599) are correctly propagated for production sites where error display is disabled. Additionally, a new SimpleJsonHandler provides sanitized JSON error responses for API/AJAX requests when error display is off, preventing the leakage of internal file paths and exception details to unauthenticated clients.

system/src/Grav/Common/Errors · high confidence

Refactored object property storage with new trait hierarchy

The property handling in the Grav Framework Object system has been restructured into a modular trait hierarchy. A new \ArrayPropertyTrait\ stores properties in a simple array, while \ObjectPropertyTrait\ enforces strict, pre-defined class member variables with lazy loading and serialization hooks (\offsetLoad\, \offsetPrepare\, \offsetSerialize\). These are combined into \MixedPropertyTrait\ (allowing both defined and undefined properties) and \LazyPropertyTrait\ (lazy-loading undefined properties from the array). This change alters how object properties are stored, accessed, and serialized, potentially affecting any code relying on the previous internal property management implementation.

system/src/Grav/Framework/Object/Property · high confidence

Refactored user authentication, authorization, and avatar handling

The UserTrait now centralizes core user logic, introducing stricter two-factor authentication checks that only exempt exact login actions (login, site.login, admin.login) from the 2FA requirement. Avatar retrieval has been improved to support StaticImageMedium formats and robustly handle URLs provided by third-party providers, falling back to configured generators like Multiavatar or Gravatar when no local image is found.

system/src/Grav/Common/User/Traits · high confidence

Replace external DOM iterators with internal implementations

The system now uses internally maintained \DOMLettersIterator\ and \DOMWordsIterator\ classes to iterate over text and CDATA nodes in the DOM, replacing the previously used external \DOMIterators\ library. This change resolves PHP 8.1 deprecation warnings associated with the unmaintained external package and includes a fix for an off-by-one error in the iterator keys, ensuring accurate position tracking for characters and words within the document structure.

system/src · high confidence

Request lifecycle refactored into PSR-15 middleware processors

Grav's request handling has been restructured from a monolithic initialization sequence into a chain of distinct, PSR-15 compliant processor classes (e.g., InitializeProcessor, RequestProcessor, PagesProcessor, RenderProcessor). This change allows plugins and core components to hook into specific stages of the request lifecycle via new events (such as onAssetsInitialized, onPluginsInitialized, and onPageTask) and enables the use of custom task controllers. The refactoring also introduces lazy initialization for the scheduler to reduce overhead and adds support for JSON request bodies and markdown output headers.

system/src/Grav/Common/Processors · high confidence

Resilient Twig template cache prevents 500 errors on unreliable filesystems

Grav now uses a custom \ResilientFilesystemCache\ for Twig template compilation that catches write failures (such as those caused by VirtualBox shared folders, network mounts, or full disks) and logs a warning instead of throwing a fatal error. This ensures that concurrent requests or race conditions during cache clearing no longer result in 500 Internal Server Errors for visitors, as the current request will still render correctly via Twig's eval fallback while the failed cache write is retried on the next request.

system/src/Grav/Common/Twig · high confidence

Reworked Object and Collection interfaces with nested property support

The Object framework interfaces have been significantly updated to support nested property access and enhanced collection operations. ObjectInterface and ObjectCollectionInterface now define methods for getting, setting, and checking properties, while new NestedObjectInterface and NestedObjectCollectionInterface add support for accessing nested properties using dot-notation separators. ObjectCollectionInterface also introduces grouping capabilities via group() and collectionGroup(), along with ordering and limiting methods (orderBy, limit) and a copy() method for deep-cloning collections. These changes represent a major update to the object model, potentially affecting existing implementations that rely on the previous interface structure.

system/src/Grav/Framework/Object/Interfaces · high confidence

Security and validation improvements for user account management

The DataUser implementation now enforces stricter validation when saving user accounts, specifically checking for path traversal attacks and ensuring username uniqueness to prevent overwriting existing accounts. Username filtering is standardized to lowercase to support case-insensitive handling, and password updates now require matching confirmation fields before hashing. Additionally, saving a user now explicitly clears the Flex cache to ensure consistency, and the UserCollection implements the Countable interface to allow checking the total number of existing user accounts.

system/src/Grav/Common/User/DataUser · high confidence

Styling updates for the Whoops error handler interface

The Whoops error handler's visual presentation has been updated with new CSS rules. The header background is now blue (\#3085EE), primary exception titles are white, secondary titles are light gray (\#ddd), and non-active stack frames turn light gray on hover. The left panel background now inherits from its parent.

system/assets · high confidence

Updated jQuery to version 2.2.4

The jQuery library in system/assets/jquery has been updated to version 2.2.4. This change replaces the previous version with the new minified file, ensuring that applications relying on this asset use the updated library which includes bug fixes and performance improvements from the 2.2.x series.

system/assets/jquery · high confidence

Fixes

Flex User system refactored with new collection, index, and object classes

The Flex User implementation has been restructured into dedicated \UserCollection\, \UserIndex\, and \UserObject\ classes. This change introduces case-insensitive user lookups by normalizing usernames and emails, ensures the user index properly implements the \UserCollectionInterface\, and adds support for searching users by email, storage key, and flex key. It also standardizes user creation and deletion workflows within the Flex directory structure.

system/src/Grav/Common/Flex/Types/Users · high confidence

Test coverage

Added Codeception test support classes and helpers; Added Markdown conformance and performance testing harness; Added PHPStan static analysis configuration and custom extensions; Added functional test infrastructure and skeleton for DirectInstallCommand; Added test fixtures for Twig-first and Markdown-first page processing; Added test fixtures for asset timestamps and strict blueprint validation; Added unit tests for CsvFormatter and Filesystem classes; Added unit tests for Excerpts and FileReader helpers; Added unit tests for GPM console commands; Added unit tests for GPM dependency merging, installer destination checks, license resolution, and upgrade family gating; Added unit tests for Grav Twig Extension filters and functions; Added unit tests for InitializeProcessor trailing-slash redirect behavior; Added unit tests for Twig 3 compatibility transformations; Added unit tests for Twig extension behavior and compatibility; Added unit tests for atomic compiled file caching and parallel access safety; Added unit tests for blueprint validation, security guards, and field constraints; Added unit tests for core security hardening measures; Added unit tests for image format/quality propagation, media URL handling, metadata queries, and accessibility attributes; Added unit tests for installer compatibility checks and version upgrade logic; Added unit tests for language code orientation and HTTP accept-language fallback; Added unit tests for native .env configuration support; Added unit tests for page content processing, ordering, and URL generation; Added unit tests for service providers; Added unit tests for the Markdown parsing engine and extensions; Added unit tests for the Twig Sandbox Config facade; Expanded unit test coverage for Grav Common components; Initial Codeception test infrastructure setup; Unit tests for Markdown output feature.

Dependencies

Updated bundled composer.phar binary to version 2.0.9

The bundled composer.phar binary has been updated to version 2.0.9. This ensures that local package management operations performed via the Grav CLI continue to function correctly with the latest Composer release.

(repo-wide) · high confidence

Upgrade to PHP 8.3 and Symfony 7 components

The project now requires PHP 8.3 and has upgraded core Symfony dependencies (Cache, YAML, Console, EventDispatcher, VarExporter, VarDumper, Process, HttpClient) to version 7.0. Other key library updates include Twig (3.x-dev), Monolog (^3.0), Doctrine Collections (^2.2), Parsedown (^2.0), and the custom getgrav/image (^4.0) and getgrav/cache (^2.0) packages. Development tooling has also been updated, including PHPStan (^2.1), PHPUnit code coverage (^11.0), and Codeception (^5.1).

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 59 → 55 (-3.6)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 71 → 82 (+10.5)
  • Architecture 100 → 97 (-3.3)
  • Maturity 52 → 53 (+0.4)
  • Readiness 65 → 83 (+18.5)
  • Security 58 → 73 (+14.8)
  • Accessibility 43 (new)

Resolved (111)

  • Backups.backup (cyclomatic 16) (system/src/Grav/Common/Backup/Backups.php)
  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (composer.lock)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (10 lines × 2) (system/src/Grav/Common/Flex/Types/Pages/PageIndex.php)
  • Duplicated block (10 lines × 2) (system/src/Grav/Common/Media/Traits/MediaObjectTrait.php)
  • Duplicated block (10 lines × 2) (system/src/Grav/Installer/Install.php)
  • Duplicated block (10 lines × 3) (system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php)
  • Duplicated block (10 lines × 3) (system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php)
  • Duplicated block (10 lines × 3) (system/src/Grav/Common/Service/ConfigServiceProvider.php)
  • Duplicated block (10 lines × 3) (system/src/Grav/Framework/Flex/FlexCollection.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/Filesystem/ZipArchiver.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/GPM/GPM.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/Grav.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/Page/Page.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Common/Scheduler/Scheduler.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Console/Gpm/SelfupgradeCommand.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Framework/ContentBlock/HtmlBlock.php)
  • Duplicated block (11 lines × 2) (system/src/Grav/Framework/ContentBlock/HtmlBlock.php)
  • …and 91 more

New (336)

  • Change coupling: InfoCommand.php ↔ UpdateCommand.php (system/src/Grav/Console/Gpm/InfoCommand.php)
  • Change coupling: PageCollection.php ↔ PageIndex.php (system/src/Grav/Common/Flex/Types/Pages/PageCollection.php)
  • ClassTooLong: Debugger (system/src/Grav/Common/Debugger.php)
  • ClassTooLong: FlexDirectory (system/src/Grav/Framework/Flex/FlexDirectory.php)
  • ClassTooLong: FlexObject (system/src/Grav/Framework/Flex/FlexObject.php)
  • ClassTooLong: GPM (system/src/Grav/Common/GPM/GPM.php)
  • ClassTooLong: GravExtension (system/src/Grav/Common/Twig/Extension/GravExtension.php)
  • ClassTooLong: Install (system/src/Grav/Installer/Install.php)
  • ClassTooLong: InstallCommand (system/src/Grav/Console/Gpm/InstallCommand.php)
  • ClassTooLong: Installer (system/src/Grav/Common/GPM/Installer.php)
  • ClassTooLong: Job (system/src/Grav/Common/Scheduler/Job.php)
  • ClassTooLong: Page (system/src/Grav/Common/Page/Page.php)
  • ClassTooLong: PageIndex (system/src/Grav/Common/Flex/Types/Pages/PageIndex.php)
  • ClassTooLong: Pages (system/src/Grav/Common/Page/Pages.php)
  • ClassTooLong: Scheduler (system/src/Grav/Common/Scheduler/Scheduler.php)
  • ClassTooLong: SelfupgradeCommand (system/src/Grav/Console/Gpm/SelfupgradeCommand.php)
  • ClassTooLong: Uri (system/src/Grav/Common/Uri.php)
  • ClassTooLong: Utils (system/src/Grav/Common/Utils.php)
  • ClassTooLong: Validation (system/src/Grav/Common/Data/Validation.php)
  • Coverage not measured — no coverage collector is wired up
  • …and 316 more

Changes since last survey

  • 225 commits — 194 feature/other, 31 fixes

By area

  • (root) — 80 commits
  • (repo) — 65 commits
  • system/src — 60 commits
  • tests/unit — 8 commits
  • system/defines.php — 5 commits
  • .github/workflows — 2 commits
  • system/config — 2 commits
  • tests/fake — 1 commit
  • tests/phpstan — 1 commit
  • webserver-configs/lighttpd.conf — 1 commit

Notable commits

  • fix: Add CHANGELOG entry for #3540 media player alt fix (#4253)
  • fix: Add a catch-up run mode and fix five scheduler defects
  • fix: Changelog: custom_base_url prefix fix (#4296)
  • fix: Correct the $_SERVER fallback in Uri::ip() and log both env fixes
  • fix: Document image alternative settings fix and clean up test nullability
  • fix: Enforce minlength/maxlength server side, and fix the inverted step check
  • fix: Fix GRAV_CONFIG env override gate to also check $_SERVER/$_ENV (#4286)
  • fix: Fix custom_base_url matching pages by literal prefix instead of path segment (#4296)
  • fix: Fix date2timestamp() misparsing non-string dates (#3812) (#4292)
  • fix: Fix form fields printing their attributes as text (#4256)
  • fix: Fix invalid alt attributes on media players
  • fix: Follow-ups to the merged 2.0.20 bugfix PRs
  • fix: Guard the Twig fork patches with tests, and fix custom escaper registration
  • fix: Merge branch 'fix/admin-next-16-scheduler-proc-open' into develop
  • fix: Merge branch 'fix/media-remove-pattern-anchor' into develop
  • fix: Revert "Register theme blueprints when any blueprints/ folder exists"
  • fix: Serve avatars and user/data media again, and finish the AllowOverride fix
  • fix: Update getgrav/image to v4.1.4 for the AVIF quality fix (#4059)
  • fix: [bugfix] debug bar missing on pages that replace the resolved page
  • fix: [bugfix] guard force_ssl against an undetermined hostname (#3703, #3702)
  • …and 205 more

Architecture

  • Containers 0 added · 0 removed · contexts 1 added · 0 removed · edges 0 added · 0 removed

Added bounded contexts (1)

  • getgrav/grav

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

getgrav/grav was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 978f7a8fde6e9f3e3252979ee64747a46c3280a5 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-be726e82e277.