Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/agence-adeliom/easy-media-bundle
A Symfony Media manager bundle for EasyAdmin
https://github.com/agence-adeliom/easy-media-bundle
easyadmin media media-manager symfony
Last synced: 4 days ago
JSON representation
A Symfony Media manager bundle for EasyAdmin
- Host: GitHub
- URL: https://github.com/agence-adeliom/easy-media-bundle
- Owner: agence-adeliom
- License: mit
- Created: 2021-08-23T12:09:46.000Z (over 3 years ago)
- Default Branch: 2.x
- Last Pushed: 2024-07-02T16:28:00.000Z (6 months ago)
- Last Synced: 2024-11-24T17:49:08.432Z (29 days ago)
- Topics: easyadmin, media, media-manager, symfony
- Language: PHP
- Homepage:
- Size: 4.59 MB
- Stars: 27
- Watchers: 4
- Forks: 18
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
![Adeliom](https://adeliom.com/public/uploads/2017/09/Adeliom_logo.png)
[![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=agence-adeliom_easy-media-bundle)](https://sonarcloud.io/dashboard?id=agence-adeliom_easy-media-bundle)# Easy Media Bundle
A VueJS media-manager for Easyadmin.
## Versions
| Repository Branch | Version | Symfony Compatibility | PHP Compatibility | Status |
|-------------------|---------|-----------------------|-------------------|----------------------------|
| `2.x` | `2.x` | `5.4`, and `6.x` | `8.0.2` or higher | New features and bug fixes |
| `1.x` | `1.x` | `4.4`, and `5.x` | `7.2.5` or higher | No longer maintained |## 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](doc/shortcuts.md)
+ 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, pressing `space` 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.
+ 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*** the `modal background` to do so. **"to avoid accidentally canceling your changes"**.> To stop interfering with other `keydown` events you can toggle the manager listener through `EventHub.fire('disable-global-keys', true/false)`.
## Installation with Symfony Flex
Add our recipes endpoint
```json
{
"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
```bash
composer require agence-adeliom/easy-media-bundle
```#### Without Symfony Flex
```yaml
# config/packages/easy_media.yamltwig:
form_themes:
- '@EasyMedia/form/easy-media.html.twig'doctrine:
dbal:
types:
easy_media_type: Adeliom\EasyMediaBundle\Types\EasyMediaTypeflysystem:
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
``````yaml
# config/routes/easy_media.yamleasy_media:
resource: '@EasyMediaBundle/Resources/config/routes.xml'
prefix: /admineasy_media_public:
resource: '@EasyMediaBundle/Resources/config/public_routes.xml'
prefix: /
``````php
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
```yaml
#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
```yaml
#config/packages/liip_imagine.yaml
liip_imagine:
data_loader: easy_media_data_loader
``````php
{{ object.media|resolve_media|imagine_filter('filter_name') }}
```### Field's usage
#### Usage
```php
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
```php
# 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
```php
/* @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
```yaml
# config/packages/doctrine.yaml
doctrine:
dbal:
...
types:
easy_media_type: Adeliom\EasyMediaBundle\Types\EasyMediaType
```In your entity
```php
class Article
{
#[ORM\Column(type: 'easy_media_type', nullable: true)]
private Media|string|null $file;
...
```### Configurations
```yaml
# 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
- pyextended_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```
### Events
| type | event-name | description |
| --------------- | -------------------------------------------------- | -------------------------------------------------------------------------- |
| [JS][js] | | |
| | modal-show | when modal is shown |
| | modal-hide | when modal is hidden |
| | file_selected *(when inside modal)* | get selected file url |
| | multi_file_selected *(when inside modal)* | get bulk selected files urls |
| | folder_selected *(when inside modal)* | get selected folder path |
| [Symfony][symfony] | | |
| | em.file.uploaded($file_path, $mime_type, $options) | get uploaded file storage path, mime type |
| | em.file.saved($file_path, $mime_type) | get saved (edited/link) image full storage path, mime type |
| | em.file.deleted($file_path, $is_folder) | get deleted file/folder storage path, if removed item is a folder |
| | em.file.renamed($old_path, $new_path) | get renamed file/folder "old & new" storage path |
| | em.file.moved($old_path, $new_path) | get moved file/folder "old & new" storage path |[js]: https://github.com/gocanto/vuemit
[symfony]: https://symfony.com/doc/current/event_dispatcher.html## License
[MIT](https://choosealicense.com/licenses/mit/)
## Authors
- [@arnaud-ritti](https://github.com/arnaud-ritti)
## Thanks to
[ctf0/Laravel-Media-Manager](https://github.com/ctf0/Laravel-Media-Manager)