SlideShare a Scribd company logo
1 of 66
Download to read offline
Working with the admin
      generator
My background
John Cleveley
Trained as a Systems Engineer with BAE Systems
Started my own business in 2006
Created symfony apps for NHS, V&A Museum and
Hornby.
Currently work at the BBC using their Forge
platform (ZF)
Objectives

Provide information beyond the docs
Update on what’s new
Suggest a few best practices
Real world examples of customising
How to get the best from the form framework
Utilise the various ways of extending
It’s super awesome.
Saves huge amount of development time and costs
Provides most common admin requirements out of
the box
Can be extended to provide bespoke needs
Fully tested and documented
It’s free!
What’s new since 1.0?
Completely re-written for the form framework
Relationships including m2m work without
configuration
Generator.yml is validated
Batch actions (delete)
Less reliance on generator.yml (DRY)
More templates and actions to override
Different configuration for the edit and new form
Adds a REST route for your module
New PHP configuration file
Configure generator via PHP to be more dynamic:
lib/newsGeneratorConfiguration.class.php

The generated class in the cache lists functions
cache/backend/dev/modules/autoNews/lib/BaseNe
wsGeneratorConfiguration.class.php

You can also mix configuration between the two
New helper file
      Provides html snippets for action links
      lib/[module]GeneratorHelper.class.php
getUrlForAction ()
linkToDelete ()
linkToEdit ()
linkToList ()
linkToNew ()
linkToSave ()
linkToSaveAndAdd ()



    Create custom links with extra javascript etc
Your thoughts?




PHP!               YAML!
Is it the right tool?



               …maybe.
Think requirements!




Don’t jump to use the admin generator
Analyse what’s needed first
A bespoke solution may be more appropriate
Misusing the admin generator could cause big
problems in the future
How do we decide?
Admin                           Bespoke
  Normal CRUD operations          Public interface to data
  Non – technical users           Sophisticated sorting
  need to add data                and searching of data
  Trusted site administrators
  Ownership of all records


        The admin site can take you a long way….
        …. But be careful it doesn’t become a mess.
admin
The 10 Commandments
10 Commandments (1-5)
1. Understand the client’s workflow and customise
   admin to suit
2. Think about security from the start
3. Look through and understand the cached php
   files
4. Change table_method to reduce db calls
5. Use bespoke Form class for admin if different
10 Commandments (6-10)
6. Keep all form form configuration in the Form Class
7. If you need to make changes to multiple admin
   modules – create a theme.
8. Think about small screens and target browser
9. Create functional tests – guard against regression
10. Maintain good MVC and decoupling practices
What’s the object-oriented way
    to become wealthy?
           Inheritance!
John’s Top tips!
1. The URL
  Clients don’t like using:
application.com/admin.php

         Option 1:
  application.com/admin

        Option 2:
  admin.application.com
1. The URL: /admin
Modify web/.htaccess
 RewriteCond %{REQUEST_URI} ^/admin/?
 RewriteRule ^(.*)$ admin.php [QSA,L]

 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php [QSA,L]

Change all your standard routes – routing.yml
  homepage:
      url:   /admin
      param: { module: default, action: index }
  test:
      url: /admin/test
      ...
1. The URL: /admin
Change your route collections – routing.yml

  prefix_path:   /admin/module_name



Remove script name in urls – settings.yml

  prod:
     .settings:
        no_script_name:   true
1. The URL: admin.app
Create a new virtual host in httpd.conf
   <VirtualHost *:80>
     ServerName admin.application.com
     DirectoryIndex admin.php
     DocumentRoot "/path/to/web/folder"
     <Directory "/path/to/web/folder">
       AllowOverride All
       Allow from All
     </Directory>
   </VirtualHost>

Tell symfony not to output admin.php in urls
   Prod
     .settings:
        no_script_name:   true
2. Dynamic MaxPerPage
    Add a select box within the _list_header.php
                                            js onchange
                                            submits to action


    Add an action to set a user attribute
public function executeChangeMaxPage(sfWebRequest $request){

    $this->getUser()->setAttribute('maxPage',
       $request->getParameter('maxPage'));

    $this->redirect($request->getReferer());
}
2. Dynamic MaxPerPage

    Override getPagerMaxPerPage()

class employeeGeneratorConfiguration extends BaseEmployee
{
  public function getPagerMaxPerPage()
  {
    $maxPage = sfContext::getInstance()->getUser()
            ->getAttribute('maxPage', 10);
    return $maxPage;
  }
}
3. Adding relations
Fewest clicks for common tasks
Relevant data placed together
Currently unsupported by the generator
Symfony provides functions to help
  sfForm : : mergeForm()
  sfForm : : embedForm()
  sfFormDoctrine : : embedRelation()
Employee has many phones
Employee:                    Phone:
  columns:                     columns:
    id:                          id:
      type: integer(4)              type: integer(4)
      primary: true                 primary: true
      autoincrement: true           autoincrement: true
    name:                        number:
      type: string(255)             type: string(255)
      notnull: true                 notnull: true
  relations:                     employee_id:
    Phones:                         type: integer(4)
      type: many                    notnull: true
      class: Phone               type:
      local: id                     type: enum
      foreign: employee_id          values: [mobile, home, work]
      onDelete: CASCADE
3. Adding relations
Add ability to edit existing phone numbers from
within employee form

Embed the ‘Phones’ relation in EmployeeForm::configure

   class EmployeeForm extends BaseEmployeeForm
   {
     public function configure()
     {
       $this->embedRelation('Phones');
     }
   }
Hide employee_id in PhoneForm::configure()
class PhoneForm extends BasePhoneForm
{
  public function configure()
  {
    $this->widgetSchema['employee_id'] =
      new sfWidgetFormInputHidden();
  ...




                                      No Delete?
                                      No Add?
There’s a symfony plugin for that!
 Thanks to ahDoctrineEasyEmbeddedRelationsPlugin by
 Daniel Lohse
4. Translate admin interface
  Add chosen culture to settings.yml
.all:
  .settings:
    i18n: on
    default_culture: fr




  ./symfony cc and delete browser cookies
4. Translate admin interface
Create a new startrek catalogue

Add vulcan XLIFF files to:
   apps/admin/il8n/
    • startrek.vu.xml
    • startrek_forms.vu.xml
4. Translate admin interface
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN"
"http://www.oasis-
open.org/committees/xliff/documents/xliff.dtd" >
<xliff version="1.0">
  <file original="global" source-language="en" target-
language="vu_VU" datatype="plaintext">
    <header />
    <body>
      <!-- Actions -->
      <trans-unit>
        <source>New</source>
                               startrek.vu.xml
        <target>Uzh</target>
      </trans-unit>
      <trans-unit>
        <source>Edit</source>
        <target>Ver-tor</target>
      </trans-unit>
...
4. Translate admin interface
  Tell admin generator to use alternative catalogue
           generator:
             class: sfDoctrineGenerator
             param:
               i18n_catalogue: startrek

  Tell the forms as well – sfFormDoctrine::setup()
abstract class BaseFormDoctrine extends sfFormDoctrine
{
  public function setup()
  {
    $this->widgetSchema->getFormFormatter()
       ->setTranslationCatalogue('startrek_forms');
  }
}
5. Tidy up filters
Filters work great – but the default style is a bit off




A few CSS tweaks
#sf_admin_container #sf_admin_bar   {
   float:none;
   margin-left: 0px;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tr {
   clear: none;
   border: 1px solid #DDD;
   padding: 0px;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tr td {
   height: 50px;
   vertical-align: middle;
   border: none;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tbody {
   clear: none;
   float: left;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tbody tr {
   float: left;
   border-right: none;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tfoot {
   clear: none;
   float: right;
}
#sf_admin_container #sf_admin_bar   .sf_admin_filter table tfoot tr {
   float: right;
}
                                              Thanks to Sebastien
What is the definition of
     programmer?

Programmers are machines that turn
        coffee into code.
6. Timestampable fields
   Generally don’t need to edit these



   Simply unset them in form class
class NewsForm extends BaseNewsForm
{
  public function configure()
  {
    unset($this['created_at'], $this['updated_at']);
  }
}
6. Timestampable fields
What if you still need to see the value?
6. Timestampable fields
         Use sfWidgetFormPlain widget
    http://trac.symfony-project.org/attachment/ticket/7963/sfWidgetPlain.diff


public function configure()
{
 $this->setWidget('created_at',
   new sfWidgetFormPlain(array('value'=>$this->getObject()->created_at)));

unset($this->validatorSchema['created_at']);

$this->setWidget('updated_at',
  new sfWidgetFormPlain(array('value'=>$this->getObject()->updated_at)));

 unset($this->validatorSchema['updated_at']);
...



                                                            Thanks to Stephen.Ostrow
7. Pre-filter list
7. Pre-filter list
        Add an object action to generator.yml
list:
  object_actions:
    _edit:        ~
    viewPhones:   { label: Phone numbers, action: viewPhones }


        Set filter atribute in user session
class employeeActions extends autoEmployeeActions
{
   public function executeViewPhones($request){

         $this->getUser()->setAttribute(
            'phone.filters',
            array('employee_id' => $request->getParameter('id')),
            'admin_module'
            );
         $this->redirect($this->generateUrl('phone'));
    }
}
8. Row level ownership
Only allow owners of objects access
Example presumes:
  sfGuard plugin is installed
  Objects have a user_id field fk
8. Row level ownership
Secure the list page - moduleActions::buildquery()

protected function buildQuery(){

    $query = parent::buildQuery();

    $query->andWhere(
     'user_id = ?', $this->getUser()->getId()
    );

    return $query;
}                            This belongs in the model!!
8. Row level ownership
        Secure all other actions - moduleActions::preExecute()
public function preExecute(){

    if($this->getActionName()!= 'new' &&
                       $this->getActionName()!= 'index'){

        $this->forward404Unless(

          $this->getUser()->isOwner($this->getRoute()->getObject())

        );
    }

    parent::preExecute();
}
8. Row level ownership
    Add a new method to user class - myUser::isOwner()

class myUser extends sfGuardSecurityUser
{
  public function isOwner($obj){

        if(is_object($obj)){

          if($this->getId() == $obj->getUserId()) return true;

        }
        return false;
    }
}
8. Row level ownership
What about the user_id field in the form?
  Don’t want users to change owner
  Also be careful with injected data
8. Row level ownership
   We need to remove the widget - Form::configure()
           public function configure()
             {
               unset($this['user_id']);
             ...

   Set the user_id manually – Form::doUpdateObject()
public function doUpdateObject($values){

        $userId = sfContext::getInstance()->getUser()->getId();
        $this->getObject()->setUserId($userId);

        return parent::doUpdateObject($values);
    }
                               eatmymonkeydust.com
9. Custom filters
Find out who has a birthday today
Add the new filter name to generator.yml
filter:
  display: [ name, birthday_today ]
  fields:
    birthday_today:
      help: Employees who have a birthday today!




                           Based on info from Tomasz Ducin and dlepage
9. Custom filters
Create a new widget in - xxFormFilter::configure()
public function configure()
{
  $this->widgetSchema['birthday_today'] =
    new sfWidgetFormInputCheckbox();

    $this->validatorSchema['birthday_today'] =
      new sfValidatorPass();
}

Filter form is now displayed
9. Custom filters
      Add a add*ColumnQuery to FormFilter class

public function addBirthdayTodayColumnQuery($query,$field,$value)
{
  if($value){
    $query->andWhere("SUBSTRING(`birthday`, 6, 5)
                    = SUBSTRING(NOW(), 6, 5)");
  }

return $query;
}


      Now buy the presents!
Plugins
sfAdminDashPlugin
     Kevin Bond
            Joomla style admin
            Adds a dashboard
            Configurable admin
            navigation

            Replaces the admin css
            Manually add header
            component and footer
            partial to layout
sfAdminThemejRollerPlugin
       Gerald Estadieu
                 Looks stunning
                 jQuery
                 Theme roller system
                 Popup filters
                 Tabs in edit view

                 Completely new admin
                 theme
Optimist : The glass is half full.
Pessimist : The glass is half empty..
  Coder: The glass is twice as big as it needs
                     to be
Extending Methods

What degree of customisation do you need?
Will you need to re-use the functionality?
Extending - CSS
Define an alternative CSS
     generator:
          class: sfDoctrineGenerator
          param:
            model_class:           News
            theme:                 admin
            non_verbose_templates: true
            with_show:             false
            singular:              ~
            plural:                ~
            route_prefix:          news
            with_doctrine_route:   1
            css:                   funkystyle
Extending - Override code
Override individual templates and actions
Quick and easy
Can’t be re-used between modules
Can become untidy
Extending – Create a theme
More work upfront
Can be used for multiple modules / projects
Much more scope for customising
Steep learning curve – PHP in PHP!
Extending – Create a theme
     Create container folder for new theme
    mkdir -p data/generator/sfDoctrineModule/newtheme




    Copy the generator files from sfDoctrine plugin
cp -r lib/vendor/symfony/lib/plugins/

→ sfDoctrinePlugin/data/generator/sfDoctrineModule/admin/*

→   data/generator/sfDoctrineModule/newtheme/
Extending – Create a theme
      Name of theme

             Parts – Snippets of code
             included into cache

             Skeleton – copied to admin
             module

                Templates – generated into
                cache
Extending – Create a theme
Change theme name in generator.yml
    generator:
      class: sfDoctrineGenerator
      param:
        model_class:           News
        theme:                 newtheme
    ...


Clear cache

You’ve made your own theme!
Extending – Admin events
admin.pre_execute: Notified before any action is
executed.
admin.build_criteria: Filters the Criteria used for the
list view.
admin.save_object: Notified just after an object is
saved.
admin.delete_object: Notified just before an object
will be deleted.
So, what does…


                 …do?
Dashboard




Show
related
models
Object history



Delete related
objects
warning
Future….
What do you want the admin generator to do?
What should the scope of the generator be?

Better support for embedded forms?
More customisable list view (sfGrid)?
Fulltext search in the fields?
Saving goes back to list view?
Dashboard?
Nested sets? Ordering?
Inherit from multiple themes?
Thanks for listening!
   Twitter: @jcleveley

More Related Content

What's hot

Forms, Getting Your Money's Worth
Forms, Getting Your Money's WorthForms, Getting Your Money's Worth
Forms, Getting Your Money's WorthAlex Gaynor
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindiaComplaints
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3Javier Eguiluz
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-searchRazvan Raducanu, PhD
 
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Antonio Peric-Mazar
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2RORLAB
 
Custom post-framworks
Custom post-framworksCustom post-framworks
Custom post-framworksKiera Howe
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your AppLuca Mearelli
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyAlessandro Cucci
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Edureka!
 
WordPress plugin #2
WordPress plugin #2WordPress plugin #2
WordPress plugin #2giwoolee
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkDirk Haun
 
Custom Signals for Uncoupled Design
Custom Signals for Uncoupled DesignCustom Signals for Uncoupled Design
Custom Signals for Uncoupled Designecomsmith
 

What's hot (20)

Forms, Getting Your Money's Worth
Forms, Getting Your Money's WorthForms, Getting Your Money's Worth
Forms, Getting Your Money's Worth
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3
 
CRUD with Dojo
CRUD with DojoCRUD with Dojo
CRUD with Dojo
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search15.exemplu complet eloquent view add-edit-delete-search
15.exemplu complet eloquent view add-edit-delete-search
 
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2Getting started with Rails (2), Season 2
Getting started with Rails (2), Season 2
 
Custom post-framworks
Custom post-framworksCustom post-framworks
Custom post-framworks
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Wheels
WheelsWheels
Wheels
 
Rest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemyRest API using Flask & SqlAlchemy
Rest API using Flask & SqlAlchemy
 
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
 
Apache Click
Apache ClickApache Click
Apache Click
 
WordPress plugin #2
WordPress plugin #2WordPress plugin #2
WordPress plugin #2
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Custom Signals for Uncoupled Design
Custom Signals for Uncoupled DesignCustom Signals for Uncoupled Design
Custom Signals for Uncoupled Design
 

Viewers also liked

Plano de Estudo para o TRE-SP (Técnico Judiciário)
Plano de Estudo para o TRE-SP (Técnico Judiciário)Plano de Estudo para o TRE-SP (Técnico Judiciário)
Plano de Estudo para o TRE-SP (Técnico Judiciário)Ricardo Torques
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Have you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentHave you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentMike Taylor
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsBartosz Kosarzycki
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreRyan Weaver
 
Git-flow workflow and pull-requests
Git-flow workflow and pull-requestsGit-flow workflow and pull-requests
Git-flow workflow and pull-requestsBartosz Kosarzycki
 
Weaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryWeaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryAlexander Lisachenko
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Ryan Weaver
 
Plano de Estudos para o XIX Exame da OAB
Plano de Estudos para o XIX Exame da OABPlano de Estudos para o XIX Exame da OAB
Plano de Estudos para o XIX Exame da OABRicardo Torques
 
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)Ricardo Torques
 
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)Ricardo Torques
 
Comentários à prova de Pessoas com Deficiência - TRT 11ª Região
Comentários à prova de Pessoas com Deficiência - TRT 11ª RegiãoComentários à prova de Pessoas com Deficiência - TRT 11ª Região
Comentários à prova de Pessoas com Deficiência - TRT 11ª RegiãoRicardo Torques
 
Event management system
Event management systemEvent management system
Event management systemD Yogendra Rao
 
Tabela Editais FCC de Raciocínio Lógico e Matemática
Tabela Editais FCC de Raciocínio Lógico e MatemáticaTabela Editais FCC de Raciocínio Lógico e Matemática
Tabela Editais FCC de Raciocínio Lógico e MatemáticaEstratégia Concursos
 

Viewers also liked (20)

Plano de Estudos para Concurso INSS
Plano de Estudos para Concurso INSSPlano de Estudos para Concurso INSS
Plano de Estudos para Concurso INSS
 
Plano de Estudo para o TRE-SP (Técnico Judiciário)
Plano de Estudo para o TRE-SP (Técnico Judiciário)Plano de Estudo para o TRE-SP (Técnico Judiciário)
Plano de Estudo para o TRE-SP (Técnico Judiciário)
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Presentation1
Presentation1Presentation1
Presentation1
 
Have you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentHave you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web development
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Web based booking a car taxi5
Web based booking a car taxi5Web based booking a car taxi5
Web based booking a car taxi5
 
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and moreSymfony Guard Authentication: Fun with API Token, Social Login, JWT and more
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
 
Git-flow workflow and pull-requests
Git-flow workflow and pull-requestsGit-flow workflow and pull-requests
Git-flow workflow and pull-requests
 
Weaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryWeaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP library
 
Online event management system
Online event management systemOnline event management system
Online event management system
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
Plano de Estudos para o XIX Exame da OAB
Plano de Estudos para o XIX Exame da OABPlano de Estudos para o XIX Exame da OAB
Plano de Estudos para o XIX Exame da OAB
 
Ementas PGE-SP
Ementas PGE-SPEmentas PGE-SP
Ementas PGE-SP
 
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Administrativa)
 
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)
Plano de Estudo para o TRE-SP (Analista Judiciário - Área Judiciária)
 
Comentários à prova de Pessoas com Deficiência - TRT 11ª Região
Comentários à prova de Pessoas com Deficiência - TRT 11ª RegiãoComentários à prova de Pessoas com Deficiência - TRT 11ª Região
Comentários à prova de Pessoas com Deficiência - TRT 11ª Região
 
Event management system
Event management systemEvent management system
Event management system
 
Mprs 2017
Mprs 2017Mprs 2017
Mprs 2017
 
Tabela Editais FCC de Raciocínio Lógico e Matemática
Tabela Editais FCC de Raciocínio Lógico e MatemáticaTabela Editais FCC de Raciocínio Lógico e Matemática
Tabela Editais FCC de Raciocínio Lógico e Matemática
 

Similar to Working With The Symfony Admin Generator

Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfonyFrancois Zaninotto
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction PresentationNerd Tzanetopoulos
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Hugo Hamon
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii FrameworkNoveo
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...King Foo
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Folio3 - An Introduction to PHP Yii
Folio3 - An Introduction to PHP YiiFolio3 - An Introduction to PHP Yii
Folio3 - An Introduction to PHP YiiFolio3 Software
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
WordPress basic fundamental of plugin development and creating shortcode
WordPress basic fundamental of plugin development and creating shortcodeWordPress basic fundamental of plugin development and creating shortcode
WordPress basic fundamental of plugin development and creating shortcodeRakesh Kushwaha
 
Some tips to improve developer experience with Symfony
Some tips to improve developer experience with SymfonySome tips to improve developer experience with Symfony
Some tips to improve developer experience with Symfonytyomo4ka
 
Ctools presentation
Ctools presentationCtools presentation
Ctools presentationDigitaria
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Getting started with WordPress development
Getting started with WordPress developmentGetting started with WordPress development
Getting started with WordPress developmentSteve Mortiboy
 
Codebits 2012 - Fast relational web site construction.
Codebits 2012 - Fast relational web site construction.Codebits 2012 - Fast relational web site construction.
Codebits 2012 - Fast relational web site construction.Nelson Gomes
 

Similar to Working With The Symfony Admin Generator (20)

Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction Presentation
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii Framework
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Folio3 - An Introduction to PHP Yii
Folio3 - An Introduction to PHP YiiFolio3 - An Introduction to PHP Yii
Folio3 - An Introduction to PHP Yii
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
WordPress basic fundamental of plugin development and creating shortcode
WordPress basic fundamental of plugin development and creating shortcodeWordPress basic fundamental of plugin development and creating shortcode
WordPress basic fundamental of plugin development and creating shortcode
 
Some tips to improve developer experience with Symfony
Some tips to improve developer experience with SymfonySome tips to improve developer experience with Symfony
Some tips to improve developer experience with Symfony
 
Ctools presentation
Ctools presentationCtools presentation
Ctools presentation
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Getting started with WordPress development
Getting started with WordPress developmentGetting started with WordPress development
Getting started with WordPress development
 
Codebits 2012 - Fast relational web site construction.
Codebits 2012 - Fast relational web site construction.Codebits 2012 - Fast relational web site construction.
Codebits 2012 - Fast relational web site construction.
 

Recently uploaded

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 

Recently uploaded (20)

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 

Working With The Symfony Admin Generator

  • 1. Working with the admin generator
  • 2. My background John Cleveley Trained as a Systems Engineer with BAE Systems Started my own business in 2006 Created symfony apps for NHS, V&A Museum and Hornby. Currently work at the BBC using their Forge platform (ZF)
  • 3.
  • 4. Objectives Provide information beyond the docs Update on what’s new Suggest a few best practices Real world examples of customising How to get the best from the form framework Utilise the various ways of extending
  • 5. It’s super awesome. Saves huge amount of development time and costs Provides most common admin requirements out of the box Can be extended to provide bespoke needs Fully tested and documented It’s free!
  • 6. What’s new since 1.0? Completely re-written for the form framework Relationships including m2m work without configuration Generator.yml is validated Batch actions (delete) Less reliance on generator.yml (DRY) More templates and actions to override Different configuration for the edit and new form Adds a REST route for your module
  • 7. New PHP configuration file Configure generator via PHP to be more dynamic: lib/newsGeneratorConfiguration.class.php The generated class in the cache lists functions cache/backend/dev/modules/autoNews/lib/BaseNe wsGeneratorConfiguration.class.php You can also mix configuration between the two
  • 8. New helper file Provides html snippets for action links lib/[module]GeneratorHelper.class.php getUrlForAction () linkToDelete () linkToEdit () linkToList () linkToNew () linkToSave () linkToSaveAndAdd () Create custom links with extra javascript etc
  • 10. Is it the right tool? …maybe.
  • 11. Think requirements! Don’t jump to use the admin generator Analyse what’s needed first A bespoke solution may be more appropriate Misusing the admin generator could cause big problems in the future
  • 12. How do we decide? Admin Bespoke Normal CRUD operations Public interface to data Non – technical users Sophisticated sorting need to add data and searching of data Trusted site administrators Ownership of all records The admin site can take you a long way…. …. But be careful it doesn’t become a mess.
  • 14. 10 Commandments (1-5) 1. Understand the client’s workflow and customise admin to suit 2. Think about security from the start 3. Look through and understand the cached php files 4. Change table_method to reduce db calls 5. Use bespoke Form class for admin if different
  • 15. 10 Commandments (6-10) 6. Keep all form form configuration in the Form Class 7. If you need to make changes to multiple admin modules – create a theme. 8. Think about small screens and target browser 9. Create functional tests – guard against regression 10. Maintain good MVC and decoupling practices
  • 16. What’s the object-oriented way to become wealthy? Inheritance!
  • 18. 1. The URL Clients don’t like using: application.com/admin.php Option 1: application.com/admin Option 2: admin.application.com
  • 19. 1. The URL: /admin Modify web/.htaccess RewriteCond %{REQUEST_URI} ^/admin/? RewriteRule ^(.*)$ admin.php [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] Change all your standard routes – routing.yml homepage: url: /admin param: { module: default, action: index } test: url: /admin/test ...
  • 20. 1. The URL: /admin Change your route collections – routing.yml prefix_path: /admin/module_name Remove script name in urls – settings.yml prod: .settings: no_script_name: true
  • 21. 1. The URL: admin.app Create a new virtual host in httpd.conf <VirtualHost *:80> ServerName admin.application.com DirectoryIndex admin.php DocumentRoot "/path/to/web/folder" <Directory "/path/to/web/folder"> AllowOverride All Allow from All </Directory> </VirtualHost> Tell symfony not to output admin.php in urls Prod .settings: no_script_name: true
  • 22. 2. Dynamic MaxPerPage Add a select box within the _list_header.php js onchange submits to action Add an action to set a user attribute public function executeChangeMaxPage(sfWebRequest $request){ $this->getUser()->setAttribute('maxPage', $request->getParameter('maxPage')); $this->redirect($request->getReferer()); }
  • 23. 2. Dynamic MaxPerPage Override getPagerMaxPerPage() class employeeGeneratorConfiguration extends BaseEmployee { public function getPagerMaxPerPage() { $maxPage = sfContext::getInstance()->getUser() ->getAttribute('maxPage', 10); return $maxPage; } }
  • 24. 3. Adding relations Fewest clicks for common tasks Relevant data placed together Currently unsupported by the generator Symfony provides functions to help sfForm : : mergeForm() sfForm : : embedForm() sfFormDoctrine : : embedRelation()
  • 25. Employee has many phones Employee: Phone: columns: columns: id: id: type: integer(4) type: integer(4) primary: true primary: true autoincrement: true autoincrement: true name: number: type: string(255) type: string(255) notnull: true notnull: true relations: employee_id: Phones: type: integer(4) type: many notnull: true class: Phone type: local: id type: enum foreign: employee_id values: [mobile, home, work] onDelete: CASCADE
  • 26. 3. Adding relations Add ability to edit existing phone numbers from within employee form Embed the ‘Phones’ relation in EmployeeForm::configure class EmployeeForm extends BaseEmployeeForm { public function configure() { $this->embedRelation('Phones'); } }
  • 27. Hide employee_id in PhoneForm::configure() class PhoneForm extends BasePhoneForm { public function configure() { $this->widgetSchema['employee_id'] = new sfWidgetFormInputHidden(); ... No Delete? No Add?
  • 28. There’s a symfony plugin for that! Thanks to ahDoctrineEasyEmbeddedRelationsPlugin by Daniel Lohse
  • 29. 4. Translate admin interface Add chosen culture to settings.yml .all: .settings: i18n: on default_culture: fr ./symfony cc and delete browser cookies
  • 30. 4. Translate admin interface Create a new startrek catalogue Add vulcan XLIFF files to: apps/admin/il8n/ • startrek.vu.xml • startrek_forms.vu.xml
  • 31. 4. Translate admin interface <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis- open.org/committees/xliff/documents/xliff.dtd" > <xliff version="1.0"> <file original="global" source-language="en" target- language="vu_VU" datatype="plaintext"> <header /> <body> <!-- Actions --> <trans-unit> <source>New</source> startrek.vu.xml <target>Uzh</target> </trans-unit> <trans-unit> <source>Edit</source> <target>Ver-tor</target> </trans-unit> ...
  • 32. 4. Translate admin interface Tell admin generator to use alternative catalogue generator: class: sfDoctrineGenerator param: i18n_catalogue: startrek Tell the forms as well – sfFormDoctrine::setup() abstract class BaseFormDoctrine extends sfFormDoctrine { public function setup() { $this->widgetSchema->getFormFormatter() ->setTranslationCatalogue('startrek_forms'); } }
  • 33. 5. Tidy up filters Filters work great – but the default style is a bit off A few CSS tweaks
  • 34. #sf_admin_container #sf_admin_bar { float:none; margin-left: 0px; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tr { clear: none; border: 1px solid #DDD; padding: 0px; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tr td { height: 50px; vertical-align: middle; border: none; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tbody { clear: none; float: left; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tbody tr { float: left; border-right: none; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tfoot { clear: none; float: right; } #sf_admin_container #sf_admin_bar .sf_admin_filter table tfoot tr { float: right; } Thanks to Sebastien
  • 35. What is the definition of programmer? Programmers are machines that turn coffee into code.
  • 36. 6. Timestampable fields Generally don’t need to edit these Simply unset them in form class class NewsForm extends BaseNewsForm { public function configure() { unset($this['created_at'], $this['updated_at']); } }
  • 37. 6. Timestampable fields What if you still need to see the value?
  • 38. 6. Timestampable fields Use sfWidgetFormPlain widget http://trac.symfony-project.org/attachment/ticket/7963/sfWidgetPlain.diff public function configure() { $this->setWidget('created_at', new sfWidgetFormPlain(array('value'=>$this->getObject()->created_at))); unset($this->validatorSchema['created_at']); $this->setWidget('updated_at', new sfWidgetFormPlain(array('value'=>$this->getObject()->updated_at))); unset($this->validatorSchema['updated_at']); ... Thanks to Stephen.Ostrow
  • 40. 7. Pre-filter list Add an object action to generator.yml list: object_actions: _edit: ~ viewPhones: { label: Phone numbers, action: viewPhones } Set filter atribute in user session class employeeActions extends autoEmployeeActions { public function executeViewPhones($request){ $this->getUser()->setAttribute( 'phone.filters', array('employee_id' => $request->getParameter('id')), 'admin_module' ); $this->redirect($this->generateUrl('phone')); } }
  • 41. 8. Row level ownership Only allow owners of objects access Example presumes: sfGuard plugin is installed Objects have a user_id field fk
  • 42. 8. Row level ownership Secure the list page - moduleActions::buildquery() protected function buildQuery(){ $query = parent::buildQuery(); $query->andWhere( 'user_id = ?', $this->getUser()->getId() ); return $query; } This belongs in the model!!
  • 43. 8. Row level ownership Secure all other actions - moduleActions::preExecute() public function preExecute(){ if($this->getActionName()!= 'new' && $this->getActionName()!= 'index'){ $this->forward404Unless( $this->getUser()->isOwner($this->getRoute()->getObject()) ); } parent::preExecute(); }
  • 44. 8. Row level ownership Add a new method to user class - myUser::isOwner() class myUser extends sfGuardSecurityUser { public function isOwner($obj){ if(is_object($obj)){ if($this->getId() == $obj->getUserId()) return true; } return false; } }
  • 45. 8. Row level ownership What about the user_id field in the form? Don’t want users to change owner Also be careful with injected data
  • 46. 8. Row level ownership We need to remove the widget - Form::configure() public function configure() { unset($this['user_id']); ... Set the user_id manually – Form::doUpdateObject() public function doUpdateObject($values){ $userId = sfContext::getInstance()->getUser()->getId(); $this->getObject()->setUserId($userId); return parent::doUpdateObject($values); } eatmymonkeydust.com
  • 47. 9. Custom filters Find out who has a birthday today Add the new filter name to generator.yml filter: display: [ name, birthday_today ] fields: birthday_today: help: Employees who have a birthday today! Based on info from Tomasz Ducin and dlepage
  • 48. 9. Custom filters Create a new widget in - xxFormFilter::configure() public function configure() { $this->widgetSchema['birthday_today'] = new sfWidgetFormInputCheckbox(); $this->validatorSchema['birthday_today'] = new sfValidatorPass(); } Filter form is now displayed
  • 49. 9. Custom filters Add a add*ColumnQuery to FormFilter class public function addBirthdayTodayColumnQuery($query,$field,$value) { if($value){ $query->andWhere("SUBSTRING(`birthday`, 6, 5) = SUBSTRING(NOW(), 6, 5)"); } return $query; } Now buy the presents!
  • 51. sfAdminDashPlugin Kevin Bond Joomla style admin Adds a dashboard Configurable admin navigation Replaces the admin css Manually add header component and footer partial to layout
  • 52. sfAdminThemejRollerPlugin Gerald Estadieu Looks stunning jQuery Theme roller system Popup filters Tabs in edit view Completely new admin theme
  • 53. Optimist : The glass is half full. Pessimist : The glass is half empty.. Coder: The glass is twice as big as it needs to be
  • 54. Extending Methods What degree of customisation do you need? Will you need to re-use the functionality?
  • 55. Extending - CSS Define an alternative CSS generator: class: sfDoctrineGenerator param: model_class: News theme: admin non_verbose_templates: true with_show: false singular: ~ plural: ~ route_prefix: news with_doctrine_route: 1 css: funkystyle
  • 56. Extending - Override code Override individual templates and actions Quick and easy Can’t be re-used between modules Can become untidy
  • 57. Extending – Create a theme More work upfront Can be used for multiple modules / projects Much more scope for customising Steep learning curve – PHP in PHP!
  • 58. Extending – Create a theme Create container folder for new theme mkdir -p data/generator/sfDoctrineModule/newtheme Copy the generator files from sfDoctrine plugin cp -r lib/vendor/symfony/lib/plugins/ → sfDoctrinePlugin/data/generator/sfDoctrineModule/admin/* → data/generator/sfDoctrineModule/newtheme/
  • 59. Extending – Create a theme Name of theme Parts – Snippets of code included into cache Skeleton – copied to admin module Templates – generated into cache
  • 60. Extending – Create a theme Change theme name in generator.yml generator: class: sfDoctrineGenerator param: model_class: News theme: newtheme ... Clear cache You’ve made your own theme!
  • 61. Extending – Admin events admin.pre_execute: Notified before any action is executed. admin.build_criteria: Filters the Criteria used for the list view. admin.save_object: Notified just after an object is saved. admin.delete_object: Notified just before an object will be deleted.
  • 65. Future…. What do you want the admin generator to do? What should the scope of the generator be? Better support for embedded forms? More customisable list view (sfGrid)? Fulltext search in the fields? Saving goes back to list view? Dashboard? Nested sets? Ordering? Inherit from multiple themes?
  • 66. Thanks for listening! Twitter: @jcleveley