Blog» An introduction to fetching content in eZ Publish 4 and eZ Publish 5

An introduction to fetching content in eZ Publish 4 and eZ Publish 5

By Ernesto Buenrostro  | April 28, 2014  |  eZ Publish development tips

Fetching content in eZ Publish 4 (the "legacy" stack) and eZ Publish 5 (the "new" stack) follow many of the same principles, which is not surprising since the data layer is the same for both versions. You typically have a parent node or location and a set of filters. User permissions -- especially bypassing those permissions -- is often a consideration. In this post we'll explore how to fetch content in the legacy and new stack (as of eZ Publish 5.2).

In our example, let's suppose that we are displaying a set of images in the media library. These images are displayed within the content structure tree, but aren't supposed to be directly accessible in the media library. Therefore, the anonymous user does not have permission to directly view those images and we need to bypass that permission limitation in our fetches.

Fetching content in eZ Publish legacy

Using the current user

This simple fetch will return a list of the images that we have, although if the anonymous user does not have permissions for that folder in the media library, we will get an empty result.

(In our eZ Publish legacy code examples, we are showing example template code. For eZ Publish 5, we are showing PHP code in a custom controller, since data fetches are now expected to be done in PHP land. Please see the official eZ Publish documentation for more information.)

 
{def
    $image_parent_node_id = 63
    $images = fetch( "content", "list", hash(
        "parent_node_id"       => $image_parent_node_id
        , "class_filter_type"  => "include"
        , "class_filter_array" => array( "image" )
    ) )
}
 
{* Do something with the results *}
...

Overriding permissions

We can override the permissions for our fetch by passing an empty array as the "limitation" parameter in our fetch:

 
{def
    $image_parent_node_id = 63
    $images = fetch( "content", "list", hash(
        "parent_node_id"       => $image_parent_node_id
        , "class_filter_type"  => "include"
        , "class_filter_array" => array( "image" )
        , "limitation"         => array()
    ) )
}
 
{* Do something with the results *}
...

For more information on the fetch function parameters, see the eZ Publish 4.x documentation.

Fetching content in eZ Publish 5.x

eZ Publish 5.x fetches are based on a new API that introduces a new query handler and "Criterion" objects.

Using the current user

The example below is similar in its parameters to the legacy example, except that you have to explicitly specify that you want to fetch visible (and not hidden) content. However, if the current user does not have the necessary permissions to read content in the media library folder, we will get an exception of the type \eZ\Publish\API\Repository\Exceptions\NotFoundException.

 
public function getImagesAction()
{
    $repository = $this->getRepository();
 
    $imageParentNodeID = 63;
 
    // here we are going to use the Query and Criterion objects to do our fetch
    $query = new Query();
    $query->criterion = new Criterion\LogicalAnd(array(
        new Criterion\Subtree($repository->getLocationService()->loadLocation( $imageParentNodeID )->pathString ),
        new Criterion\ContentTypeIdentifier( 'image' ),
        new Criterion\Visibility( Criterion\Visibility::VISIBLE ),
    ) );
 
    /* To execute our query we are going to pass it as a argument to the method
     * SearchService::findContent()
     */
    $searchHits = $repository->getSearchService()->findContent( $query )->searchHits;
 
    // Then we have to build the array to be passed to our view
    $contentArray = new array();
    foreach( $searchHits as $searchHit )
    {
        $content = $searchHit->valueObject;
        $contentArray[] = $content;
    }
 
    return $this->render(
        'MugoTestBundle:Parts:image_list.html.twig'
        , array(
            'content' => $contentArray
        )
    );
}
 
 

Using an admin user

We can use a user with the necessary permissions in order to do the fetch. We can do this with the user service and either the username or user ID:

loadUserByLogin( $userName )

or

loadUser( $userId )

 

 
public function getImagesAction()
{
    $repository = $this->getRepository();
 
    // Setting the repository user
    $repository->setCurrentUser( $repository->getUserService()->loadUserByLogin( 'admin' ) );
 
    $imageParentNodeID = 63;
 
    $query = new Query();
    $query->criterion = new Criterion\LogicalAnd( array(
        new Criterion\Subtree($repository->getLocationService()->loadLocation( $imageParentNodeID )->pathString ),
        new Criterion\ContentTypeIdentifier( 'image' ),
        new Criterion\Visibility( Criterion\Visibility::VISIBLE ),
    ) );
 
    $searchHits = $repository->getSearchService()->findContent( $query )->searchHits;
    $contentArray = new array();
    foreach( $searchHits as $searchHit )
    {
        $content = $searchHit->valueObject;
        $contentArray[] = $content;
    }
 
    return $this->render(
        'MugoTestBundle:Parts:image_list.html.twig'
        , array(
            'content' => $contentArray
        )
    );
}

Using the sudo method

Wait what is sudo? No, you don't have to use the command line. sudo is an undocumented (so far) eZ Publish function to bypass permission limitations without having to switch to a specific user.

The way to use the sudo method is with a PHP closure; you fetch the content within the closure:

 
public function getImagesAction()
{
    $repository = $this->getRepository();
    $imagesNodeId = 63;
 
    $restrictedContent = $repository->sudo(
        function( $repository ) use( $imagesNodeId ) {
            $query = new Query();
            $query->criterion = new Criterion\LogicalAnd( array(
                new Criterion\Subtree( $repository->getLocationService()->loadLocation( $imagesNodeId )->pathString ),
                new Criterion\ContentTypeIdentifier( 'image' ),
                new Criterion\Visibility( Criterion\Visibility::VISIBLE ),
            ));
 
            $searchHits = $repository->getSearchService()->findContent( $query )->searchHits;
 
            // We will create an array with all the content objects
            $contentArray = new array();
            foreach( $searchHits as $searchHit )
            {
                $content = $searchHit->valueObject;
                $contentArray[] = $content;
            }
 
            return $contentArray;
        }
    );
    return $this->render(
        'MugoTestBundle:Parts:image_list.html.twig'
        , array(
            'content' => $restrictedContent
        )
    );
}

Extra note: exceptions in eZ Publish 5.x

In the eZ Publish legacy kernel, you get a result of null or false if you tried to fetch an object or node/location that didn't exist. Or if you didn't have the necessary permissions, you just get an empty result. eZ Publish 5 relies heavily on exceptions in such cases, and you must catch those exceptions.

Expanding on our last example above, below we fetch a specific content object based on its ID with the sudo function and with proper exception handling.

 
public function getImageAction()
{
    $repository = $this->getRepository();
 
    // Restricted image located in the media library
    $contentId = 66;
 
    $restrictedContent = $repository->sudo(
        function( $repository ) use( $contentId )
        {
            try
            {
                $contentInfo = $repository->getContentService()->loadContent( $contentId );
            }
            catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
            {
                // this exception would occur if we weren't using sudo or an authorized user
                return false;
            }
            catch( \eZ\Publish\API\Repository\Exceptions\NotFoundException $e )
            {
                // this exception would occur if the content we are looking does not exist
                return false;
            }
            return $content;
        }
    );
 
    return $this->render(
        'MugoTestBundle:Parts:image.html.twig'
        , array(
            'content' => $restrictedContent
        )
    );
}

Fetching content in eZ Publish 5 has many similarities to fetching content in eZ Publish 4. If you give proper attention to handling permissions and catching exceptions, you can ensure that you get the content results you need!


Join our mailing list for news, events, tips, and tools

Related Blog Posts

How to use Composer to set up an eZ Publish install

Composer is a dependency management tool for PHP that eZ Publish 5 uses. The following is simple step-by-step how-to on using Composer to install eZ Publish...

Read more »

Using VirtualBox to install and test eZ Publish 5

Using virtual machines when developing eZ Publish websites have been useful in 2 main ways (if not more): working in a different server environment than...

Read more »

Getting started with eZ Publish 5 and Symfony

Recently, eZ Systems announced that the next major version of eZ Publish will use the Symfony framework. Having heard good things about Symfony as a modern,...

Read more »

Comments

blog comments powered by Disqus

Hi, we're Mugo Web - Nice to meet you!

We're a group of web experts who solve complex web problems.

Learn more about us »

Search


Categories


Yes - we can do that.

Many years of experience with complex websites allows us to offer total solutions.

Learn more about what we can do »

We love our clients (and they love us too)

We've solved problems across North America and around the world.

Learn more about what we've done »

We tweet too

Follow us on Twitter for the latest Mugo happenings

mugo twitter page @mugo

© 2008 - 2019 Mugo Web. All rights reserved.