PHPCR: Quick overview Store content in a tree of nodes Each node has a name and a type Nodes can have children Nodes can have properties with values A value can be almost anything
Best of both worlds RDBMS Transactions Query Structure Integrity Filesystem Binary Hierarchy Locking Access Control And more Unstructured Versioning Full-Text Multi-value
Example < j c r : r o o t > < c m s > < p a g e s > < h o m e t i t l e = " H o m e p a g e " > < b l o c k t i t l e = " N e w s " c o n t e n t = " T o d a y : S y m f o n y C M F p r e s e n t a t i o n " / > < / h o m e > < c o n t a c t t i t l e = " C o n t a c t " c o n t e n t = " s y m f o n y - c m f - d e v s @ g o o g l e g r o u p s . c o m " / > < / p a g e s > < / c m s > < / j c r : r o o t > Node home Path: /cms/pages/home Parent: /cms/pages Name: home
Article.php MyController.php < ? p h p c l a s s A r t i c l e i m p l e m e n t s P u b l i s h a b l e I n t e r f a c e , P u b l i s h T i m e P e r i o d I n t e r f a c e { / * * @ v a r \ D a t e T i m e * / p r i v a t e $ i s P u b l i s h a b l e ; p u b l i c f u n c t i o n i s P u b l i s h a b l e ( ) { r e t u r n $ t h i s - > i s P u b l i s h a b l e ; } } < ? p h p / / c h e c k i f c u r r e n t u s e r i s a l l o w e d t o s e e t h i s d o c u m e n t $ p w c = $ c o n t a i n e r - > g e t ( ' c m f _ c o r e . p u b l i s h _ w o r k f l o w . c h e c k e r ' ) ; i f ( ! $ p w c - > i s G r a n t e d ( P u b l i s h W o r k f l o w C h e c k e r : : V I E W _ A T T R I B U T E , $ d o c u m e n t ) ) { / / f . e . r e d i r e c t t o 4 0 4 } Most of the time, this is handled by the RequestListener
CoreBundle Templating { % f o r n e w s I t e m i n c m f _ c h i l d r e n ( p a g e ) | r e v e r s e % } < l i > < a h r e f = " { { p a t h ( n e w s I t e m ) } } " > { { n e w s I t e m . t i t l e } } < / a > ( { { n e w s I t e m . p u b l i s h S t a r t D a t e | d a t e ( ' Y - m - d ' ) } } ) < / l i > { % e n d f o r % }
Routing + RoutingBundle Extends Symfony Routing Component Introduces ChainRouter Has the possibility to load routes from the database Bundle simply integrates the component
RouteContentEnhancer When the found route is an instance of RouteObjectInterface < ? p h p c l a s s R o u t e i m p l e m e n t s R o u t e O b j e c t I n t e r f a c e { } Set's the contentDocument in the route < ? p h p $ r o u t e - > g e t C o n t e n t ( ) ; ? >
FieldMapEnhancer Sets a value in the route, based on a hashmap < ? p h p u s e S y m f o n y \ C m f \ C o m p o n e n t \ R o u t i n g \ E n h a n c e r \ F i e l d M a p E n h a n c e r ; $ h a s h M a p = a r r a y ( ' f o o ' = > ' 0 1 0 P H P ' ) ; $ e n h a n c e r = n e w F i e l d M a p E n h a n c e r ( ' b a r ' , ' t i t l e ' , $ h a s h M a p ) ; Imagine a Route, that has a property bar with value foo After the enhancer is applied, the route will also have a property title with value 010PHP
BlockBundle Available types StringBlock SimpleBlock ContainerBlock ReferenceBlock ActionBlock RssBlock ImagineBlock SlideshowBlock Very easy to create your own block
CreateBundle Integrates CreateJS and CreatePHP into Symfony2 Uses RDFa meta-data (like Doctrine's mapping) Support for CKEditor and Hallo.js Twig example { % c r e a t e p h p p a g e a s = " r d f " n o a u t o t a g % } < d i v { { c r e a t e p h p _ a t t r i b u t e s ( r d f ) } } > < h 1 c l a s s = " m y - t i t l e " { { c r e a t e p h p _ a t t r i b u t e s ( r d f . t i t l e ) } } > { { c r e a t e p h p _ c o n t e n t ( r d f . t i t l e ) } } < / h 1 > < d i v { { c r e a t e p h p _ a t t r i b u t e s ( r d f . b o d y ) } } > { { c r e a t e p h p _ c o n t e n t ( r d f . b o d y ) } } < / d i v > < / d i v > { % e n d c r e a t e p h p % }
MediaBundle Basic documents Controllers for showing and downloading Helper for uploading Adapters for 3rd-party integration LiipImagine elFinder Gaufrette