SlideShare a Scribd company logo
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
Symfony2 for Midgard Developers
Symfony2 for Midgard Developers
Symfony2 for Midgard Developers
Under MIT License
Copyright (c) 2004-2011 Fabien Potencier
Permission 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 following
conditions:
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 OR
OTHER DEALINGS IN THE SOFTWARE.
Symfony 2.0 was released on July 28 2011
Symfony2 for Midgard Developers
Symfony2 is a collection of standalone PHP components
bundled 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 change
any of these to another implementation
<?php
 $this->container->get('security.context')->isGranted(
  'READ', $object)

The actual service checking this could be
MidCOM-style ACL, or simple "allow authenticated
users to do anything" check.
PHP 5.3 and namespaces
Midgard MVC & MidCOM

<?php
class example_mycomponent_controllers_some
{

Symfony2

<?php
namespace ExampleMyBundleController;
use SymfonyFrameworkWebBundleController;
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
Symfony2 for Midgard Developers
$ 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 dir
stuff 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 from
vendor/Midgard/AppServerBundle
to the app dir as aip.yaml
Add Midgard namespace to autoloader

$loader->registerNamespaces(array(
  ...
  'Midgard'      => __DIR__.'/../vendor',
Start AiP aip app app/aip.yaml
Go 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 AcmeExampleBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;
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 AcmeExampleBundleControllerDefaultController
3. 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
Symfony2 for Midgard Developers
Symfony2 for Midgard Developers
In Midgard you only define the elements you want to override

In Twig you define a new root element that inherits and then
overrides.
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 engines
TAL, PHP, MidCOM, ...

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

Create your own base layout template
Make 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 and
http://localhost:8001/hello/World.html
will 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 MidgardConnectionBundleMidgardConnectionBundle()
);
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 person
objects 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 MidgardMidcomCompatBundleMidgardMidcomCompatBundle()
);
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 MidgardMidcomCompatBundleBundleComponentBundle(
      '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

More Related Content

Symfony2 for Midgard Developers