ezpublish meets simfony2 - phpday2013
TRANSCRIPT
eZPublish meets Symfony
Gaetano Giunta | phpDay 2013 | 17.5.2013
5/17/2013 [email protected] Slide 2
Not your grandpa’s CMS
The drivers
5/17/2013 [email protected] Slide 5
Why change? The need to refactor
Existing codebase is 10 years old
High maintenance cost
Started with no unit tests - singletons everywhere
Layers and roles not properly defined / documented - interdependencies
OOP before php had
Private/protected/static
Closures
Namespaces
Late static binding
And much more
Not built for an AJAX and REST world
5/17/2013 [email protected] Slide 6
Why change? Everyone loves NEW!
Existing codebase is 10 years old
Widely deployed
Well debugged
Pitfalls have mostly been uncovered by now
Proven to scale
Well known:
Documentation improved over years
Tutorials, forums, blogs, aggregators
Active community of practitioners
Official training courses
5/17/2013 [email protected] Slide 7
Why change? Do not forget drawbacks
Focus on our core business Experience Management
Content Management
NOT Framework maintenance
Durable Architecture
API stability
Battle tested / not (only) the latest trend
Scalability
Lively Community!
5/17/2013 [email protected] Slide 8
Picking a framework for a platform rebuild
• Simple Integration with existing API
• HMVC (Hierarchical Model View Controller) stack
• Decoupled Components
• Dependency Injection
• Good Template Engine
• Extensible, Open, Reliable ;-)
5/17/2013 [email protected] Slide 9
Prerequisites
• Homebrew
• Zeta Components
• Zend Framework 2
• Symfony 2
5/17/2013 [email protected] Slide 10
Candidates
5/17/2013 [email protected] Slide 11
And the winner is… Title of presentation is a hint, really...
5/17/2013 [email protected] Slide 12
And the winner is…
5/17/2013 [email protected] Slide 13
This is eZ Publish 5!
Standard
Symfony2 App. (=app)
+ eZ Publish
bundles (PHP & REST APIs
+ Legacy)
vendor/
ezsystems/
ezpublish-kernel
+ Full-blown
Back-office
The challenge
Product Management SCRUM Story:
«As an existing user, I don’t want to be pissed off by a new
#@!$% version!»
5/17/2013 [email protected] Slide 15
Backwards compatibility (life sucks)
Product Management SCRUM Story:
«As an existing user, I don’t want to be pissed off by a new
#@!$% version!»
• 100% Data Compatible (same DB scheme)
• Possibility to include legacy templates in the new ones
• Routing fallback
• Load legacy content templates with legacy rules
• Settings
• Access Symfony services from legacy modules
5/17/2013 [email protected] Slide 16
Backwards compatibility: the objectives
Product Management SCRUM Story:
«As an existing user, I don’t want to be pissed off by a new
#@!$% version!»
• 100% Data Compatible (same DB scheme)
• Possibility to include legacy templates in the new ones
• Routing fallback
• Load legacy content templates with legacy rules
• Settings
• Access Symfony services from legacy modules
5/17/2013 [email protected] Slide 17
Backwards compatibility: the objectives
A new architecture
Product Management SCRUM Story:
«As an existing user, I don’t want to be pissed off by a new
#@!$% version!»
• 100% Data Compatible (same DB scheme)
• Possibility to include legacy templates in the new ones
• Routing fallback
• Load legacy content templates with legacy rules
• Settings
• Access Symfony services from legacy modules
Challenge Accepted 5/17/2013 [email protected] Slide 19
BC: the challenge
5/17/2013 [email protected] Slide 20
Dual-core architecture Where the magic is
Legacy version still works perfectly standalone
5/17/2013 [email protected] Slide 21
BC: icing on the cake
Taming the beast
New Core: a standard Simfony app
Legacy stack isolated in a dedicated
directory
5/17/2013 [email protected] Slide 23
Refactoring: directory layout
use Symfony\Component\HttpFoundation\Request;
require_once __DIR__ . '/../ezpublish/autoload.php'; // set up class autoloading
require_once __DIR__ . '/../ezpublish/EzPublishKernel.php';
$kernel = new EzPublishKernel( 'dev', true ); // extends the Sf Kernel class
$kernel->loadClassCache(); // a method from parent class
$request = Request::createFromGlobals();
$response = $kernel->handle( $request );
$response->send();
$kernel->terminate( $request, $response );
The Kernel class wraps the HTTPKernel
It adds a Service Container
It allows to register bundles via registerBundles()
5/17/2013 [email protected] Slide 24
The new frontend controller Using Symfony HTTP Kernel
Sandbox legacy code in a closure
Index.php had to be refactored (from 1100 lines to 20)
Logic moved to a php class
Separated environment setup from execution and teardown
runCallback() sets up the global legacy environment
5/17/2013 [email protected] Slide 25
Refactoring: bridging Legacy code
The ChainRouter from the Sf CMF project is used
5/17/2013 [email protected] Slide 26
Routing: seamless integration
eZ4 had an incomplete REST API
Only functionality available: reading content
Based on Zeta Components MVC component
A new API has been implemented
Full reading and writing of content is possible
All “dictionary” data is also available
Content-type for response can be JSON or XML (with an XSD!)
Fully restful
Usage of all HTTP verbs (and then some: PATCH)
Respect http headers of request (eg: “Accept”)
HATEOAS: use urls as resource ids
No separate request handling framework needed: pure Symfony routing
Bonus points: a client for the REST API, implements the same interfaces exposed by the local PHP API – network transparency!!!
5/17/2013 [email protected] Slide 27
REST API
An ongoing story
5/17/2013 [email protected] Slide 29
Version 5.1 is around the corner
Where to go from here
There’s a few tickets left!
Did I tell you it’s on the sea?
Want to dive in?
5/17/2013 [email protected] Slide 31
Sf2 book – jolly good looking docs:
http://symfony.com/doc/current/book/index.html
eZ Publish:
Community: http://share.ez.no
Source code: https://github.com/ezsystems
API docs: http://pubsvn.ez.no/preview.html
Slides soon on Slideshare
Contact me: @gggeek, [email protected]
THANK YOU
5/17/2013 [email protected] Slide 32
The usual suspects
5/17/2013 [email protected] Slide 33
And now for something completely different