Message-ID: <529099335.3084.1485851948020.JavaMail.confluence@ip-10-127-227-164> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_3083_1251912984.1485851948020" ------=_Part_3083_1251912984.1485851948020 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html 1. Getting started

1. Getting started

With the introduction of Symfony 2 as the framework powering eZ = Publish 5, the whole eZ Publish 4.x extensions system is changing. Pretty m= uch everything needs to be done with entirely new concepts. In this chapter= , we will see two ways of customizing eZ Publish 5: command line scripts (f= or import scripts, for instance), and custom controllers, the eZ Publish 5 = equivalent of eZ Publish 4.x custom modules.

=20 =20

Symfony bundle

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 Publish. Symfony 2 provides code generation tools that will let y= ou 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 a= ction and view. All shell commands assume that you use some Linux shell, bu= t those commands would of course also work on Windows systems.

Generating a new bundle=

First, change the directory to your eZ Publish root.

=20
$ cd /path/to/ezpublish5
=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, l= ocated in the src directory.

=20
$ php ezpublish/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.

Bundle namespace
=20
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 Bund= le's name, used to reference your bundle in your code. We can go with the d= efault, EzSystemsCookbookBundle. Just hit enter to accept= the default.

Bundle name
=20
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 lo= cation. By default, the script offers to place it in the src folder. This is perfectly acceptable unless you have a good reason= to place it somewhere else. Just hit enter to accept the default.

Bundle directory
=20
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 generate= d configuration's format, out of YAML, XML, PHP or annotations. We mostly u= se yaml in eZ Publish 5, and we will use it in this cookbook. Enter 'yml', = and hit enter.

Configuration format
=20
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 s= nippets demonstrating the Symfony directory structure. If you're learning S= ymfony, it is a good idea to accept, as it will pre-create a controller, ya= ml files, etc.

Generate snippets & directory structure
=20
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 confirmation. Hit enter to confirm.

Summary and confirmation
=20
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 to both questions to have your bundl= e automatically added to your Kernel (ezpublish/EzPublishKernel.php) and routes from your bundle added to the existing routes (ezpu= blish/config/routing.yml).

Activation and generation
=20
  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.

Creating a command line script in your bundle

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 ezpublish/console <command> (= app/console in a default symfony 2 application). You can = get the complete list of existing command line scripts by executing php ezpublish/console list from the eZ Publish 5 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 bun= dle's directory (src/EzSystems/CookbookBundle), create a new d= irectory named Command, and in this directory, a new file= named HelloCommand.php.

Add this code to the file:

HelloCommand.php
=20
<?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: configure(), and execute(). We also import seve= ral classes & interfaces with the use keyword. The first two, InputInterface and 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 option= s and arguments. Execute will contain the actual implementation of your com= mand. Let's start by creating the configure() method= .

TestCommand::configure()
=20
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:co= okbook:hello".  We then use setDefinition()&n= bsp;to add an argument, named name, to our command.

You can read more about arguments definitions and further options in the=  Symfony 2 Console documenta= tion. Once this is done, if you run php ezpublish/conso= le list, you should see ezpublish:cookbook:hello&n= bsp;listed in the available commands. If you run it, it should just do noth= ing.

Let's just add something very simple to our execute() method so that our= command actually does something.

TestCommand::execute()
=20
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 Publish 5 root.

Hello world
=20
$ php ezpublish/console ezpublish:cookbook:hello world
Hello world
=20

Cr= eating a custom route with a controller action

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.

eZ Publish 4 equivalent

This eZ Publish 5 extension would have been a custom module, with its ow= n module.php file, in eZ Publish 4.

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 default snippets. We just need to do some editing, in particular in = two locations: src/EzSystems/CookbookBundle/Resources/config/rou= ting.yml and src/EzSystems/CookbookBundle/Controller= s/DefaultController.php. The first one will be used to configure our= route (/cookbook/test) as well as the controller action the r= oute should execute, while the latter will contain the actual action's code= .

routing.yml

This is the file where we define our action's URL matching. The generate= d file contains this YAML block

Generated routing.yml
=20
ez_systems_cookbook_homepage:
    pattern:  /hello/{name}
    defaults: { _controller: EzSystemsCookbookBundle:Default:index }
= =20

We can safely remove this default code, and replace it with this

Edited routing.yml
=20
ezsystems_cookbook_hello:
    pattern:  /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 step is to creat= e this method in the controller.

DefaultController.php<= /h4>

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.

DefaultController::helloAction()
=20
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 named "name" in the route definiti= on, and must be named $name in the matching action. Since the action is nam= ed "hello" in routing.yml, the expected method name is&nb= sp;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". Sim= ple. Go to http://ezpublish5/co= okbook/hello/YourName, and you should get "Hello 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()
    Returns the Public API repository, that gives you ac= cess to the various services through getContentService(), getLocationServic= e() and so on; 
  • getLegacyKernel()
    Returns an instance of the eZ\Publish\Cor= e\MVC\Legacy\Kernel, that you can use to interact with the Legacy eZ Pu= blish kernel
  • getConfigResolver()
    Returns the ConfigResolver that gives you access to configuration dat= a.

You are encouraged to use it for your custom controllers that interact w= ith eZ Publish.

 

With both command line scripts and HTTP routes, you have the basics you = need to start writing Public API code.

------=_Part_3083_1251912984.1485851948020--