agence-adeliom / easy-media-bundle
A Symfony Media manager bundle for EasyAdmin
Installs: 12 132
Dependents: 2
Suggesters: 0
Security: 0
Stars: 27
Watchers: 4
Forks: 16
Open Issues: 14
Type:symfony-bundle
Requires
- php: >=8.0.2
- ext-json: *
- agence-adeliom/easy-common-bundle: ^2.0.122
- easycorp/easyadmin-bundle: ^3.4 || ^v4.0
- embed/embed: ^4.2
- illuminate/support: ^9.2
- james-heinrich/getid3: ^1.9
- league/flysystem-bundle: ^3.0
- liip/imagine-bundle: ^2.8
- maennchen/zipstream-php: ^2.1.0
- nyholm/psr7: ^1.4
- stof/doctrine-extensions-bundle: ^1.6
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/deprecation-contracts: ^2.2 || ^v3.0
- symfony/event-dispatcher: ^5.4 || ^6.0
- symfony/filesystem: ^5.4 || ^6.0
- symfony/form: ^5.4 || ^6.0
- symfony/framework-bundle: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/options-resolver: ^5.4 || ^6.0
- symfony/property-access: ^5.4 || ^6.0
- symfony/psr-http-message-bridge: ^2.0
- dev-main
- 3.x-dev
- 2.x-dev
- 2.0.122
- 2.0.121
- 2.0.120
- 2.0.119
- 2.0.118
- 2.0.117
- 2.0.116
- 2.0.115
- 2.0.114
- 2.0.112
- 2.0.111
- 2.0.110
- 2.0.109
- 2.0.108
- 2.0.107
- 2.0.106
- 2.0.105
- 2.0.104
- 2.0.103
- 2.0.102
- 2.0.101
- 2.0.100
- 2.0.99
- 2.0.98
- 2.0.97
- 2.0.96
- 2.0.95
- 2.0.94
- 2.0.93
- 2.0.92
- 2.0.91
- 2.0.90
- 2.0.89
- 2.0.88
- 2.0.87
- 2.0.86
- 2.0.85
- 2.0.84
- 2.0.83
- 2.0.82
- 2.0.81
- 2.0.80
- 2.0.79
- 2.0.78
- 2.0.77
- 2.0.76
- 2.0.75
- 2.0.74
- 2.0.73
- 2.0.72
- 2.0.71
- 2.0.70
- 2.0.69
- 2.0.68
- 2.0.67
- 2.0.66
- 2.0.65
- 2.0.64
- 2.0.63
- 2.0.62
- 2.0.61
- 2.0.60
- 2.0.59
- 2.0.57
- 2.0.56
- 2.0.55
- 2.0.54
- 2.0.53
- 2.0.52
- 2.0.49
- 2.0.48
- 2.0.47
- 2.0.46
- 2.0.45
- 2.0.44
- 2.0.43
- 2.0.42
- 2.0.41
- 2.0.40
- 2.0.39
- 2.0.38
- 2.0.37
- 2.0.36
- 2.0.35
- 2.0.34
- 2.0.33
- 2.0.32
- 2.0.31
- 2.0.30
- 2.0.29
- 2.0.28
- 2.0.27
- 2.0.26
- 2.0.25
- 2.0.24
- 2.0.23
- 2.0.22
- 2.0.19
- 2.0.18
- 2.0.17
- 2.0.16
- 2.0.15
- 2.0.10
- 2.0.9
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- dev-revert-34-sf7-compat
- dev-dependabot/npm_and_yarn/webpack-5.76.1
- dev-develop
- dev-orm-managed
This package is auto-updated.
Last update: 2024-10-29 10:44:29 UTC
README
Easy Media Bundle
A VueJS media-manager for Easyadmin.
Versions
Features
- Image editor
- Multi
- Upload
- Move
- Delete
- Upload by either
- Using the upload panel
- Drag&Drop anywhere
- Click&Hold on an empty area "items container"
- From a url "images only"
- From a url rich embed element like Youtube video
- Preview files before uploading
- Toggle between
random/original
names for uploaded files - Bulk selection
- Bookmark visited directories for quicker navigation
- Change item/s visibility
- Update the page url on navigation
- Show audio files info "artist, album, year, etc.."
- Dynamically hide files / folders
- Restrict access to path
- Download selected "including bulk selection"
- Directly copy selected file link
- Use the manager
- from modal
- with any wysiwyg editor
- Auto scroll to selected item using "left, up, right, down, home, end"
- Lock/Unlock item/s.
- Filter by
- Folder
- Image
- Audio
- Oembed
- Video
- text/pdf
- application/archive
- Locked items
- Selected items
- Sort by
- Name
- Size
- Last modified
- Items count for
- All
- Selected
- Search found
- File name sanitization for
- Upload
- Rename
- New folder
- Disable/Enable buttons depend on the usage to avoid noise & keep the user focused
- Shortcuts / Gestures
- If no more rows available, pressing
down
will go to the last item in the list "same as native file manager". - When viewing a
audio/video
file in the preview card, pressingspace
will play/pause the item instead of closing the modal. - Double click/tap
- any file of type
audio/video/oembed
will open it in the preview card "same as images". - any file of type
application/archive
will download it.
- any file of type
- All the left/right gestures have their counterparts available as well.
- Pressing
esc
while using the image editor wont close the modal but you can dbl click/tap themodal background
to do so. "to avoid accidentally canceling your changes".
- If no more rows available, pressing
To stop interfering with other
keydown
events you can toggle the manager listener throughEventHub.fire('disable-global-keys', true/false)
.
Installation with Symfony Flex
Add our recipes endpoint
{ "extra": { "symfony": { "endpoint": [ "https://api.github.com/repos/agence-adeliom/symfony-recipes/contents/index.json?ref=flex/main", ... "flex://defaults" ], "allow-contrib": true } } }
Install with composer
composer require agence-adeliom/easy-media-bundle
Without Symfony Flex
# config/packages/easy_media.yaml twig: form_themes: - '@EasyMedia/form/easy-media.html.twig' doctrine: dbal: types: easy_media_type: Adeliom\EasyMediaBundle\Types\EasyMediaType flysystem: storages: medias.storage: adapter: 'local' options: directory: '%kernel.project_dir%/var/storage/medias' easy_media: storage_name: medias.storage media_entity: App\Entity\EasyMedia\Media folder_entity: App\Entity\EasyMedia\Folder
# config/routes/easy_media.yaml easy_media: resource: '@EasyMediaBundle/Resources/config/routes.xml' prefix: /admin easy_media_public: resource: '@EasyMediaBundle/Resources/config/public_routes.xml' prefix: /
<?php // src/Entity/EasyMedia/Folder.php namespace App\Entity\EasyMedia; use Adeliom\EasyMediaBundle\Entity\Folder as BaseFolder; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'easy_media__folder')] class Folder extends BaseFolder { }
<?php // src/Entity/EasyMedia/Media.php namespace App\Entity\EasyMedia; use Adeliom\EasyMediaBundle\Entity\Media as BaseMedia; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'easy_media__media')] class Media extends BaseMedia { }
Setup database
Using doctrine migrations
php bin/console doctrine:migration:diff php bin/console doctrine:migration:migrate
Without
php bin/console doctrine:schema:update --force
Documentation
Manage medias in your Easyadmin dashboard
Go to your dashboard controller, example : src/Controller/Admin/DashboardController.php
<?php namespace App\Controller\Admin; ... class DashboardController extends AbstractDashboardController { ... // Add the custom form theme public function configureCrud(): Crud { return parent::configureCrud() ->addFormTheme('@EasyMedia/form/easy-media.html.twig') ; } public function configureMenuItems(): iterable { ... yield MenuItem::linkToRoute('Medias', 'fa fa-picture-o', 'media.index'); ...
Integrate with FOS CKEditor
#config/packages/fos_ck_editor.yaml fos_ck_editor: configs: main_config: ... filebrowserBrowseRoute: media.browse filebrowserImageBrowseRoute: media.browse filebrowserImageBrowseRouteParameters: provider: 'image' restrict: uploadTypes: - 'image/*' uploadSize: 5
Integrate with LiipImagineBundle
#config/packages/liip_imagine.yaml liip_imagine: data_loader: easy_media_data_loader
{{ object.media|resolve_media|imagine_filter('filter_name') }}
Field's usage
Usage
use Adeliom\EasyMediaBundle\Admin\Field\EasyMediaField; ... yield EasyMediaField::new('property', "label") // Apply restrictions by mime-types ->setFormTypeOption("restrictions_uploadTypes", ["image/*"]) // Apply restrictions to upload size in MB ->setFormTypeOption("restrictions_uploadSize", 5) // Apply restrictions to path ->setFormTypeOption("restrictions_path", "users/" . $userID) // Hide fiels with extensions (null or array) ->setFormTypeOption("hideExt", ["svg"]) // Hide folders (null or array) ->setFormTypeOption("hidePath", ['others', 'users/testing']) // Enable/Disable actions ->setFormTypeOption("editor", true) ->setFormTypeOption("upload", true) ->setFormTypeOption("bulk_selection", true) ->setFormTypeOption("move", true) ->setFormTypeOption("rename", true) ->setFormTypeOption("metas", true) ->setFormTypeOption("delete", true) ;
Twig usage
# Render the media {{ easy_media(object.media, format, options) }} // By default format is the reference file and options # Examples : {{ easy_media(object.media, "reference") }} {{ easy_media(object.media, "cover_full", {'class': 'myclass'}) }} ## For images {{ easy_media(object.media, "cover_full", {'loading': "lazy"}) }} {{ easy_media(object.media, "cover_full", {'picture': ["cover_full__2xl","cover_full__xl","cover_full__lg","cover_full__sm","cover_full__xs"]}) }} {{ easy_media(object.media, "cover_full", {'srcset': ["cover_full__2xl","cover_full__xl","cover_full__lg","cover_full__sm","cover_full__xs"]}) }} {{ easy_media(object.media, "cover_full", {'loading': "lazy", 'srcset': {'(max-width: 500px)': 'cover_full__2xl', '(max-width: 1200px)': 'cover_full__xl'}}) }} ## For oembed {{ easy_media(object.media, "reference") }} {{ easy_media(object.media, "reference", {'responsive': true}) }} ## For video {{ easy_media(object.media, "reference") }} {{ easy_media(object.media, "reference", {"responsive" : true, "controls" : true, "autoplay" : true}) }} # Get media path {{ easy_media_path(object.media, format) }} // By default format is the reference file # Get media URL {{ object.media|resolve_media }} # Get media metadatas {{ object.media|media_meta }} # Get single media metadata {{ object.media|media_meta('key') }} # Get complete media informations {{ object.media|media_infos }} # Get test file type # type_to_test: can be a mime_type or # oembed for any embed type # image for any image type # pdf for pdf files # compressed for archives files {{ file_is_type(object.media, type_to_test) }} # Get mimetype icon (font-awesome) {{ mime_icon("text/plain") }}
You can override media render with twig
- For images :
@EasyMedia/render/image.html.twig
- For oembed :
@EasyMedia/render/oembed.html.twig
- For video :
@EasyMedia/render/oembed.html.twig
Manage medias and folders programmatically
/* @var EasyMediaManager $manager */ # Get media by id or null $media = $manager->getMedia($id); # Get folder by id or null $folder = $manager->getFolder($id); # Get folder by path $folder = $manager->folderByPath($path); # Create a folder $folder = $manager->createFolder($folderName, $path = null) # Create a media # $source can be a UploadedFile, File, Image URL, Oembed URL, Base64 URI $folder = $manager->createMedia($source, $path = null, $name = null) # Save a folder or media $manager->save($entity, $flush = true); # Delete a folder or media $manager->delete($entity, $flush = true);
Use the Doctrine type (optional)
It automatically converts the stored path into a Media entity
# config/packages/doctrine.yaml doctrine: dbal: ... types: easy_media_type: Adeliom\EasyMediaBundle\Types\EasyMediaType
In your entity
class Article { #[ORM\Column(type: 'easy_media_type', nullable: true)] private Media|string|null $file; ...
Configurations
# config/packages/easy_media.yaml easy_media: storage: '%kernel.project_dir%/public/upload' base_url: /upload/ # ignore any file starts with "." ignore_files: '/^\..*/' # remove any file special chars except # dot . # dash - # underscore _ # single quote '' # white space # parentheses () # comma , allowed_fileNames_chars: '\._\-\''\s\(\),' # remove any folder special chars except # dash - # underscore _ # white space # # to add & nest folders in one go add '\/' # avoid using '#' as browser interpret it as an anchor allowed_folderNames_chars: _\-\s # disallow uploading files with the following mimetypes (https://www.iana.org/assignments/media-types/media-types.xhtml) unallowed_mimes: # Defaults: - php - java # disallow uploading files with the following extensions (https://en.wikipedia.org/wiki/List_of_filename_extensions) unallowed_ext: # Defaults: - php - jav - py extended_mimes: # any extra mime-types that doesnt have "image" in it image: # Required # Default: - binary/octet-stream # any extra mime-types that doesnt have "compressed" in it archive: # Required # Defaults: - application/x-tar - application/zip # display file last modification time as last_modified_format: Y-m-d # hide file extension in files list hide_files_ext: true # loaded chunk amount "pagination" pagination_amount: 50