Monday 18 October 2010 1:38:28 am
This example is slightly more complicated. We want to extract users who were modified in the last calendar month but this can not include users who were created. Recall that fetch statements can have multiple attribute filters. To carry out our query we need to ensure two things:
In our last example we used "between" to extract the users who were published within the previous month so to exclude those users we can modify the code to be "not_between". We can then use "between" on the modified date to ensure we pick up the modified users. The following code should do the trick:
//working out the month start and end dates for the previous month, compatible with all versions of PHP 5: $first_of_month = strtotime( date( "Y-m-1" ) ); //this is our endtime, midnight on the first of the current month $first_of_last_month = strtotime( '-1 month' , $first_of_month ); //our start time is one month before then. $attributeFilter = array( array( 'modified', 'between', array( $first_of_last_month,$first_of_month ) ), array( 'published', 'not_between', array( $first_of_last_month, $first_of_month ) ) );
As you can see the only addition to the attribute_filter is an additional array element. For a fully functional example, we can modify our previous code to the following:
$includeClasses = array( 'user' ); $sortBy = array( "name", true ); //let's sort by name //working out the month start and end dates for the previous month, compatible with all versions of PHP 5: $first_of_month = strtotime( date( "Y-m-1" ) ); //this is our endtime, midnight on the first of the current month $first_of_last_month = strtotime( '-1 month' , $first_of_month ); //our start time is one month before then. $attributeFilter = array( array( 'modified', 'between', array( $first_of_last_month,$first_of_month ) ), array( 'published', 'not_between', array( $first_of_last_month, $first_of_month ) ) ); $params = array( 'SortBy' => $sortBy, 'ClassFilterType' => 'include', 'ClassFilterArray' => $includeClasses, 'AttributeFilter' => $attributeFilter); //getting the ID of where the users sit in the cms (limiting the area eZ has to search for the objects): $parent_node = eZContentObjectTreeNode::fetchByURLPath( 'users/members' ); //note the lowercase. Use underscores rather than hyphens if spaces are included in the path $parent_node_id = $parent_node->attribute( 'node_id' ); $modified_users = eZContentObjectTreeNode::subTreeByNodeID( $params, $parent_node_id ); $monthly_modified_user_count = eZContentObjectTreeNode::subTreeCountByNodeID( $params,$parent_node_id );
Many commercial sites need content such as this and you may well require multiple fields (e.g. contact by third parties, contact by phone, contact by post etc). When you start adding custom fields to the user class I would suggest creating a new content class as the content will not be required for some user types (admin users for instance). In this case though for simplicity we will add a new field to the standard user type.
Go to the Setup in the CMS and then click on the "Classes" link. Within the Class Groups you should see "Users" listed so click on this. If we were creating a new user type here we can choose to copy the existing user type and add new fields to the new class. Since we are not just click on the pencil symbol to edit the class. Once you do so go to the bottom of the class definition and you should be given an option to add an attribute (below is what you see in eZ Publish 4.3 where it is located in the bottom right but in previous versions it has been in the bottom left):
Create a field similar to the one in the screenshot. The details for it are as follows:
Now create a user and make sure your new checkbox is checked, otherwise we will have no results.
We now need to write an attribute filter that checks for users who wish to be contacted. This will work in the same way as it does in template files. The following code we do what we need:
$attributeFilter = array( array( 'user/contact_by_email', '=', 1 ) );
We don't need to check any dates in this case so our final code is as follows:
$includeClasses = array( 'user' ); $sortBy = array( "name", true ); //let's sort by name $attributeFilter = array( array( 'user/contact_by_email', '=', 1 ) ); $params = array( 'SortBy' => $sortBy, 'ClassFilterType' => 'include', 'ClassFilterArray' => $includeClasses, 'AttributeFilter' => $attributeFilter); //getting the ID of where the users sit in the cms (limiting the area eZ has to search for the objects): $parent_node = eZContentObjectTreeNode::fetchByURLPath( 'users/members' ); //note the lowercase. Use underscores rather than hyphens if spaces are included in the path $parent_node_id = $parent_node->attribute( 'node_id' ); $users_to_email = eZContentObjectTreeNode::subTreeByNodeID( $params,$parent_node_id ); $users_to_email_count = eZContentObjectTreeNode::subTreeCountByNodeID( $params,$parent_node_id );