Introduction

The public API will give you an easy access to the eZ Publish content repository. This repository is the core component that manages content, locations (former Nodes), sections, content types (former Content Classes), user groups, users and roles. It also provides a new, clear interface for plugging in custom field types (former Datatypes).
 
The public API is built on top of a layered architecture including a new persistence layer for abstracting the storage functionality. By using the public API, your applications will be forward compatible with future releases based on enhanced,  scalable and high-performance storage engines. Applications based on the public API are also fully backwards compatible by using the included storage engine based on the current kernel and database model.


Recipe 1 - Setting up a sample commandline symfony bundle which uses the public API

This receipt shows how to setup a simple symfony bundle with a commandline script using the public API. The command is executable within the ezpublish/console and dumps a content object for a given content id.

Go to the eZ publish installation

cd <ezpublish installation root>

Generate a new Bundle

php ezpublish/console generate:bundle

Now follow the instructions. This will create a bundle EzSystems/CookBookBundle in the src directory of the installation root (Note: this bundle exists already so a different namespace will be required).

                                            
  Welcome to the Symfony2 bundle generator  
                                            


Your application code must be written in bundles. This command helps
you generate them easily.

Each bundle is hosted under a namespace (like Acme/Bundle/BlogBundle).
The namespace should begin with a "vendor" name like your company name, your
project name, or your client name, followed by one or more optional category
sub-namespaces, and it should end with the bundle name itself
(which must have Bundle as a suffix).

See http://symfony.com/doc/current/cookbook/bundles/best_practices.html#index-1 for more
details on bundle naming conventions.

Use / instead of \  for the namespace delimiter to avoid any problem.

Bundle namespace: EzSystems/Bundles/CookbookBundle

In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest EzSystemsCookbookBundle.

Bundle name [EzSystemsCookbookBundle]: 

The bundle can be generated anywhere. The suggested default directory uses
the standard conventions.

Target directory [.../ezpublish5/src]: 

Determine the format to use for the generated configuration.

Configuration format (yml, xml, php, or annotation) [annotation]: yml

To help you get started faster, the command can generate some
code snippets for you.

Do you want to generate the whole directory structure [no]? yes

                             
  Summary before generation  
                             

You are going to generate a "EzSystems\CookbookBundle\EzSystemsCookBookBundle" bundle
in ".../ezpublish5/src/" using the "yml" format.

Do you confirm generation [yes]? yes

                     
  Bundle generation  
                     

Generating the bundle code: OK
Checking that the bundle is autoloaded: OK
Confirm automatic update of your Kernel [yes]? yes  
Enabling the bundle inside the Kernel: OK
Confirm automatic update of the Routing [yes]? yes
Importing the bundle routing resource: OK

                                               
  You can now start using the generated code!  
                                               

Add a Command directory to the bundle

cd <ezpublish installation root>/src/EzSystems/CookbookBundle

mkdir Command

add the following class file CookbookCommand.php in the directory Command

 

<?php
/**
 * File containing the CookBookCommand class.
 *
 * @copyright Copyright (C) 2012 eZ Systems AS. All rights reserved.
 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
 * @version //autogentag//
 */
namespace EzSystems\CookBookBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class CookBookCommand extends ContainerAwareCommand
{
    /**
     * This method override configures on input argument for the content id
     */
    protected function configure()
    {
        $this->setName( 'cookbook:run' )->setDefinition(
            array(
                new InputArgument( 'contentId', InputArgument::REQUIRED, 'An existing content id' )
            )
        );
    }

    /**
     * execute the command
     * @param InputInterface $input
     * @param OutputInterface $output
     */
    protected function execute( InputInterface $input, OutputInterface $output )
    {
        // fetch the input argument
        $contentId = $input->getArgument( 'contentId' );

        // get the repository from the di container
        $repository = $this->getContainer()->get( 'ezpublish.api.repository' );

        // get the content service from the repsitory
        $contentService = $repository->getContentService();

        try
        {
            // print out the content info for the given content id
            print_r( $contentService->loadContentInfo( $contentId ) );
        }
        catch( \eZ\Publish\API\Repository\Exceptions\NotFoundException $e )
        {
            // if the id is not found
            $output->writeln( "No content with id $contentId" );
        }
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // not allowed to read this content
            $output->writeln( "Anonymous users are not allowed to read content with id $contentId" );
        }
    }
}





run f.e.

php ezpublish/console cookbook:run  5


eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentService

eZ\Publish\API\Repository\Values\Content\ContentInfo

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

 

Recipe 2 - Creating a content type group

This snippet creates a content type group for a given identifier (Full code here).

        $contentTypeService = $repository->getContentTypeService();
        try
        {
            // instanciate a create struct
            $contentTypeGroupCreateStruct = $this->contentTypeService->newContentTypeGroupCreateStruct($groupIdentifier);
            // call service method
            $contentTypeGroup =  $this->contentTypeService->createContentTypeGroup( $contentTypeGroupCreateStruct );
            // print out the group
            print_r($contentTypeGroup);
        }
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
        catch( \eZ\Publish\API\Repository\Exceptions\ForbiddenException $e )
        {
            // react on identifier already exists
            $output->writeln($e->getMessage());
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentTypeService
eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroupCreateStruct
eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup  

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\ForbiddenException

 

If this snipped is run with the same init code from receipt 1 we will get an UnauthorizedException.

The solution is described in the next receipt.

Recipe 3 - Setting the user for authorizing actions

By default the repository assumes the anonymous user is acting. To change this the following code can be executed

        // get the user service from the repository
		$userService = $repository->getUserService();
        // load user by credentials
        $user = $userService->loadUserByCredentials($user,$password);
        // set user in repository
        $repository->setCurrentUser($user);

If the user is identified by other mechanisms the user also can be loaded by its id via the service method

$userService->loadUser($id)

 


eZ\Publish\API\Repository\Repository
 eZ\Publish\API\Repository\UserService
eZ\Publish\API\Repository\Values\User\User


 

Recipe 4 - Creating a content type

With this snipped a content type with two fields of type 'ezstring' is created. (Full code here).

        // get content type service from repository
        $contentTypeService = $repository->getContentTypeService();
        // load the content type group
        try
        {
            $contentTypeGroup = $contentTypeService->loadContentTypeGroupByIdentifier($groupIdentifier);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            $output->writeln("content type group with identifier $groupIdentifier not found");
            return;
        }
        // instanciate a ContentTypeCreateStruct with the given content type identifier
        $contentTypeCreateStruct = $contentTypeService->newContentTypeCreateStruct($contentTypeIdentifier );
        // the main language code for names and description
        $contentTypeCreateStruct->mainLanguageCode = 'eng-GB';
        // the name schema for generating the content name by using the title attribute
        $contentTypeCreateStruct->nameSchema = '<title>';
        // set names for the content type
        $contentTypeCreateStruct->names = array(
                'eng-GB' => $contentTypeIdentifier . 'eng-GB',
                'ger-DE' => $contentTypeIdentifier . 'ger-DE',
        );
        // set description for the content type
        $contentTypeCreateStruct->descriptions = array(
                'eng-GB' => 'Description for ' . $contentTypeIdentifier . 'eng-GB',
                'ger-DE' => 'Description for ' . $contentTypeIdentifier . 'ger-DE',
        );
        /********************** add fields ***************************************/
        // add a title field
        $titleFieldDefinitionCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('title', 'ezstring');
        // set names and description for display
        $titleFieldDefinitionCreateStruct->names = array('eng-GB' => 'Title','ger-DE' => 'Titel',);
        $titleFieldDefinitionCreateStruct->descriptions = array('eng-GB' => 'The Title','ger-DE' => 'Der Titel');
        // set an group for the field
        $titleFieldDefinitionCreateStruct->fieldGroup = 'content';
        // set position inside the content type
        $titleFieldDefinitionCreateStruct->position = 1;
        // enable translation
        $titleFieldDefinitionCreateStruct->isTranslatable = true;
        // require this field to set on content creation
        $titleFieldDefinitionCreateStruct->isRequired = true;
        // enabled to find field via content search
        $titleFieldDefinitionCreateStruct->isSearchable = true;
        // add field definition to content create struct
        $contentTypeCreateStruct->addFieldDefinition( $titleFieldDefinitionCreateStruct );
        // add a body field
        $bodyFieldDefinitionCreateStruct = $contentTypeService->newFieldDefinitionCreateStruct('body', 'ezstring');
        // set names and description for display
        $bodyFieldDefinitionCreateStruct->names = array('eng-GB' => 'Body','ger-DE' => 'Text');
        $bodyFieldDefinitionCreateStruct->descriptions = array('eng-GB' => 'Description for Body','ger-DE' => 'Beschreibung Text');
        $bodyFieldDefinitionCreateStruct->fieldGroup = 'content';
        $bodyFieldDefinitionCreateStruct->position = 2;
        $bodyFieldDefinitionCreateStruct->isTranslatable = true;
        $bodyFieldDefinitionCreateStruct->isRequired = true;
        $bodyFieldDefinitionCreateStruct->isSearchable = true;
        // add field definition to content create struct
        $contentTypeCreateStruct->addFieldDefinition( $bodyFieldDefinitionCreateStruct );
        // set the content type group for the content type
        $contentTypeGroups = array($contentTypeGroup);
        // start a transaction
        $repository->beginTransaction();
        try
        {
            // create the content type - the returned content type is in status DRAFT
            $contentTypeDraft = $contentTypeService->createContentType($contentTypeCreateStruct,$contentTypeGroups);
            // publish the content type draft
            $contentTypeService->publishContentTypeDraft($contentTypeDraft);
            // commit the transaction
            $repository->commit();
        }
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // react on permission denied
            $output->writeln($e->getMessage());
            $repository->rollback();
        }
        catch( \eZ\Publish\API\Repository\Exceptions\ForbiddenException $e )
        {
            // react on identifier already exists
            $output->writeln($e->getMessage());
            $repository->rollback();
        }
        catch( \Exception $e )
        {
            $output->writeln($e->getMessage());
            $repository->rollback();
        }
    }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentTypeService
eZ\Publish\API\Repository\Values\ContentType\ContentTypeGroup
eZ\Publish\API\Repository\Values\ContentType\ContentTypeCreateStruct
eZ\Publish\API\Repository\Values\ContentType\FieldDefinitionCreateStruct
eZ\Publish\API\Repository\Values\ContentType\ContentTypeDraft

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\ForbiddenException

eZ\Publish\API\Repository\Exceptions\NotFoundException

 

Recipe 5 - Creating content

In this receipt content is created under a given parent location. It is assumed that the loaded content type is the one created in receipt 4. (Full code here).

        // get the content service from the repository
        $contentService = $repository->getContentService();
        // get the location service from the repsitory
        $locationService = $repository->getLocationService();
        // get the user service from the repsitory
        $contentTypeService = $repository->getContentTypeService();
        try
        {
            // load the content type with identifier
            $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
            // instanciate a location create struct
            $locationCreateStruct = $locationService->newLocationCreateStruct($parentLocationId);
            // instanciate a content creation struct
            $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
            // set title field
            $contentCreateStruct->setField('title',$title);
            // set body field
            $contentCreateStruct->setField('body', $body);
            // create a draft using the content and location create structs
            $draftContent = $contentService->createContent($contentCreateStruct, array($locationCreateStruct));
            // publish the content draft
            $content = $contentService->publishVersion($draftContent->versionInfo);
            // print out the content
            print_r($content);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on content type or location not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException $e)
        {
            // react on remote id exists already
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException $e)
        {
            // react on a field is not valid
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentValidationException $e)
        {
            // react on a required field is missing or empty
            $output->writeln($e->getMessage());
        } 
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
    }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentService
eZ\Publish\API\Repository\Values\Content\ContentInfo
eZ\Publish\API\Repository\Values\Content\Content
eZ\Publish\API\Repository\Values\Content\VersionInfo
eZ\Publish\API\Repository\Values\Content\ContentCreateStruct
eZ\Publish\API\Repository\Values\Content\LocationCreateStruct
eZ\Publish\API\Repository\Exceptions\InvalidArgumentException

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException

eZ\Publish\API\Repository\Exceptions\ContentValidationException

eZ\Publish\API\Repository\Exceptions\NotFoundException

 

Recipe 6 - Updating Content

In this receipt the previously created content is updated with a new title and body in the same language. (Full code here)

        try
        {
            // load the content info for the given id
            $contentInfo = $contentService->loadContentInfo($contentId);
            // create a draft from the current published version
            $contentDraft = $contentService->createContentDraft($contentInfo);
            // instanciate a content update struct
            $contentUpdateStruct = $contentService->newContentUpdateStruct();
            // set language for new version
            $contentUpdateStruct->initialLanguageCode = 'eng-GB';
            // set fields
            $contentUpdateStruct->setField( 'title', $newtitle );
            $contentUpdateStruct->setField( 'body', $newbody );
            // update draft
            $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
            // publish draft
            $content = $contentService->publishVersion($contentDraft->versionInfo);
            print_r($content);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on content not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException $e)
        {
            // react on a field is not valid
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentValidationException $e)
        {
            // react on a required field is missing or empty
            $output->writeln($e->getMessage());
        }
    }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentService
eZ\Publish\API\Repository\Values\Content\ContentInfo
eZ\Publish\API\Repository\Values\Content\Content
eZ\Publish\API\Repository\Values\Content\VersionInfo
eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct
eZ\Publish\API\Repository\Exceptions\InvalidArgumentException

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException

eZ\Publish\API\Repository\Exceptions\ContentValidationException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 7 - Translating content

It is the same code as for updating (see Receipt 6). The initial language should be set to the translation language.

            // set language for new version
            $contentUpdateStruct->initialLanguageCode = $newLanguage;
            // set fields
            $contentUpdateStruct->setField( 'title', $newtitle );
            $contentUpdateStruct->setField( 'body', $newbody );

Recipe 8 - Multiple translations at once

It is possible to to make an update in content  or create content with more than one language. But there is a restriction - only one language can be assigned to the newly created version (which is displayed in the 4.x admin GUI in the translations column).

            // set one language for new version
            $contentUpdateStruct->initialLanguageCode = 'fra-FR';
			// set fields for german - here the language has to be passed in third argument
            $contentUpdateStruct->setField( 'title', $newgermantitle, 'ger-DE' );
            $contentUpdateStruct->setField( 'body', $newgermanbody, 'ger-DE' );
            // set fields for french
            $contentUpdateStruct->setField( 'title', $newfrenchtitle);
            $contentUpdateStruct->setField( 'body', $newfrenchbody);


Recipe 9 - Performing a simple full text search

In this receipt a simple full text search is performed. (Full code here)

        // get the search service
        $searchService = $repository->getSearchService();
        // create a new query object
        $query = new \eZ\Publish\API\Repository\Values\Content\Query();
        // add a fulltext criterion
        $query->criterion = new \eZ\Publish\API\Repository\Values\Content\Query\Criterion\Fulltext($text);
        // call findContent
        $result = $searchService->findContent($query);
        // print the total count of the search hits
        $output->writeln('Found ' . $result->totalCount . ' items');
        // iterate over the search hits
        foreach( $result->searchHits as $searchHit ) {
            // print out the content name
            $output->writeln($searchHit->valueObject->contentInfo->name);
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\SearchService

eZ\Publish\API\Repository\Values\Content\Query

eZ\Publish\API\Repository\Values\Content\Query\Criterion

eZ\Publish\API\Repository\Values\Content\Query\Criterion\Fulltext

eZ\Publish\API\Repository\Values\Content/Search/SearchResult

eZ\Publish\API\Repository\Values\Content/Search/SearchHit

eZ\Publish\API\Repository\Values\Content\ContentInfo

 

Recipe 10 - Performing an advanced search

In this receipt different criteria is combined using a logic and operation. The result is restricted additional (see Receipt 9) to a given content type and subtree. (Full code here)

        // create a full text criterion
        $criterion1 = new \eZ\Publish\API\Repository\Values\Content\Query\Criterion\FullText($text);
        // create a subtree criterion (restrict results to belong to the subtree)
        $criterion2 = new \eZ\Publish\API\Repository\Values\Content\Query\Criterion\Subtree($location->pathString);
        // create a content type criterion (restrict to the given content type)
        $criterion3 = new \eZ\Publish\API\Repository\Values\Content\Query\Criterion\ContentTypeId($contentTypeId);
        // make a logical AND of the two criteria
        $query->criterion = new \eZ\Publish\API\Repository\Values\Content\Query\Criterion\LogicalAND(
                array($criterion1,$criterion2,$criterion3));

 

Recipe 11 - Browsing Locations

This receipt shows how to browse a subtree starting from a given location. (Full code here)

        // get the location service from the repsitory
        $this->locationService = $repository->getLocationService();
        try
        {
            $location = $this->locationService->loadLocation($locationId);
            $this->browseLocation($location,0,$output);
        }
        catch( \eZ\Publish\API\Repository\Exceptions\NotFoundException $e )
        {
            // if the location was not found
            $output->writeln( "No content with id $locationId" );
        }
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // not allowed to read this location
            $output->writeln( "Anonymous users are not allowed to read location with id $locationId" );
        }
    /**
     * this method prints out the location name and calls this method recursive for the locations children
     *
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
     * @param int $depth the current depth
     * @param OutputInterface $output
     */
    private function browseLocation(Location $location, $depth, OutputInterface $output) {
        // indent according to depth
        for($k=0;$k<$depth;$k++)
        {
            $output->write(' ');
        }
        // write the content name
        $output->writeln($location->contentInfo->name);
        // get location children
        $children = $this->locationService->loadLocationChildren($location);
        // browse children
        foreach($children as $childLocation) 
        {
            $this->browseLocation($childLocation, $depth +1,$output);
        }
    }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\LocationService

eZ\Publish\API\Repository\Values\Content\Location

eZ\Publish\API\Repository\Values\Content\ContentInfo

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 12 - Adding a new location to content

This receipt shows how to add a new location to a given content object. (Full code here)

        // get the location service from the repsitory
        $locationService = $repository->getLocationService();
        try
        {
            // instanciate a location create struct
            $locationCreateStruct = $locationService->newLocationCreateStruct($parentLocationId);
            // load the content info from the given content id
            $contentInfo = $contentService->loadContentInfo($contentId);
            // create a new location below the given parent
            $newLocation = $locationService->createLocation($contentInfo,$locationCreateStruct);
            // print out the new location
            print_r($newLocation);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on content or location not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e)
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\LocationService
eZ\Publish\API\Repository\ContentService
eZ\Publish\API\Repository\Values\Content\LocationCreateStruct
eZ\Publish\API\Repository\Values\Content\ContentInfo

eZ\Publish\API\Repository\Values\Content\Location

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 13 - Move or Copy Subtree

This receipt shows how to move or copy a subtree to a given parent location (Full code here)

        // get the location service from the repsitory
        $locationService = $repository->getLocationService();
        try
        {
            // load the location from the given location id
            $location = $locationService->loadLocation($locationId);
            // load the parent location to move/copy to
            $parentLocation = $locationService->loadLocation($parentLocationId);
            if($operation == 'copy') 
            {
                $newLocation = $locationService->copySubtree($location, $parentLocation);
            }
            else if($operation == 'move')
            {
                $newLocation = $locationService->moveSubtree($location, $parentLocation);
            }
            else
            {
                $output->writeln("operation must be copy or move");
                return;
            }
            print_r($newLocation);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on parent location or location not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e)
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
    }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\LocationService

eZ\Publish\API\Repository\Values\Content\Location

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 14 - Hide/Unhide Location

This receipt shows how to hide/unhide a location. (Full code here)

        // get the location service from the repository
        $locationService = $repository->getLocationService();
        // get the user service from the repsitory
        $userService = $repository->getUserService();
        // load admin user
        $user = $userService->loadUser(14);
        // set current user to admin
        $repository->setCurrentUser($user);
        try
        {
             // load the location info from the given location id
            $location = $contentService->loadContentInfo($contentId);
            // hide the location
            $hiddenLocation = $locationService->hideLocation($location);
            // print out the location
            print_r($hiddenLocation);
            // unhide the location
            $unhiddenLocation = $locationService->unhideLocation($hiddenLocation);
            // print out the location
            print_r($unhiddenLocation);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on location not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e)
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\LocationService

eZ\Publish\API\Repository\Values\Content\Location

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 15 - Deleting locations

If a content has more than one location the method

LocationService::delete(Location $location) 

removes the location and if exists all descendants of the location. However the content itself is untouched as it has still other locations.

If the deleted location is the last one of the content the content itself is deleted. This applies also to all descendants of the location.

Alternatively a location can also moved to the trash via the method:

TrashService::trash(Location $location)

Recipe 16 - Deleting Content

The result of deleting content is equivalent to deleting all locations of content (see Receipt 15).

It is done via the method:

ContentService::delete(ContentInfo $contentInfo)

 

Recipe 17 - Assinging section to content

On creation of content  the section of the parent location's content is assigned by default to the new content. However it is possible to assign a specific section on creation by setting it in the ContentCreateStruct (Receipt 5):

$contentCreateStruct->section = $sectionId

Later on sections can be assigned with the following code (Full code here):

        // get the content service from the repository
        $contentService = $repository->getContentService();
        // get the section service from the repsitory
        $sectionService = $repository->getSectionService();
        // get the user service from the repsitory
        try
        {
            // load the content info from the given content id
            $contentInfo = $contentService->loadContentInfo($contentId);
            // load the section
            $section = $sectionService->loadSection($sectionId);
            // assign the section to the content
            $sectionService->assignSection($contentInfo, $section);
            // realod an print out
            $contentInfo =  $contentService->loadContentInfo($contentId);
            // should show the new section id
            $output->writeln($contentInfo->sectionId);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on content or section not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e)
        {
            // react on permission denied
            $output->writeln($e->getMessage());
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\SectionService
eZ\Publish\API\Repository\ContentService

eZ\Publish\API\Repository\Values\Content\Section

eZ\Publish\API\Repository\Values\Content\ContentInfo

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

Recipe 18 - Viewing Content

This receipt shows how to view fields of the content int the main language.

        // get the content service from the repsitory
        $contentService = $repository->getContentService();
        // get the field type service
        $fieldTypeService = $repository->getFieldTypeService();
        try
        {
            // load the content including all fields
            $content = $contentService->loadContent($contentId);
            // load the content type
            $contentType = $content->contentType;
            // iterate over field definitions
            foreach($contentType->fieldDefinitions as $fieldDefinition ) {
                // ignore ezpage
                if($fieldDefinition->fieldTypeIdentifier == 'ezpage') continue;
                // get the field type
                $fieldType = $fieldTypeService->getFieldType($fieldDefinition->fieldTypeIdentifier);
                // write field definition identifier
                $output->write($fieldDefinition->identifier . ": ");
                // use the field type toHash function to get a readable representation of the value
                $output->writeln($fieldType->toHash($content->getField($fieldDefinition->identifier)->value));
            }
        }
        catch( \eZ\Publish\API\Repository\Exceptions\NotFoundException $e )
        {
            // if the id is not found
            $output->writeln( "No content with id $contentId" );
        }
        catch( \eZ\Publish\API\Repository\Exceptions\UnauthorizedException $e )
        {
            // not allowed to read this content
            $output->writeln( "Anonymous users are not allowed to read content with id $contentId" );
        }
eZ\Publish\API\Repository\Repository
eZ\Publish\API\Repository\ContentService
eZ\Publish\API\Repository\FieldTypeService

eZ\Publish\API\Repository\Values\Content\Content

eZ\Publish\API\Repository\Values\ContentType\ContentType
eZ\Publish\API\Repository\Values\ContentType\FieldDefinition
eZ\Publish\API\Repository\FieldType
eZ\Publish\API\Repository\Values\Content\Field

eZ\Publish\API\Repository\Exceptions\UnauthorizedException

eZ\Publish\API\Repository\Exceptions\NotFoundException

 

Other languages are accessible via the the language parameter in the method

$content->getField( $fieldDefinition->identifier, $otherlanguage)

Recipe 19 - Creating an Image

This receipt shows how to create an image content object.

// get the content service from the repsitory
        $contentService = $repository->getContentService();


        // get the location service from the repsitory
        $locationService = $repository->getLocationService();

        // get the content type service from the repsitory
        $contentTypeService = $repository->getContentTypeService();

        try
        {
            // load the content type with identifier
            $contentType = $contentTypeService->loadContentTypeByIdentifier("image");

            // instanciate a location create struct
            $locationCreateStruct = $locationService->newLocationCreateStruct($parentLocationId);

            // instanciate a content creation struct
            $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');

            // set title field
            $contentCreateStruct->setField('name',$name);

            // set image file field
            $value = new \eZ\Publish\Core\FieldType\Image\Value(
                     array('path' => $file,'fileSize' => filesize($file),'fileName' => basename($file),'alternativeText' => $name ));

            $contentCreateStruct->setField("image",$value);

            // create a draft using the content and location create structs
            $draft = $contentService->createContent($contentCreateStruct,array($locationCreateStruct));

            // publish the content draft
            $content = $contentService->publishVersion($draft->versionInfo);

            // print out the content
            print_r($content);
        }
        catch(\eZ\Publish\API\Repository\Exceptions\NotFoundException $e)
        {
            // react on content type or location not found
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\InvalidArgumentException $e)
        {
            // react on remote id exists already
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException $e)
        {
            // react on a field is not valid
            $output->writeln($e->getMessage());
        }
        catch(\eZ\Publish\API\Repository\Exceptions\ContentValidationException $e)
        {
            // react on a required field is missing or empty
            $output->writeln($e->getMessage());
        }

 

Recipe 20 - Create Content with XML Text

This receipt shows how to create content with xml text. As content type the folder is used where the description is filled with xml. It is also shown how to embed the previously created image in the description. The image Id is given by a command line argument.

          // load the content type with identifier
            $contentType = $contentTypeService->loadContentTypeByIdentifier("folder");


            // instanciate a location create struct
            $locationCreateStruct = $locationService->newLocationCreateStruct($parentLocationId);


            // instanciate a content creation struct
            $contentCreateStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');


            // set name field
            $contentCreateStruct->setField('name',$name);


            // contruct a xml text


            $xmltext = "<?xml version='1.0' encoding='utf-8'?><section xmlns:image='http://ez.no/namespaces/ezpublish3/image/' xmlns:xhtml='http://ez.no/namespaces/ezpublish3/xhtml/' xmlns:custom='http://ez.no/namespaces/ezpublish3/custom/'><paragraph>This is a <strong>image test</strong></paragraph><paragraph><embed view='embed' size='medium' object_id='$imageId' custom:offset='0' custom:limit='5'/></paragraph></section>";


            // add the xmltext field
            $contentCreateStruct->setField("description",$xmltext);


            // create a draft using the content and location create structs
            $draft = $contentService->createContent($contentCreateStruct,array($locationCreateStruct));


            // publish the content draft
            $content = $contentService->publishVersion($draft->versionInfo);


            // print out the content
            print_r($content);