Symfony2 for Midgard Developers

Post on 10-May-2015

7.786 views 1 download

Tags:

description

Symfony2 tutorial geared towards Midgard developers

Transcript of Symfony2 for Midgard Developers

Symfony2 for Midgard Developers

Symfony2 is becoming the de-facto web framework for PHP 5.3

Drupal

Zend Framework

Midgard MVC

MidCOM

The PHP world is starting to unite around Symfony2

Under MIT LicenseCopyright (c) 2004-2011 Fabien PotencierPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the followingconditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.

Symfony 2.0 was released on July 28 2011

Symfony2 is a collection of standalone PHP componentsbundled together into a single framework

You can choose what to take, and what to not use

✔ Authentication and Authorization✔ Forms and Validation✔ Templating✔ Logging✔ Asset Management✔ Routing✔ Internationalization✔ Console Tasks✔ Caching

Dependency Injection means you can changeany of these to another implementation

<?php $this->container->get('security.context')->isGranted( 'READ', $object)

The actual service checking this could beMidCOM-style ACL, or simple "allow authenticatedusers to do anything" check.

PHP 5.3 and namespaces

Midgard MVC & MidCOM

<?php class example_mycomponent_controllers_some {

Symfony2

<?php namespace Example\MyBundle\Controller; use Symfony\Framework\WebBundle\Controller; class SomeController extends Controller {

\ is the new _

With namespaces all projects can share one autoloader.

<?php $crRoot = realpath(__DIR__ . '/..');

// register the autoloaders require "{$crRoot}/SplClassLoader.php";

// Tell where Midgard stuff is $midgardAutoloader = new SplClassLoader('Midgard', "{$crRoot}/src"); $midgardAutoloader->register();

// Tell where code from some other project is $phpcrAutoloader = new SplClassLoader('PHPCR', "{$crRoot}/lib/PHPCR/src"); $phpcrAutoloader->register();

Time to get the hands dirty

You'll need:

• PHP 5.3• php5-midgard2• PEAR installer• Git

Symfony2 Standard Edition

http://symfony.com/download

$ php app/check.php ******************************** * * * Symfony requirements check * * * ********************************

php.ini used by PHP: /etc/php5/cli/php.ini

** Mandatory requirements **

OK Checking that PHP version is at least 5.3.2 (5.3.5-1ubuntu7.2 installed) OK Checking that the "date.timezone" setting is set OK Checking that app/cache/ directory is writable ...

Dependencies are defined in the deps file

[AsseticBundle] git=http://github.com/symfony/AsseticBundle.git target=/bundles/Symfony/Bundle/AsseticBundle version=v1.0.0RC2

Now you could just use the web dirstuff in your regular web server.

However, we'll be using AppServer-in-PHP

$ pear channel-discover pear.indeyets.pp.ru $ pear install indeyets/aip

Add AiP integration as dependency

[AppServerBundle] git=http://github.com/bergie/MidgardAppServerBundle.git target=Midgard/AppServerBundle

Install with $ php bin/vendors install --reinstall

Copy aip.yaml.example fromvendor/Midgard/AppServerBundleto the app dir as aip.yaml

Add Midgard namespace to autoloader

$loader->registerNamespaces(array( ... 'Midgard' => __DIR__.'/../vendor',

Start AiP aip app app/aip.yamlGo to http://localhost:8001

Now, to write some code!

$ php app/console generate:bundle

Let Symfony2 create a Acme/ExampleBundle for you.

src/Acme/ExampleBundle

http://localhost:8001/hello/World

src/Acme/ExampleBundle/Controller/DefaultController.php

<?php namespace Acme\ExampleBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class DefaultController extends Controller { /** * @Route("/hello/{name}") * @Template() */ public function indexAction($name) { return array('name' => $name); } }

src/Acme/ExampleBundle/Resources/views/Default/index.html.twig

Hello {{ name }}!

How did this template get loaded?

/** * @Template() */ ... return array('name' => $name);

⇒ Defaults to Bundle/Resources/views/Controller/action.html.twig

We could also do:

return $this->render( 'AcmeExampleBundle:Default:index.html.twig', array('name' => $name) );

Page generation process:

1. Match the URL to a route (/hello/{name}) /hello/World ⇒ /hello/{name}2. Instantiate Controller new Acme\ExampleBundle\Controller\DefaultController3. Run action method with arguments ->indexAction('World')3. Controller returns a Response Hello World!

Templating in Symfony2

Twig is the default templating engine for Symfony2

In Midgard you only define the elements you want to override

In Twig you define a new root element that inherits and thenoverrides.

src/Acme/ExampleBundle/Resources/views/Default/index.html.twig

{% extends 'AcmeDemoBundle::layout.html.twig' %}

{% block content %} Hello {{ name }}! {% endblock %}

http://localhost:8001/hello/World

You can also use other templating enginesTAL, PHP, MidCOM, ...

http://symfony.com/doc/2.0/cookbook/templating/PHP.html

Exercise:

Create your own base layout templateMake the route's template inherit that

Routing in Symfony2

Registering routes with PHP

app/config/routing.yml

AcmeExampleBundle: resource: "@AcmeExampleBundle/Controller/" type: annotation prefix: /

In Controller action methods:

/** * @Route("/hello/{name}") */

Registering routes with YAML

AcmeExampleBundle: resource: "@AcmeExampleBundle/Resources/config/routing.yml" prefix: /example

src/Acme/ExampleBundle/Resources/config/routing.yml

hello_user: pattern: /hello/{name} defaults: { _controller: AcmeExampleBundle:Default:index}

(format is NamespaceBundle:Controller:action)

$ php app/console router:debug

[router] Current routes Name Method Pattern _welcome ANY / _demo_login ANY /demo/secured/login _security_check ANY /demo/secured/login_check _demo_logout ANY /demo/secured/logout ... _configurator_final ANY /_configurator/final acme_example_default_index ANY /example/hello/{name}

Supporting other output formats

/** * @Route("/hello/{name}.{_format}", defaults={"_format"="html"}) */

http://localhost:8001/hello/World andhttp://localhost:8001/hello/World.htmlwill both work

src/Acme/ExampleBundle/Resources/views/Default/index.json.twig

{% set arr = { 'name': name } %} {{ arr | json_encode | raw }}

http://localhost:8001/hello/World.json

Exercise:

Create two routes• One with no parameters• One with two parameters• Provide a default value for parameter

Using Midgard inside Symfony2

Add Midgard ConnectionBundle as dependency

[MidgardConnectionBundle] git=git://github.com/bergie/MidgardConnectionBundle.git target=Midgard/ConnectionBundle

Install with $ php bin/vendors install

Enable in app/AppKernel.php

$bundles = array( ... new Midgard\ConnectionBundle\MidgardConnectionBundle() );

Configure Midgard connection

app/config/config.yml

midgard_connection: type: SQLite name: midgard2 databasedir: "%kernel.root_dir%" logfile: "%kernel.root_dir%/logs/midgard2.log" loglevel: debug blobdir: "%kernel.root_dir%/blobs" sharedir: "/usr/share/midgard2"

Now you can create a database

$ php app/console midgard:connection:init

Using Midgard in controllers

src/Acme/ExampleBundle/Controller/DefaultController.php

/** * @Route("/hello/{name}.{_format}", defaults={"_format"="html"}) * @Template() */ public function indexAction($name) { $qb = new \midgard_query_builder('midgard_person'); $qb->add_constraint('firstname', '=', 'Midgard'); $persons = $qb->execute(); return array('name' => $persons[0]->firstname); }

Hello, Midgard!

Exercise:

Create a route displaying all personobjects in the Midgard database

MidCOM components inside Symfony2

Warning: Here be Dragons

Add Midgard MidcomCompatBundle as dependency

[MidcomCompatBundle] git=git://github.com/bergie/MidgardMidcomCompatBundle.git target=Midgard/MidcomCompatBundle

Install with $ php bin/vendors install

Enable in app/AppKernel.php

$bundles = array( ... new Midgard\MidcomCompatBundle\MidgardMidcomCompatBundle() );

Install Flack's version of MidCOM

$ git clone https://github.com/flack/openpsa.git

Copy schemas from openpsa/schemas to MgdSchema dir

app/config/config.yml

midgard_midcom_compat: root: "%kernel.root_dir%/../openpsa/lib"

framework: templating: { engines: ['twig', 'midcom'] }

Run $ php app/console midgard:connection:init

Enable component in app/AppKernel.php

$bundles = array( ... new Midgard\MidcomCompatBundle\Bundle\ComponentBundle( 'net.nehmer.blog') );

Add a component to routing configuration:

NetNehmerBlog: resource: "net.nehmer.blog" type: midcom prefix: /blog

http://localhost:8001/blog/

Loading a layout for your MidCOM views

app/config/config.yml

midgard_midcom_compat: layout: "MidgardMidcomCompatBundle::layout.html.twig"

Some areas to follow:

• Symfony CMF: node-based routing, etc• PHPCR: standard content repository APIs• MidCOM and Midgard MVC compat work

Photos:http://www.flickr.com/photos/bfs_man/4939624151/http://www.flickr.com/photos/jeremyhiebert/5105804864/http://www.flickr.com/photos/donkeyhotey/5527263186/http://www.flickr.com/photos/eustaquio/2750429774/http://www.flickr.com/photos/hatwar/5022365448/http://www.flickr.com/photos/jordanfischer/72510316/http://www.flickr.com/photos/bellatrix6/130907944/

Inspiration:http://www.slideshare.net/weaverryan/handson-with-the-symfony2-framework