Are you enjoying the extensions? Did you like the support? Help others decide.

Leave a review

Create your own resource plugin


Resource plugins are found under the lockedresources folder.

The name of the plugin is the name of the resource it is supposed to protect from.
For instance, to prevent access to articles, the plugin is named plg_lockedresources_content since the management of articles is made through the com_content component.

A few pre-requisites

Install the extension that will correspond to the resource type that needs to be created. Add some data for testing.
For instance, if you decide to create a plugin to prevent access to downloads in Phoca Download, install Phoca Download first and create categories and files in that extension.

The resource plugin building blocks

For a quick setup, the easiest route is to duplicate an existing plugin.

The language keys

PLG_LOCKEDRESOURCES_RESOURCE_[resource name] is used in the list of resources and the selection of resource types. The .sys file is used on install, mostly.

The image

The image representing the resource is a png file, squared, 48x48. It is used in the resources list, as a visual aid. It must be included in the media folder.

The fields

It may be necessary to create specific fields for the resource.
For instance, for the Kunena plugin, it was necessary to create a field to select the categories of Kunena Forum.

The sub-form

The form entries specific to the resource are found under forms/[resource name].xml. This form is plugged into the more general resource edit form.
For instance, for the menu item resource, the field specific to the resource is a select box allowing the selection of a menu item.

<?xml version="1.0" encoding="utf-8"?>
    <fields name="resourceparams">
        <fieldset name="resourceparams">
            <field name="menuitem" type="menuitem" default="" published="1" required="true" />

The fields are included into the resourceparams fieldset. This has repercussions on how the fields are retrieved and saved into the system

The plugin's engine

The PHP class is extended from LockedResources class, which sets basic functionality. It is responsible for loading the form containing the resource fields, for instance.
The plugin's PHP class tests that the LockedResources class is properly installed. It is in the extension's system plugin.


This function checks that the extension the resource plugin is supposed to limit access to is present and enabled. This will determine if the resource can be used by the system.


This function retrieves the value of the resource fields before being sent to the edit form.

First, we ensure we are in the right plugin (all plugins with onContentPrepareData are called when opening a form). It is done by calling onContentPrepareData of the parent and making sure the resource type that is called is the same as the plugin's name.

Second, values are set in the resourceparams array.

The values that have been stored (if the resource has been saved previously) are located in resource_id and resource_params.
For instance, in the content resource, resource_id is the id of the article that has been selected (or -1 if all articles of a category must be prevented access). resource_params contains the content category and the pay to read more switch.

PayPerDownload used to store resource params as a string, values dash separated (most of the time). Now, the parameters are stored as json strings. If the plugin created is a rewrite of an old existing one, the code must reflect that and be able to retrieve the data in both cases.


This function saves the values set or selected in the form.

First, we ensure we are in the right plugin (all plugins with onContentBeforeSave are called before saving data from a form). It is done by calling onContentBeforeSave of the parent and making sure the resource type that is called is the same as the plugin's name.

Second, we set resource_option_parameter. It is the name of the extension the resource is supposed to protect.
For instance, com_content is the name of the extension that manages articles. The URL's option parameter is com_content.

The string must remain empty when the resource does not protect a specific resource coming from an extension.
For instance, menu items are created for any kind of extension, therefore the string must remain empty (URLs will contain the option parameter, which is not com_menus. It could be com_contact).

We can only catch the field's information of the form through the application's input parameter.

In this function, we need to set resource_id and resource_params. It is also possible to prefill resource_description automatically in case the user did not do so.


This is where a resource is checked and denied access if necessary. By default, access is granted, unless a resource exists.

The resources are loaded from the database and every integer value is returned as a string. As such, when comparing values, especially if the value to compare to is an integer, the resource value must be cast as int.

We loop through all available resources and check the parameter to see if they correspond to the parameters of the element that is supposed to show on the page.
For instance, we check if the resource_id corresponding to an article id is the same id as the article that is going to show on the page.


set to false when resource and targeted entity match.

$requiredLicenses and $resourcesId

These 2 arrays correspond to the license(s) and/or resource(s) that a user needs to be able to access the targeted entity.


This function returns the URL of the resource targeted.


Returns the URL of the resource that is protected when creating an access link (or download link) manually in the console.


This function validates if there is a decrease in count for users for that resource when it has been used (viewed for an article, downloaded for a file…) after payment.


This function returns the id of the resource that is protected.
For instance, the id of the article that is protected by the content plugin

onAjax[plugin name]()

This function gets data for the combo boxe parameters that are filled on-the-fly.
For instance, once a file download category has been selected in a combo box, it may trigger the filling of the next combo box that contains the files for that category.

The returned value must be a json string.

What is happening:

combo box 'categories' -> onchange -> call com_ajax -> escalate to the plugin -> get the data as json string from the plugin -> parse the data and fill the combo box 'files'.

A good example can be found in the phocadownload plugin.


Create resources of the new resource type.
For instance, to test the Content resource, create resources that will prevent access to specific articles.

In the frontend, when accessing those articles, the user is redirected to a payment form (on the home page or on the menu item selected in the configuration).