Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Repository plugins

From MoodleDocs

Introduction

Repository plugin allow Moodle to bring contents into Moodle from external repositories.

Prerequisites

Before starting coding, it is necessary to know how to use repository administration pages and how to use the file picker.

Overview

The 3 different parts to write

  1. Administration - You can customise the way administrators and users can configure their repositories.
  2. File picker integration - The core of your plugin, it will manage communication between Moodle and the repository service, and also the file picker display.
  3. I18n - Internationalization should be done at the same time as you're writing the other parts.

History

Repository plugins exists from 2.0

Example

Template

There is a template available in Dongsheng Cai's github

Creating new repository plugin

  1. Create a folder for your plugin in /repository/ e.g. /repository/myplugin
  2. Create the following files in your plugin folder:
    • /repository/myplugin/lib.php
    • /repository/myplugin/pix/icon.png - the icon displayed in the file picker (16x16)
    • /repository/myplugin/version.php
    • /repository/myplugin/lang/en/repository_myplugin.php - language file
    • /repository/myplugin/db/access.php
  3. Declare class repository_myplugin extends repository in your lib.php
  4. In your repository_myplugin class overwrite function get_listing() to return array('list' => array());
  5. Add at least strings $string['pluginname'] and $string['configplugin'] to your language file
  6. Add capability 'repository/myplugin:view' to your access.php file
  7. Create install and upgrade scripts (optional or you can do it later)
  8. Login as admin on your website and run upgrade
  9. Open Site Administration->Plugins->Repositories->Manage Repositories and make your repository 'Enabled and visible'

For a more detailed explanation of each of each of the files that have been created here, along with code examples, see Repository plugin files.

Administration APIs

Fixed settings

These are settings that are hard-coded into your repository plugin and can only be updated by changing the plugin code.

supported_returntypes()

Return any combination of the following values:

  • FILE_INTERNAL - the file is uploaded/downloaded and stored directly within the Moodle file system
  • FILE_EXTERNAL - the file stays in the external repository and is accessed from there directly
  • FILE_REFERENCE - the file may be cached locally, but is automatically synchronised, as required, with any changes to the external original

The type used by Moodle depends on the choices made by the end user (e.g. inserting a link, will result in 'FILE_EXTERNAL'-related functions being used, using a 'shortcut/alias' will result in the 'FILE_REFERENCE'-related functions being used). function supported_returntypes() {

   return FILE_REFERENCE|FILE_INTERNAL|FILE_EXTERNAL;

}

supported_filetypes()

Optional. Returns '*' for all file types (default implementation), or an array of types or groups (e.g. array('text/plain', 'image/gif', 'web_image') ) function supported_filetypes() {

   //return '*';
   //return array('image/gif', 'image/jpeg', 'image/png');
   return array('web_image');

} For a full list of possible types and groups, look in lib/filelib.php, function get_mimetypes_array().

Global settings

These are settings that are configured for the whole Moodle site and not per instance of your plugin. All of these are optional, without them there will be no configuration options in the Site administration > Plugins > Repositories > Myplugin page.

get_type_option_names()

This function must be declared static
Optional. Return an array of string. These strings are setting names. These settings are shared by all instances. Parent function returns an empty array.

For example: public static function get_type_option_names() {

  return array_merge(parent::get_type_option_names(), array('rootpath'));

}

type_config_form($mform, $classname='repository')

Optional. This is for modifying the Moodle form displaying the plugin settings. lib/formslib.php Form Definition has details of all the types of elements you can add to the settings form.

For example, to display the standard repository plugin settings along with the custom ones use: public function type_config_form($mform) {

   parent::type_config_form($mform);
   $rootpath = get_config('repository_someplugin', 'rootpath');
   $mform->addElement('text', 'rootpath', get_string('rootpath', 'repository_someplugin'), array('size' => '40'));
   $mform->setDefault('rootpath', $rootpath);

}

type_form_validation($mform, $data, $errors)

Optional. Use this function if you need to validate some variables submitted by plugin settings form. To use it, check through the associative array of data provided ('settingname' => value) for any errors. Then push the items to $error array in the format ("fieldname" => "human readable error message") to have them highlighted in the form.

With the example above, this function may look like: public static function type_form_validation($mform, $data, $errors) {

   if (!is_dir($data['rootpath'])) {
       $errors['rootpath'] = get_string('invalidrootpath', 'repository_someplugin');
   }
   return $errors;

}

Instance settings

These functions relate to a specific instance of your plugin (e.g. the URL and login details to access a specific webdav repository). All of these are optional, without them, the instance settings form will only contain a single 'name' field.

get_instance_option_names()

This function must be declared static
Optional. Return an array of strings. These strings are setting names. These settings are specific to an instance. If the function returns an empty array, the API will consider that the plugin displays only one repository in the file picker. Parent function returns an empty array. This is equivalent to get_type_option_names(), but for a specific instance. public static function get_instance_option_names() {

   return array('fs_path'); // From repository_filesystem

}

instance_config_form($mform)

Optional. This is for modifying the Moodle form displaying the settings specific to an instance. This is equivalent to type_config_form($mform, $classname) but for instances.

For example, to add a required text box called email_address: $mform->addElement('text', 'email_address', get_string('emailaddress', 'repository_flickr_public')); $mform->addRule('email_address', $strrequired, 'required', null, 'client');

Note: mform has by default a name text box (cannot be removed).

Parent function does nothing.

instance_form_validation($mform, $data, $errors)

Optional. This allows us to validate what has been submitted in the instance configuration form. This is equivalent to type_form_validation($mform, $data, $errors), but for instances. For example: public static function instance_form_validation($mform, $data, $errors) {

   if (empty($data['email_address'])) {
       $errors['email_address'] = get_string('invalidemailsettingname', 'repository_flickr_public');
   }
   return $errors;

}

Getting / updating settings

Both global and instance settings can be retrieved, from within the plugin, via $this->get_option('settingname') and updated via $this->set_option(array('settingname' => 'value')).

plugin_init()

This function must be declared static
Optional. This function is called when the administrator adds the plugin. So unless the administrator deletes the plugin and re-adds it, it should be called only once. Parent function does nothing.

Example of using the settings

As an example, let's create a Flickr plugin for accessing a public flickr account. The plugin will be called "Flickr Public".

Firstly the skeleton:

<?php /**

* repository_flickr_public class
* Moodle user can access public flickr account
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  • /

class repository_flickr_public extends repository { }

Then consider the question "What does my plugin do?"

In the Moodle file picker, we want to display some flickr public repositories directly linked to a flickr public account. For example My Public Flickr Pictures, and also My Friend's Flickr Pictures. When the user clicks on one of these repositories, the public pictures are displayed in the file picker.

In order to access to a flickr public account, the plugin needs to know the email address of the Flickr public account owner. So the administrator will need to set an email address for every repository. Let's add an "email address" setting to every repository.

//We tell the API that the repositories have specific settings: "email address"

   public static function get_instance_option_names() {
       return array('email_address');
   }

//We add an "email address" text box to the create/edit repository instance Moodle form

   public function instance_config_form(&$mform) {
       $mform->addElement('text', 'email_address', get_string('emailaddress', 'repository_flickr_public'));
       $mform->addRule('email_address', get_string('required'), 'required', null, 'client');
   }

So at this moment all our Flickr Public Repositories will have a specific email address. However this is not enough. In order to communicate with Flickr, Moodle needs to know a Flickr API key (http://www.flickr.com/services/api/). This API key is the same for any repository. We could add it with the email address setting but the administrator would have to enter the same API key for every repository. Hopefully the administrator can add settings to the plugin level, impacting all repositories. The code is similar the repository instance settings: //We tell the API that the repositories have general settings: "api_key"

   public static function get_type_option_names() {
       return array('api_key');
   }

//We add an "api key" text box to the create/edit repository plugin Moodle form (also called a Repository type Moodle form)

   public function type_config_form(&$mform) {
       //the following line is needed in order to retrieve the API key value from the database when Moodle displays the edit form
       $api_key = get_config('flickr_public', 'api_key');
       $mform->addElement('text', 'api_key', get_string('apikey', 'repository_flickr_public'), 
                          array('value'=>$api_key,'size' => '40'));
       $mform->addRule('api_key', get_string('required'), 'required', null, 'client');
   }

Have we finished yet?

Yes! We have created everything necessary for the administration pages. But let's go further. It would be good if the user can enter any "Flickr public account email address" in the file picker. In fact we want to display in the file picker a Flickr Public repository that the Moodle administrator can never delete. Let's add:

    //this function is only called one time, when the Moodle administrator add the Flickr Public Plugin into the Moodle site.
    public static function plugin_init() {
       //here we create a default repository instance. The last parameter is 1 in order to set the instance as readonly.
       repository_static_function('flickr_public','create', 'flickr_public', 0, get_system_context(), 
                                   array('name' => 'default instance','email_address' => null),1);
    }

That's all - the administration part of our Flickr Public plugin is done. For your information, Box.net, Flickr, and Flickr Public all have similar administration APIs.

Repository APIs

Quick Start

First of all, the File Picker using intensively Ajax you will need a easy way to debug. Install FirePHP (MDL-16371) and make it works. It will save you a lot of time. (You might give the FirePHP plugin for Moodle a try, it's still work in progress, though.)

  • Your first question when you write your plugin specification is 'Does the user need to log-in'? If they do, in your plugin you have to detect user session in constructor() function, and use print_login() if required, see more details below.
  • For most of plugins, you need to establish a connection with the remote repository. This connection can be done into the get_listing(), constructor() function, see more details below.
  • You wanna retrieve the file that the user selected, rewrite get_file() if required, see more details below.
  • Optional question that you should ask yourself is 'Does the user can execute a search', if they do, you will have to rewrite search() method, see more details below.

Functions you *MUST* override

These functions cover the basics of initialising your plugin each time the repository is accessed and listing the files available to the user from within the plugin.

__construct($respoitoryid, $context=SYSCONTEXTID, $options=array(), $readonly=0)

Should be overridden to do any initialisation required by the repository, including:

  • logging in via optional_param, if required - see 'print_login', below
  • getting any options from the database

The possible items in the $options array are:

  • 'ajax' - bool, true if the user is using the AJAX filepicker
  • 'mimetypes' - array of accepted mime types, or '*' for all types

Calling parent::__construct($repositoryid, $context, $options, $readonly); is essential and will set up various required member variables:

  • $this->id - the repository instance id (the ID of the entry in mdl_repository_instances)
  • $this->context - the context in which the repository instance can be found
  • $this->instance - the repository instance record (from mdl_repository_instances)
  • $this->readonly - whether or not the settings can be changed
  • $this->options - the above options, combined with the settings saved in the database
  • $this->name - as specified by $this->get_name()
  • $this->returntypes - as specified by $this->supported_returntypes()

get_listing($path="", $page="")

This function will return a list of files to be displayed to the user, the list must be a array like this: $list = array(

//this will be used to build navigation bar

'path'=>array(array('name'=>'root','path'=>'/'), array('name'=>'subfolder', 'path'=>'/subfolder')), 'manage'=>'http://webmgr.moodle.com', 'list'=> array(

   array('title'=>'filename1', 'date'=>'1340002147', 'size'=>'10451213', 'source'=>'http://www.moodle.com/dl.rar'),
   array('title'=>'folder', 'date'=>'1340002147', 'size'=>'0', 'children'=>array())

) ); Amongst other details, this returns a title for each file (to be displayed in the filepicker) and the source for the file (which will be included in the request to 'download' the file into Moodle or to generate a link to the file). Directories return a children value, which is either an empty array (if 'dynload' is specified) or an array of the files and directories contained within it.

The full specification of list element:

array(
  // 'path' is used to build navegation bar, so you need to include all parents folders
  // array(array('name'=>'root','path'=>'/'), array('name'=>'subfolder', 'path'=>'/subfolder'))
  'path' => (array) this will be used to build navigation bar
  // 'dynload' tells file picker to fetch list dynamically.
  // When user clicks the folder, it will send a ajax request to server side.
  // Default value is false but note that non-Javascript file picker always acts as if dynload was set to true
  'dynload' => (bool) use dynamic loading,
  // if you are using pagination, 'page' and 'pages' parameters should be set.
  // It is not recommended to use pagination and subfolders at the same time, the tree view mode can not handle it correctly
  'page' => (int) which page is this list
  'pages' => (int) how many pages. If number of pages is unknown but we know that the next page exists repository may return -1
  'manage' => (string) url to file manager for the external repository, if specified will display link in file picker
  'help' => (string) url to the help window, if specified will display link in file picker
  'nologin' => (bool) requires login, default false, if set to true the login link will be removed from file picker
  'norefresh' => (bool) no refresh button, default false
  'logouttext' => (string) in case of nologin=false can substitute the text 'Logout' for logout link in file picker
  'nosearch' => (bool) no search link, default false, if set to true the search link will be removed from file picker
  'issearchresult' => (bool) tells that this listing is the result of search
  // for repositories that actually upload a file: set 'upload' option to display an upload form in file picker
  'upload' => array( // upload manager
    'label' => (string) label of the form element,
    'id' => (string) id of the form element
  ),
  // 'list' is used by file picker to build a file/folder tree
  'list' => array(
    array( // file
      'title' => (string) file name,
      'shorttitle' => (string) optional, if you prefer to display a short title
      'date' => (int) UNIX timestamp, default value for datemodified and datecreated,
      'datemodified' => (int) UNIX timestamp when the file was last modified [2.3+],
      'datecreated' => (int) UNIX timestamp when the file was last created [2.3+],
      'size' => (int) file size in bytes,
      'thumbnail' => (string) url to thumbnail for the file,
      'thumbnail_width' => (int) the width of the thumbnail image,
      'thumbnail_height' => (int) the height of the thumbnail image,
      'source' => plugin-dependent unique path to the file (id, url, path, etc.),
      'url' => the accessible url of file,
      'icon' => (string) url to icon of the image (24x24px), if omitted the moodle filetype icon will be used [2.3+],
      'realthumbnail' => (string) url to image preview to be lazy-loaded when scrolled to it (if it requires to be generated and can not be returned as 'thumbnail') [2.3+],
      'realicon' => (string) url to image preview in icon size (24x24) [2.3+],
      'author' => (string) default value for file author,
      'license' => (string) default value for license (short name, see class license_manager),
      'image_height' => (int) if the file is an image, image height in pixels, null otherwise [2.3+],
      'image_width' =>  (int) if the file is an image, image width in pixels, null otherwise [2.3+]
    ),
    array( // folder - similar to file, has also 'path' and 'children' but no 'source' or 'url'
      'title' => (string) folder name,
      'shorttitle' => (string) optional, if you prefer to display a short title
      'path' => (string) path to this folder. In case of dynload=true (and for non-JS filepicker) the value will be passed to repository_xxx::get_listing() in order to retrieve children
      'date', 'datemodified', 'datecreated', 'thumbnail', 'icon' => see above,
      'children' => array( 
        // presence of this attribute actually tells file picker that this is a folder. In case of dynload=true, it should be empty array
        // otherwise it is a nested list of contained files and folders
      )
    ),
  )

// The 'object' tag can be used to embed an external web page or application within the filepicker

  'object' => array(
     'type' => (string) e.g. 'text/html', 'application/x-shockwave-flash'
     'url' => (string) the website address to embed in the object
  )
)

Dynamically loading Some repositories contain many files which cannot load in one time, in this case, we need dynamically loading to fetch them step by step, files in subfolder won't be listed until user click the folder in file picker treeview.

As a plug-in developer, if you set dynload flag as true, you should return files and folders (set children as a null array) in current path only instead of building the whole file tree.

Example of dynamically loading See Alfresco plug-in

The use of the object tag, instead of returning a list of files, allows you to embed an external file chooser within the repository panel. See Repository plugins embedding external file chooser for details about how to do this.

User login (optional)

If the plugin requires login from the user at the time when they use it, then these functions can be used.

print_login

Returns an array of the elements required in the login form. If no login form is required, then the default implementation of this will redirect to the files list. If $this->options['ajax'] is not set, then an HTML-snippet with the login fields (but not the form tags) should be output, instead of returning the form details. public function print_login() { // From repository_alfresco

   if ($this->options['ajax']) {
       $user_field = new stdClass();
       $user_field->label = get_string('username', 'repository_alfresco').': ';
       $user_field->id    = 'alfresco_username';
       $user_field->type  = 'text';
       $user_field->name  = 'al_username';
       $passwd_field = new stdClass();
       $passwd_field->label = get_string('password', 'repository_alfresco').': ';
       $passwd_field->id    = 'alfresco_password';
       $passwd_field->type  = 'password';
       $passwd_field->name  = 'al_password';
       $ret = array();
       $ret['login'] = array($user_field, $passwd_field);
       return $ret;
   } else { // Non-AJAX login form - directly output the form elements

echo '

'; echo ''; echo ''; echo ''; echo ''; echo '
<label>'.get_string('username', 'repository_alfresco').'</label><input type="text" name="al_username" />
<label>'.get_string('password', 'repository_alfresco').'</label><input type="password" name="al_password" />

';

       echo '<input type="submit" value="Enter" />';
   }

} This will help to generate a form by file picker which contains user name and password input elements.

For plugins that do not fully process the login via a popup window, the submitted details can be retrieved, from within the '__construct' function, via $submitted = optional_param('fieldname', [defaultvalue], PARAM_INT/PARAM_TEXT). public function __construct($repositoryid, $context = SYSCONTEXTID, $options = array()) { // Taken from repository_alfresco

/* Skipping code that is not relevant to user login */

       $this->alfresco = new Alfresco_Repository($this->options['alfresco_url']);        
       $this->username = optional_param('al_username', , PARAM_RAW);
       $this->password = optional_param('al_password', , PARAM_RAW);
       try{
           // deal with user logging in
           if (empty($SESSION->{$this->sessname}) && !empty($this->username) && !empty($this->password)) {
               $this->ticket = $this->alfresco->authenticate($this->username, $this->password);
               $SESSION->{$this->sessname} = $this->ticket;
           } else {
               if (!empty($SESSION->{$this->sessname})) {
                   $this->ticket = $SESSION->{$this->sessname};
               }
           }
           $this->user_session = $this->alfresco->createSession($this->ticket);
           $this->store = new SpacesStore($this->user_session);
       } catch (Exception $e) {
           $this->logout();
       }
       $this->current_node = null;

/* Skipping code that is not relevant to user login */

}

Many types include a single element of type 'popup' with the param 'url' pointing at the URL used to authenticate the repo instance. public function print_login(){ // Code taken from repository_boxnet

   $t = $this->boxclient->getTicket();
   if ($this->options['ajax']) {
       $popup_btn = new stdClass();
       $popup_btn->type = 'popup';
       $popup_btn->url = ' https://www.box.com/api/1.0/auth/' . $t['ticket'];
       $ret = array();
       $ret['login'] = array($popup_btn);
       return $ret;
   } else {

echo '

'; echo ''; echo ''; echo ''; echo '';
       echo '<input type="hidden" name="ticket" value="'.$t['ticket'].'" />';
echo '
<label>'.get_string('username', 'repository_boxnet').'</label><input type="text" name="boxusername" />
<label>'.get_string('password', 'repository_boxnet').'</label><input type="password" name="boxpassword" />

';

       echo '<input type="submit" value="'.get_string('enter', 'repository').'" />';
   }

}

check_login

This function will return a boolean value to tell Moodle whether the user has logged in. By default, this function will return true. public function check_login() { // Taken from repository_alfresco

   global $SESSION;
   return !empty($SESSION->{$this->sessname});

}

logout

When a user clicks the logout button in file picker, this function will be called. You may clean up the session or disconnect the connection with remote server here. After this the code should return something suitable to display to the user (usually the results of calling $this->print_login() ): public function logout() { // Taken from repository_alfresco

   global $SESSION;
   unset($SESSION->{$this->sessname});
   return $this->print_login();

}

Transferring files to Moodle (optional)

These functions all relate to transferring the files into Moodle, once they have been chosen in the filepicker. All of them are optional and have default implementations which are often suitable to use as they are.

get_file_reference($source)

Rarely does anything other than return the $source param (the default action if not overridden), but takes the 'source' reference from the browser (originally specified in the list returned by 'get_listing') and makes sure it is ready to be passed on to the 'get_file' or 'get_file_by_reference' functions (below).

get_file($url, $filename = "")

For FILE_INTERNAL or FILE_REFERENCE this function is called at the point when the user has clicked on the file and then on 'select this file' to add it to the filemanager / editor element. It does the actual transfer of the file from the repository and onto the Moodle server. The default implementation is to download the $url via CURL. The $url parameter is the $reference returned by get_file_reference (above, but usually the same as the 'source' returned by 'get_listing'). The $filename should usually be processed by $path = $this->prepare_file($filename), giving the full 'path' where the file should be saved locally. This function then returns an array, containing:

  • path - the local path where the file was saved
  • url - the $url param passed into the function

public function get_file($url, $filename = ) { // Default implementation from the base 'repository' class

   $path = $this->prepare_file($filename); // Generate a unique temporary filename
   $c = new curl;
   $result = $c->download_one($url, null, array('filepath' => $path, 'timeout' => self::GETFILE_TIMEOUT));
   if ($result !== true) {
       throw new moodle_exception('errorwhiledownload', 'repository', , $result);
   }
   return array('path'=>$path, 'url'=>$url);

} public function get_file($reference, $filename = ) { // Slightly extended version taken from repository_equella

   global $USER;

// Extract the details saved in the 'source' param by // repository/equella/callback.php (now in the $reference paramater)

   $ref = @unserialize(base64_decode($reference));
   if (!isset($ref->url) || !($url = $this->appendtoken($ref->url))) {
       // Occurs when the user isn't known..
       return null;
   }
   $path = $this->prepare_file($filename);
   $cookiepathname = $this->prepare_file($USER->id. '_'. uniqid(, true). '.cookie');
   $c = new curl(array('cookie'=>$cookiepathname));
   $result = $c->download_one($url, null, array('filepath' => $path, 'followlocation' => true, 'timeout' => self::GETFILE_TIMEOUT));
   // Delete cookie jar.
   if (file_exists($cookiepathname)) {
       unlink($cookiepathname);
   }
   if ($result !== true) {
       throw new moodle_exception('errorwhiledownload', 'repository', , $result);
   }
   return array('path'=>$path, 'url'=>$url);

}

get_link($url)

Used with FILE_EXTERNAL to convert a reference (from 'get_file_reference', but ultimately from the output of 'get_listing') into a URL that can be used directly by the end-user's browser. Usually just returns the original $url, but may need further transformation based on the internal implementation of the repository plugin.

get_file_source_info($source) (2.3+)

Takes the 'source' field from 'get_listing' (as returned by the user's browser) and returns the value to be stored in files.source field in DB (regardless whether file is picked as a copy or by reference). It indicates where the file came from. It is advised to include either full URL here or indication of the repository. Examples: 'Dropbox: /filename.jpg', 'http://fullurl.com/path/file', etc. This value will be used to display warning message if reference can not be restored from backup. Also it can (although not has to) be used in get_reference_details() to produce the human-readable reference source in the fileinfo dialogue in the file manager.

Search functions (optional)

print_search

When a user clicks the search button on file picker, this function will be called to return a search form. By default, it will create a form with single search bar - you can override it to create a advanced search form.

A custom search form must include the following:

  • A text field element named s, this is where users will type in their search criteria

The following fields are automatically inserted in Moodle 2.3+ (but may need to be manually included in earlier versions):

  • A hidden element named repo_id and the value must be the id of the repository instance
  • A hidden element named ctx_id and the value must be the context id of the repository instance
  • A hidden element named sesskey and the value must be the session key

public function print_search() {

   // The default implementation in class 'repository'
   global $PAGE;
   $renderer = $PAGE->get_renderer('core', 'files');
   return $renderer->repository_default_searchform();

}

// From core_files_renderer (repository/renderer.php) public function repository_default_searchform() {

$str = '

';

   return $str;

}

class repository_myrepo extends repository {

   // other required functions
   ....
   public function search($search_text, $page = 0) { // Since Moodle 2.3, the page argument is required
       // label search name
       $param = array('for' => 'label_search_name');
       $title = get_string('search_name', 'myrepo_search_name');
       $html .= html_writer::tag('label', $title, $param);
       $html .= html_writer::empty_tag('br');
       // text field search name
       $attributes['type'] = 'text';
       $attributes['name'] = 's';
       $attributes['value'] = ;
       $attributes['title'] = $title;
       $html .= html_writer::empty_tag('input', $attributes);
       $html .= html_writer::empty_tag('br');
       
       return $html;
   }

}

search

This function will do the searching job. You can obtain the POST parameters from the forum you created in print_search function This function will return a file list exactly like the one from get_listing.

get_name

This function will return the name of the repository instance.

Repository support for returning file as alias/shortcut

From Moodle 2.3 it became possible to link to the file from external (or internal) repository by reference. In UI it is called “create alias/shortcut”. This creates a row in {files} table but the contents of the file is not stored. Although it may be cached by repository if developer wants to.

Make sure that function supported_returntypes() returns FILE_REFERENCE among other types.

Note that external file is synchronised by moodle when UI wants to show the file size.

get_reference_details

When file in moodle filearea is a reference to file in some repository, filemanager can display the location of the original. This function is responsible for returning human-readable location. It is usually prefixed with repository name and semicolon.

get_reference_file_lifetime

how often to synchronise the file

sync_individual_file

Decide whether or not the file should be synced (by default true). This is checked after the lifetime is checked.

get_file_by_reference

This is actual synchronisation performed when sync conditions are met. Note that it is not necessary to download file here. This is just needed to find out if filesize and/or contenthash have changed since the last synchronization. This function returns null if source file can not be found any more. Otherwise it returns an object with file information (see phpdocs). The preferable output is only contenthash/filesize: if repository is able to retrieve this information without downloading file into moodle it is the best. Don’t forget that this function might be called quite often since filemanager always wants to know the file size.

send_file

Repository method to serve the referenced file. This function is called when user actually tries to download/view the file. But it still can return the cached copy if repository developer wishes so.

I18n - Internationalization

These following strings are required in moodle/repository/myplugin/lang/en/repository_myplugin.php or moodle/lang/en/repository_myplugin.php:

$string['pluginname'] = 'Flickr Public'; $string['configplugin'] = 'Flickr Public configuration'; $string['pluginname_help'] = 'A Flickr public repository';

See also