ranky/media-bundle
54.8
Adequate · 22 September 2026
9.2k
lines of production code
PHP
with TypeScript
7
measurements over time
What this system is
This system is a media management service built on Symfony and React, designed to handle the storage, retrieval, and display of digital assets. It provides a comprehensive API and UI components for uploading, browsing, and filtering media files, with support for multiple database backends including PostgreSQL and MySQL. The architecture emphasizes flexibility through interface-based domain models and extensible form transformers, enabling integration with admin panels like EasyAdmin and headless API consumers.
How it got here
2022 — database and framework upgrades
40 changes.
The project expanded database support to include PostgreSQL and upgraded to Symfony 7 and React 18, requiring significant refactoring of the persistence and presentation layers. This period focused on aligning the media domain with modern Doctrine and Symfony APIs, while also introducing EasyAdmin integration and comprehensive test coverage for the new database drivers.
2023–2024 — Media management and extraction features
4 changes.
This period focused on implementing comprehensive media management capabilities, including a new React-based media library and Symfony bundle integration. It also introduced PostgreSQL-specific DQL functions for media type and date extraction, while refactoring the application layer to support path-based media lookups.
Features
Add EasyAdmin field for media file management
A new EasyAdmin field class, EARankyMediaFileManagerField, has been introduced to integrate the media file manager into the EasyAdmin interface. This field supports configuration for multiple selection, association modes, modal titles, save paths, and alignment options for image previews and buttons, enabling users to manage media files directly within the admin panel.
src/Presentation/Form/EasyAdmin · high confidence
Add PostgreSQL support and environment variable configuration
The application now supports PostgreSQL in addition to MariaDB/MySQL, allowing developers to switch database platforms via the DB\_CONNECTION environment variable. The .env file has been updated to include PostgreSQL connection parameters (POSTGRES\_VERSION, POSTGRES\_DB, etc.) and the Makefile has been improved to load environment files dynamically and pass the DB\_CONNECTION variable to the PHP container. A new docker-compose.ci.yml file and cook.yaml recipe file have been added to support CI workflows and Symfony Flex integration.
(repo-wide) · high confidence
Add Postgres DQL functions for media type and date extraction
New DQL function nodes are introduced for PostgreSQL to support media type extraction (MimeSubType, MimeType) and date component extraction (Month, Year). Each function implements a custom SQL generation (using SUBSTRING and EXTRACT) and includes a compatibility check for Doctrine ORM's Lexer/TokenType classes, ensuring support for both Doctrine ORM 2.x and 3.x versions.
src/Infrastructure/Persistence/Dql/Postgresql · high confidence
Add Ranky Media bundle recipe for Symfony
Added recipe files to configure the Ranky Media bundle in a Symfony application. This includes the bundle configuration in \ranky\_media.yaml\ (setting media/user entities and upload paths), route imports in \ranky\_media.yaml\, and the \Media\ entity and \MediaRepository\ classes required for media management.
recipes · high confidence
Add ability to retrieve media by file paths
Users can now retrieve media items by their file paths. A new \FindMediaByPaths\ class allows finding multiple media items by an array of file paths, while a new \GetMediaByFilePath\ class enables retrieving a single media item by its file path. Additionally, the existing \FindMediaByIds\ class was updated to use a local variable for ID conversion, improving code clarity.
src/Application/FindMedia · high confidence
Add database-specific DQL function registration for MySQL, PostgreSQL, and SQLite
The media bundle now registers custom DQL functions (MIME\_TYPE, MIME\_SUBTYPE, YEAR, MONTH) for MySQL, PostgreSQL, and SQLite databases. A new DqlFunctionsManager resolves the appropriate function set based on the database driver or platform class, and a LoadDqlFunctionsSubscriber automatically registers these functions during the loadClassMetadata event, ensuring consistent media metadata querying across supported database engines.
src/Infrastructure/Persistence/Dql · high confidence
Add media preview templates for EasyAdmin integration
The templates/preview directory now includes a new set of Twig templates for rendering media previews within the EasyAdmin interface. This includes a main template (easyadmin.html.twig) that routes single or multiple media fields to specific mime-type renderers (image, video, audio, text, application). Separate template files handle the visual output for each media type in both list and show views, enabling users to see previews of uploaded files directly in the admin panel.
templates/preview · high confidence
Added media library and form preview components
The assets directory now includes the complete React-based media library implementation, including the main App wrapper, MediaManager for browsing and selecting media, and MediaFormPreview for displaying selected items in forms. The update also introduces supporting hooks for media queries, filters, and settings, along with UI components like the upload dropzone, pagination, and filter controls.
assets · high confidence
Adds DQL functions for MySQL and SQLite with Doctrine ORM 3.0 compatibility
The media bundle now provides database-specific DQL functions for MySQL and SQLite, enabling SQL generation for extracting MIME types, months, and years from date fields. The implementation adds new \MimeSubType\, \MimeType\, \Month\, and \Year\ classes in both \Mysql\ and \Sqlite\ namespaces. To ensure compatibility with Doctrine ORM 3.0, the code dynamically checks for the existence of \Doctrine\\ORM\\Query\\TokenType\ and falls back to \Lexer\ for older versions, updating the parser logic to use the appropriate token type constant.
src/Infrastructure/Persistence/Dql/Mysql, src/Infrastructure/Persistence/Dql/Sqlite · high confidence
Introduce MediaPathTransformer and refactor form transformers to use MediaInterface
Added a new MediaPathTransformer that converts between media IDs and file paths, supporting both single and multiple selection modes. Refactored existing form transformers (MediaCollectionTransformer, MediaEntityTransformer) to depend on the new MediaInterface rather than the concrete Media class, improving flexibility and decoupling the presentation layer from specific domain implementations.
src/Presentation/Form/DataTransformer · high confidence
Behavioural changes
Add ULID filter support and fix month formatting in date filters
The system now supports filtering media by ULID, with a new DoctrineUlidFilterExtensionVisitor handling single and multiple ULID lookups via the UidMapperPlatform. Additionally, the year-month date filter now formats the month with a leading zero (e.g., '01' instead of '1') to ensure correct SQL query generation.
src/Infrastructure/Persistence/Orm/Filter · medium confidence
Code style fixes in ListAvailableDatesFilterResponse
The ListAvailableDatesFilterResponse class has been updated to resolve code style issues identified by PHP-CS-Fixer. This change improves code formatting and consistency within the application layer's list filtering logic.
src/Application/ListFilter · medium confidence
Enhanced media configuration API response and improved code formatting
The media configuration API now includes two new fields in its JSON response: 'supported\_image\_types' and 'placeholder\_image\_image\_types', which provide the client with the list of supported image MIME types and placeholder image types respectively. Additionally, the API controllers have been reformatted to comply with PHP CS Fixer standards, including the addition of a blank line after the opening PHP tag and improved formatting of attribute declarations.
src/Presentation/Api · high confidence
Expanded Makefile tooling with new Git, testing, and CI targets
The \tools/make\ directory now includes new Makefiles for Git operations (\git.Makefile\) and general tools (\tools.Makefile\), while existing Makefiles (\composer\, \docker\, \lint\, \test\) have been updated. Users can now use new Git commands for versioning, commit fixups, and release management. Testing targets have been enhanced with CI-specific variants (e.g., \phpunit-ci\, \behat-ci\) that run as root, and the \phpunit\ and \behat\ targets now exclude specific groups or suites (e.g., \aws\_s3\) and use \--do-not-cache-result\. Docker targets now support \--wait\ and log following. Linting targets have been split into CI and local variants, and paths for tools like \php-cs-fixer\ and \phpstan\ are now relative to \APP\_DIRECTORY\.
tools/make · medium confidence
French translation added and modal title formatting updated
A complete French translation file for the media library has been added, enabling the interface to display in French. Additionally, the 'modal\_title' translation key has been updated in both English and Spanish to remove parentheses around the file ID, aligning the formatting with the English source.
translations · medium confidence
GIF and image resize operations now return a boolean status
The \resize\ method in the file manipulation infrastructure now returns a boolean value (\true\ on success) instead of \void\. This change, applied to the FFmpeg, Gifsicle, Imagick, and Intervention resize handlers, allows callers to programmatically verify whether a resize operation completed successfully. Additionally, the Intervention handler now explicitly checks for and logs warnings for unsupported image extensions (such as WebP, AVIF, and BMP) and validates GD/Imagick extension availability before attempting to process files.
src/Infrastructure/FileManipulation · high confidence
Image preview form alignment configuration
The image preview form now supports alignment configuration. The form template has been updated to include new data attributes for preview and button justification, allowing users to control the alignment of the image preview and button elements within the form.
templates · medium confidence
Improved file renaming and URL resolution
The local file repository now automatically creates the necessary directory structure before renaming a file, preventing errors when the target directory does not exist. Additionally, the local file URL resolver has been updated to use the concrete SiteUrlResolver class instead of the interface, and now strips breakpoint identifiers from file paths during URL resolution.
src/Infrastructure/Filesystem · medium confidence
Make media entity configuration optional with default value
The media entity configuration is now optional, defaulting to 'App\\Entity\\Media' if not specified, whereas previously it was required. This change also updates the dependency injection container to register the media entity for Doctrine's target entity resolution and adds new repository definitions for MIME and available dates media queries.
src/Infrastructure/DependencyInjection · medium confidence
Make user entity optional and support custom media entity classes
The repository implementations now accept a configurable media entity class name and, for the user media repository, an optional user entity class. This allows the media bundle to work with custom media models rather than a hardcoded \Media\ class. Additionally, the \DoctrineOrmAvailableDatesMediaRepository\ now uses native SQL functions (\YEAR\, \MONTH\) instead of Doctrine's \year()\/\month()\ helpers, and the \DoctrineOrmMimeMediaRepository\ uses \MIME\_TYPE\/\MIME\_SUBTYPE\ functions, improving SQL compatibility across different database platforms.
src/Infrastructure/Persistence/Orm/Repository · high confidence
Media domain refactored to use interfaces and support additional image formats
The Media domain now relies on the new MediaInterface, with all repository contracts (MediaRepositoryInterface, MimeMediaRepositoryInterface, etc.) updated to return MediaInterface instead of the concrete Media class. The Media entity itself is now a mapped superclass implementing MediaInterface, with properties and constructor visibility relaxed to protected/static. New repository methods allow finding media by file path or name, and the NotFoundMediaException includes a new static factory for file paths. Additionally, the ImageResizeDriver enum now supports BMP and PSD formats, and the MimeType enum exposes browser-supported image types and placeholders for unsupported types.
src/Domain · high confidence
Media file manager form adds path saving and alignment options
The MediaFileManagerType now supports saving media paths instead of IDs via the new 'save\_path' option, which replaces the previous 'mapping' option. Additionally, the form now accepts 'preview\_justification' and 'button\_justification' options to control the alignment of image previews and buttons in the UI.
src/Presentation/Form · medium confidence
MediaIdType now extends UlidType
The MediaIdType class in the MediaBundle has been updated to extend UlidType, replacing its previous inheritance from a different base type. This change aligns the media identifier's database mapping with the Ulid format, ensuring consistent handling of media IDs in the persistence layer.
src/Infrastructure/Persistence/Dbal · medium confidence
Refactor Docker build and CI environment for improved isolation and PHP-FPM configuration
The Dockerfile structure is reorganized by renaming existing files to build.Dockerfile and introducing new ci.Dockerfile variants for MariaDB and PHP-FPM, separating CI build contexts from development ones. The PHP-FPM image is updated to include the pgsql and pdo\_pgsql extensions, and the entrypoint script is modified to run composer install with --no-scripts for all tool directories (behat, phpstan, php-cs-fixer) during development, while CI environments trigger a full autoload dump. Additionally, the PHP-FPM www.conf is updated to use the 'appuser' instead of 'www-data' for process ownership, and the PHP-CS-Fixer configuration is adjusted to use a different cache file path.
tools/docker · high confidence
Refactored MediaService with expanded path-based lookup capabilities
The MediaTwigService has been renamed to MediaService and moved to the Application layer, reflecting a shift in architectural responsibility. The service now supports finding media by file path (single or multiple) in addition to its existing ID-based lookups. Internally, it now relies on new FindMediaByPaths and GetMediaByFilePath application services, and its public API has been updated to accept MediaInterface rather than the concrete Media class, improving flexibility for consumers.
src/Application · high confidence
Support for custom media entity classes
The application now allows specifying a custom media entity class via the $mediaEntity constructor parameter in CreateMedia, enabling the system to instantiate and interact with subclasses or alternative implementations of the Media model. This change is accompanied by updating the data transformer layer (MediaToResponseTransformer and MediaResponse) to accept the MediaInterface instead of the concrete Media class, ensuring the transformation logic works with any implementation of the interface.
src/Application/CreateMedia · medium confidence
Twig media filters accept MediaInterface and Thumbnail objects
The \mediaUrl\ and \mediaThumbnailUrl\ Twig filters now accept \MediaInterface\ and \Thumbnail\ objects in addition to strings. When passed these objects, the filters automatically extract the file path or breakpoint, allowing templates to pass media entities directly rather than requiring manual ID or path resolution. A new \isMediaId\ filter has been added to check if a value is a valid media ID.
src/Presentation/Twig · high confidence
Updated PHPStan configuration to exclude new paths and suppress specific errors
The PHPStan static analysis configuration has been updated to exclude additional source and test paths, specifically \../../tests/var/\*\, \../../src/Infrastructure/DependencyInjection/MediaCompilerPass.php\, and \../../src/Presentation/Form/EasyAdmin/EARankyMediaFileManagerField.php\. Additionally, a new ignore rule has been added to suppress errors related to \Doctrine\\DBAL\\DriverManager\ parameters, ensuring that these specific issues are no longer reported during analysis.
tools/phpstan · high confidence
Updated PHPUnit configuration for test execution and deprecation handling
The PHPUnit configuration in tools/phpunit/phpunit.xml.dist has been modified to change the cache result file path from var/.phpunit.result.cache to .phpunit.result.cache. Additionally, the SYMFony\_DEPRECATIONS\_HELPER environment variable has been changed from max\[direct\]=0 to weak, altering how deprecations are reported during tests. The configuration also includes an excluded directory for DQL tests, though it is currently commented out.
tools/phpunit · high confidence
Updated RankyMediaBundle to support Doctrine ORM mapping
The RankyMediaBundle was updated to register a Doctrine ORM mappings pass, enabling automatic mapping of entities in the src/Domain directory. This change ensures compatibility with modern Doctrine versions by explicitly configuring the AttributeDriver for the specified domain path.
src · high confidence
Updated routing and service configuration for Symfony 7 compatibility
The application now supports Symfony 7 by conditionally importing route definitions based on the Symfony version. For Symfony 7.0 and above, routes are loaded using the 'attribute' format, while older versions continue to use the 'annotation' format. Additionally, the service configuration has been refactored to explicitly load controllers from the 'Api' and 'BackOffice' directories, and the manual registration of specific repository services has been removed in favor of auto-registration.
config · high confidence
Test coverage
Add database-specific DQL tests for MySQL, PostgreSQL, and SQLite; Added Doctrine fixtures for test data seeding; Test configuration updated to support multiple database platforms; Update form type tests to use 'association' instead of 'mapping'; Updated Behat test suite for media API; Updated media repository tests for platform compatibility and new query methods; Updated test dummy models and repository interfaces; Updated test factories and type handlers to use new MediaId creation method; Updated test infrastructure with Doctrine fixtures and interface changes; Updated tests for MediaTwigService and MediaTwigExtension; Updated translation test expectations for modal\_title.
Dependencies
Update PHP and JavaScript dependencies for Symfony 7 and React 18
The project has updated its dependency tree to support Symfony 7.0 alongside existing 5.4 and 6.0 versions, and upgraded to React 18.3.1. Specifically, the \composer.json\ now allows \^7.0\ for Symfony components (framework, translation, validator, mime, form, twig-bundle, security-bundle, uid, phpunit-bridge, dotenv, http-kernel) and \doctrine/orm\ ^3.0, while \assets/package.json\ introduces React 18.3.1 and related libraries like \@uppy\ v3 and \jotai\.
(dependencies) · high confidence
Upgrade React to version 18.3.1
The project has upgraded the React library to version 18.3.1. This update includes the latest React core implementation, which may bring performance improvements, bug fixes, and new features available in this version of the library.
public · 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 55 → 55 (-0.7)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 92 → 91 (-1.5)
- Architecture 87 → 79 (-7.9)
- Maturity 54 → 50 (-3.9)
- Readiness 52 → 58 (+5.9)
- Security 50 → 56 (+6.0)
- Domain Modelling 100 → 100 (-0.0)
- Accessibility 68 → 52 (-15.5)
Resolved (65)
- Coverage not included — suite not readable by the collector
- Critical CVE: [GHSA redacted] (assets/package-lock.json)
- Critical CVE: [GHSA redacted] (assets/package-lock.json)
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- …and 45 more
New (100)
- CI installs an unverified third-party binary (.github/workflows/ci.yaml)
- Critical CVE: [GHSA redacted] (assets/package-lock.json)
- Critical CVE: [GHSA redacted] (assets/package-lock.json)
- Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
- Documentation: no architecture or design documentation (README.md)
- Documentation: no installation or build instructions (README.md)
- Duplicated block (13 lines × 2) (src/Application/DataTransformer/Response/ThumbnailsResponse.php)
- Duplicated block (16 lines × 2) (src/Infrastructure/Persistence/Dql/Mysql/Month.php)
- Duplicated block (19 lines × 2) (src/Infrastructure/Persistence/Dql/Postgresql/Month.php)
- Duplicated block (23 lines × 6) (src/Infrastructure/Persistence/Dql/Mysql/MimeSubType.php)
- Duplicated block (6 lines × 3) (src/Domain/Service/FileCompressHandler.php)
- FormFilters.FormFilters (cognitive 16) (assets/src/components/Form/Filters/FormFilters.tsx)
- FunctionTooLong: ModalFile.ModalFile (assets/src/components/Modal/File/ModalFile.tsx)
- FunctionTooLong: ModalFileContent.ModalFileContent (assets/src/components/Modal/File/ModalFileContent.tsx)
- FunctionTooLong: PageListLayout.PageListLayout (assets/src/components/Layout/PageListLayout.tsx)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- High CVE: [GHSA redacted] (assets/package-lock.json)
- …and 80 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
ranky/media-bundle 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 611a3c3e2405d1db94a184051dcd607761971453 — 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-821afab8930d.