J3.x:Developing an MVC Component/Adding Access
From Joomla! Documentation
Articles in This Series
- Introduction
- Developing a Basic Component
- Adding a View to the Site Part
- Adding a Menu Type to the Site Part
- Adding a Model to the Site Part
- Adding a Variable Request in the Menu Type
- Using the Database
- Basic Backend
- Adding Language Management
- Adding Backend Actions
- Adding Decorations to the Backend
- Adding Verifications
- Adding Categories
- Adding Configuration
- Adding ACL
- Adding an Install/Uninstall/Update Script File
- Adding a Frontend Form
- Adding an Image
- Adding a Map
- Adding AJAX
- Adding an Alias
- Using the Language Filter Facility
- Adding a Modal
- Adding Associations
- Adding Checkout
- Adding Ordering
- Adding Levels
- Adding Versioning
- Adding Tags
- Adding Access
- Adding a Batch Process
- Adding Cache
- Adding a Feed
- Adding an Update Server
- Adding Custom Fields
- Upgrading to Joomla4
This is a multiple-article series of tutorials on how to develop a Model-View-Controller Component for Joomla! Version
.
Begin with the Introduction, and navigate the articles in this series by using the navigation button at the bottom or the box to the right (the Articles in this series).
This tutorial is part of the Developing an MVC Component for Joomla! 3.2 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.
In this step we add access capability to our component, which allows us to restrict the set of users who can view our helloworld data. This step really fits before Adding ACL, but is added belatedly for completeness here.
There is a video accompanying this step (which was originally produced at the same time as the other videos for ACL) available at Access Levels.
Under Construction!
Introduction
If you're not familiar with Access within Joomla, then it's worthwhile playing around with the functionality – setting access on menuitems and articles, setting the accesslevels of user groups (and hence of users), and confirming that users can see only the items to which they have been granted access. This works on both the site front end, and the admin back end.
The diagram shows how Joomla user access levels work.

Each item – eg an article, a menuitem, or in our case a helloworld record – has an access level assigned.
Each user is assigned one or more user groups, and user groups have a hierarchical (tree) structure, so that if a user belongs to a user group which is a child of another, then that user is also a member of the parent user group.
Each access level has one more associated user groups, who will then have view access to items which have that access level.
When the user requests to view a particular item, then the functionality
- obtains the set of accesslevels that the user has
- checks if the accesslevel of the requested item is within the set of accesslevels of that user
- if it is, then the item is presented to the user
- if it isn't, then an HTTP response with status 403 (forbidden) is returned.
Approach
To enable us to have an Access Level against a helloworld record, we need to specify a new field in the database, which we'll call "access". We'll set the database default value of this access field to be 1, which means that by default everyone can see the record.
To enable the administrator to set this field, we will add an Access field within the back-end edit form, and we use the "accesslevel" field type within the Joomla standard form field types. As is often the case, this field will get automatically saved to the "access" field in the database by our existing code.
On our administrator helloworlds view we'll add a column to display the Access Level assigned to that item. This will involve a change to the layout file to display the column. We also want to restrict the administrator to only those helloworld records that he/she has access to view, so this will involve a filter within the SQL query in our model.
The key Joomla method which we use to find the accesslevels which a user has is JUser::getAuthorisedViewLevels(), and for a user to be allowed to view an item, the item's accesslevel must be within the array of accesslevels returned by getAuthorisedViewLevels(). This is true for both front end and back end.
We will also follow the pattern in Joomla, which specifies that to view an item the user must have access to both the item itself and to the category (if any) associated with the item. Joomla already allows us to set an accesslevel against a category, and where categories are being displayed (both on front end and back end) it filters them to show only those which the user is entitled to see. However, we must write the code in the case where we're displaying helloworld records, to check that the user is entitled to view the associated category as well.
On the front end, whenever a single helloworld record is displayed, we will have to check that the user has access to that record, and if not, return an HTTP status 403.
If a number of helloworld records are being displayed, then we will change the SQL query to filter by the set of accesslevels which the user has.
Finally, as helloworld records may be viewed (to a certain extent) via the tags functionality, we update our field mappings so that our access field is copied into the ucm_content table. This means that the same restrictions will apply to viewing both the helloworld record and its copy in the ucm_content table.
Packaging the Component
Contents of your code directory. Each file link below takes you to the step in the tutorial which has the latest version of that source code file.
- helloworld.xml
- script.php
- site/router.php
- site/helloworld.php
- site/index.html
- site/controller.php
- site/controllers/helloworld.php
- site/views/index.html
- site/views/helloworld/index.html
- site/views/helloworld/view.html.php
- site/views/helloworld/view.json.php
- site/views/helloworld/tmpl/index.html
- site/views/helloworld/tmpl/default.xml
- site/views/helloworld/tmpl/default.php
- site/views/form/index.html
- site/views/form/view.html.php
- site/views/form/tmpl/index.html
- site/views/form/tmpl/edit.php
- site/views/form/tmpl/edit.xml
- site/views/category/index.html
- site/views/category/view.html.php
- site/views/category/tmpl/index.html
- site/views/category/tmpl/default.php
- site/views/category/tmpl/default.xml
- site/models/index.html
- site/models/helloworld.php
- site/models/form.php
- site/models/category.php
- site/models/forms/index.html
- site/models/forms/add-form.xml
- site/models/forms/filter_category.xml
- site/language/index.html
- site/language/en-GB/index.html
- site/language/en-GB/en-GB.com_helloworld.ini
- site/helpers/index.html
- site/helpers/route.php
- site/helpers/category.php
- site/helpers/association.php
- admin/index.html
- admin/helloworld.php
- admin/config.xml
- admin/controller.php
- admin/access.xml
- admin/helpers/helloworld.php
- admin/helpers/associations.php
- admin/helpers/index.html
- admin/helpers/html/helloworlds.php
- admin/helpers/html/index.html
- admin/sql/index.html
- admin/sql/install.mysql.utf8.sql
- admin/sql/uninstall.mysql.utf8.sql
- admin/sql/updates/index.html
- admin/sql/updates/mysql/index.html
- admin/sql/updates/mysql/0.0.1.sql
- admin/sql/updates/mysql/0.0.6.sql
- admin/sql/updates/mysql/0.0.12.sql
- admin/sql/updates/mysql/0.0.13.sql
- admin/sql/updates/mysql/0.0.14.sql
- admin/sql/updates/mysql/0.0.16.sql
- admin/sql/updates/mysql/0.0.17.sql
- admin/sql/updates/mysql/0.0.18.sql
- admin/sql/updates/mysql/0.0.20.sql
- admin/sql/updates/mysql/0.0.21.sql
- admin/sql/updates/mysql/0.0.24.sql
- admin/sql/updates/mysql/0.0.25.sql
- admin/sql/updates/mysql/0.0.26.sql
- admin/sql/updates/mysql/0.0.27.sql
- admin/sql/updates/mysql/0.0.28.sql
- admin/models/index.html
- admin/models/fields/index.html
- admin/models/fields/helloworld.php
- admin/models/fields/helloworldordering.php
- admin/models/fields/helloworldparent.php
- admin/models/fields/modal/index.html
- admin/models/fields/modal/helloworld.php
- admin/models/helloworlds.php
- admin/models/helloworld.php
- admin/models/forms/filter_helloworlds.xml
- admin/models/forms/index.html
- admin/models/forms/helloworld.js
- admin/models/forms/helloworld.xml
- admin/models/rules/greeting.php
- admin/models/rules/index.html
- admin/controllers/helloworld.php
- admin/controllers/helloworlds.php
- admin/controllers/index.html
- admin/views/index.html
- admin/views/helloworld/index.html
- admin/views/helloworld/view.html.php
- admin/views/helloworld/tmpl/index.html
- admin/views/helloworld/tmpl/edit.php
- admin/views/helloworld/submitbutton.js
- admin/views/helloworlds/index.html
- admin/views/helloworlds/view.html.php
- admin/views/helloworlds/tmpl/index.html
- admin/views/helloworlds/tmpl/default.php
- admin/views/helloworlds/tmpl/modal.php
- admin/tables/index.html
- admin/tables/helloworld.php
- admin/language/index.html
- admin/language/en-GB/index.html
- admin/language/en-GB/en-GB.com_helloworld.ini
- admin/language/en-GB/en-GB.com_helloworld.sys.ini
- media/index.html
- media/images/index.html
- media/images/tux-16x16.png
- media/images/tux-48x48.png
- media/js/index.html
- media/js/openstreetmap.js
- media/js/admin-helloworlds-modal.js
- media/css/index.html
- media/css/openstreetmap.css
helloworld.xml
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.0" method="upgrade">
<name>COM_HELLOWORLD</name>
<!-- The following elements are optional and free of formatting constraints -->
<creationDate>January 2018</creationDate>
<author>John Doe</author>
<authorEmail>john.doe@example.org</authorEmail>
<authorUrl>http://www.example.org</authorUrl>
<copyright>Copyright Info</copyright>
<license>License Info</license>
<!-- The version string is recorded in the components table -->
<version>0.0.29</version>
<!-- The description is optional and defaults to the name -->
<description>COM_HELLOWORLD_DESCRIPTION</description>
<!-- Runs on install/uninstall/update; New in 2.5 -->
<scriptfile>script.php</scriptfile>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update; New since J2.5 -->
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<!-- Site Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /site/ in the package -->
<files folder="site">
<filename>index.html</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<filename>router.php</filename>
<folder>controllers</folder>
<folder>views</folder>
<folder>models</folder>
<folder>helpers</folder>
</files>
<languages folder="site/language">
<language tag="en-GB">en-GB/en-GB.com_helloworld.ini</language>
<language tag="fr-FR">fr-FR/fr-FR.com_helloworld.ini</language>
</languages>
<media destination="com_helloworld" folder="media">
<filename>index.html</filename>
<folder>images</folder>
<folder>js</folder>
<folder>css</folder>
</media>
<administration>
<!-- Administration Menu Section -->
<menu link='index.php?option=com_helloworld' img="../media/com_helloworld/images/tux-16x16.png">COM_HELLOWORLD_MENU</menu>
<!-- Administration Main File Copy Section -->
<!-- Note the folder attribute: This attribute describes the folder
to copy FROM in the package to install therefore files copied
in this section are copied from /admin/ in the package -->
<files folder="admin">
<!-- Admin Main File Copy Section -->
<filename>index.html</filename>
<filename>config.xml</filename>
<filename>helloworld.php</filename>
<filename>controller.php</filename>
<filename>access.xml</filename>
<!-- SQL files section -->
<folder>sql</folder>
<!-- tables files section -->
<folder>tables</folder>
<!-- models files section -->
<folder>models</folder>
<!-- views files section -->
<folder>views</folder>
<!-- controllers files section -->
<folder>controllers</folder>
<!-- helpers files section -->
<folder>helpers</folder>
</files>
<languages folder="admin/language">
<language tag="en-GB">en-GB/en-GB.com_helloworld.ini</language>
<language tag="en-GB">en-GB/en-GB.com_helloworld.sys.ini</language>
<language tag="fr-FR">fr-FR/fr-FR.com_helloworld.ini</language>
<language tag="fr-FR">fr-FR/fr-FR.com_helloworld.sys.ini</language>
</languages>
</administration>
</extension>