Symfony 2 Tutorial Giuseppe Attardi Alexios Tzanetopoulos What
- Slides: 86
Symfony 2 Tutorial Giuseppe Attardi Alexios Tzanetopoulos
What is Symfony 2? l PHP Web Application Framework that provides: § Object Oriented programming style through ORM § a MVC GUI § Automatic code generation § a collection of components and third-party libraries § configuration and a "glue" library that ties all of these pieces together
Difference between Web Framework and CMS l l l A web (application) framework is a lower level, generic toolkit for the development of web applications A web application exposes its data and services to users and machines via the http protocol A CMS is one type of such applications: a system to manage content shown in websites CMS are built on top of a WAF Drupal 7 has its own CMS, Drupal 8 uses Symfony 2
Problems Solved by Symfony 2 l l l l Data persistence (via Doctrine) Security Forms Validation Templating Autoloading Logging l l l l Asset Management Routing File+Dir Traversing Translation Dependency Injection Image Manipulation Console Tasks Caching
Performance l Symfony 2. 0 is about 3 times faster than Zend Framework 1. 10, while taking up 2 times less memory
Symfony Bundles
What is Model-View. Controller? l MVC is a software architecture that separates the representation of information from the user’s interaction with it § the model represents the state of the application § a view displays a representation of the model § the controller mediates input, converting it to commands for the model or view
Interactions
Component Interactions l A controller sends commands: § to the model to perform actions that may update the model state § to the view to change the view’s presentation of the model (e. g. , by scrolling through a document). After a model update the model notifies its associated views and controllers, so that the views can produce updated output, and the controllers to change the available set of commands l A view requests from the model information needed to generate an output representation l
ORM (Object Relational Mapping) l l l A technique for converting data in a Relational DB into Objects and vice versa The program manipulates objects which are persisted typically as a row in a table and read back from the table The attributes of an object correspond to columns A table is mapped to a repository object that represent the collection of objects Queries are submitted to a repository and return a list of objects or a cursor on such list
Symfony 2 Benefits l l l A Framework simplifies development by providing structure and reusable modules Fast and less gready Allows choosing which ORM to use Web Debug Toolbar Plentiful documentation and tutorials Drupal 8 uses Symfony instead of its own framework
Cons Requires command line (troll) l Not easy to learn l
Flat PHP (blog posts page) <? php // index. php $link = mysql_connect('localhost', 'myuser', 'mypassword'); mysql_select_db('blog_db', $link); $result = mysql_query('SELECT id, title FROM post', $link); ? > <!DOCTYPE html> <html><head> <title>List of Posts</title> </head> <body> <h 1>List of Posts</h 1> <ul> <? php while ($row = mysql_fetch_assoc($result)): ? > <li><a href="/show. php? id=<? php echo $row['id'] ? >"> <? php echo $row['title'] ? > </a> </li> <? php endwhile; ? > </ul> </body> </html> <? php mysql_close($link); ? >
Result? No error-checking l Poor organization l Difficult to reuse code l
Hands on Symfony 2
st 1 step - Installation Download from http: //symfony. com/download (standard version) l Unpack folder in /var/www l Test it @ http: //localhost/Symfony/web/app_dev. php l Go to folder > cd Symfony l
Folder Structure � Symfony � app � bin � src � vendor � web � bundles �app. php �app_dev. php �config. php
2 nd step - Create Application Bundle A Symfony 2 project is made up of bundles l Create bundle: l > app/console generate: bundle --namespace=Rosi/People. Bundle --format=annotation l Generates code in directory src/Rosi/People. Bundle
Folder Structure � Entity �Person. php �Person. Repository. php �Category. php � Controller �Person. Controller. php � Form �Person. Type. php � Resources � views � Person �new. html. twig �edit. html. twig �index. html. twig Model Controller Views
Folder Structure � Resources � public � css � images � js �config �routing. yml �services. xml �validation. yml
rd 3 step - The l Data Model Edit the parameters file ; app/config/parameters. yml parameters: database_driver: pdo_mysql database_host: localhost database_name: symfony database_user: user database_password: password l Use doctrine in command line to auto-create the database in my. Sql: > app/console doctrine: database: create
rd 3 step - The Data Model Mapping to column class Person { /** @ORMColumn(name="id", type="integer") * @ORMId * @ORMGenerated. Value(strategy="AUTO") */ private $id; /** @ORMColumn(name="Name", type="string", length=30) */ public $name; /** @ORMColumn(name="room", type="string", length=30) */ public $room; … }
3 rd step - The Data Model - Repository class Person. Repository extends Entity. Repository { public function find. All. Ordered. By. Name() { return $this->get. Entity. Manager() ->create. Query( 'SELECT p FROM Person p ORDER BY p. Name ASC‘) ->get. Result(); }
rd 3 Step – Data Model - Query /** * Delete person with id $id. */ public function remove($id) { $this->create. Query. Builder('p') ->delete('Rosi. People. Bundle: Person', 'p') ->where('p. id = : id') ->set. Parameter('id', $id) ->get. Query() ->execute(); }
3 rd step - The Data Model - Associations /** * @ORMMany. To. One(target. Entity="Category", inversed. By="members") * @ORMJoin. Column(name="category_id", referenced. Column. Name="id") */ public $category; /** @ORMMany. To. One(target. Entity="Department", inversed. By="members") * @ORMJoin. Column(name="department_id", referenced. Column. Name="id") */ public $department;
3 rd step - The Data Model - Associations class Department { … /** * @ORMOne. To. Many(target. Entity="Person", mapped. By="department") */ private $members;
3 rd step - The Data Model l Doctrine generates the accessor methods: > app/console doctrine: generate: entities Rosi. People. Bundle public function get. Name() { return $this->name; }
rd 3 step - The l ORM We can ask Doctrine to create our database tables (or to update them to reflect our setup) with the command: > app/console doctrine: schema: update --force Updating database schema. . . Database schema updated successfully! "7" queries were executed
th 4 step - Initial Data > mysql –u root -p use symfony; INSERT into Category VALUES ("PO"); INSERT into Category VAUES ("PA"); INSERT into Person VALUES ("Albano", "2743"); INSERT into Person VALUES ("Attardi”, "2744");
Request Processing Request /blog/life /blog/friends /blog/about Bootstrap Kernel Controller Response /blog/{title} Blog. Controller: show. Action($title) Rendered view
th 5 Step – Generate CRUD > app/console doctrine: generate: crud --entity="Rosi. People. Bundle: Person“ --with-write l Generates controller Person. Controller that provides methods: § § § index. Action new. Action show. Action edit. Action delete. Action
Generated Person. Controller class Person. Controller extends Controller { /** @Route("/", name="dept_persona") * @Method("GET") * @Template() */ public function index. Action() { $em = $this->get. Doctrine()->get. Manager(); $repo = $em->get. Repository(‘Rosi. Bundle: Person'); $entities = $repo->find. All(); return array('entities' => $entities); }
th 6 step - The Routing Associates URLs to controller methods l Example: l ; Rosi/People. Bundle/Resource/config/routing. yml rosi_person_edit: pattern: /person/{id}/edit defaults: { _controller: Rosi. People. Bundle: Person: edit } l symfony/app. php/person/123/edit
Symfony Application Flow
Routing Annotation l Can be provided in annotation to the method /** * Displays a form to edit an existing Person entity. * * @Route("/{id}/edit", name=“rosi_person_edit") * @Method("GET") * @Template() */ public function edit. Action($id) { } l Modifying app/config/routing. yml rosi_persona: resource: "@Rosi. People. Bundle/Controller/Person. Controller. php" type: annotation
th 5 step - The l Routing Edit the rosi_person_show route from the rosi. yml file: #src/Rosi. People. Bundle/Resources/config/routing/rosi. yml rosi_person_show: pattern: /rosi/person/{id} defaults: { _controller: "Rosi. People. Bundle: Person: show" }
th 6 step - Route Debugging l See every route in your application: > app/console router: debug l Or a single route: > app/console router: debug rosi_person_show
router: debug > app/console router: debug [router] Current routes Name Method _wdt ANY rosi_people ANY people_add_person ANY people_person_delete ANY people_person_edit ANY people_person_grid ANY people_person_main ANY Scheme ANY ANY Host ANY ANY Path /_wdt/{token} /people /person/add /person/delete /person/edit/{id} /person/grid /person/main
So far? Barely written PHP code l Working web module for the job model l Ready to be tweaked and customized l Remember, no PHP code also means no bugs!
th 7 step - The l View Create the file layout. html. twig in the directory: src/Rosi/People. Bundle/Resources/views/
th 7 Step – Twig Templates l Variables: {{ var }} {{ var | upper }} {{ var | raw }} {{ object. property }} {{ true ? ‘yes’ : ‘no’ }} l Blocks {% if foo is ‘bar’ %}. . . {% else %}. . . {% endif %}
Twig Templates l Extends: {% extends "Bundle: : layout. html. twig" %} Notice: there is no PHP code in Twig l Full separation between logic and presentation l
Twig Layouts A base layout defines blocks l Each block can have a default value l {% block header %} <h 1>Welcome!</h 1> {% endblock %} header side bar content
Twig Layouts A child layout extends the parent l And overrides its blocks l {% block header %} {{ parent() }} back {% endblock %} header side bar content
th 7 step - The l View Tell Symfony to make them publicly available: > app/console assets: install web --symlink l Creates symlink: web/bundles/rosi -> src/Rosi/People. Bundle/Resources/public
th 8 step - Testing l 2 methods: Unit tests and Functional tests Unit tests verify that each method and function is working properly l Functional tests verify that the resulting application behaves correctly as a whole l
th 9 and last step - Bundles are like modules in Drupal l Even symfony 2 is a bundle itself l Many useful bundles such as l § § FOSUser. Bundle (user management) Sonata. Admin. Bundle (Admin Generator) FOSFacebook. Bundle (Integrate the Facebook) Pagefanta. Bundle (paginate)
Data. Grid with Pager. Fanta
Composer Manage bundle installation and update l Example: l § Include bundle in composer. json: "require": { "apy/datagrid-bundle": "dev-master“ § Invoke composer: > php composer. phar update apy/datagrid-bundle
Dependency Injection Aka Control Inversion l Quite simply: l § Pass an object to a class instead of letting class create its own instance l l Typically used for services. An instance of the service is supplied to an application Allows customization Typically from configuration files Increases flexibility
Services l Service § objects that provide particular functions, e. g. § DB, mailer l Configuration file: § Resources/config/services. yml l Example: doctrine: dbal: driver: host: l pdo_mysql localhost Use: $db = $this->get('doctrine');
Import from DB
Sql. Server driver ; app/config/parameters. yml parameters: database_driver: pdo_dblib database_host: 131. 114. 3. 27 database_port: null database_name: Dipartimento database_user: username database_password: password
Install driver l See https: //github. com/intellectsoft-uk/Mssql. Bundle > php composer. phar require "isoft/mssqlbundle: master-dev" > sudo apt-get install php 5 -sybase Add to vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver. Manag er. php 'pdo_dblib' => 'RealestateDBALDriverPDODblibDriver', l
Generate Bundle > app/console generate: bundle --namespace=Compass/Dip. Bundle --bundle-name=CompassDip. Bundle Fixes to Mssql. Bundle l Rename uniqueidentifier -> timestamp in: l § vendor/isoft/mssqlbundle/Realestate/Mssql. Bundle/Realestate. Mssql. Bundl e. php § vendor/isoft/mssqlbundle/Realestate/Mssql. Bundle/Types/Uniqueidentifier Type. php
Generate Classes Step 1 > app/console doctrine: mapping: import --em=compass 2 –force Compass. Dip. Bundle annotation l Step 2 > app/console doctrine: generate: entities Compass. Dip. Bundle l
CRUD for imported tables > app/console doctrine: generate: crud --entity="Compass. Dip. Bundle: Gen. Persone“ --with-write --route-prefix=/dept/person > app/console doctrine: generate: crud --entity="Compass. Dip. Bundle: Gen. Organizzazione“ --with-write --route-prefix=/dept/organization
Write Entity for Views are not imported l Write class Person, corresponding to view PTS_V_Persone. Dipartimento l
Doctrine ORM
Querying By Primary Key $user = $repo->find($id); l By Simple Conditions l $users = $repo->find(array('id' => $id)); $users = $repo->find. By(array( 'name' => $name)); l Find all $users = $repo->find. All();
Query Builder $qb = $em->create. Query. Builder(); $qb->select('u') ->from('User', 'u') ->where('u. id = : id) ->order. By('u. name', 'ASC'); $query = $qb->get. Query(); $result = $query->get. Result(); $single = $query->get. Single. Result();
Joins $query = $em->create. Query( "SELECT u FROM User u JOIN u. address a WHERE a. city = 'Berlin'"); $query = $em->create. Query( 'SELECT u FROM Forum. User u WHERE u. username = : name'); $query->set. Parameter('name', 'Bob'); $users = $query->get. Result();
Hydration The process of transforming a SQL result set into objects l Hydration modes: l § § Collection of objects Single object Nested array Set of scalar values
Result iterator l Avoid hydration of a large result set $q = $em->create. Query( 'select u from ModelUser u'); $iterable = $q->iterate(); foreach ($iterable as $row) { $user = $row[0]; $user->increase. Credit(); }
Annotations
Security /** * @extra: Route("/hello/admin/{name}") * @extra: Secure(roles="ROLE_ADMIN") * @extra: Template() */ public function helloadmin. Action($name) { return array('name' => $name); }
Caching /** * @extra: Route("/hello/{name}“) * @extra: Template() * @extra: Cache(maxage="86400") */ public function hello. Action($name) { return array('name' => $name); }
Validation Rosi. People. BundleEntityPerson: properties: name: - Length: {max: 30, max. Message: “Il nome non può superare 30 caratteri. "} - Not. Blank: {message: "Inserire il nome. "} category: - Not. Blank: {message: "Indicare una categoria. "}
Summary l l l l Generate bundle Register bundle Create model (entities, ORM) Establish routing Implement actions in controller Use Forms for interaction Use Twig for presentation
IDE l Net. Beans IDE plugin § http: //download. netbeans. org/netbeans/7. 4/final/bu ndles/netbeans-7. 4 -php-windows. exe
Embedded Forms Handle a collection objects
Bagdes
Example: Badges class Bagde { private $id; private $code; private $person; /* @ORMOne. To. Many(target. Entity="Access. Permit", mapped. By="badge", cascade={"persist", "remove"}) */ protected $permits; }
Badge Permit class Badge. Permit { private $id; /* @ORMMany. To. One(target. Entity="Badge", inversed. By="permits") @ORMJoin. Column(name="badge", referenced. Column. Name="ID") */ private $badge; /* @ORMOne. To. One(target. Entity="Access") @ORMJoin. Column(name="access", referenced. Column. Name="ID") */ private $access; private $start; }
Form for editing Badges l Problem: § User submits form, Symfony turns form data into an object § Controller action deals with the object § Easy when form corresponds to a single Entity § Fairly easy if number of items is fixed § Complicated if user is allow to add/remove items l Solution: § Modify DOM in the client adding new fields to the form § New fields must have proper names
Fields <select id="badge_permits_1_access" name="badge[permits][1][permit]"> … <select id="badge_permits_2_access" name="badge[permits][2][permit]"> …
Details j. Query(document). ready(function() { collection. Holder = $('tbody. permits: first'); // Save the last row, so that it can be replicated var last. Row = collection. Holder. children(). last(); prototype = last. Row[0]. outer. HTML; // clear fields last. Row. find('td'). not('. actions'). each(function() { $(this). html(''); }); rows = collection. Holder. find('tr. permit'). length; if (rows == 1) add. Row(); });
Prototype trick function add. Row() { // Replace '__name__' in the prototype's HTML with a progressive number var new. Row = prototype. replace(/__name__/g, rows); var last. Row = collection. Holder. children(). last(); last. Row. before(new. Row); new. Row = last. Row. prev(); // set an id = '__accesso_row_' + rows + '__'; new. Row. attr('id', id); // change action var action = new. Row. find('. actions: first'); var a = action. find('a: first'); a. attr('onclick', 'del. Row("#' + id + '"); return false; '); // replace icon, title, etc. rows++; }
Appointments
Filter data by user
Benefits l Code reduction: § From 200 lines of ASP to 30 lines
Further Reading l Manual § http: //symfony. com/doc/current/book/index. html l Tutorials § http: //tutorial. symblog. co. uk/ § http: //www. ens. ro/2012/03/21/jobeet-tutorial-withsymfony 2/ § http: //juandarodriguez. es/tutoriales/inyeccion-dedependencias-en-symfony 2/
- Gerardo attardi
- Symfony toric calculator
- Disfotopsie
- Pager fanta
- Giuseppe piperata
- Giuseppe valitutti
- Giuseppe giammanco
- Giuseppe maria garibaldi
- La traviata tesina terza media
- Mario montessori giuseppe montesano
- Bosco di courton luglio 1918
- Giuseppe piperata
- Fisica
- Giuseppe gullo
- Pier giuseppe rossi
- Giuseppe melfi
- Pier giuseppe rossi
- Giuseppe angelica
- Nabucco mappa concettuale
- Giuseppe prigiotti
- Giuseppe flavio contro apione pdf
- Giuseppe avolio
- Free car giuseppe calvanese
- Giuseppe brancatelli
- Giuseppe fiorelli pompeii excavation
- Giuseppe roncalli
- Fratelli ungaretti poesia analisi
- Giuseppe carenini
- Giuseppe de marinis
- Marco falasca
- Giuseppe gionta
- Giuseppe nardin
- Giuseppe rossi unical
- Giuseppe lo re
- Giuseppe tizza
- Giuseppe d'agostino unifi
- Giuseppe fortuna
- Giuseppe valitutti
- Giuseppe matematico logico e glottoteta piemontese
- Istituto comprensivo san giuseppe calasanzio
- Giuseppe letizia la mafia uccide solo d'estate
- Giuseppe carenini
- Scuola san giuseppe foggia
- Giuseppe verdi sävellykset
- Laura bassi giuseppe veratti
- San martino del carso mappa concettuale
- Nabucco trama breve
- Giuseppe arcimboldo biografia
- Giuseppe biondi-zoccai
- Renato cacciapuoti
- Giuseppe garibaldi biography
- Economic advance and social unrest
- Biografia di giuseppe ungaretti
- Il romanticismo musicale
- Giuseppe verdi composities
- Dr. giuseppe costa
- Giuseppe valitutti
- Giuseppe peano
- Giuseppe di guglielmo
- Bismarck and garibaldi
- Giuseppe chiumeo
- Istituto san giuseppe lugo
- Giuseppe aliperti md
- Giuseppe quaglia ey
- Giuseppe garibaldi házastárs
- Storie di giuseppe ghiberti
- Giuseppe pernigo
- Istituto mazzini napoli
- Valitutti soluzioni
- Morte alla francia italia anelia
- Istituto san giuseppe lugo
- Giuseppe arcimboldo quotes
- Tagliente giuseppe
- Giuseppe valitutti
- Giuseppe acciaro
- Scuola giuseppe grassa mazara del vallo
- Giuseppe baldacci
- Giuseppe della ricca
- Giuseppe di biase
- Significato poesia fratelli
- Giuseppe ramognino
- Camillo cavour nickname
- Giuseppe diegoli
- Parini biografia
- Giuseppe perpiglia
- Giuseppe piperata
- Breve biografia di ungaretti