class AppKernel extends Kernel
{
/**
* {@inheritDoc}
*/
public function __construct($environment, $debug)
{
// Set the default timezone to UTC.
date_default_timezone_set('UTC');
parent::__construct($environment, $debug);
}
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
}
return $bundles;
}
// ...
}
Symfony project structure
Symfony project structure
Symfony project structure
Symfony project structure
Symfony project structure
Development workflow
Push buttons
Write code
Click "clear cache"
git commit
Profit!
Write code
Run in dev mode
Clear prod cache (several cmds)
Build deploy snapshot
Profit!
Same kernel, different patterns
Drupal always uses View event
Symfony discourages it
Example Symfony controller
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', array(
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..'),
));
}
}
Drupal always wants a render array
Paths and routing
$module.routing.yml, or event
No path nesting
Fixed paths with aliasing
routing.[yml|xml|php], or annotation
Path nesting
Slugs
Storing data
Entities
State API
Configuration API
Key/Value
Doctrine
Or whatever you want to use
Doctrine
Stand-alone PHP project
Simple objects only
1:1 field->property
MongoDB requires ODM add-on
Drupal Entities vs Doctrine
Configuration-driven
Fields
Multi-value
Rich data types
All custom classes
Simple properties
No multi-value
Simple data types
Doctrine gotchas
Primitive data only
SQL and Mongo are different APIs
Different event listeners from Symfony
Very primitive file handling
But still many similarities!
(In Drupal 8)
Services
All meaningful logic in services
Services are stateless objects
Event listeners are just glue code
Still the same kernel
Hooks ~ Listeners
But also tagged services
Twig
(modulo template inheritance)
Go forth and make music!
Assumption: You know Drupal (version?)
Want to learn Symfony
Read the docs!
Gotchas that are different, so you know not to trip
Audience
- No expectation of UI config; all config is direct YAML.
-- parameters.yml compiled into container
-- other config is compiled out to separate PHP file from container, but one big file.
- Single dev/prod toggle.
- Enable module by editing code.
- Code scaffolding from CLI is a big thing. (Will be in D8, too.)
- Most dev tools are CLI commands.
- Sonata Admin bundle? Still not the same.
- Organic Groups: It's Not a Thing
Architecture
- No functions! (capes)
- Theme whole page at once, with one Twig template/inheritance.
- Services, shallow access.
- Always 4 ways of doing everything: YAML, XML, Annotation, PHP (at least)
-- "Drupal way" is much stricter than "Symfony way".
-- May even vary by 3rd party bundle within a single project. Stick to one for your own code.
- Metaprogramming via YAML/Annotations rather than user config. Both metaprogramming.
Extending
*- "You're supposed to hack core". (Or at least anything outside vendor.)
*- Bundles vs modules: Not huge difference.
*- AppBundle ~ custom module
- Listeners vs. Hooks
-- See KNP videos "Journey to the center of Symfony"
-- Symfony limits use of view listener; Drupal uses it heavily.
*- Composer all the things.
-- Deployment changes, need to produce prod artifact or similar.
-- Need to manually regen more (assetic, etc.). Doctrine migrations, run yourself.
-- Drupal has more tools to help here (auto-detect out of sync DB, clear cache from UI, etc.)
- Nested routes in Symfony, not in Drupal.
- No URL aliases. Use lookup slugs instead, manually.
Similarities:
- Container and services, yo!
- HttpKernel, Request/response, kernel listeners
- Twig, although used a bit differently (nesting templates)
- Hook ~ Listener
-
Data
- Doctrine
-- All entities in code
-- All fields single-value; need separate Entity for multi-value.
-- Many differences between SQL and Mongo, mostly in service names.
-- Different event listeners from core. :-(
- File handling is even more primitive than Drupal (if you believe that...)
- Something about forms? Need to use Symfony forms first...
Security
- Authentication/authorization is totally weird, hard, different.
-- Security bundle is odd, easy to get wrong.
-- See alternative: https://packagist.org/packages/knpuniversity/guard
-- security.yml: regex on path to determine needed role.
-- Recently added expressions on route def
-- Annotations on controller method (http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html)