Message-ID: <663747907.3688.1485854835092.JavaMail.confluence@ip-10-127-227-164> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_3687_665455085.1485854835092" ------=_Part_3687_665455085.1485854835092 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
In this chapter, we will see two ways of customizing eZ Platform: comman= d line scripts (for import scripts, for instance), and custom controllers.<= /p>
In order to test and use Public API code, you will need to build a custo= m bundle. Bundles are Symfony's extensions, and are therefore also used to = extend eZ Platform. Symfony 2 provides code generation tools that will let = you create your own bundle and get started in a few minutes.
In this chapter, we will show how to create a custom bundle, and impleme= nt both a command line script and a custom route with its own controller ac= tion and view. All shell commands assume that you use some Linux shell, but= those commands would of course also work on Windows systems.
First, change the directory to your eZ Platform root.
$ cd /path/to/ezplatform=20
Then use the app/console application with the generate:bundle command to start the bundle generation wizard.
Let's follow the instructions provided by the wizard. Our objective is t=
o create a bundle named EzSystems/Bundles/CookBookBundle
, loca=
ted in the src
directory.
$ php app/console generate:bundle=20
The wizard will first ask about our bundle's namespace. Each bundle's na=
mespace should feature a vendor name (in our own case: EzSystems=
), optionally followed by a sub-namespace (we could have chosen to u=
se Bundle
), and end with the actual bundle's name, suffix=
ed with Bundle: CookbookBundle
.
Your application code must be written in bundles. This command hel= ps 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, you= r project name, or your client name, followed by one or more optional categ= ory sub-namespaces, and it should end with the bundle name itself (which mu= st have Bundle as a suffix). See http://symfony.com/doc/current/cookbook/bundles/best_practices.html#ind= ex-1 for more details on bundle naming conventions.=20 Use / instead of \ for the namespace delimiter to avoid any problem. Bundle namespace: EzSystems/CookbookBundle=20
You will then be asked about the Bundle's name, used to reference your b=
undle in your code. We can go with the default, EzSystemsCookboo=
kBundle
. Just hit Enter to accept the default.
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]:=20
The next question is your bundle's location. By default, the script offe=
rs to place it in the src
folder. This is perfectly =
acceptable unless you have a good reason to place it somewhere else. Just h=
it Enter to accept the default.
The bundle can be generated anywhere. The suggested default direc= tory uses the standard conventions. Target directory [/path/to/ezpublish5/src]:=20
Next, you need to choose the generated configuration's format, out of YA= ML, XML, PHP or annotations. We mostly use yaml in eZ Platform, and we will= use it in this cookbook. Enter 'yml', and hit Enter.
Determine the format to use for the generated configuration. = = =20 Configuration format (yml, xml, php, or annotation) [annotation]: yml= =20
The last choice is to generate code snippets demonstrating the Symfony d= irectory structure. If you're learning Symfony, it is a good idea to accept= , as it will create a controller, yaml files, etc.
To help you get started faster, the command can generate some cod= e snippets for you. Do you want to generate the whole directory structure [no]? yes=20
The generator will then summarize the previous choices, and ask for conf= irmation. Hit Enter to confirm.
You are going to generate a "EzSystems\Bundle\CookbookBundle\EzSy= stemsCookbookBundle" bundle in "/path/to/ezpublish5/src/" using the "yml" f= ormat. Do you confirm generation [yes]? yes=20
The wizard will generate the bundle, check autoloading, and ask about th=
e activation of your bundle. Hit Enter in the answer to both questions to h=
ave your bundle automatically added to your Kernel (app/AppKernel.php=
) and routes from your bundle added to the existing routes (ap=
p/config/routing.yml
).
Bundle generation Generating the bundle code: OK Checking that the bundle is autoloaded: OK Confirm automatic update of your Kernel [yes]? Enabling the bundle inside the Kernel: OK Confirm automatic update of the Routing [yes]? Importing the bundle routing resource: OK You can now start using the generated code!=20
Your bundle should be generated and activated. Let's now see how you can= interact with the Public API by creating a command line script, and a cust= om controller route and action.
Writing a command line script with Symfony 2 is very =
easy. The framework and its bundles ship with a few scripts. They are all s=
tarted using php app/console <command>
. You can get=
the complete list of existing command line scripts by executing php app/console list
from the eZ Platform root.
In this chapter, we will create a new command, identified as =
ezpublish:cookbook:hello
, that takes an optional name argument, and =
greets that name. To do so, we need one thing: a class with a name ending w=
ith "Command" that extends Symfony\Component\Console\Command\Com=
mand
. Note that in our case, we use ContainerAwareCommand=
instead of Command
, since we need the depend=
ency injection container to interact with the Public API. In your bund=
le's directory (src/EzSystems/CookbookBundle
), create a new di=
rectory named Command
, and in this directory, a new file =
named HelloCommand.php
.
Add this code to the file:
<?php namespace EzSystems\CookBookBundle\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputArgument; class HelloCommand extends \Symfony\Bundle\FrameworkBundle\Command\Containe= rAwareCommand { /** * Configures the command */ protected function configure() { } /** * Executes the command * @param InputInterface $input * @param OutputInterface $output */ protected function execute( InputInterface $input, OutputInterface $out= put ) { } }=20
This is the skeleton for a command line script.
One class with a name ending with "Command" (HelloCommand
),=
extends Symfony\Bundle\FrameworkBundle\Command\Command
, =
and is part of our bundle's Command namespace. It has two methods: execute()
. We also import seve=
ral classes & interfaces with the use keyword. The first two, OutputInterface
are=
used to 'typehint' the objects that will allow us to provide input & o=
utput management in our script.
Configure
will be used to set your command's name, as well =
as its options and arguments. Execute
will contain the actual =
implementation of your command. Let's start by creating the conf=
igure()
method.
protected function configure() { $this->setName( 'ezpublish:cookbook:hello' ); $this->setDefinition( array( new InputArgument( 'name', InputArgument::OPTIONAL, 'An argumen= t' ) ) ); }=20
First, we use setName()
to set our command's name to "ezpublish:cookbook:hello
". We then use setDefinition()=
code> to add an argument, named
name
, to our command=
.
You can read more about argument definitions and further options in the&=
nbsp;Symfony 2 Console documentat=
ion. Once this is done, if you run php app/console list=
, you should see ezpublish:cookbook:hello
lis=
ted in the available commands. If you run it, it will however still do noth=
ing.
Let's just add something very simple to our execute()
metho=
d so that our command actually does something.
protected function execute( InputInterface $input, OutputInterface = $output ) { // fetch the input argument if ( !$name =3D $input->getArgument( 'name' ) ) { $name =3D "World"; } $output->writeln( "Hello $name" ); }=20
You can now run the command from the eZ Platform root.
$ php app/console ezpublish:cookbook:hello world Hello world=20
In this short chapter, we will see how to create a new route that will c=
atch a custom URL and execute a controller action. We want to create a new =
route, /cookbook/test
, that displays a simple 'Hello world' me=
ssage. This tutorial is a simplified version of the official one that can b=
e found on http://symfony.com/doc/curren=
t/book/controller.html.
During our bundle's generation, we have chosen to generate the bundle wi=
th default code snippets. Fortunately, almost everything we need is part of=
those snippets. We just need to do some editing, in particular in two loca=
tions: src/EzSystems/Resources/CookbookBundle/config/routing.yml=
and src/EzSystems/CookbookBundle/Controllers/Defaul=
tController.php
. The first one will be used to configure our route (=
/cookbook/test
) as well as the controller action the route sho=
uld execute, while the latter will contain the actual action's code.
This is the file where we define our action's URL matching. The generate= d file contains this YAML block:
ez_systems_cookbook_homepage: path: /hello/{name} defaults: { _controller: EzSystemsCookbookBundle:Default:index }= =20
We can safely remove this default code, and replace it with this:
ezsystems_cookbook_hello: path: /cookbook/hello/{name} defaults: { _controller: EzSystemsCookbookBundle:Default:hello }= =20
We define a route that matches the URI /cookbook/* and executes the acti=
on hello
in the Default controller of our bundle. The next ste=
p is to create this method in the controller.
This controller was generated by the bundle generator. It contains one m=
ethod, helloAction()
, that matched the YAML configuration=
we have changed in the previous part. Let's just rename the ind=
exAction()
method so that we end up with this code.
public function helloAction( $name ) { $response =3D new \Symfony\Component\HttpFoundation\Response; $response->setContent( "Hello $name" ); return $response; }=20
We won't go into details about controllers in this cookbook, but let's w=
alk through the code a bit. This method receives the parameter defined=
in routing.yml
. It is called "name" in the route definit=
ion, and must be called $name in the matching action. Since the action is n=
amed "hello" in routing.yml
, the expected method name is&=
nbsp;helloAction
.
Controller actions must return a Response obj=
ect that will contain the response's content, the headers, and various opti=
onal properties that affect the action's behavior. In our case, we simply s=
et the content, using setContent()
, to "Hello $name". Go =
to http://ezplatform/cookbook/hello/YourName, and you should get "Hell=
o YourName".
The custom EzPublishCoreBundle Controller
For convenience, a custom controller is available at eZ\Bundle\EzPublishCoreBundle\C= ontroller. It gives you with a few commodity methods:
getRepository()
getContentService()=
, getLocationService()
and so on; getLegacyKernel()
getConfigResolver()
You are encouraged to use it for your custom controllers that interact w= ith eZ Platform.
With both command line scripts and HTTP routes, you have the basics you = need to start writing Public API code.