There are specific cases where you need to pull the eZ Publish information directly in your PHP scripts. There are options available for both users and nodes. There is already an excellent article about doing this here. This guide extends this by providing a detailed guide to extracting User Information through a script and going through some practical examples.
I have split this tutorial into two parts. In this part, we will look at how you can retrieve individual users from the eZUser class and how to extract information from the eZUser class. I will then show you how to use some of the functions within eZUser and eZRole to extract multiple users.
The second part of this tutorial will detail how to extract user information through eZContentTreeNode::subTreeByNodeID(). As well as demonstrating this function, it will provide practical examples of its use and provide you with a cronjob you can use for your own user exports. If you want to skip straight to this part, click here.
Basic Script
Before we start we need a basic PHP script which will handle the import. Although it is just a PHP script, let’s create it within a directory for cronjobs so that the script can be automated when it is finished. Please note debug is turned on in the script below so make sure to turn it off when you have finished the script.
set_time_limit ( 0 ); //ensure the script does not time out
require ‘autoload.php’;//make sure relevant eZ Classes can be loaded
$cli = eZCLI::instance();//provides interface with CLI
//Setting up the script object itself:
$script = eZScript::instance( array‘description’ => ("eZ Publish user export.\n\n" .
"Methods of exporting user information from eZ Publish \n" .
"\n",
‘use-session’ => false,
‘use-modules’ => true,
‘use-extensions’ => true,
‘debug-output’ => true,
‘debug-message’ =>true
) );
$script->startup();
$script->initialize();
/*ensuring the current user has the rights to the user information:*/
$user = eZUser::fetchByName( ‘admin’ );
eZUser::setCurrentlyLoggedInUser( $user, $user->attribute(‘contentobject_id’) );
/*********************
Export User Info Here
*********************/
$script->shutdown();//stop the script
?>
For all further code just replace the comment block “Export User Info Here” with the code you need.
You may notice from this example we have already pulled out a user. We need to make sure the current user has the right to view user information in the CMS. By default, the anonymous account is used in the script which will not have access to this information. We therefore change the current user to be admin so that the person does have rights. We will now look at all the ways we could have pulled the admin user out of the CMS.
Fetching a specific user
A specific user can be pulled out of the system by Object ID, email address or their username (as we just did). We can also pull out the user based on the Node ID, but this means extracting the user information has to be approached slightly differently (we will cover doing this later in the tutorial). Below we pull out three users, one using each method. Since we have just pulled out the admin user, we will do the same here using each method. If you are statically using a user, I would advise using the email address or username where possible for clarity.
$users[‘email’] = eZUser::fetchByEmail( ‘admin@admin.com’ );
$users[‘object_id’] = eZUser::fetch(14);
print_r($users);
You should see from the results that they all return eZUser Objects.
Fetching the current user
If we were not running a standalone script and were instead adding some functionality to the CMS, we may need to pull out the currently logged in user. This can be done easily using the code below. Since we are using a script, we will not use this method further here:
Extracting user information
Now that we have a few user objects to play with, let’s look at how we can use pull out the user information from them. Looking at the dump of the information from the users array we can see pulling out the email address and username are both straightforward and can be extracted straight from the eZ User object. Since we are currently only pulling out the same user multiple times we will just use one of the array elements for the next code examples. Later we will add code to extract information from multiple users:
$cli->output("Username: $user->Login");
$cli->output("Email: $user->Email");
Fetching Other User Fields
Pulling out the other user fields is trickier and is hard to do with the eZUser class. Luckily, the eZContentObject class allows you to pull out the DataMap of an object in an associative array. We can convert an eZUser class into an eZContentObject class really easily using the contentObject() function of the eZUser class:
$contentObject = $eZUserObject->contentObject();//converting it to a eZContentObject
//outputting the eZUser information:
$cli->output("Username: $eZUserObject->Login");
$cli->output("Email: $eZUserObject->Email");
//Outputting our user information from a eZContentObject:
$dataMap = $contentObject->dataMap();
foreach($dataMap as $key=>$value)
{
$cli->output("$key: $value->DataText");
}
The results of the script should be as follows:
As you can probably see from the example, even when you run the script with the default User class, there are a couple of things to look out for:
Field Types and Displaying Information
Although the majority of the user details are displayed properly, there are two fields which are not. We will look at the user_account field next but let’s look at the image field first. The image field displays with a lot of XML around it. Consider the following template code:
Price: {$node.data_map.price.data_float}
In Stock: {$node.data_map.no_in_stock.data_int}
This example illustrates how different fields are displayed in different ways in the eZ Publish templating language. This is also the case when you extract the information in PHP. The example code we have been using is simplified in that we have assumed every item can be returned as a string (or DataText as it is known in eZ.) Depending on the type of your variable you will want to display, you need to display it in the same way you would as if you were in the template.
For the image, this is more complicated than it is above. Rather than using the text, int or float value, we have a lot more content contained in the image. Each attribute in the data map is of the type eZContentObjectAttribute. Although simple information can often be extracted straight from this, in cases where it is not you need to use the content() method which will return the object as it sits natively in eZ Publish. In the case of the image, the content will return an ezimage. Probably the most useful information we can extract for this are the url for the image and the alternate text. Looking at the ezimage class reference, these are quite simple to pull out. The most useful way of extracting the useful information on a class basis is to find out what content type we are dealing with and display content based on this. By doing so, we can then easily extend when we need to extract additional field types:
$cli->output("Username: $user->Login");
$cli->output("Email: $user->Email");
$contentObject = $user->contentObject();
$dataMap = $contentObject->dataMap();
foreach($dataMap as $key=>$value)//looping through each field
{
$type = $value->dataType();//looking at what type the current field is
switch($type->DataTypeString)//base the switch on the type name
{
case ‘ezstring’://for basic text
$cli->output("$key: $value->DataText");
break;
case ‘ezint’:
$cli->output("$key: $value->DataInt");
break;
case ‘ezfloat’:
$cli->output("$key: $value->DataFloat");
break;
case ‘ezimage’:
$cli->output(‘ezimage’);
$content = $value->content();
$displayText = $content->displayText();
$imageAlias = $content->imageAlias(‘original’);
$imagePath = $imageAlias[‘url’];
$cli->output("$key: $displayText ($imagePath)");
//print_r($value->content());
break;
default://by default let’s show what the type is:
$cli->output($key.‘ ‘.$type->DataTypeString);
break;
}
}
User Account – User Email and Login
The other field of note is called user_account. In the last example if you run the code it will tell you this is an eZUser object. In the cases we have been looking at so far we have always started with a eZUser object and this merely returns the same object. That being the case, why is this useful? Well mostly because you won’t always start with an eZUser object. The next part of this tutorial will look at fetches using a method in eZContentObjectTreeNode. This method will return eZContentObjectTreeNode, which means we can not access the eZUser attribute method directly to give us the user’s email address and username. In this situation we can instead pull this information from the user account (if you are working with eZContentObjects you would need to do something similar).
The following code adds to the above to ensure user accounts are dealt with appropriately.
switch($type->DataTypeString)
{
case ‘ezuser’:
$user_account = $dataMap[‘user_account’]->content();
$cli->output("Username: $user_account->Login");
$cli->output("Email: $user_account->Email");
break;
case ‘ezstring’:
$cli->output("$key: $value->DataText");
break;
case ‘ezint’:
$cli->output("$key: $value->DataInt");
break;
case ‘ezfloat’:
$cli->output("$key: $value->DataFloat");
break;
case ‘ezimage’:
$cli->output(‘ezimage’);
$content = $value->content();
$displayText = $content->displayText();
$imageAlias = $content->imageAlias(‘original’);
$imagePath = $imageAlias[‘url’];
$cli->output("$key: $displayText ($imagePath)");
//print_r($value->content());
break;
default:
$cli->output($key.‘ ‘.$type->DataTypeString);
break;
}
…
Extracting User information from a Node ID
As previously explained, pulling out user information based on Node ID is slightly different. Rather than being returned a eZUser object, if we have a Node ID we are returned an eZContentObjectTreeNode:
To handle this we can convert it into an eZContentObject and we can then repeat the process we have just carried out. The key difference to pulling out eZUser objects is that we do not have a eZUser to extract the login or email from, so we will need to access it through the data map:
$userObj =$userNode->object();//we will handle pulling the information out of these later.
$dataMap = $userObj->dataMap();
$user_account = $dataMap[‘user_account’]->content();
$cli->output("Username: $user_account->Login");
$cli->output("Email: $user_account->Email");
I would recommend using the switch statement in the preceding example to pull this information out.
Fetching User Roles
Fetching user roles is straightforward straight from the user. We can use the method roles() to establish which roles the user fulfills. The following example shows its use with a known user, and when we only have a content object id:
$user = eZUser::fetchByName( ‘admin’ );
$roles = $user->roles();
//if we have a eZContentObjectTreeNode:
$userNode = eZContentObjectTreeNode::fetch(15);
$roles = $user->roles(false,$node->ContentObjectID);
//if we have a eZContentObject
$userObj = $userNode->object();//use the $userNode created in the code above to make things easier
$roles = $user->roles(false,$userObj->ID);
Fetching content created by the user
Since we have the ID for the user, we can also pull out what content they have created. The eZContentObjectVersion class has the method we need, all we need to do is tell it what status the content should have. In this example we are using just published content but your other options are also given below.
Here are a list of all possible eZContentObjectVersions:
- eZContentObjectVersion::STATUS_DRAFT
- eZContentObjectVersion::STATUS_PENDING
- eZContentObjectVersion::STATUS_PUBLISHED
- eZContentObjectVersion::>STATUS_REJECTED
Fetching multiple users
The same fetches you can use in your template files can also be used in your PHP scripts. You can also pull out all users and all users of a particular user group. Please note that for any large website due to the amount of data being extracted if you are running the script through a template or through your web browser there is a very good chance the script will time out so care is needed when running these scripts. One solution is to run the scripts through a cronjob and allow the duration of the script to be extended, that way you can limit the script’s use to when your server is at it’s quietest. We will look at ready made fetches we can use in the next part of this tutorial but for now we will look at other ways we can extract multiple users.
Extracting All Users
eZUser has a function to pull out all users currently enabled in your CMS. The code below pulls all of the users out and returns their name and email. You can use the code we have already looked at if you want to pull out other information.
foreach($allUsers as $key=>$user)
{
$userObj = eZUser::fetch($user[‘id’]);
$cli->output(‘Element: ‘.$key);
$cli->output(‘Username: ‘.$userObj->attribute(‘login’));
$cli->output(‘Email: ‘.$userObj->attribute(‘email’));
$cli->output(‘Content Object ID: ‘.$userObj->attribute(‘contentobject_id’));
$cli->output(‘**********’);
}
Users By User Role
A similar requirement to pulling out all users is to pull out all users for a specific role.To do this, we need to use the eZRole class. This has the perfect function but first we need to create a role. The following code will create a role and then pull out all of the users who fulfill it:
$roleUsers = $adminRole->fetchUserByRole();//this will return eZContentObjects within
separate arrays
foreach($roleUsers as $key=>$userHolder)
{
$object_type = $userHolder[‘user_object’]->ClassName();
if ($object_type==‘user_group’)//we will more than likely be dealing with a user group so we need to pull out the users from this
{
$user_group = $userHolder[‘user_object’]->mainNode();//convert so we can access the children of the node
foreach($user_group->children() as $group_user)//user_group will contain eZContentObjectTreeNodes, let’s just output the name (details above on accessing other fields).
{
$cli->output(‘name: ‘.$group_user->attribute(‘name’));
}
}
else//if we have a user we are looking at a eZContentObject
{
$cli->output(‘name: ‘.$userHolder[‘user_object’]->attribute(‘name’));
}
}
The key part to the script occurs once you;ve established whether you’e looking at a user or a user group. If you have a user, it is easy enough to show information almost directly since we are dealing with a eZContentObject (you can use the code from previous examples to display the user information).
For User Groups, we need to carry out additional steps. You will be aware that eZContentObjects do not have a hierarchy in eZ Publish, the hierarchy is established by nodes rather than objects. Therefore, to work out the users which sit under a particular user group (in other words the users who belong to the user group), we must firstl convert the eZUserObject to a node. The following code in the previous example performs this transformation and then iterates through the users below the group, displaying the name for each user:
$user_group = $userHolder[‘user_object’]->mainNode();//convert so we can access the
children of the node
foreach($user_group->children() as $group_user)//user_group will contain
eZContentObjectTreeNodes, let’s just output the name (details above on accessing other
fields).
{
$cli->output(‘name: ‘.$group_user->attribute(‘name‘));
}
Get all currently Logged In Users
The eZUser class also provides methods for providing a list of users who are currently logged in which may be of use. It work in a very similar way to the methods we have just covered (you can also pull out a count of the number of users currently logged in):
$loggedIn = eZUser::fetchLoggedInList();
$cli->output(‘Logged in Users: ‘.$loggedInCount);
print_r($loggedIn);
That’s it for Part 1…
There are lots of possible ways to extract the user information from eZ and here we’ve covered the most basic. Part 2 covers subTreeByNodeID which allows us to filter the result set we retrieve from eZ Publish to allow us to have much more flexibility.
To continue to Part 2, click here



Hi
Excellent and useful.
Just a quick note : It’s a bad practice to access data directly from properties (Username: $user->Login). You should always use the attribute() accessor when your object is extending eZPersistentObject (Username: $user->attribute(‘login’).
See eZUser::definition() to list all attributes available with this method (see “fields” and “function_attributes”
Cheers !
Hi Jérôme, thanks for the advice, I’ll be sure to make a note of that. Can I check why the attributes are available as public when they shouldn’t be accessed in this way? I would of thought they should be marked as private. Also, I guess I prefer the ease of use you get when you do it as I have done rather than using a bespoke function. Do you know whether the attribute() method will be converted to a standard PHP5 __get function at some point?
“why the attributes are available as public when they shouldn’t be accessed in this way”
I guess it has to do with historical reasons – eZP was developed in a time when private/protected did not exist in php.
In the end it is more a matter of style (or philosophy): using $obj->attribute(‘xxx’) and $obj->setattribute(‘xxx’, ‘val’) is more verbose but:
- it matches more closely the way the objects are accessed in templates (ie. every property of an object that is available in template code you can access in php code via attribute() calls)
- it matches more closely the “property” pattern that was intended in the beginning by the developers (some of those calls to attribute() will access actual object members, some will access functions, so if you access members directly it means you either have checked that they are members and not functions and that your code will break in the future if the object definition is changed – unlikely but possible)
As a side note: an interesting projects (on projects.ez.no) to help you extracting data from ezpersitsentobjects: ggxmlview.
It allows to
- map ezpo to json or xml using templates
- map ezpo to a plain php array using a single php call
(of course recursion is considered)
Hey Gaetano, Thanks, that makes sense. I wasn’t aware of the extension you mentioned. One of my previous posts showed a quick way of creating a blank page layout for XML based content but this extension looks a much better way of dealing with it in a lot of situations. Thanks again, David