Adding file description to Properties dialog - Studio-42/elFinder GitHub Wiki

Sometimes you need to describe files, for example if you are integrating elFinder with an enterprise document management system. This howto will show how to extend elFinder to show a file description gotten from external source.

  1. Add command for getting/setting description to volume driver. In this example using a file named elFinderVolumeMyDrive.class.php.
<?php

class elFinderVolumeMyDriver extends elFinderVolumeLocalFileSystem {
  // ...

  // Command to implement
  public function desc($target, $newdesc = NULL) {
    // get readable path from hash
    $path = $this->decode($target);

    if ($newdesc == NULL) {
      // Get current the description
      $desc = $this->getYourCoolDescription($target);
    } else {
      // Write a new description
      $desc = $this->writeYourCoolDescription($target, $newdesc);
    }

    return $desc;
  }

  // Get a description of the $target
  // @return the description if it exists; -1 otherwise
  protected function getYourCoolDescription($target) {
    // Your implementation here
    // This one just returns 'desc' every time
    return 'desc';
  }

  // Writing a description for the $target
  // @return the description if successful; -1 otherwise
  protected function writeYourCoolDescription($target, $newdesc) {
    // Your implementation here
    // This one just returns the new description
    return $newdesc;
  }

  // ...
}

Implement getYourCoolDescription($target) and writeYourCoolDescription($target, $newdesc) with real code for getting/setting the description from external source.

  1. Register the command in the elFinder object. In this example using a file named myelFinder.class.php.
<?php

class myelFinder extends elFinder {
  // Custom error message if description isn't found
  const ERROR_DESC_NOT_FOUND = 'Description not found';

  // ...

  // Modify the constructor
  // Run the old constructor and register 'desc' as a new command
  public function __construct($opts) {
    parent::__construct($opts);
    $this->commands['desc'] = array('target' => TRUE, 'content' => FALSE);
  }

  // Implement the desc command
  protected function desc($args) {
    // Get the target directory and $desc parameter
    $target = $args['target'];
    $desc   = $args['content'];

    // Get the volume, and if successful, the file
    $volume = $this->volume($target);
    $file   = $volume ? $volume->file($target) : false;

    // Check if desc is disabled, and if we can get the true description
    $disabled = $volume ? $volume->commandDisabled('desc') : false;
    $desc     = (!$disabled && $volume) ? $volume->desc($target, $desc) : false;

    // Start accumulating the results
    $results = array();

    if (!$file) {
      // File not found; send "file not found" error message
      $results['error'] = $this->error(self::ERROR_FILE_NOT_FOUND);
    } elseif ($disabled) {
      // Command disabled; send "access denied" messsage, with filename
      $results['error'] = $this->error(self::ERROR_ACCESS_DENIED, $file['name']);
    } elseif ($desc == -1) {
      // No description; send "description not found" message, with filename
      $results['error'] = $this->error(self::ERROR_DESC_NOT_FOUND, $file['name']);
    } else {
      // Success!
      $results['desc'] = $desc; 
    }

    return $results;
  }

  // ...
}
  1. Include these extended files (elFinder subclass and custom volume driver) in the connector.
<?php
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderConnector.class.php';
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinder.class.php';
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeDriver.class.php';
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeLocalFileSystem.class.php';
// don't forget our new included files
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeMyDrive.class.php';
include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elmyFinder.class.php';

$opts = array( 
 'roots' => array(
    array(
      'driver' => 'MyDriver',  // use my custom volume driver
      'path' => '/tmp/myfiles',
      'URL' => 'http://example.com/my-files/',
    ),
 ),
);

$connector = new elFinderConnector(new elmyFinder($opts), true);  // instantiate using our custom elFinder object
$connector->run();
  1. Edit js/commands/info.js and extend it with following code using the new connector command to get/set description
// add a 'desc' item to the 'msg' variable near the top of the file
        msg = {
            calc : fm.i18n('calc') ,
            size : fm.i18n('size') ,
            unknown : fm.i18n('unknown') ,
            path : fm.i18n('path') ,
            aliasfor : fm.i18n('aliasfor') ,
            modify : fm.i18n('modify') ,
            perms : fm.i18n('perms') ,
            locked : fm.i18n('locked') ,
            dim : fm.i18n('dim') ,
            kind : fm.i18n('kind') ,
            files : fm.i18n('files') ,
            folders : fm.i18n('folders') ,
            items : fm.i18n('items') ,
            yes : fm.i18n('yes') ,
            no : fm.i18n('no') ,
            link : fm.i18n('link') ,
            desc: fm.i18n('desc') // our new property
        };
// add the dialog control markup after the 3 'content.push' lines in the middle of the file
var editDesc = true;
var desc = '<div id="elfinder-fm-file-desc">' + msg.calc + '</div>';        
if (editDesc)  {    
	desc  = '<textarea cols="20" rows="5" id="elfinder-fm-file-desc" class="ui-widget ui-widget-content" disabled="true" >' + msg.calc + '</textarea><input type="button" id="elfinder-fm-file-desc-btn-save" value="' + fm.i18n('btnSave') + '" />';
}

content.push(row.replace(l, 'Description').replace(v , desc));
        
fm.request({
	data : {
		cmd : 'desc', 
		target : file.hash
		},
	preventDefault : true
})
.done(function(data) {
	var fieldDesc = dialog.find('#elfinder-fm-file-desc');
          
	if (editDesc)  {
		fieldDesc.val(data.desc || '');
		fieldDesc.removeAttr('disabled');
	} else {
		fieldDesc.empty();
		fieldDesc.html(data.desc || '');
	}
});
// just above the 'Load Thumbnail' code
    if (editDesc) {
      var inputDesc = $('#elfinder-fm-file-desc', dialog);
      var btnSave = $('#elfinder-fm-file-desc-btn-save', dialog).button();
      
      btnSave.click(function() {
        fm.lockfiles({files : [file.hash]});
        fm.request({
          data   : {cmd : 'desc', target : file.hash, content : inputDesc.val()},
          notify : {type : 'desc', cnt : 1}
          })
					.always(function() {
						fm.unlockfiles({files : [file.hash]})
					});
      });
    }

Full extended info command source code can be found at http://drupalcode.org/project/elfinder.git/blob/refs/heads/7.x-2.x:/js/info.js

  1. Finally, initialize the client using the following:
<script type="text/javascript" src="elfinder.min.js"></script>
<script type="text/javascript" src="info.js"></script>
<script type="text/javascript">

$().ready(function() {
  if (Drupal.settings.elfinder) {

    var elfinderOpts = {
      url : Drupal.settings.elfinder.connectorUrl,
      lang : Drupal.settings.elfinder.langCode,
      rememberLastDir : Drupal.settings.elfinder.rememberLastDir,
      closeOnEditorCallback : false
    }
	
    $('#finder').elfinder(elfinderOpts);
  }
});
</script>
⚠️ **GitHub.com Fallback** ⚠️