The use of Symfony2 @ Overblog By Xavier HAUSHERR and Gérald Lonlas
The use of Symfony2 @ Overblog
By Xavier HAUSHERR and Gérald Lonlas
About Us
Xavier HAUSHERRCTO
Twitter: @xkobal
Gerald LONLASProject manager
Twitter: @geraldlonlas
What is OverBlog?
It’s also:2 millions blogs in 5 languages35 millions uniques visitors per month250 millions pages views per month13th French site audience50 servers to serve blogs
Born in 2004, OverBlog is the top leading European blogging platform.
Was the first platform to share the revenue generated by the audience.
OverBlog before Symfony 2
The previous version of OverBlog is based on:Jelix framework 1.1 CustomPHP 5.2Postgresql 8
Spread on 50 servers:1 database master 11 databases slaves38 hits and caches
OverBlog technical specifications
Capable of handling the loadBe scalableSeparate services: may be switch offReducing the pages execution timeSpeed up data accessStop with the monolithTest driven developmentTake pleasure to develop
PHP Frameworks
Jelix 1.3: Small communityProduct continuity
Zend framework 1: Not full stackNot a framework
Symfony 1: End of lifenot enough modularperformances
Full stack frameworkDependency injectionGood performancesTwig & I18NSymfony communitySensio supportTeam experience in Symfony 1
Why Symfony 2?
Young frameworkToo few bundlesStrongly coupled with DoctrineTime/cost to learn
The use of Symfony2 @ Overblog
Service Oriented Architecture
Projects Distribution
One Symfony project for each part of the platform.Each project must be independent and could be in any language
Portal
Administra-on
Users00(SSO)
Comments Core
Developer0Center Sta-s-cs
Software Used
Projects Distribution
Service Architecture
Databases
Project API
Front End Web
www InternalAPI
The use of Symfony2 @ Overblog
Transport Layer
First Try: JSON-RPC
Easy to codeREST is natively integrated into Symfony
Object must be rebuilt from JSONNo type validationNo standardNo data model
Poor performance
Some statistics about Web Services
http://jnb.ociweb.com/jnb/jnbJun2009.html
Thrif - TCompactProtocolThrift - TBinaryProtocol
Protocol BuffersRemote Method Invocation (RMI)
REST - JSONREST - XML
0 100 200 300 400 500 600 700 800 900 1000
Size (bytes)
Thrif - TCompactProtocolThrift - TBinaryProtocol
Protocol BuffersRemote Method Invocation (RMI)
REST - JSONREST - XML
0 50 100 150 200 250 300 350 400
Average Wall Time for 10000 queries (s)
Second Try: Apache ThriftDeveloped by FacebookIncubated by Apache Software Foundation
Object data modelDefinition are compiled into classes and interfacesCross languageBasic type validationBinary transferPHP extension
No Symfony integrationObsolete PHP LibrarySmall community
Client
Thrift Bundle
Service client
Controler
write () / read ()
TProtocol
TTransport
Input / output
Server
Service client
Business Service
write () / read ()
TProtocol
TTransport
Input / output
}}
Gen
erat
ed c
ode
Thrift Integration In Symfony
1. Thrift forkGive compatibility with
UniversalClassLoaderReal namespace usageRemove hardcoded inclusion
2. We create a bundle to integrate Thrift into Symfony
Dependency injection integrationDefinitions are compiled at cache warmup
in cache directoryAutoloader or Factory to instantiate object2 modes: HTTP Controller or Socket
daemonUnit Tests
3. Work with developers to integrate these modifications into the next Thrift release.
Thrift Definitionnamespace php ThriftModel.Usernamespace java com.overblog.thriftModel.user
include "Generic/Image.thrift"
exception InvalidValueException{ 1: i32 code, 2: string message}
enum Lang{ FR, EN}
struct User{ 1: i64 id, 2: string email, 3: optional string password, 4: optional Image avatar}
service UserService{ User getUserById(1: i64 id) throws (1: InvalidValueException e), bool deleteUser(1: i64 id) throws (1: InvalidValueException e)}
Thrift Integration In Symfonyservices: overblog_api.extension.user: class: OverblogUser\InternalApiBundle\Api\UserExtension arguments: [@service_container] tags: -: { name: "thrift.extension" }
overblog_thrift: services: user: definition: User namespace: ThriftModel\User bundleNameIn: OverblogCommonBundle server: true
servers: user: service: user handler: overblog_api.extension.user clients: comment: service: user type: http hosts: comment: host: 192.168.0.1 port: 8080
Thrift Integration In Symfonynamespace OverblogUser\InternalApiBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserController extends Controller{ public function getUserAction($id) { try { $p = $this->get('thrift.client.user') ->getClient() ->getUserById($id); } catch (\Exception $e) { throw $this->createNotFoundException(); } }}
Thrift Integration In Symfonynamespace OverblogUser\InternalApiBundle\Api;
use ThriftModel\User\UserIf;use Overblog\ThriftBundle\Api\Extensions\BaseExtension;
class UserExtension extends BaseExtension implements UserIf{ public function getUserById($id) { return $this->getInstance( 'ThriftModel\User\User', array( 'id' => $id, 'email' => '[email protected]', 'lang' => ThriftModel\User\Lang::FR ) ); }}
The use of Symfony2 @ Overblog
Security Bundle: Overblog SSO
Why a SSO ?
Need only one authentication for several services:
•Administration, •Comments, •Portal•Public API (Mobile app)
Session must be checked in PHP or JavascriptScalability.Must be able to kill a sessionCan be plugged with other system
SSO with Security Bundle
Use the Symfony Security LayerOne provider per serviceBundle creation to secure servicesMain entry point is located on SSOLogout disconnect from project and SSOToken definition with rights embeddedUse RememberMe functionality to have long authenticationCatch security exception to return 401 instead of redirect
User
SSO Diagram
1. User hit a protected ressource
2. User is redirected to SSO
3. User is prompted to log in
4. SSO notifies the server that access has been granted by redirecting user with token
5. User can now access the ressource
The use of Symfony2 @ Overblog
Blog themes with Twig sandbox
Blog rendering
Functional specifications:Allow the fully customization of themesFriendly meta language
Sandbox the theme executionCache pagesGood performance
Why Twig?
The markupAllow sandboxing & policiesMaking our own filtersCompiling theme markupPacked with Symfony 2
Twig usage
Twig_loader_stringNo cache
Twig_loader_stringWith cache
Sandbox configuration# Twig sandbox policy parameters sandbox_policy.tags: [if,list] sandbox_policy.filters: [capitalize, date, default, upper, lower] sandbox_policy.function: [Custom] sandbox_policy.properties: {} sandbox_policy.methods: Overblog\ThemeServiceBundle\Model\BlogInterface: - getTitle - getUrl
# Init Sandbox parameterstwig.extension.sandbox.policy: class: Twig_Sandbox_SecurityPolicy arguments: [ %sandbox_policy.tags%, %sandbox_policy.filters%, %sandbox_policy.methods%, %sandbox_policy.properties%, %sandbox_policy.function% ]
# Enable Twig Sandbox extensiontwig.extension.sandbox: class: Twig_Extension_Sandbox arguments: [@twig.extension.sandbox.policy, false]
Evaluate Twig markup
$source = '<html>.....</html>';
require_once '/path/to/lib/Twig/Autoloader.php';Twig_Autoloader::register();
$loader = new Twig_Loader_String();$twig = new Twig_Environment($loader, array( 'cache' => false,));
$sandboxExtension = new Twig_Extension_Sandbox();$sandboxExtension->enableSandbox();$twig->addExtension($sandboxExtension);
try{ // Evaluate theme with Twig Sandbox $twig->loadTemplate($source)->render( $this->getMockParams() );}catch (Twig_Sandbox_SecurityError $e){ throw new \Exception('Syntax not allowed');}
The use of Symfony2 @ Overblog
Internationalization
Internationalization
OverBlog is ported in 5 languagesEnglish, French, Spanish, Italian, German
Our best comboXLIFF format.Pootle opensource tool
XLIFF markup
<trans-unit id="january" approved="yes"> <source>january</source> <target state="translated">January</target></trans-unit>
XLIFF generated by Pootle
Thanks for your time
Questions?
Take some time to create your blog on en.over-blog.com
Links
Thrift fork: https://github.com/ebuzzing/thrift
Thrift bundle: https://github.com/ebuzzing/OverblogThriftBundle
JIRA: https://issues.apache.org/jira/browse/THRIFT-1615
Pootle: http://translate.sourceforge.net/wiki/pootle/index