helios-ag/fm-elfinder-bundle

ElFinder bundle, adds ElFinder file manager to your Symfony2 project

Installs: 117 064

Dependents: 15

Stars: 74

Watchers: 12

Forks: 52

Open Issues: 10

Language: PHP

5.0.5 2015-07-16 05:41 UTC

README

ElFinder integration in Symfony2

Gitter chat

Join the chat at https://gitter.im/helios-ag/FMElfinderBundle

Code Quality Assurance

SensioLabs Insight Travis CI Scrutinizer CI SensioLabsInsight Build Status Build Status Code Coverage Code Coverage

Dependency Status Latest Stable Version Total Downloads Latest Unstable Version License Bitdeli Badge

elFinder is an open-source file manager for web, written in JavaScript using jQuery UI. Creation is inspired by simplicity and convenience of Finder program used in Mac OS X operating system.

Recommended bundles to use with:

Table of contents

Installation

To install this bundle, you'll need both the lib ElFinderPHP and this bundle.

This instruction explain how to setup bundle on Symfony 2.1 and newer

Step 1: Installation

Version 5:

Add FMElfinderBundle to your composer.json:

{
    "require": {
        "helios-ag/fm-elfinder-bundle": "~5",
    }
}

also add component-dir under config node of composer.json

{
    "config": {
        "component-dir": "web/assets"
    }
}

Version 4:

This version dont use component library

composer require helios-ag/fm-elfinder-bundle: "~4.0"

For Symfony between 2.1 and 2.3 (2.3 included) use version ~2.3

composer require helios-ag/fm-elfinder-bundle: "~2.3"

Now tell composer to download the bundle by running the command:

composer update helios-ag/fm-elfinder-bundle

Install legacy version of the bundle (documentation):

composer require helios-ag/fm-elfinder-bundle: "~1.5"

Step 2: Enable the bundle

Enable the bundle in the kernel:

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new FM\ElfinderBundle\FMElfinderBundle(),
    );
}

Step 3: Import FMElfinderBundle routing file

# app/config/routing.yml
elfinder:
     resource: "@FMElfinderBundle/Resources/config/routing.yml"

Step 4: Configure your application's security.yml

Secure ElFinder with access_control:

# app/config/security.yml
security:

    //....
    access_control:
        - { path: ^/efconnect, role: ROLE_USER }
        - { path: ^/elfinder, role: ROLE_USER }

Step 5: Install assets

Install and dump assets via symfony built-in command:

app/console assets:install web

Basic configuration

Add configuration options to your config.yml

fm_elfinder:
    instances:
        default:
            locale: %locale% # defaults to current request locale
            editor: ckeditor # other options are tinymce, tinymce4, form, custom and simple
            fullscreen: true # defaults true, applies to simple and ckeditor editors
            theme: smoothness # jquery theme
            include_assets: true # disable if you want to handle loading of the javascript and css assets yourself
            connector:
                debug: false # defaults to false
                roots:       # at least one root must be defined
                    uploads:
                        show_hidden: false # defaults to false
                        driver: LocalFileSystem
                        path: uploads
                        upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
                        upload_deny: ['all']
                        upload_max_size: 2M
  • default - instance of elfinder, can be used to define multiple configurations of ElFinder, allows simultaneous configuration for different types of WYSIWYG editors in your project
  • path - define root directory for the files inside web/ directory, default is "uploads". Make sure to set proper write/read permissions to this directory.
  • url - url to be prefixed to image path, for displaying. Can be either absolute or relative. If relative, it will be prefixed with the applications base-url. If left blank, url will be the base-url, append with the value of the 'path' parameter
  • driver - can be LocalFileSystem, FTP or MySQL2, currently supported only LocalFileSystem, default is LocalFileSystem
  • locale - locale determines, which language, ElFinder will use, to translate user interface, default is current request locale
  • cors_support - allows cross domain responses handling (default false)
  • editor - determines what template to render, to be compatible with WYSIWYG web editor, currently supported options are: "ckeditor", "tinymce" for tinymce3, "tinymce4" for tinymce4, "form" for form type, "simple" for standalone and "custom". How to configure CKEDitor and TinyMCE to work with this bundle, will be explained further in this document.
  • editor_template - define template to render editor is set to "custom".
  • connector - root node for defining options for elfinder root directories.
  • roots - define "virtual directories" that reflect directories in your project.
  • path_prefix - path prefix with relative_path enabled, default is slash ('/')
    • show_hidden - show files and folders that starts from . (dot)
    • driver - driver type, LocalFileSystem, Dropbox, FTP
    • volume_id - (optional) can be used to force a volume id when mounting volume (default auto-increments). If provided, it must be an integer bigger than 0.
    • alias - directory alias
    • path - directory that contains files
    • upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
    • upload_deny: ['all']
    • upload_max_size: 2M

You can see the full list of roots options here. To use them, convert camelCased option name to under_scored option name.

Note: crypt_lib option is not available as not implemented yet by elFinder PHP library.

Use multiple upload folder by instance

You can set multiple upload root folder by instance configuration.

If you have configured your instance with /uploads path, you can provide an additional folder as a home folder (e.g. for a multi-users application) when accessing to the instance URL :

/elfinder/{instance}/{homeFolder} or /efconnect/{instance}/{homeFolder}

For example, accessing to /elfinder/acmeInstance/bob URL will open up elfinder with /uploads/bob as root directory which only contains Bob's files.

Then, accessing to /elfinder/acmeInstance/alice URL will re-use your instance, but open up elfinder with /uploads/alice folder as root directory, containing only Alice's files.

To use this feature, you must provide the instance name in the URL, and of course be sure to set proper write/read permissions on home folders.

Note: this feature is only available with LocalFileSystem driver.

CORS support

If you want access connector URL from an other domain on the client side, simply configure FMElFinder bundle as you used to, and add the cors_support: true option to the cross domain instance:

# app/config/config.yml
fm_elfinder:
    instances:
        default:
            locale: %locale% # defaults to current request locale
            cors_support: true # allows cross domain responses handling (default false)
            editor: ckeditor # other options are tinymce, tinymce4, form, custom and simple,
            # ...

Then you have to add the CORS headers (Access-Control-Allow-Origin) to the response. It can be easily done with NelmioCORSBundle :

# app/config/config.yml
nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: []
        allow_headers: []
        allow_methods: []
        expose_headers: []
        max_age: 0
        hosts: []
    paths:
        '^/efconnect':
            allow_origin: ['*']
            allow_headers: ['X-Custom-Auth', 'Content-Type', 'X-Requested-With']
            allow_methods: ['POST', 'GET', 'PATCH', 'PUT', 'DELETE']
            max_age: 3600
            allow_credentials: true

Events listeners / subscribers

Events

The bundle is throwing some events during an elFinder command execution :

  • FM\ElfinderBundle\Event\ElFinderEvents::PRE_EXECUTION : fm_elfinder.event.pre_execution
  • FM\ElfinderBundle\Event\ElFinderEvents::POST_EXECUTION : fm_elfinder.event.post_execution

The pre execution event has its own class (FM\ElfinderBundle\Event\ElFinderPreExecutionEvent) which contains the http request object, the elFinder instance name and the home folder.

The post execution event (FM\ElfinderBundle\Event\ElFinderPostExecutionEvent) has the same attributes than the pre execution events, plus the command result and a hasErrors() function indicating if errors has been encountered during command execution.

You can register event listeners with the fm_elfinder.event_listener tag and event subscribers with the fm_elfinder.event_subscriber tag.

Note: you must set the cors_support option to true to use events. If you don't, the symfony life cycle won't end properly and so the event won't be dispatched.

You can access to all commands names here.

Sub requests

Events allows you to perform sub requests (only for commands used with HTTP GET method, i.e. not to upload a file). These subrequests are working the same way than forward function on symfony controllers, and are also hookable.

Note: You will have to set a volume_id to your instance's root to be sure the volume is mounted with the same ID between each requests.

Here is an exemple of event listener on the post execution event, making a sub request :

<!-- src/AppBundle/Resources/config/services.xml -->
<service id="app_bundle.listener.elfinder_post_execution" class="AppBundle\EventListener\ElFinder\PostExecutionListener">
    <tag name="fm_elfinder.event_listener" event="fm_elfinder.event.post_execution" method="onPostExecute" />
</service>
// src/AppBundle/EventListener/ElFinder/PostExecutionListener.php
namespace AppBundle\EventListener\ElFinder;

use FM\ElfinderBundle\Event\ElFinderPostExecutionEvent;

class PostExecutionListener
{
    /**
     * @param  ElFinderPostExecutionEvent $event
     */
    public function onPostExecute(ElFinderPostExecutionEvent $event)
    {
        if (!$event->hasErrors() && $event->getCommand() == 'tmb') { // 'tmb', 'mkdir', 'open', etc...
            // do your stuff here
            // ...
            // you can perform a sub request
            $queryParameters = $event->getRequest()->query->all(); // getting original request parameters
            $queryParameters['cmd'] = 'info'; // changing the command to execute in sub request

            $jsonResponse = $event->subRequest(array(
                'instance' => $event->getInstance(),    // you can also make a subrequest on an other instance
                'homeFolder' => $event->getHomeFolder() // and an other homeFolder
            ), $queryParameters);

            $data = json_decode($jsonResponse->getContent());
            // work with sub request data
            // ...
        }
    }
}

Elfinder Form Type

Bundle come with custom form type, html <input type="text"/>, that provide elfinder callback (opens Elfinder window).

First, define instance with editor set to "form":

fm_elfinder:
    instances:
        form:
            locale: %locale% # defaults to current request locale
            editor: form # other choices are tinymce or simple, and form
            show_hidden: false # defaults to false
            fullscreen: true # defaults true, applies to simple and ckeditor editors
            include_assets: true # disable if you want to handle loading of the javascript and css assets yourself
            compression: false # enable if you configured the uglifycss and uglifyjs2 assetic filters and want compression
            connector:
                debug: false # defaults to false
                roots:       # at least one root must be defined
                    uploads:
                        driver: LocalFileSystem
                        path: uploads
                        upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
                        upload_deny: ['all']
                        upload_max_size: 2M

On second step, add to your form builder (or form class), elfinder type, and pass instance and enable parameters:

$form = $this->createFormBuilder()
    ->add('elfinder','elfinder', array('instance'=>'form', 'enable'=>true))
    ->getForm();

Third step, render form with twig as usual, please note that you need to include jQuery (>=1.7) library on your page

<form action="" method="post" {{ form_enctype(form) }}>
        {{ form_widget(form) }}
        <input type="submit" />
    </form>

CKEditor integration

Mostly filebrowsers used with WYSIWYG editors to upload images and other files. There are two bundles to work with CKEditor available: TrsteelCKEditorBundle and IvoryCKEditorBundle Both will work with this bundle.

Step 1: Installation

Install both bundles according README files

Step 2: Configure CKEditor setting via settings.yml or through form builder:

trsteel_ckeditor:
    ...
    filebrowser_image_browse_url:
        route: elfinder
        route_parameters:
             instance: ckeditor

or if you prefer Ivory CKEditor Bundle

ivory_ck_editor:
    default_config: default
    configs:
        default:
            filebrowserBrowseRoute: elfinder
            filebrowserBrowseRouteParameters: []

Note that instance name should be the same as configured in elfinder bundle

<?php
// applies to Ivory CKEditor Bundle
$form = $this->createFormBuilder()
            ->add('content', 'ckeditor', array(
                 'config' => array(
                'filebrowserBrowseRoute' => 'elfinder',
                'filebrowserBrowseRouteParameters' => array('instance' => 'default')
                ),
                ),
            ))
            ->getForm()
;

ElFinder will be available under Insert Image dialog

TinyMCE integration

You can integrate TinyMCE byself or use Bundles that already add TinyMCE functionality to your Symfony project. Below instruction how to integrate FMElfinderBundle with TinyMCEBundle

How to use ElfinderBundle with TinyMCEBundle

TinyMCE 3.x

Instruction for version 0.2.1 (TinyMCE 3.x) Download bundles, configure, dump and install assets as written in installation steps

Configuration

Update the editor property in your app/config.yml Set TinyMce popup path:

fm_elfinder:
    editor: tinymce
    tinymce_popup_path: "asset[bundles/stfalcontinymce/vendor/tiny_mce/tiny_mce_popup.js]"

Under tinymce configuration node, theme configuration, add: file_browser_callback : 'elFinderBrowser'

stfalcon_tinymce:
    theme:
        simple:
            file_browser_callback : 'elFinderBrowser'

after ( {{ tinymce_init() }} ) function call place ElfinderBundle's function:

{{ elfinder_tinymce_init('instance_name', {'width':'900', 'height': '450', 'title':'ElFinder 2.0'}) }}

as shown below

{{ tinymce_init() }}
{{ elfinder_tinymce_init('instance_name') }}

instance_name is an instance of elfinder's configuration

TinyMCE 4.x

Update the editor property in your app/config.yml

 fm_elfinder:
     editor: tinymce4

Under tinymce configuration node, theme configuration, add: file_browser_callback : elFinderBrowser

stfalcon_tinymce:
     theme:
         simple:
             file_browser_callback : elFinderBrowser

before ( {{ tinymce_init() }} ) function call (order is important) place ElfinderBundle's function: {{ elfinder_tinymce_init4('instance_name', {'width':'900', 'height': '450', 'title':'ElFinder 2.0'} ) }} as shown below

     {{ elfinder_tinymce_init4('instance_name') }}
     {{ tinymce_init() }}

instance_name is instance of elfinder configuration

Advanced configuration

Custom configuration provider

ElFinder bundle allows to override his configuration provider service:

fm_elfinder:
    configuration_provider: elfinder.configurator

where 'elfinder.configurator' is default ElFinder's bundle service to read configuration from DIC

To override service, simply define your own service:

services:
    my_elfinder_configurator:
        class:        Acme\DemoBundle\MyElfinderConfigurator
        arguments:    ["%my_arguments%"]

Configuration class must implement ElFinderConfigurationProviderInterface

method getConfiguration($instance) should return array of parameters compatible with ElFinder bundle configuration

Custom loader

It is possible to override loader service with your own class:

services:
    my_loader:
        class:        AppBundle\Service\MyElFinderLoader
        arguments:    [@fm_elfinder.configurator]

fm_elfinder:
  loader: my_loader

Plugins

ElFinder comes with some plugins, like auto-resize, which can be enabled, by the following configuration:

fm_elfinder:
  instances:
    tinymce:
      locale: %locale%
      editor: tinymce4
      include_assets: true
      relative_path: true
      fullscreen: true
      connector:
          debug: true # defaults to false
          binds:
              upload.presave:
                  - Plugin.AutoResize.onUpLoadPreSave
          plugins:
              AutoResize: # global resize options, applies to root which don't have his own resize configuraion
                  enable: true
                  maxWidth: 750
                  maxHeight: 750
                  quality: 95 # JPEG image save quality
          roots:       # at least one root must be defined
              uploads:
                  driver: LocalFileSystem
                  path: uploads
                  plugins:
                      AutoResize:
                          enable: true
                          maxWidth: 500
                          maxHeight: 500
                          quality: 95 # JPEG image save quality
                  upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
                  upload_deny: ['all']
                  upload_max_size: 2M
              resize1:
                  driver: LocalFileSystem
                  path: uploads
                  plugins:
                      AutoResize:
                          enable: true # For control by volume driver
                          maxWidth: 800 # Path to Water mark image
                          maxHeight: 800 # Margin right pixel
                          quality: 95 # JPEG image save quality
                  upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
                  upload_deny: ['all']
                  upload_max_size: 2M
              resize2:
                  driver: LocalFileSystem
                  path: uploads
                  plugins:
                      AutoResize:
                          enable: true
                          maxWidth: 800
                          maxHeight: 800
                          quality: 95
                  upload_allow: ['image/png', 'image/jpg', 'image/jpeg']
                  upload_deny: ['all']
                  upload_max_size: 2M

ElFinder comes with other plugins, check Plugins folder under ElFinderPHP for more information.

Symfony service as a volume driver

volumeDriver can be declared as Symfony service The service should however be an instance of the FM\ElFinderPHP\Driver\ElFinderVolumeDriver class. This check is to ensure the service is a valid ElFinder VolumeDriver.

To configure a root with a service-driver you can simply use the service id as the drive key:

fm_elfinder:
    connector:
        roots:
            uploads:
                driver: elfinder.driver.filesystem
                path: uploads

This means that if you add the service definition:

<service id="elfinder.driver.filesystem" class="FM\ElFinderPHP\Driver\ElFinderVolumeLocalFileSystem" />

Flysystem configuration

Since 4.0 bundle supports flysystem filesystem abstraction library

Example configuration can be found here Flysystem