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

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

This article by James Kennard shows how we can interact with the current user, logged in or not, and how we can interact with their session.

This article contains the following recipes:

  • Getting the session handler
  • Adding data to the session
  • Getting session data
  • Checking for session data
  • Checking the session token
  • Getting the user
  • Determining if the current user is a guest
  • Getting the user's name and username
  • Getting the user's group ID and type
  • Restricting a user's access using Public, Registered, and Special
  • Getting the user's parameters
  • Setting the user's parameters
  • Extending and editing user parameters
  • Sending an email to the user

Introduction

When a user starts browsing a Joomla! web site, a PHP session is created. Hidden away in the session is user information, this information will either represent a known registered user or a guest.

We can interact with the session using the session handler, a JSession object.

When we work with the session in Joomla!, we must not use the global PHP $_SESSION variable or any of the PHP session functions.

Getting the session handler

To interact with the session we use the session handler; this is a JSession object that is globally available via the static JFactory interface. It is imperative that we only use the global JSession object to interact with the PHP session. Directly using $_SESSION or any of the PHP session functions could have unintended consequences.

How to do it...

To retrieve the JSession object we use JFactory. As JFactory returns an object, we must use =& when assigning the object to a variable. If we do not and our server is running a PHP version prior to PHP 5, we will inadvertently create a copy of the global JSession object.

$session =& JFactory::getSession();

How it works...

If we look at the JSession class, we will notice that there is a getInstance() method. It is tempting to think of this as synonymous with the JFactory::getSession() method. There is, however, an important difference, the JSession::getInstance() method requires configuration parameters. The JFactory::getSession() method accepts configuration parameters, but they are not required.

The first time the JFactory::getSession() method is executed, it is done by the JApplication object (often referred to as mainframe). This creates the session handler. It is the application and JFactory that deal with the configuration of the session. Subsequent usage of the JFactory::getSession() method will not require the creation of the object, and thus simply returns the existing object. The following sequence diagram shows how this process works the first time it is executed by the JApplication object:

Joomla! 1.5 Development Cookbook

When the JFactory::getSession() method is subsequently executed, because session will already exist, the _createSession() method is not executed.

The diagram is a simplification of the process; additional complexity has not been included because it is outside the scope of this recipe.

See also

For information about setting and retrieving values in the session, refer to the next two recipes, Adding data to the session and Getting session data.

Adding data to the session

Data that is set in the session is maintained between client requests. For example, we could display announcements at the top of all our pages and include an option to hide the announcements. Once a user opts to hide the announcements, by setting a value in the session, we would be able to 'remember' this throughout the user's visit.

To put this into context, we would set a session value hideAnnouncements to true when a user opts to hide announcements. In subsequent requests, we will be able to retrieve the value of hideAnnouncements from the session and its state will remain the same.

In Joomla!, session data is maintained using a JSession object, which we can retrieve using JFactory. This recipe explains how to set data in the session using this object instead of using the global PHP $_SESSION variable.

Getting ready

We must get the session handler, a JSession object. For more information, refer to the first recipe in this article, Getting the session handler.

$session =& JFactory::getSession();

How to do it...

The JSession::set() method is used to set a value in the session. The first parameter is the name of the value we want to set; the second is the value itself.

$session->set('hideAnnouncements', $value);

The JSession::set() method returns the previous value. If no value was previously set, the return value will be null.

// set the new value and retrieve the old
$oldValue = $session->set('hideAnnouncements', $value);
echo 'Hide Announcement was ' . ($oldValue ? 'true' : 'false');
echo 'Hide Announcement is now ' . ($value ? 'true' : 'false');

Lastly, we can remove data from the session by setting the value to null.

// remove something
$session->set('hideAnnouncements', null);

How it works...

The session contains a namespace-style data structure. Namespaces are required by JSession and by default all values are set in the default namespace. To set a value in a different namespace, we use the optional JSession::set() third parameter.

$session->set('something', $value, 'mynamespace');

Sessions aren't just restricted to storing basic values such as strings and integers. The JUser object is a case in point—every session includes an instance of JUser that represents the user the session belongs to. If we add objects to the session, we must be careful. All session data is serialized. To successfully unserialize an object, the class must already be known when the session is restored. For example, the JObject class is safe to serialize because it is loaded prior to restoring the session.

$value = new JObject();
$session->set('aJObject', $value);

If we attempt to do this with a class that is not loaded when the session is restored, we will end up with an object of type __PHP_Incomplete_Class. To overcome this, we can serialize the object ourselves.

// serialize the object in the session
$session->set('anObject', serialize($anObject));

To retrieve this, we must unserialize the object after we have loaded the class. If we do not do this, we will end up with a string that looks something like this O:7:"MyClass":1:{s:1:"x";s:10:"some value";}.

// load the class
include_once(JPATH_COMPONENT . DS . 'myclass.php');
// unserialize the object from the session
$value = unserialize($session->get('anObject'));

There's more...

There is an alternative way of setting data in the session. User state data is also part of the session, but this data allows us to save session data using more complex hierarchical namespaces, for example com_myextension.foo.bar.baz. To access this session data, we use the application object instead of the session handler.

// get the application
$app =& JFactory::getApplication();
// set some data
$app->setUserState('com_myextsion.foo.bar.baz, $value);

An advantage of using user state data is that we can combine this with request data. For more information refer to the next recipe, Getting session data.

The JApplication::setUserState() method is documented as returning the old value. However, a bug prevents this from working; instead the new value is returned.

See also

For information about retrieving values from the session, refer to the next recipe, Getting session data.

Getting session data

Data that is set in the session is maintained between client requests. For example if during one request we set the session value of hideAnnouncements to true, as described in the previous recipe, in subsequent requests we will be able to retrieve the value of hideAnnouncements and its state will remain the same.

In Joomla!, session data is maintained using the global JSession object. This recipe explains how to get data from the session using this object instead of from the normal global PHP $_SESSION variable.

Getting ready

We must get the session handler, a JSession object. For more information, refer to the first recipe in this article, Getting the session handler.

$session =& JFactory::getSession();

How to do it...

We use the JSession::get() method to retrieve data from the session.

$value = $session->get('hideAnnouncements');

If the value we attempt to retrieve is not set in the session, the value null is returned. It is possible to specify a default value, which will be returned in instances where the value is not currently set in the session.

$defaultValue = false;
$value = $session->get('hideAnnouncements', $defaultValue);

How it works...

The session contains a namespace-style data structure. Namespaces are required by JSession and by default all values are retrieved from the default namespace. To get a value from a different namespace, we use the optional third JSession::get() parameter.

$value = $session->get('hideAnnouncements', $defaultValue,
'mynamespace');

It is possible to store objects in the session. However, these require special attention when we extract them from the session. For more information about storing objects in the session, refer to the previous recipe, Adding data to the session.

There's more...

There is an alternative way of getting data from the session. User state data is also part of the session. The user state data allows us to store session data using more complex hierarchical namespaces, for example com_myextension.foo.bar.baz. To access user state data, we use the application object instead of the session handler.

// get the application (this is the same as $mainframe)
$app =& JFactory::getApplication();
// get some user state data
$value = $app->getUserState('com_myextsion.foo.bar.baz');

User state data is usually combined with request data. For example, if we know the request may include a value that we want to use to update the user state data, we use the JApplication::getUserStateFromRequest() method.

// get some user state data and update from request
$value = $app->getUserStateFromRequest(
'com_myextsion.foo.bar.baz',
'inputName',
$defaultValue,
'INTEGER'
);

The four parameters we provide this method with are the path to the value in the state data, the name of the request input from which we want to update the value, the default value (which is used if there is no value in the request), and the type of value. This method is used extensively for dealing with display state data, such as pagination.

// get global default pagination limit
$defaultListLimit = $app->getCfg('list_limit');
// get limit based on user state data / request data
$limit = $app->getUserStateFromRequest(
'global.list.limit',
'limit',
$defaultListLimit,
'INTEGER'
);

See also

For information about setting values in the session, refer to the previous recipe, Adding data to the session.

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:

Checking for session data

A little known, or at least little used ability of JSession is the capability to check whether or not a value has already been set in the session. This can be useful to determine the current state of an extension in the current session. For example, we may have a plugin that we want to behave differently the first time it is executed in a session.

Getting ready

We must have an instance of the session handler, which is a JSession object. For more information refer to the first recipe in this article, Getting the session handler.

$session =& JFactory::getSession();

How to do it...

The JSession::has() method determines if a value exists in the session. The method returns a Boolean response, true means that the session has the value, while false means the session has not got the value.

if ($session->has('someValue')) {
// some value exists in the session :)
} else {
// some value does not exist in the session :(
}

How it works...

The session contains a namespace style data structure. Namespaces are required by JSession, and by default, existence of a value is checked in the namespace default. To check for a value in a different namespace, we use the optional second parameter.

if ($session->has('someValue', 'mynamespace')) {
// mynamespace some value exists in the session
} else {
// mynamespace some value does not exist in the session
}

See also

For more information about dealing with session data, refer to the previous three recipes, Getting the session handler, Adding data to the session, and Getting session data.

Checking the session token

Every session contains a token. This is a random generated string that is used to prevent security weaknesses such as Cross-Site Request Forgery (CSRF).

How to do it...

We can access the token directly in the session using the JSession::getToken() method.


$token = JSession::getToken();

Although this is acceptable, it does not really conform to the standard Joomla! way of dealing with tokens.

The token value should be kept a closely guarded secret. It is crucial that we do not give away the value of the token, because it could be used to compromise the site.

Getting the user

A JUser object describes a user of the system. The user who initiated the request is always represented as a JUser object, even if the user is not logged in! This recipe explains how we retrieve the JUser object that represents the current user.

In instances where the user is not logged in, the JUser object represents an anonymous user. In Joomla! we refer to anonymous users as guests. The following diagram expresses the guest state of the global JUser object:

Joomla! 1.5 Development Cookbook

How to do it...

To retrieve the JUser object that represents the current user, we use JFactory. As JFactory returns an object we must use =& when assigning the object to a variable. If we do not and our server is running a PHP version prior to PHP 5, we will inadvertently create a copy of the global JUser object.


$user =& JFactory::getUser();

So now that we have the global JUser object, what do we do with it? We generally retrieve JUser objects when we want to find out something about a user. For example, we can use a JUser object to determine a user's email address (as described in the last recipe, Sending an email to the user). All of the remaining recipes in this article explain what we can do with JUser objects.

There's more...

Sometimes we may want to retrieve data that relates to other users. If we want to retrieve a different user (represented as a JUser object) when we call the static JFactory::getUser() method, we add the numeric ID or the username of the user we want to retrieve.

// retrieve a user based on ID
$aUser =& JFactory::getUser(100);
// retrieve a user based on username
$anotherUser =& JFactory::getUser('anotherusername');

Obviously, we wouldn't use hardcoded values. This is simply intended to make the usage of the method clearer, that is, a number to load based on ID, and an alphanumeric string to load based on a username.

Use ID whenever possible

As Joomla! uses the PHP is_numeric() function to determine if it is retrieving a user based on an ID or a username, if a username contained only numbers, the method could be tricked into retrieving a different user. For this reason we should use a user's ID whenever possible. If we only have the user's username, we can use the static JUserHelper::getUserId() method to manually retrieve their ID.

On the other hand, if we want to retrieve a number of users and we are executing a query that will retrieve data to which users are associated, we can JOIN with the #__users table. The following example shows a query in which the table #__mytable contains the foreign key owner, which relates to the primary key (id) of the #__users table:

SELECT `mytable`.*, `u`.`name` AS `owner`
FROM `#__mytable` AS `mytable`
LEFT JOIN `#__users` AS `u` ON `mytable`.`owner` = `u`.`id`

The following table describes some of the more useful #__users fields that are available to us:

Field

Type

Description

id

INTEGER

Unique identifier (PK) should always be used for foreign keys.

name

VARCHAR(255)

Actual name, for example, Fred Bloggs

username

VARCHAR(150)

Username for login credentials, for example fbloggs

email

VARCHAR(100)

Email address, for example fred.bloggs@example.org

sendemail

TINYINT(4)

Boolean value represented as 0 or 1. If true, the user is willing to accept system email notifications.

See also

The next recipe explains how to determine if the current user is or is not logged in.

Determining if the current user is a guest

Guests are users who are not logged into the site. Guests generally have very restricted access rights, which can significantly modify the way in which the logic of an extension flows. This recipe explains how to determine if the current user is a guest or a registered user.

Getting ready

To complete this recipe, we need the current user represented as a JUser object. For more information, refer to the previous recipe, Getting the user.

$user =& JFactory::getUser();

How to do it...

We use the JUser::get() method to retrieve the Boolean value of guest. If this value is true, the user is a guest, otherwise they are a registered user.

if ($user->get('guest') {
// user is a guest
} else {
// user is logged in user
}

How it works...

Whenever a user starts browsing an instance of Joomla! they always start off as a guest. We can, therefore, think of JUser objects as being guests by default. Once a user successfully logs in, the value of guest is set to false. Technically, the user's ID is also set at this point, and so it is possible to use the ID to determine if the user is a guest. However, this is not recommended. There is a useful diagram in the introduction to the previous recipe that explains this in more detail.

Getting the user's name and username

A user's name is their actual name, for example Fred Bloggs. A user's username is the name they use to log into the system, for example fbloggs. An important distinction between the two is that the username is unique while the name is not. As usernames are unique, when we display information about a user to another user, we tend to use usernames, for example in a thread on a forum. Conversely, when addressing a user directly we tend to use their name, for example in an email notification or a welcome message.

Getting ready

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

$user =& JFactory::getUser();

How to do it...

The following example extracts the user's username and name and outputs them:

// get username and name of user
$username = $user->get('username');
$name = $user->get('name');
// output information about the user
echo "$username's real name is $name";

How it works...

The JUser::get() method retrieves public data from the JUser object. Note that by public data we mean public in terms of object access, not legally public for everyone to see. When dealing with a user that is logged in, their username and name is directly populated in the JUser object with data from the #__users table in the database (or from a comparable source, dependent on the user plugins).

There's more...

Sometimes a user may not be logged in, that is, they may be a guest. In these instances, we need to pay a little more attention because the username and name will both be set to null. The following example shows how combining this recipe with the previous recipe, Determining if the current user is a guest, we can better deal with usernames and names

if ($user->get('guest') {
// user is a guest
$username = JText::_('ANONYMOUS');
$name = JText::_('ANONYMOUS');
} else {
// user is a registered user
$username = $user->get('username');
$name = $user->get('name');
}

ANONYMOUS is not defined in any of the core language files, so we must define this, or a suitable equivalent, in our extension's language files.

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

 

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

jQuery 1.3 with PHP
jQuery 1.3 with PHP

Ext JS 3.0 Cookbook
Ext JS 3.0 Cookbook

 

Your rating: None Average: 5 (4 votes)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
a
9
E
n
Y
6
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