The Session and the User with Joomla! 1.5: Part 2

Exclusive offer: get 50% off this eBook here
Joomla! 1.5 Development Cookbook

Joomla! 1.5 Development Cookbook — Save 50%

Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes

$26.99    $13.50
by James Kennard | October 2009 | Cookbooks Joomla! MySQL Content Management Open Source PHP

Read Part One of The Session and the User with Joomla! 1.5 here.

Getting the user's group ID and type

The following organized list describes the user groups in Joomla! 1.5 in a way in which we are all probably familiar. Each of these groups has an ID and a name; these are the group's ID and type respectively.

Joomla! 1.5 Development Cookbook

This recipe explains how to find the group ID and group type of the current user. Note that the hard coded group IDs should not generally be used for access control; for this it is best to take advantage of the JAuthorization class. For more information, refer to the Joomla! API site: http://api.joomla.org/.

Dynamic permissions

There is no administrative functionality that allows the modification of groups. It is, however, possible to programmatically modify groups and group permissions. Most of the time a Joomla! 1.5 extension will opt to implement its own permission management rather than use the incomplete Joomla! solution.

Joomla! 1.6, in development at the time of writing, promises a complete GACL (Group Access Control List) implementation.

Getting ready

To complete this recipe, we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe covered earlier in this article.

$user =& JFactory::getUser();

How to do it...

The group ID is held in the gid field in the #__users table. We use the JUser::get() method to extract the user's group ID.

// determine group ID
$groupID = $user->get('gid');

The group type is held in the usertype field in the #__users table. Again, we use the JUser::get() method to extract the user's group ID.


$usertype = $user->get('usertype');

How it works...

Apart from the obvious format of the data, there is a subtle difference between the gid and usertype fields. The gid field is always populated, where as the usertype field is populated only if the user is not blocked. When dealing with the current user, the user will never be blocked, but when dealing with other users there is a possibility that the usertype field will not be populated. Therefore, we need to be careful that we select the most appropriate field, depending on the context of what we are doing.

The user groups that we have mentioned are maintained in the #__core_acl_aro_groups table, or as it can also be called, the Access Control List Access Request Object Groups table. This table holds a tree structure, as indicated in the introduction of the recipe. What is noticeable is that Public Frontend and Public Backend are both technically user groups. As this is a tree structure, we can use the left and right values to perform all sorts of neat tricks.

The #__core_acl_aro_groups table employs the nested set model: http://dev.mysql.com/tech-resources/articles/hierarchical-data.html.

See also

The next recipe explains how to use the Public, Registered, and Special access levels.

Restricting a user's access using Public, Registered, and Special

In Joomla! we often define access based on three simple access levels. These levels relate to the user groups described in the previous recipe, Getting the user's group ID and type. This recipe explains how to use these access levels to restrict access to resources.

  • Public (0)
  • Registered (1)
  • Special (2)

Getting ready

To complete this recipe, we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe covered earlier in this article.

$user =& JFactory::getUser();

How to do it...

The JUser::get() method can be used to retrieve the user's aid. This is the access level number, as shown in braces in the recipe introduction.

// get access level
$aid = $user->get('aid');

For each resource we want to restrict access to, we must define the required access level. This is normally done in a database TINYINT(3) field named access. This can then be used to restrict the access using a database query (used when listing)...

// get the DBO
$db =& JFactory::getDBO();
// prepare access field name
$access = $db->nameQuote('access');
// restrict query by access level
$where = "WHERE $access <= " . intval($aid);

...or when viewing a single record. Note that ALERTNOTAUTH is a core translation string, which in en-GB is equivalent to You are not authorised to view this resource.

// make sure the user has the necessary access rights
if ($table->get('access') > $aid) {
JError::raiseError(403, JText::_('ALERTNOTAUTH'));
jexit();
}

How it works...

A good example of this in action is the content component. If we take a look at the article manager, we can see that there is an Access Level associated with each article that determines which users can access the article.

Joomla! 1.5 Development Cookbook

These access levels are relatively primitive and we don't have any bona fide control over them. So how do they translate into concrete user groups? The following table describes the seven user groups and the guest group, and shows how these relate to the access levels:

User Group

User Group ID

Access Level

Access Level ID

None (Guest)

0

Public

0

Registered

18

Registered

1

Author

19

Special

2

Editor

20

Special

2

Publisher

21

Special

2

Manager

23

Special

2

Administrator

24

Special

2

Super Administrator

25

Special

2

See also

The previous recipe explains how to work with the user group ID and group type. This can also be useful for dealing with access control.

Getting the user's parameters

User parameters provide a mechanism for including additional user data without the need to modify the database. The core user parameters are defined in the XML files located in the administratorcomponentscom_usersmodels folder.

Getting ready

To complete this recipe, we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe.

$user =& JFactory::getUser();

How to do it...

To retrieve a parameter we must first know the name of the parameter we want to retrieve. One example of a common parameter is timezone. This is an integer that defines the hours offset from UTC (Coordinated Universal Time), also known as GMT (Greenwich Mean Time) and Z (Zulu).

To retrieve a parameter, we can use the JUser::getParam() method.

$timezone = $user->getParam('timezone');

It is also possible to provide a default value. This is useful especially if the user we are dealing with is a guest because guest users do not have any parameters defined by default.


$timezone = $user->getParam('timezone', '0');

How it works...

A user's parameters are represented as a JParameter object. We do not have to interact directly with this object because JUser will do this for us.

A minor problem with this method is the default value. Technically the XML files define the default values, but by default these XML files are not loaded by the JUser class. Therefore, the XML defined default values are not employed. One way to overcome this is to interact directly with the JParameter object. The next section explains how to do this.

There's more...

The JUser::getParamters() method allows us to directly access the user's JParameter object. Note that we must use =& when assigning the return value to a variable. If we do not and we are using a PHP version prior to PHP 5, we will inadvertently create a copy of the returned JParameter object.

// get parameters with XML definition file loaded
$params =& $user->getParameters(true);

When we retrieve the JParameter object there are two optional parameters. The first parameter $loadsetupfile determines whether or not the XML file that defines the user's parameters should be loaded. Loading this file gives meaning to the data and also provides default values for defined data.

For information about the second optional parameter, refer to the recipe, Extending and editing user parameters.

To retrieve a value, we use the JParameter::get() method. We pass two parameters to this method—the name of the parameter we want the value of, and the default value to return if the parameter does not exist.

// get timezone (hours UTC offset)
$timezone = $params->get('timezone', '0');

See also

The next recipe, Setting the user's parameters, explains how to set a value in the user's parameters.

Setting the user's parameters

User parameters provide a mechanism for including additional user data without the need to modify the database. The parameters are defined in the XML files located in the administratorcomponentscom_usersmodels folder.

User parameters are not restricted to the parameters defined in the XML files. It is perfectly acceptable to add additional parameters.

Getting ready

To complete this recipe, we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe.


$user =& JFactory::getUser();

How to do it...

To set the value of a parameter, we use the JUser::setParam() method. This method requires two parameters—the name of the parameter we want to set and the value to which we want to set the parameter. For example, we could change the user's editor preference to use no editor.

// set value of someparameter to some value
$user->setParam('editor', 'none');

There's more...

If we have retrieved the JParamter object directly from the user, we can alternatively use that object to set the user's parameters. For information about retrieving the user's parameters, refer to the previous recipe, Getting the user's parameters. To set data in the JParameter object, we use the JParameter::set() method.

// set value of someparameter to some value
$params->set('editor', 'none');

See also

The previous recipe explains how to get a value from the user's parameters.

Joomla! 1.5 Development Cookbook Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes
Published: September 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Extending and editing user parameters

It is often desirable to store additional information about users. A common solution is to create another user table and implement a one-to-one relationship. However, this is problematic because a great deal of maintenance is required to preserve the integrity of that relationship.

This recipe explains how we can store additional user data without the problems associated with having two user tables.

Note that the solution described here does not allow us to use the additional data for database querying purposes. This solution assumes we are creating a component extension.

Getting ready

To complete this recipe we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe earlier in this article.

$user =& JFactory::getUser();

How to do it...

The first step is to define the new parameters in an XML metadata file. This is done using a normal <params> element. The following example defines one parameter, myparameter. This file is named user.xml and is defined in the models folder in our component's administrative area. We are not editing the core user XML files.

<?xml version="1.0" encoding="utf-8"?>
<user>
<params group="com_mycomponent">
<param name="myparameter"
type="text"
size="20"
default=""
label="MY PARAMETER"
description="MY PARAMETER DESCRIPTION" />
</params>
</user>

To use this file, we must use the JUser::getParameters() method. This method allows us to tell Joomla! about our bespoke users.xml file.

// define path to the XML file
$path = JPATH_COMPONENT_ADMINISTRATOR . DS . 'models';
// load the XML file and get the JParameter object
$params =& $user->getParameters(true, $path);

We can now use the JParameter::render() method to generate HTML form elements that can be used to enable editing of the bespoke user parameters.

// output parameters
echo $params->render('bespokeparams', 'com_mycomponent');

Because this is sensitive data, we should also make use of the token in the form.

echo JHTML::_('form.token');

All of this form data should obviously be used in an edit user type page. The next half of this recipe explains how to deal with the form submission. For security reasons, we check the token before continuing.


// make sure the token is valid
JRequest::checkToken() or jexit('Invalid Token');

The next step is to retrieve the input data and set the parameters in the user object.

// load the raw array of params
$rawParams = JRequest::getVar(
'bespokeparams',
array(),
'POST',
'ARRAY'
);
// build an array from the raw array
$besokeParams['myparameter'] = $rawParams['myparameter'];
// bind with the user's parameters
$params->bind($bespokeParams);

Now that we have bound the input data with the user's parameters, we need to save the changes.


// save changes to the user
if ($user->save()) {
JError::raiseNotice("200", JText::_("Saved User"));
}

That's it! All done!

How it works...

XML files are used by JParamater to define data. When we automatically load XML files for JUser parameters, the name of the XML file relates to the usertype. The only exception is user.xml; this is a default file. For example, if we wanted to have different parameters for the usertype publisher, we would need to create a file named publisher.xml. For more information, refer to the Getting the user's group ID and type recipe earlier in this article.

We purposely set the group of the <params> element to that of the extension name. This ensures that we keep our data separate from other data. A design flaw exists in JParameter, which means when we render a JParameter object, the data is always taken from the default group. In other words, our data is not logically separated from other data. Therefore, we need to be careful when choosing names for each of our bespoke parameters.

The JUser::getParameters() method accepts two parameters. The first defines whether or not we want to load the XML metadata. The second optionally defines an alternative location, in our case this is the models folder.

The token is included in the form to help prevent various security attacks. For more information about using the token, refer to the Using the token recipe in the article, Keeping Extensions Secure with Joomla! 1.5: Part 1.

When dealing with the input data, we must be very cautious. If we are not, we could easily end up with an injection weakness. The JParameter::bind() method is not choosy, it will bind with any data. This is why we process the raw parameters data before binding.

The JUser::save() method is self explanatory, it literally saves changes made to the JUser object to the database. It is important to deal with any database params field carefully, using JUser to save the changes rather than directly editing the database ensures that we do not corrupt any other data held in the params field. Remember, this field contains compound data.

There's more...

This recipe explains one way to achieve extending the user parameters field. The following two subsections suggest two alternatives:

Set rather than bind

Binding is a good and simple option for dealing with parameters. However, it is also perfectly acceptable to set each parameter individually. For more information, refer to the previous recipe, Setting the user's parameters.

// bind with the user's parameters
$params->set('myparameter', $rawParams['myparameter']);

Forget about XML

The recipe uses an XML file to define data. There is only any need to define data in this way if we want to use JParameter to render HTML form elements. It is perfectly possible to skip this step entirely. Instead, we could simply output fields manually. The disadvantage of this approach is that it is less flexible. However, if we are only saving one to two extra user parameters, this may make more sense.

<input type="text"
size="20"
class="text_area"
value="<?php echo $params->get('myparameter'); ?>"
name="myparameter"/>

See also

The previous two recipes, Getting the user's parameters and Setting the user's parameters, explain how to interact with a user's parameter data.

Sending an email to the user

Email is a good mechanism for providing confirmation of actions, for example confirmation that an order has been received in a shopping cart. In Joomla! we can send emails to any email address. This recipe explains how to send an email to the currently logged in user.

Only send emails to users who want email notifications

Depending on the context of the email, it is a good idea to only send emails to users who have explicitly requested email notification. For example, system notifications are only sent to user's who have set their sendemail parameter to true.

Getting ready

To complete this recipe we need the JUser object that represents the current user. For more information, refer to the Getting the user recipe.

$user =& JFactory::getUser();

How to do it...

The quick and easy way to send an email is to use the static JUtility::sendMail() method. This method has a very long signature! The following table describes the parameters we can pass to this method, only the first five of the eleven parameters are required:

Despite the number of parameters, the method signature is relatively easy to understand. To use this method we first need to get and build the data we are going to pass to the method. We'll begin by getting the from details from the Joomla! configuration.

// get the Joomla! configuration
$config =& JFactory::getConfig();
// get the email 'from' details
$from = $config->getValue('mailfrom');
$fromname = $config->getValue('fromname');

We get the recipient email address from the $user object.

$recipient = $user->get('email');

The body and the subject are very straightforward. If we want to add a personal touch, we can easily include things such as the user's name.

// get the users name
$name = $user->get('name');
$subject = 'My First Joomla! Email';
$body = "Hi $name nnDo you like my email?";

All that is left to do is to send the email itself.

if (JUtility::sendMail($from, $fromname, $recipient, $subject, $body)
!== true) {
JError::raiseNotice(
'500',
JText::_('ERROR SENDING EMAIL')
);
}

Notice that we check the mixed return value of JUtility::sendMail() to check if the email was sent successfully. The return value will always be true on success and a JException object on failure.

Common problems

Many of the problems associated with sending email stem from incorrect configuration, and the error messages we receive often fail to point us towards this. If you encounter problems, always start by making sure that the Joomla! Global Configuration—Mail Settings are correct.

How it works...

Behind the scenes Joomla! uses a JMail object. The JMail objects are very powerful; there is not a great deal that we cannot do with these that we cannot do with a fully fledged email client. The power of the JMail object comes from its parent class, PHPMailer. This class is a part of the PHPMailer library. For more information about the PHPMailer library, refer to http://phpmailer.codeworxtech.com/.

There's more...

The static JUtility::sendMail() method is a no nonsense way of quickly sending emails. It does not however provide us with the same power as directly using a JMail object. In this section, we look at how to use a JMail object to achieve the same result as in the How to do it section.

We retrieve the mailer using the static JFactory::getMailer() method. The mailer is a JMail object that is preconfigured based on the Joomla! Global Configuration Server settings.


// get the JMail object
$mailer =& JFactory::getMailer();

To this object we add the recipient.


// add recipient
$mailer->addRecipient($recipient);

Now we compose the email itself. The composed email consists of a subject line and a plain text body.


// compose the email
$mailer->setSubject($subject);
$mailer->setBody($body);

Sending HTML emails

To send an HTML email using the mailer, we use the JMail::isHTML() method to tell the mailer we want to send the email in HTML format. For best results when sending HTML emails, in addition to setting the body, set the value of the AltBody instance variable. This is a plain text alternative for email clients that cannot read HTML emails.

We are now ready for the real magic, sending the email! For this we use the JMail::Send() method. This method returns true on success and a JException object on failure. Note that if the method does fail, a notice will be raised. For this reason, we may not need to display an error message of our own.


// send email
if ($mailer->Send() !== true) {
// uh oh, sending of email failed!
}

See also

It can be useful to include a user's name and username in an email. For more information, refer to the Getting the user's name and username recipe, earlier in this article.

For more information about JMail, refer to the official API documentation at http://api.joomla.org.

Summary

This article explains how to use Joomla! sessions and how to work with Joomla! users.

[ 1 | 2 ]

If you have read this article you may be interested to view :

Joomla! 1.5 Development Cookbook Solve real world Joomla! 1.5 development problems with over 130 simple but incredibly useful recipes
Published: September 2009
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


James Kennard

James Kennard is a computer programmer. He has worked with various PHP and MySQL applications, since 2002. He quickly discovered Mambo/Joomla! because of its flexible extension manager. James currently maintains one open-source Joomla! component, which has been translated into over fifteen languages. Moreover, he has plans to build two more open-source components. Examples of his work can be found on his personal website www.webamoeba.co.uk.

Books From Packt

Symfony 1.3 web application development
Symfony 1.3 web application development

Zend Framework 1.8 Web Application Development
Zend Framework 1.8 Web Application Development

Papervision3D Essentials
Papervision3D Essentials

Joomla! 1.5 SEO
Joomla! 1.5 SEO

Joomla! 1.5x Customization: Make Your Site Adapt to Your Needs
Joomla! 1.5x Customization: Make Your Site Adapt to Your Needs

Pentaho Reporting 3.5 for Java Developers
Pentaho Reporting 3.5 for Java Developers

Drupal 6 Site Blueprints
Drupal 6 Site Blueprints

Ext JS 3.0 Cookbook
Ext JS 3.0 Cookbook

 

No votes yet
Joomla 1.6 by
Hi, thank you for the tutorial. Is it working for Joomla 1.6 as well? Could you please provide the final code? Thanks

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
F
U
a
L
3
w
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software