PHPackages                             netbull/media-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. netbull/media-bundle

ActiveSymfony-bundle[Image &amp; Media](/categories/media)

netbull/media-bundle
====================

Media bundle

v7.2.13(1w ago)115.9k↓36.8%MITPHPPHP &gt;=8.3CI passing

Since Jun 11Pushed 1w ago1 watchersCompare

[ Source](https://github.com/netbull/MediaBundle)[ Packagist](https://packagist.org/packages/netbull/media-bundle)[ RSS](/packages/netbull-media-bundle/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (42)Versions (156)Used By (0)

NetBull MediaBundle
===================

[](#netbull-mediabundle)

A Symfony bundle for managing media — images, files and video providers (YouTube, Vimeo, Youku) — with pluggable storage (local filesystem or Amazon S3), thumbnail generation and configurable access-control strategies for downloads/views. Originally a trimmed fork of [SonataMediaBundle](https://github.com/sonata-project/SonataMediaBundle).

- **PHP:** &gt;= 8.3
- **Symfony:** 7.4 (LTS)

Installation
------------

[](#installation)

```
composer require netbull/media-bundle
```

### Register the bundle

[](#register-the-bundle)

With Symfony Flex this is automatic. Otherwise add it to `config/bundles.php`:

```
return [
    // ...
    NetBull\MediaBundle\NetBullMediaBundle::class => ['all' => true],
];
```

### Import the routes

[](#import-the-routes)

The download/view endpoints live in the bundle. Add to `config/routes.yaml`:

```
netbull_media:
    resource: '@NetBullMediaBundle/config/routes.yaml'
```

This registers `netbull_media_view` (`/media/view/{id}/{format}`) and `netbull_media_download` (`/media/download/{id}/{format}`).

Configuration
-------------

[](#configuration)

Create `config/packages/netbull_media.yaml`. A minimal local-development setup:

```
netbull_media:
    default_context: default

    filesystem:
        local:
            directory: '%kernel.project_dir%/public/uploads/media'
            create: true

    cdn:
        server:
            path: /uploads/media

    contexts:
        default:
            providers:
                - netbull_media.provider.image
            formats:
                thumb:  { width: 150, height: 150 }
                normal: { width: 600 }
```

Each **context** declares which providers it accepts, its image **formats**, and the **download/view** security strategy. See [`docs/example_config.yaml`](docs/example_config.yaml)for a full, annotated example (multiple contexts, S3, signed URLs, custom strategies).

### Available services

[](#available-services)

KindService idProviders`netbull_media.provider.image`, `.file`, `.youtube`, `.vimeo`, `.youku`Filesystems`netbull_media.filesystem.local`, `netbull_media.filesystem.s3`CDN`netbull_media.cdn.server`, `netbull_media.cdn.local.server`Security strategies`netbull_media.security.public_strategy`, `.forbidden_strategy`, `.superadmin_strategy`, `.connected_strategy`, `.hash_strategy`> **Upload restrictions** — each provider's `allowed_extensions` / `allowed_mime_types` are enforced on upload using the file's **sniffed** content (not the client-supplied name/type). A file is accepted only if it matches at least one of the configured lists.

> **S3 ACL** — default to `acl: private` and serve public assets through the CDN; a `public-read`ACL makes objects world-readable and bypasses the bundle's download/view security strategies.

> **Secured downloads** — for contexts behind a download/view security strategy, S3-backed media is served according to the context's `download.mode` / `view.mode`:
>
> - `stream` (default) — the bytes are proxy-streamed through PHP in **constant memory** (lazy S3 `GetObject`, not the buffering Gaufrette adapter), returning a **same-origin 200** so SPA clients can fetch it over XHR (no cross-origin redirect → no CORS).
> - `redirect` — the client is sent a short-lived (300s) **pre-signed S3 URL**, so the file streams S3 → client and never passes through PHP (best for large files).
>
> Local storage always streams the file in chunks. Either way the access-control check runs in the controller before the response is issued.

> **Video providers (SSRF)** — video providers fetch oEmbed metadata and remote thumbnails over HTTP. Thumbnail URLs are validated before fetching (http/https to public hosts only; private, loopback and cloud-metadata addresses are refused) and redirects are disabled. To route this egress through your own controls, enable `framework.http_client` and the bundle will use the configured client.

### Thumbnail generation (sync or async)

[](#thumbnail-generation-sync-or-async)

By default thumbnails are generated **in-process** when the media is flushed. To offload resizing to a worker, enable the async strategy:

```
netbull_media:
    thumbnail:
        async: true
```

> **Optional dependency** — async mode needs the [Messenger](https://symfony.com/doc/current/messenger.html)component, which the bundle treats as an optional (suggested) dependency. Install it before enabling async:
>
> ```
> composer require symfony/messenger
> ```
>
>
>
> The message handler is only registered when `symfony/messenger` is installed, and enabling `thumbnail.async: true` without it fails fast with a clear error at container compile time. In the default sync mode the bundle works without Messenger.

When `async: true`, the bundle dispatches a `NetBull\MediaBundle\Message\GenerateThumbnailMessage` per format to the Messenger bus. Route it to an async transport so a worker does the resizing (worker recycling provides the memory isolation that long-running image processing needs):

```
# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            async: '%env(MESSENGER_TRANSPORT_DSN)%'
        routing:
            NetBull\MediaBundle\Message\GenerateThumbnailMessage: async
```

```
php bin/console messenger:consume async --memory-limit=256M
```

With no transport routing configured, Messenger handles the message synchronously, so async mode is safe to enable before you have a worker.

Usage
-----

[](#usage)

### Attach media to your entity

[](#attach-media-to-your-entity)

The bundle ships a mapped `NetBull\MediaBundle\Entity\Media` entity — reference it from your own entities:

```
use Doctrine\ORM\Mapping as ORM;
use NetBull\MediaBundle\Entity\Media;

#[ORM\ManyToOne(targetEntity: Media::class, cascade: ['persist', 'remove'])]
private ?Media $image = null;
```

### Upload

[](#upload)

Set the binary content and the provider/context, then persist. The bundle's Doctrine listener transforms the upload, stores it and generates thumbnails on flush:

```
$media = new Media();
$media->setContext('default');
$media->setProviderName('netbull_media.provider.image');
$media->setBinaryContent($uploadedFile); // Symfony UploadedFile / SplFileInfo / path

$em->persist($media);
$em->flush();
```

In forms, use `NetBull\MediaBundle\Form\Type\MediaType` (or `MediaShortType`) with the `provider`and `context` options.

### Render in Twig

[](#render-in-twig)

The bundle registers these Twig **filters**:

```
{# Public URL for a format #}

{# Signed (access-controlled) URL — image/file providers #}

{# Rendered /thumbnail markup #}
{{ media|thumbnail('thumb') }}

{# Rendered provider view (image tag, video embed, file link) #}
{{ media|view('normal') }}
```

### Autowiring

[](#autowiring)

```
use NetBull\MediaBundle\Provider\PoolInterface;
use NetBull\MediaBundle\Signature\SignatureHasherInterface;

public function __construct(
    private PoolInterface $pool,
    private SignatureHasherInterface $signatureHasher,
) {}
```

Console commands
----------------

[](#console-commands)

CommandDescription`netbull:media:create-thumbnail  [format]`Generate a thumbnail for one media`netbull:media:resize [context]`Generate missing thumbnails`netbull:media:sync-thumbnails`Regenerate thumbnails`netbull:media:clone `Clone a media (and its stored file)Development
-----------

[](#development)

```
composer test        # PHPUnit
composer phpstan     # static analysis
composer cs-check    # coding standards (php-cs-fixer, dry-run)
composer check       # all of the above
```

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

63

—

FairBetter than 99% of packages

Maintenance98

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity96

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Recently: every ~5 days

Total

154

Last Release

10d ago

Major Versions

v5.5.5 → v6.1.62024-08-27

v5.5.6 → v6.4.52024-11-01

v5.5.7 → v6.4.152024-12-30

v5.5.8 → v7.0.02025-05-22

v5.5.9 → v7.0.32025-06-17

PHP version history (4 changes)v6.1.0PHP &gt;=7.4|8.\*

v6.4.0PHP 8.\*

v7.1.0PHP 8.4.\*

v7.2.1PHP &gt;=8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2797954?v=4)[Aleksandar Dimitrov](/maintainers/netbull)[@netbull](https://github.com/netbull)

---

Top Contributors

[![netbull](https://avatars.githubusercontent.com/u/2797954?v=4)](https://github.com/netbull "netbull (124 commits)")[![SLRBot](https://avatars.githubusercontent.com/u/31204388?v=4)](https://github.com/SLRBot "SLRBot (110 commits)")[![semantic-release-bot](https://avatars.githubusercontent.com/u/32174276?v=4)](https://github.com/semantic-release-bot "semantic-release-bot (57 commits)")

---

Tags

netbull media symfony bundle

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/netbull-media-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/netbull-media-bundle/health.svg)](https://phpackages.com/packages/netbull-media-bundle)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M737](/packages/sylius-sylius)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)[oro/platform

Business Application Platform (BAP)

645143.5k115](/packages/oro-platform)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M388](/packages/easycorp-easyadmin-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M203](/packages/sulu-sulu)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
