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 Getting started with the Public API

Getting started with the Public API

=20
=20
=20
=20

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>

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 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.

Generating a= new bundle

First, change the directory to your eZ Platform root.

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

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

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 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.

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 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.

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 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.

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 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.

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 conf= irmation. 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 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).

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 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:

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 options and arguments. Execute will contain the actual = implementation of your command. Let's start by creating the conf= igure() 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:cookbook:hello". We then use setDefinition() 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.

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 Platform root.

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

Creating 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.

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.

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:
    path:     /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:
    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.

DefaultCont= roller.php

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 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()
    Returns the Public API repository that= gives you access to the various services through getContentService()= , getLocationService() and so on; 
  • getLegacyKernel()
    Returns an instance of the = eZ\Publish\Core\MVC\Legacy\Kernel that you can use to interact with the= Legacy eZ Platform kernel
  • getConfigResolver()
    Returns the ConfigResolver that gives you access to conf= iguration data.

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.

=20
=20
=20
=20

In this topic:

=20
=20
=20
------=_Part_3687_665455085.1485854835092--