Message-ID: <1514302028.3086.1485851953128.JavaMail.confluence@ip-10-127-227-164> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_3085_90273839.1485851953127" ------=_Part_3085_90273839.1485851953127 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
In the following recipes, you will see how to create Content, including = complex fields like XmlText or Image.
As seen earlier, the Repository executes operations with a user's creden= tials. In a web context, the currently logged in user is automatically iden= tified. In a command line context, you need to manually log a user in. We h= ave already seen how to manually load and set a user using its ID. If you w= ould like to identify a user using his username and password instead, this = can be achieved as follows.
$user =3D $userService->loadUserByCredentials( $user, $password = ); $repository->setCurrentUser( $user );=20
Full code
We will now see how to create Content using the Public API. This example= will work with the default Folder (ID 1) Content Type from eZ Publish.
/** @var $repository \eZ\Publish\API\Repository\Repository */ $repository =3D $this->getContainer()->get( 'ezpublish.api.repository= ' ); $contentService =3D $repository->getContentService(); $locationService =3D $repository->getLocationService(); $contentTypeService =3D $repository->getContentTypeService();=20
We first need the required services. In this case: As explained in the Public AP=
I Basics, Value Objects are read only. Dedicated objects are provided f=
or Update and Create operations: structs, like ContentCreateStruct or Updat=
eCreateStruct. In this case, we need to use a ContentCreateStruct. We first need to get the Using our create struct, we can now set the values for our Content's fie=
lds, using the The In any case, whatever the FieldType is, a Value of this type can be prov=
ided. For instance, a TextLine\Value can be provided for a TextLine\Type. D=
epending on the FieldType implementation itself, more specifically on the f=
romHash() method every FieldType implements, various arrays can be accepted=
, as well as primitive types, depending on the Type. In order to set a Location for our object, we must instantiate a To actually create our Content in the Repository, we need to use Content=
Service::createContent(). This method expects a The LocationCreateStruct is provided as an array, since a Content can ha=
ve multiple locations. Full code We will now see how the previously created Content can be updated. =
To do so, we will create a new draft for our Content, update it using a To create our draft, we need to load the Content's ContentInfo using ContentService<=
/code>,
. We can then use LocationService
and ContentTypeService
.=
p>
The ContentCreateStr=
uct
$contentType =3D $contentTypeService->loadContentTypeByIdentifie=
r( 'article' );
$contentCreateStruct =3D $contentService->newContentCreateStruct( $conte=
ntType, 'eng-GB' );
=20
ContentType
we want to cre=
ate a Content
with. To do so, we use ContentTypeService::loadContentTypeByIdentifier()
, with =
the wanted ContentType
identifier, like 'article'. We finally =
get a ContentTypeCreateStruct using ContentService:=
:newContentCreateStruct()
, providing the ContentType and a Local=
e Code (eng-GB).Setting the fields v=
alues
$contentCreateStruct->setField( 'title', 'My title' );
$contentCreateStruct->setField( 'intro', $intro );
$contentCreateStruct->setField( 'body', $body );
=20
setField()
method. =
For now, we will just set the title. setField()
for a TextLine=
Field simply expects a string as input argument. More complex FieldTypes, =
like Author or Image, expect different input values.ContentCreateStruct::setField() method can take several type of arguments.
Setting the Location
LocationCreateStruct
. This is done with LocationService:=
:newLocationCreateStruct(), with the new Location's parent ID as an argumen=
t.$locationCreateStruct =3D $locationService->newLocationCreateStr=
uct( 2 );
=20
Creating and publishi=
ng
ContentCreateStruct=
code>, as well as a
LocationCreateStruct
. We have created both=
in the previous steps.$draft =3D $contentService->createContent( $contentCreateStruct,=
array( $locationCreateStruct ) );
$content =3D $contentService->publishVersion( $draft->versionInfo );<=
/pre>=20
createContent()
returns a new Content Value Object, with on=
e version that has the DRAFT status. To make this Content visible, we need =
to publish it. This is done using ContentService::publishVersion=
()
. This method expects a VersionInfo
object as its par=
ameter. In our case, we simply use the current version from $draft, with the
versionInfo
property.Updating Content
ContentUpdateStruct
, and publish the updated Version.=
$contentInfo =3D $contentService->loadContentInfo( $contentId );
$contentDraft =3D $contentService->createContentDraft( $contentInfo );=
pre>=20
ContentS=
ervice::createContentDraft()
to add a new Draft to our Content.
// instantiate a content update struct and set the new fields $contentUpdateStruct =3D $contentService->newContentUpdateStruct(); $contentUpdateStruct->initialLanguageCode =3D 'eng-GB'; // set language = for new version $contentUpdateStruct->setField( 'title', $newTitle ); $contentUpdateStruct->setField( 'body', $newBody );=20
To set the new values for this version, we request a ContentUpdate=
Struct
from the ContentService
using the newConte=
ntUpdateStruct()
method. Updating the values hasn't changed: we use =
the setField()
method.
$contentDraft =3D $contentService->updateContent( $contentDraft-= >versionInfo, $contentUpdateStruct ); $content =3D $contentService->publishVersion( $contentDraft->versionI= nfo );=20
We can now use ContentService::updateContent()
to apply our=
ContentUpdateStruct
to our draft's VersionInfo
.&=
nbsp;Publishing is done exactly the same way as for a new content, using
In the two previous examples, you have seen that we set the ContentUpdat= eStruct's initialLanguageCode property. To translate an object to a new lan= guage, set the locale to a new one.
$contentUpdateStruct->initialLanguageCode =3D 'ger-DE'; $contentUpdateStruct->setField( 'title', $newtitle ); $contentUpdateStruct->setField( 'body', $newbody );=20
It is possible to create or update content in multiple languages at once= . There is one restriction: only one language can be set a version's langua= ge. This language is the one that will get a flag in the back office. Howev= er, you can set values in other languages for your attributes, using the se= tField method's third argument.
// set one language for new version $contentUpdateStruct->initialLanguageCode =3D 'fre-FR'; $contentUpdateStruct->setField( 'title', $newgermantitle, 'ger-DE' ); $contentUpdateStruct->setField( 'body', $newgermanbody, 'ger-DE' ); $contentUpdateStruct->setField( 'title', $newfrenchtitle ); $contentUpdateStruct->setField( 'body', $newfrenchbody );=20
Since we don't specify a locale for the last two fields, they are set fo=
r the UpdateStruct
's initialLanguageCode
, fre-FR.=
Full code
As explained above, the setField() method can accept various values: an =
instance of the FieldType's Value class, a primitive type, or a hash. The l=
ast two depend on what the Type::acceptValue()
method is build=
up to handle. TextLine can, for instance, accept a simple string as an inp=
ut value. In this example, you will see how to set an Image value.
We assume that we use the default image class. Creating our Content, usi= ng the ContentType and a ContentCreateStruct, has been covered above, and c= an be found in the full code. Let's focus on how the image is provided.
$file =3D '/path/to/image.png'; $value =3D new \eZ\Publish\Core\FieldType\Image\Value( array( 'path' =3D> '/path/to/image.png', 'fileSize' =3D> filesize( '/path/to/image.png' ), 'fileName' =3D> basename( 'image.png' ), 'alternativeText' =3D> 'My image' ) ); $contentCreateStruct->setField( 'image', $value );=20
This time, we create our image by directly providing an Image\Value
ob=
ject. The values are directly provided to the constructor using a hash with=
predetermined keys that depend on each Type. In this case: the path where =
the image can be found, its size, the file name, and an alternative text.=
p>
Images also implement a static fromString()
method t=
hat will, given a path to an image, return an Image\Value
obje=
ct.
$value =3D \eZ\Publish\Core\FieldType\Image\Value::fromString( '/pa= th/to/image.png' );=20
But as said before, whatever you provide setField()
with is=
sent to the acceptValue()
method. This method really is the e=
ntry point to the input formats a FieldType accepts. In this case, you coul=
d have provided setField with either a hash, similar to the one we provided=
the Image\Value constructor with, or the path to your image, as a string.<=
/p>
$contentCreateStruct->setField( 'image', '/path/to/image.png' ); // or $contentCreateStruct->setField( 'image', array( 'path' =3D> '/path/to/image.png', 'fileSize' =3D> filesize( '/path/to/image.png' ), 'fileName' =3D> basename( 'image.png' ), 'alternativeText' =3D> 'My image' );=20
Full code
Another very commonly used FieldType is the rich text one, XmlText=
.
$xmlText =3D <<< EOX <?xml version=3D'1.0' encoding=3D'utf-8'?> <section> <paragraph>This is a <strong>image test</strong></para= graph> <paragraph><embed view=3D'embed' size=3D'medium' object_id=3D'$ima= geId'/></paragraph> </section> EOX; $contentCreateStruct->setField( 'body', $xmlText );=20
As for the last example above, we use the multiple formats accepted by <= code>setField(), and provide our XML string as is. The only accepted= format as of 5.0 is internal XML, the one stored in the Legacy database.= p>
The XSD for the internal XML representation can be found in the kernel: = https://github.com/ezsystems/ezpublish-kernel/= blob/master/eZ/Publish/Core/FieldType/XmlText/Input/Resources/schemas/ezxml= .xsd.
We embed an image in our XML, using the <embed>
tag, =
providing an image Content ID as the object_id
attribute.
Using a custom format as input
More input formats will be added later. The API for that is actually alr=
eady available: you simply need to implement the XmlText\Input
interfac=
e. It contains one method, getInternalRepresentat=
ion()
, that must return an internal XML string. Create your own =
bundle, add your implementation to it, and use it in your code!
$input =3D new \My\XmlText\CustomInput( 'My custom format string' )= ; $contentCreateStruct->setField( 'body', $input );=20
$contentService->deleteContent( $contentInfo );=20
ContentService::deleteContent()
method expec=
ts a ContentInfo
as an argument. It will delete the given Cont=
ent, all of its Locations, as well as all of the Content's Locations' desce=
ndants and their associated Content. Use with caution !