Symfony Internals
diving into symfony's guts
About me
Zend Certified Engineer
Developer at Sensio Labs Vice-President of AFSY (French Symfony User Group) Co-author of "More with symfony"
As you can see, I love bermudas
http://twitter.com/ubermuda (mostly in french sorry)
More with symfony?
Yes, I wrote the Symfony Internals chapter
Don't worry if you read it already
There's new material here
Introduction
The symfony framework
Customizable
Flexible
Extensible
Customizable
Configuration files
settings.yml
factory.yml
Hierarchical configuration
Lots of ways to handle how the framework behaves
Flexible
The framework bows to your needs
Does not enforce an ORM
Does not enforce an user management system
Does not enforce a mailer
Etc.
Extensible
You can easily add capabilities
Using plugins
Hooking up on events
Overriding entire parts of the framework
How is it achieved?
Yes, how?
The bootstrap
Retrieves the application's configuration
Instanciates sfContext
Initiates dispatching
sfContext ?
Implements the Singleton design pattern
Has its pros and cons
Mostly, cons. (testability issues, etc)
Responsible for loading factories
(We'll talk about factories later)
The application configuration
frontendConfiguration
Extends ProjectConfiguration
Shares methods
Also, constructors
Most customization usually happens in ProjectConfiguration
The project configuration
Two very important steps:
Creates an event dispatcher
Loads plugins
The event dispatcher
sfEventDispatcher
Available as a separate component
http://components.symfony-project.org/event-dispatcher/
Implements the Observer pattern
Used throughout the whole framework
The event dispatcher
Available configuration events
autoload.filter_config
Allows to customize the autoloader configuration
More events later
Plugins
Used to extend the framework capabilities
Can contain entire modules
Or just hook on some event
Or provide a specific library
Etc.
Plugins
Have their own configuration file
used to be config/config.php
Now sfMyPluginConfiguration
extends sfPluginConfiguration
sfPluginConfigurationGeneric (if none was found)
Plugins
Find plugins
http://www.symfony-project.org/plugins/
http://www.symplist.net/
More than 900 plugins available!
Write your own plugins
It's easy
Simplifies code re-use
The configuration files
settings.yml
Holds the framework settings
And there are a lot of them
Actions, security strategies, I18N, debug bar, etc
http://www.symfony-project.org/reference/1_4/en/04-Settings
The configuration files
app.yml
Application specific configuration
You decide what's in there
Project wide app.yml (config/app.yml)
Environments
Environment specific configuration
Default envs are prod, dev and test
Configuration fine-tuning
Have a different database
Use a different mailing strategy
It's all handled by a ConfigHandler
Config Handler ?
Not very well known part of symfony
Parse and translate configuration files
Each configuration file has its own handler (kinda)
sfDefineEnvironmentConfigHandler
sfDatabaseConfigHandler
sfFactoryConfigHandler
Etc.
Back to sfContext
Instanciates factories
Components that drive your application
Logger, I18N, mailer, request, response, etc.
Configured through factories.yml
Has its own ConfigHandler too!
The factories configuration
Configured per-application
In your app's config/factory.yml
Gives you control over the whole framework
Handle by sfFactoryConfigHandler
sfFactoryConfigHandler
Translates your factory.yml into executable PHP
It's all in your cache
All config handlers use the config cache
Look in your cache/ directory for more information
The factories
You can override almost every components used by symfony
There is a reference for that, of course
http://www.symfony-project.org/reference/1_4/en/05-Factories
Here be events
Events notified during the factories loading
request.filter_parameters
routing.load_configuration
context.load_factories
context.load_factories
Earliest event where access to all factories is possible
Database access anyone?
The dispatch process
and more
The front controller
sfFrontWebController implements the Front Controller pattern
http://en.wikipedia.org/wiki/Front_Controller_pattern
Grabs module and action from the request
Issues a simple forward()
sfError404Exception
Thrown if no module/action was found
Will stop symfony's workflow
Forces a redirect to configured 404 handler
sf_error_404_module
sf_error_404_action
Can be thrown from anywhere in your application
The admin generator
Well-known symfony feature
generator.yml is consumed just there
Because we need the base action classes
By its own Config Handler, of course
http://www.symfony-project.org/reference/1_4/en/06-Admin-Generator
sfGeneratorConfigHandler
Instanciates a generator
Runs it
There is no step 3
Controllers dir
You can't do much here
Except override getControllersDir()
Gives you huge control over the controllers' location
You can add any directory to the list
Or just plain replace it
The action stack
A FIFO (First In First Out) stack
Holds every action that were or will be executed
Access it through sfContext's getActionStack()
Useful to interact with the action (getActionName(), etc)
Enabling and disabling modules
Two ways of doing this
Through sf_enabled_modules, in settings.yml
Through mod_MyModule_enabled, in module.yml
The difference is how disabled modules are handled
Enabling and disabling modules
Modules disabled through settings.yml
Will cause a sfConfigurationException to be thrown
Should be used for permanently disabled modules
Enabling and disabling modules
Modules disabled through module.yml
Will redirect to the "disabled module" module
sf_module_disabled_module
sf_module_disabled_action
Should be used for temporarily disabled modules
The filter chain
and yet another design pattern
The filter chain
Implements the Chain of Responsibility pattern
http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
Configurable through filters.yml
It has a Config Handler too (sfFilterConfigHandler) :-)
Default filters configuration
Write your own filters
Extend sfFilter
Everything happens in the execute() method
Adding your own filters
It's just a matter of adding it to the filters.yml
Between security and cache, that is
Also, keep the rendering filter on top of the stack
Adding your own filters
The rendering filter
Does nothing right now
Remember, a filter can execute code
Before the rest of the stack
But also after
The security filter
First filter to actually execute code
Runs a bunch of security checks
Configured through security.yml
Checks for unauthenticated requests
Or requests with insufficient credentials
Unauthenticated requests
Redirected to the "login" page
sf_login_module
sf_login_action
Insufficient credentials
Uses the "secure" page
sf_secure_module
sf_secure_action
The cache filter
Has two bits of logic
Can prevent the rest of the chain to execute
Not very likely, though
Configures the HTTP cache headers
Fills in the cache before rendering
The execution filter
Finally! Let's get some real work done
Checks for cache
If no cache is found, executes the action
Calls the view script
The execution workflow
Quite straightforward
preExecute
execute (via sfActions' execute())
postExecute
A word on the return value
Determines what view gets executed
You already know SUCCESS
You most certainly also know NONE
You might also know ERROR
But there are more builtin types (ALERT and INPUT)
You can actually return anything you want
Handling the view
This is sfView's job
Two ways of getting a view object
Custom sfView object for a specific action
Class name from mod_module_view_class
Default is sfPHPView
sfPHPView
Loads core and standard helpers
Helper, Url, Assets, Tag and Escaping
sf_standard_helpers, in settings.yml
Executes a view script (pure PHP)
Decorates the result
Also handles some caching
sfPartialView
Responsible for rendering partials and components
Has its own logic
Handles cache for partials and components
Custom view examples
sfTwigView
Integrates the Twig template engine
http://github.com/henrikbjorn/sfTwigPlugin
sfTemplatingView
Integrates templating from the symfony components
http://www.symfony-project.org/plugins/sfTemplatingViewPlugin
The return of the rendering filter
Remember the rendering filter ?
Well it's back, and it wants to render.
Sends the response content through sfWebResponse's send method
That's all folks!
We're now ready to handle one more request
Hopefuly faster than we just did ;-)
Thank you
Hope you learned stuff!
Read the book for a more detailed (and boring) approach
http://www.symfony-project.org/more-with-symfony/1_4/en/10-Symfony-Internals
Questions?
speak slowly please
Top Related