Documentation

Getting started

Introduction

Welcome to Jits Files Picker Manager's documentation.

Jits Files Picker Manager is a symfony 6 bundle that will help you to attach files or photos to your enties using a Files Picker Custom Field through a Media Library with a built-in file uploader.
How it works? Define the links in your entities with our file table and use the predefined custom field of Jits Files Picker Manager in your existing forms. The javascript will initialized each picker present on your page.

Requirements

Jits Files Picker Manager is a Symfony >= 6.0 Bundle, works with bootstrap >= 5 and font awesome 6 free.
The javascript and css assets need to be integrated using NPM method (yarn, gulp, ...). (We're working on a standard solution).
No Jquery needed.

Installation

Before installation, add in your composer.json the reference for symfony recipe that will help you to configure properly and automatically the bundle after its installation.

"extra": {
  "symfony": {
     "endpoint": [
        "https://api.github.com/repos/julien-its/symfony-recipes/contents/index.json",
        "flex://defaults"
     ]
  }
}

The extra.symfony key will most probably already exist in your composer.json. In that case, add the "endpoint" key to the existing extra.symfony entry.

As our bundle is secured with a token, add a new entry in the repositories section of your composer.json to define the jits/files-picker-manager bundle. Note that your personal token is defined in the url. Your token has an expiration date and a maximum installation limit. Do not share your personal token

"repositories": [
    {
        "type": "composer",
        "url": "https://packages.julien-its.com/composer/jits-files-picker-manager/packages.json?token=personaltoken"
    }
]

Then install the bundle using Composer and Symfony Flex.

$ composer require jits/files-picker-manager

JavaScript dependencies

In your package.json file add the files picker manager package.

"devDependencies": {
   ...
    "jits-files-picker-manager": "file:vendor/jits/files-picker-manager/Resources/assets"
},

Install the JavaScript dependencies.

npm install --force

# or use yarn
yarn install --force

Configuration

Once installed, the bundle should have configured automatically your project thanks to the Symfony Flex. Check the manual configuration section if the recipe didn't run.

Required configuration

Congratulation! The bundle is now installed. To finalize your installation, you must execute these last steps.

Database table

Generate the table where your files will be stored in your database.

$ php bin/console doctrine:migration:diff
$ php bin/console doctrine:migration:migrate

Customize your .env file

FPM_UPLOAD_DIR=/uploads/fpm
FPM_ALLOWED_FILES_EXTENSIONS=image/*,archive/*,audio/*,video/*,pdf,xls,xlsx,doc,docx,ppt,pptx,txt
FPM_ALLOWED_PHOTOS_EXTENSIONS=image/*
FPM_MAX_FILE_SIZE=2M
fpm_upload_dir Upload directory from the public directory
fpm_allowed_files_extensions allowed extensions for the media library uploader in mode file
fpm_allowed_photos_extensions allowed extensions for the media library uploader in mode photo
fpm_max_file_size max file size allowed by file

Create the upload directory

Create the upload dir in your public folder as defined in the FPM_UPLOAD_DIR env variable. You can define another folder path but keep in mind your folder must be accessible publicly inside the directory root or your project.

cd public
mkdir uploads
cd uploads
mkdir fpm

Make sure your http user can write to this directory.

Manual configuration

These steps are done automatically by the Symfony Flex. Unless you didn't run the recipe of the bundle or forget to configure the composer extra.symfony.endpoint section. If it's the case, you can then manually configure your project by doing these steps :

config/bundles.php

return [
    ...
    ...
    Jits\FilesPickerManagerBundle\FilesPickerManagerBundle::class => ['all' => true]
];

config/packages/files_picker_manager.yaml

files_picker_manager:
    upload_dir: '%env(resolve:FPM_UPLOAD_DIR)%'
    web_dir: '%env(FPM_WEB_DIR)%'
    allowed_files_extensions: '%env(FPM_ALLOWED_FILES_EXTENSIONS)%'
    allowed_photos_extensions: '%env(FPM_ALLOWED_PHOTOS_EXTENSIONS)%'
    max_file_size: '%env(FPM_MAX_FILE_SIZE)%'

twig:
    form_themes:
        - '@FilesPickerManager/form/custom-types.html.twig'

config/routes/files_picker_manager.yaml

files_picker_manager:
    resource: '@FilesPickerManagerBundle/Resources/config/routes.yaml'

Security

The Jits Files Picker Manager Bundle uses the routes starting by /fpm/ to manage the files and uploads new files. You can manage the security by adding a rules in your security.yaml configuration file.

security:
    access_control:
        - { path: ^/fpm/, roles: ROLE_ADMIN }

Translation

Jits Files Picker Manager is translated depending on the your current symfony locale. Our Bundle is translated in 2 languages (English and French).

If you want to add another languages, duplicate the translations file from our bundle to your symfony translations folder

Usage

Initialization

Import the JavaScript

import { FilesPickerManager } from "jits-files-picker-manager";
new FilesPickerManager();                            

Import the css

@import "~jits-files-picker-manager/filesPickerManager.min.css";                            

Don't forget to compile

npm run watch

# or use yarn
yarn watch

Simple Photo Picker

Define a ManyToOne relation in your entity.

#[ORM\ManyToOne(targetEntity: \Jits\FilesPickerManagerBundle\Entity\File::class)]
#[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: "cascade")]
#[Assert\NotBlank()]
private $photo;

Add the FilePickerType in your form with the type photo.

$builder->add('photo', \Jits\FilesPickerManagerBundle\Form\Type\FilePickerType::class, array(
    'class' => \Jits\FilesPickerManagerBundle\Entity\File::class,
    'type' => 'photo'
));

Multiple Photos Picker

Define a ManyToMany relation in your entity.

#[ORM\ManyToMany(targetEntity: \Jits\FilesPickerManagerBundle\Entity\File::class)]
#[ORM\JoinTable(name: 'event_photos')]
private $photos;

Add the FilesPickerType in your form with the type photo.

$builder->add('photos', \Jits\FilesPickerManagerBundle\Form\Type\FilesPickerType::class, array(
    'class' =>\Jits\FilesPickerManagerBundle\Entity\File::class,
    'type' => 'photo'
));

Simple File Picker

Define a ManyToOne relation in your entity.

#[ORM\ManyToOne(targetEntity: \Jits\FilesPickerManagerBundle\Entity\File::class)]
#[ORM\JoinColumn(referencedColumnName: 'id', nullable: true, onDelete: "cascade")]
#[Assert\NotBlank()]
private $file;

Add the FilePickerType in your form with the type file.

$builder->add('file', \Jits\FilesPickerManagerBundle\Form\Type\FilePickerType::class, array(
    'class' => \Jits\FilesPickerManagerBundle\Entity\File::class,
    'type' => 'file'
));

Multiple Files Picker

Define a ManyToMany relation in your entity.

#[ORM\ManyToMany(targetEntity: \Jits\FilesPickerManagerBundle\Entity\File::class)]
#[ORM\JoinTable(name: 'event_files')]
private $files;

Add the FilesPickerType in your form with the type file.

$builder->add('files', \Jits\FilesPickerManagerBundle\Form\Type\FilesPickerType::class, array(
    'class' =>\Jits\FilesPickerManagerBundle\Entity\File::class,
    'type' => 'file'
));

Simple Url Photo Picker

Define a string field in your entity.

#[ORM\Column(length: 255, nullable: true)]
private ?string $coverUrl = null;

Add the UrlPickerType in your form with the type photo.

$builder->add('coverUrl', UrlPickerType::class, [
    'label' => "Cover",
    'type' => 'photo',
])

Simple Url File Picker

Define a string field in your entity.

#[ORM\Column(length: 255, nullable: true)]
private ?string $documentUrl = null;

Add the UrlPickerType in your form with the type file.

$builder->add('documentUrl', UrlPickerType::class, [
    'label' => "Document",
    'type' => 'file',
]);

Multiple Url Photos Picker

Define a array json field in your entity.

#[ORM\Column(type: Types::JSON, nullable: true)]
private array $photosUrl = [];

Add the UrlsPickerType in your form with the type photo.

$builder->add('photosUrl', UrlsPickerType::class, [
    'label' => "Photos",
    'type' => 'photo',
]);

Multiple Url Files Picker

Define a array json field in your entity.

#[ORM\Column(type: Types::JSON, nullable: true)]
private array $documentUrl = [];

Add the UrlsPickerType in your form with the type file.

$builder->add('documentsUrl', UrlsPickerType::class, [
    'label' => "Documents",
    'type' => 'file',
]);

Standalone File Picker

Create a container where you will add the needed data attributes using our fpmPickerAttributes helper.

<div id="standalonePicker" {{ fpmPickerAttributes({type: "photo"})|raw }}>
    <ul class="selected-files">

    </ul>
    <a href="#" class="link-attach">Add file</a>
</div>

Options are

type file | photo (string) default file
config See de documentation (string) default null
section See de documentation (string) default null
autoClose true | false (boolean) default true

Stand alone picker must be initialized in your javascript.

import { StandAlonePicker } from "jits-files-picker-manager";

new StandAlonePicker(document.querySelector('#standalonePicker'), {
    filePicked : (picker, fileData) => {
        let itemEl = document.createElement('li');
        itemEl.innerHTML = `${fileData.title} (${fileData.humanSize})`
        picker.element.querySelector('.selected-files').appendChild(itemEl);
    }
});

fileData response example:

{
    "id": 19,
    "title": "FA_SANTANDER_PV_NEG_RGB.png",
    "filename": "FA_SANTANDER_PV_NEG_RGB.png",
    "libraryType": "photo",
    "section": null,
    "path": "/uploads/fpm",
    "pathSuffix": "202208",
    "extension": "png",
    "size": 32270,
    "humanSize": "31.51K",
    "src": "/uploads/fpm/202208/FA_SANTANDER_PV_NEG_RGB.png",
    "dateShort": "29/08/2022",
    "dateLong": "29/08/2022 17:04:35"
}

Options

Config

If you want a specific configuration for your field, you can add a custom config that you will define in the files_picker_manager.yaml file.

Redefine allowed extensions, max file size and the upload directory for each config. All three parameters are optional.

$builder
    ->add('cover', FilePickerType::class, [
        'label' => "Cover",
        'class' => File::class,
        'type' => 'photo',
        'locale' => 'fr',
        'config' => 'event_cover'
    ]);
files_picker_manager:
    ...
    configs:
        event_cover:
            upload_dir: "/uploads/events/cover"
            allowed_extensions: 'jpg,png'
            max_file_size: '1M'
        ...

Init with n elements

For the UrlsPickerType and FilesPickerType, add by default N empty elements.

$builder
    ->add('photosUrl', UrlsPickerType::class, [
        'label' => "Photos",
        'type' => 'photo',
        'init_with_n_elements' => 1,
    ]);

Auto close

Define if the file picker automatically closes after picking the file

$builder
    ->add('photos', FilesPickerType::class, array(
        'label' => "Photos",
        'class' => File::class,
        'type' => 'photo',
        'auto_close_library' => 'true' // Default true
    ));

Section

Limitate the library to a specific section. Files will be added in the specified section and will not be visible to the main library

$builder
    ->add('photos', FilesPickerType::class, array(
        'label' => "Photos",
        'class' => File::class,
        'type' => 'photo',
        'section' => 'category-event' // default null
    ));

Allow Duplicate

Allow or forbid the picker to select the same files multiple times

$builder
    ->add('photos', FilesPickerType::class, array(
        'label' => "Photos",
        'class' => File::class,
        'type' => 'photo',
        'allow_duplicate' => 'true', // Default true
    ));

Helpers

fileWebPath

Get the public path of a file.

<img src="{{ event.cover|fileWebPath }}">

humanFileSize

Get the human size of a file.

Cover HSize : {{ event.cover.size|humanFileSize }}

fpmPickerAttributes

Get the data attributes for a standalone file picker.

<div id="standalonePicker" {{ fpmPickerAttributes({type: "photo"})|raw }}></div>

Options

type file | photo (string) default file
config See de documentation (string) default null
section See de documentation (string) default null
autoClose true | false (boolean) default true

Examples

In the following examples we collected different usages of the Jits Files Picker Manager Bundle. Don't forget that you can combine examples together.

File Picker

Simple File Picker - Multiple Files Picker

Photo Picker

Simple Photo Picker - Multiple Photos Picker

Url Picker

Simple Url Photo Picker - Multiple Urls Photo Picker - Simple Url File Picker - Multiple Urls File Picker

Standalone File Picker

Standalone File Picker

Custom File Picker

Custom Simple Photo Picker

Third Parties

Amazon S3

Coming soon

Licences

A regular license is required if you are using this bundle in one of your personal projects (including sites for your customers) and a commercial license for all commercial applications (including sites, themes and apps you plan to sell).

Sharing the source code or selling it particullary is not allowed.

Changelog

See the record of all changes made to the project.

2.0

  • Compatibility for symfony 6.1

1.0

  • Initial commit For symfony 6.0