Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Rebuilding Our Foundation
How We Used Symfony To
Rewrite Our Application
@jessicamauerhan | Symfony Live! | https://joind....
● Project History
● Problems and Goals
● Why Symfony?
● Rapid Development
of Quality Code
● Doctrine DBAL / ORM
Topics
● A...
● Learning Management System
● Content Production
● E-Commerce
● Business to Business (B2B)
Application Summary
Problematic History
● Broken Admin Panel
● No Documentation of Basic Processes
● Frontend Site Worked, Progress Stalled
● ...
Business Goals
● Add Missing Admin Panel Functionality
● Add New Features Without Breaking Existing Features
● Avoid Downt...
Technical Goals
● Maintainable Code
● Quality Code
● Documentation
● Rapid Development
● Easy Deployment
● Zero Regression...
Why Symfony?
● Community
○ Third Party Code Integration
○ Blazing Trails
○ Popularity
○ Support
Why Symfony?
● Technology & Testing
○ Dependency Injection & Decoupling
○ Unit Testing
○ Functional Testing
○ Behavior Tes...
Rapid Development of Quality Code
● Version Control: Git
● Development Workflow
Image sourced from Atlassian: https://www.atlassian.com/git/tutorials/comparing-
workflows/gitflow-workflow
Licensed under...
Rapid Development of Quality Code
● Version Control: Git
● Development Workflow: Gitflow
● Code Style Guide: PSR-2
Rapid Development of Quality Code
● Version Control: Git
● Development Workflow: Gitflow
● Code Style Guide: PSR-2
● Code ...
PHP Mess Detector
$ php composer require "phpmd/phpmd" --dev
$ php composer install --no-dev
PHP Mess Detector Rules
<?xml version="1.0"?>
<ruleset name="Code Quality"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:x...
Rapid Development of Quality Code
● Version Control
● Development Workflow: Gitflow
● Code Style Guide: PSR-2
● Code Quali...
Git Pre-Commit Code Quality Hook
#!/usr/bin/env php
<?php
require __DIR__ . '/../../vendor/autoload.php' ;
use SymfonyComp...
Git Pre-Commit Code Quality Hook
private function extractCommitedFiles()
{
$files = [];
$output = [];
exec("git diff --cac...
Git Pre-Commit Code Quality Hook
private function checkPhpMd($files)
{
$succeed = true;
foreach ($files as $file) {
$proce...
Git Pre-Commit Code Quality Hook
public function doRun(InputInterface $input,
OutputInterface $output)
{
$this->input = $i...
Rapid Development of Quality Code
● Version Control: Git
● Development Workflow: Gitflow
● Code Style Guide: PSR-2
● Code ...
Doctrine
Doctrine DBAL / ORM
● Database Abstraction Layer (DBAL)
○ Database Vendor Agnostic
○ Query Builder
● Object Relational Map...
Other Doctrine Tools
● Doctrine Migrations
● Data Fixtures Library
Introducing Automated Tests
Writing Features for Existing Code
● Write Feature
● Run Test
○ Test Passes - Double Check
○ Test Fails
■ Described Featur...
New Symfony Development
Installing Symfony Framework
Installing Symfony Framework
Merging Symfony Framework with Existing Code
● Install Separately
● Move Directories
● Combine composer.json
○ scripts
○ e...
Sonata Admin
Install Sonata Admin
$ php composer require "sonata-project/admin-bundle"
$ php composer require "sonata-project/doctrine-...
Enable Sonata Admin Bundle
//AppKernel.php
public function registerBundles ()
{
return array(
[...]
new SymfonyBundleSecur...
Configure Sonata Admin Bundle
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admi...
Sonata Admin Bundle Routing
admin:
resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin...
Configure Sonata Admin Bundle
$ php app/console assets:install web
$ php app/console cache:clear
Admin Class
<?php
namespace DemoAppBundleAdmin;
use SonataAdminBundleAdminAdmin;
use SonataAdminBundleDatagridListMapper;
...
Admin Class - Create/Edit Form
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMappe...
Admin Class - List
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMa...
Admin Class - Datagrid Filters
// Fields to be shown on filter forms
protected function configureDatagridFilters(
Datagrid...
Admin Service
# Acme/DemoBundle/Resources/config/admin.yml
services:
sonata.admin.course:
class: DemoAppBundleAdminCourseA...
Admin Services - Add to Config
# app/config/config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml ...
Done!
Optimization
Symfony Debug Toolbar
Symfony Profiler
Admin Class - Custom Query (List)
public function createQuery($context = 'list')
{
$queryBuilder = $this->getModelManager(...
Admin Class - Custom Query (Edit Page)
public function getObject($id)
{
$dql = "SELECT course, categories
FROM modelsCours...
API
Install FOS Rest Bundle
$ php composer require "friendsofsymfony/rest-bundle"
$ php composer require "jms/serializer-bundl...
Enable FOS Rest Bundle and Serializer Bundle
//AppKernel.php
public function registerBundles ()
{
return array(
[...]
new ...
Configuration
# app/config/routing.yml
NelmioApiDocBundle:
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
pr...
API Controller
<?php
use FOSRestBundleControllerFOSRestController ;
use FOSRestBundleControllerAnnotationsGet;
class Users...
Add Doc Blocks with Annotation to API Controller
/**
* @Get("/users/")
* @ApiDoc(
* resource=true,
* description="List of ...
Dependency Injection VS. Service Location
Dependency
Injection
Service
Location
Configure
Dependencies
Outside of Class
Class Requests
Dependencies
From Container
Service Location
● Messy, unclear
● Not Unit-Testable
public function getUsersAction()
{
$users = $this->getDoctrine()
->g...
Defining Services
services:
appbundle.message.factory:
class: DemoAppBundleFactoryMessageFactory
Defining Services
services:
appbundle.message.factory:
class: DemoAppBundleFactoryMessageFactory
appbundle.repositories.us...
Defining Services
services:
[...]
appbundle.command.register:
class: DemoAppBundleCommandRegisterCommand
calls:
- [ setMes...
Current Project
Status
It's stable!
● New Symfony based Admin
was complete after about 6
months (thanks developers!)
● Had...
Technical Goals
Happy Developers!
● Maintainable Code: Check
● Quality Code: Check
● Documentation: Check
● Rapid Developm...
Rebuilding Our Foundation
How We Used Symfony To
Rewrite Our Application
@jessicamauerhan | Symfony Live! | https://joind....
Resources
Gitflow: https://github.com/nvie/gitflow
PSR-2: http://www.php-fig.org/psr/psr-2/
PHPMD: http://phpmd.org/
Pre-c...
Rebuilding Our Foundation
Rebuilding Our Foundation
Upcoming SlideShare
Loading in …5
×

of

Rebuilding Our Foundation Slide 1 Rebuilding Our Foundation Slide 2 Rebuilding Our Foundation Slide 3 Rebuilding Our Foundation Slide 4 Rebuilding Our Foundation Slide 5 Rebuilding Our Foundation Slide 6 Rebuilding Our Foundation Slide 7 Rebuilding Our Foundation Slide 8 Rebuilding Our Foundation Slide 9 Rebuilding Our Foundation Slide 10 Rebuilding Our Foundation Slide 11 Rebuilding Our Foundation Slide 12 Rebuilding Our Foundation Slide 13 Rebuilding Our Foundation Slide 14 Rebuilding Our Foundation Slide 15 Rebuilding Our Foundation Slide 16 Rebuilding Our Foundation Slide 17 Rebuilding Our Foundation Slide 18 Rebuilding Our Foundation Slide 19 Rebuilding Our Foundation Slide 20 Rebuilding Our Foundation Slide 21 Rebuilding Our Foundation Slide 22 Rebuilding Our Foundation Slide 23 Rebuilding Our Foundation Slide 24 Rebuilding Our Foundation Slide 25 Rebuilding Our Foundation Slide 26 Rebuilding Our Foundation Slide 27 Rebuilding Our Foundation Slide 28 Rebuilding Our Foundation Slide 29 Rebuilding Our Foundation Slide 30 Rebuilding Our Foundation Slide 31 Rebuilding Our Foundation Slide 32 Rebuilding Our Foundation Slide 33 Rebuilding Our Foundation Slide 34 Rebuilding Our Foundation Slide 35 Rebuilding Our Foundation Slide 36 Rebuilding Our Foundation Slide 37 Rebuilding Our Foundation Slide 38 Rebuilding Our Foundation Slide 39 Rebuilding Our Foundation Slide 40 Rebuilding Our Foundation Slide 41 Rebuilding Our Foundation Slide 42 Rebuilding Our Foundation Slide 43 Rebuilding Our Foundation Slide 44 Rebuilding Our Foundation Slide 45 Rebuilding Our Foundation Slide 46 Rebuilding Our Foundation Slide 47 Rebuilding Our Foundation Slide 48 Rebuilding Our Foundation Slide 49 Rebuilding Our Foundation Slide 50 Rebuilding Our Foundation Slide 51 Rebuilding Our Foundation Slide 52 Rebuilding Our Foundation Slide 53 Rebuilding Our Foundation Slide 54 Rebuilding Our Foundation Slide 55 Rebuilding Our Foundation Slide 56 Rebuilding Our Foundation Slide 57 Rebuilding Our Foundation Slide 58 Rebuilding Our Foundation Slide 59 Rebuilding Our Foundation Slide 60 Rebuilding Our Foundation Slide 61 Rebuilding Our Foundation Slide 62 Rebuilding Our Foundation Slide 63 Rebuilding Our Foundation Slide 64 Rebuilding Our Foundation Slide 65
Upcoming SlideShare
SpecBDD in PHP
Next
Download to read offline and view in fullscreen.

Download to read offline

Rebuilding Our Foundation

Download to read offline

This talk is about how my company took a broken e-commerce and LMS site written in an older style MVC framework and re-wrote a significant portion of it in Symfony and related tools (Doctrine, FOS Bundles, Sonata) over 6 months and created a stable, well-tested application. I’ll cover the approach we took to rewriting the admin panel in Symfony, writing an API, introducing Behat and PHPUnit tests for both new and legacy code (still in a separate framework) and setting up Continuous Integration. I’ll discuss how we optimized the site as we went, by identifying weak spots in the code and how we addressed them. I’ll also cover what we would do differently now that we’ve done it once.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Rebuilding Our Foundation

  1. 1. Rebuilding Our Foundation How We Used Symfony To Rewrite Our Application @jessicamauerhan | Symfony Live! | https://joind.in/16052
  2. 2. ● Project History ● Problems and Goals ● Why Symfony? ● Rapid Development of Quality Code ● Doctrine DBAL / ORM Topics ● Automated Testing ● Sonata Admin Bundle ● Creating an API with Symfony ● Dependency Injection ● Current Project Status
  3. 3. ● Learning Management System ● Content Production ● E-Commerce ● Business to Business (B2B) Application Summary
  4. 4. Problematic History ● Broken Admin Panel ● No Documentation of Basic Processes ● Frontend Site Worked, Progress Stalled ● Complex Logic not Documented
  5. 5. Business Goals ● Add Missing Admin Panel Functionality ● Add New Features Without Breaking Existing Features ● Avoid Downtime
  6. 6. Technical Goals ● Maintainable Code ● Quality Code ● Documentation ● Rapid Development ● Easy Deployment ● Zero Regressions Per Release
  7. 7. Why Symfony? ● Community ○ Third Party Code Integration ○ Blazing Trails ○ Popularity ○ Support
  8. 8. Why Symfony? ● Technology & Testing ○ Dependency Injection & Decoupling ○ Unit Testing ○ Functional Testing ○ Behavior Testing
  9. 9. Rapid Development of Quality Code ● Version Control: Git ● Development Workflow
  10. 10. Image sourced from Atlassian: https://www.atlassian.com/git/tutorials/comparing- workflows/gitflow-workflow Licensed under the Creative Commons Attribution 2.5 Australia License.
  11. 11. Rapid Development of Quality Code ● Version Control: Git ● Development Workflow: Gitflow ● Code Style Guide: PSR-2
  12. 12. Rapid Development of Quality Code ● Version Control: Git ● Development Workflow: Gitflow ● Code Style Guide: PSR-2 ● Code Quality Rules
  13. 13. PHP Mess Detector $ php composer require "phpmd/phpmd" --dev $ php composer install --no-dev
  14. 14. PHP Mess Detector Rules <?xml version="1.0"?> <ruleset name="Code Quality" xmlns="http://pmd.sf.net/ruleset/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" xsi:noNamespaceSchemaLocation=" http://pmd.sf.net/ruleset_xml_schema.xsd"> <description>Custom Code Quality Rules</description> <!--Rulesets: http://phpmd.org/rules/index.html--> <rule ref="rulesets/cleancode.xml"/> <rule ref="rulesets/naming.xml/ShortVariable"> <properties> <property name="minimum" value="4"/> </properties> </rule> </ruleset>
  15. 15. Rapid Development of Quality Code ● Version Control ● Development Workflow: Gitflow ● Code Style Guide: PSR-2 ● Code Quality Rules: PHP Mess Detector ● Code Quality Enforcement
  16. 16. Git Pre-Commit Code Quality Hook #!/usr/bin/env php <?php require __DIR__ . '/../../vendor/autoload.php' ; use SymfonyComponentConsoleApplication; class CodeQualityTool extends Application { private $projectRoot; const PHP_FILES_IN_SRC = '/^src/(.*)(.php)$/' ; const PHP_FILES_IN_APPLICATION = '/^application/(.*)(.php)$/' ; public function __construct() { $this->projectRoot = realpath(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); parent::__construct('Code Quality Tool' , '1.0.0'); } }
  17. 17. Git Pre-Commit Code Quality Hook private function extractCommitedFiles() { $files = []; $output = []; exec("git diff --cached --name-status --diff-filter=ACM", $output); foreach ($output as $line) { $filename = trim(substr($line, 1)); $isAppFile = preg_match(self::PHP_FILES_IN_APPLICATION, $filename); $isSrcFile = preg_match(self::PHP_FILES_IN_SRC, $filename); if ($isAppFile || $isAppFile) { $files[] = $filename; } } return $files; }
  18. 18. Git Pre-Commit Code Quality Hook private function checkPhpMd($files) { $succeed = true; foreach ($files as $file) { $processArgs = ['bin/phpmd', $file, 'text', 'phpmd-rules.xml' ]; $processBuilder = new ProcessBuilder ($processArgs); $processBuilder ->setWorkingDirectory ($this->projectRoot); $process = $processBuilder ->getProcess(); $process->run(); if (!$process->isSuccessful()) { $this->output->writeln($file); $this->output->writeln('<error>'.$process->getErrorOutput (). '</error>'); $this->output->writeln('<info>'.$process->getOutput().'</info>'); $succeed = false; } } return $succeed; }
  19. 19. Git Pre-Commit Code Quality Hook public function doRun(InputInterface $input, OutputInterface $output) { $this->input = $input; $this->output = $output; $output->writeln('<info>Fetching files</info>'); $files = $this->extractCommitedFiles(); $info = '<info>Checking for messy code with PHPMD</info>'; $output->writeln($info); if (!$this->checkPhpMd($files)) { throw new Exception(sprintf('There are PHPMD violations!')); } }
  20. 20. Rapid Development of Quality Code ● Version Control: Git ● Development Workflow: Gitflow ● Code Style Guide: PSR-2 ● Code Quality Rules: PHP Mess Detector ● Code Quality Enforcement: Git Hooks
  21. 21. Doctrine
  22. 22. Doctrine DBAL / ORM ● Database Abstraction Layer (DBAL) ○ Database Vendor Agnostic ○ Query Builder ● Object Relational Mapper (ORM) ○ Maps Objects to Tables, Properties to Fields ○ Object Relationships ○ DQL - it's like SQL for your Objects
  23. 23. Other Doctrine Tools ● Doctrine Migrations ● Data Fixtures Library
  24. 24. Introducing Automated Tests
  25. 25. Writing Features for Existing Code ● Write Feature ● Run Test ○ Test Passes - Double Check ○ Test Fails ■ Described Feature Wrong ■ Mistake in Test Code ■ Feature is Broken
  26. 26. New Symfony Development
  27. 27. Installing Symfony Framework
  28. 28. Installing Symfony Framework
  29. 29. Merging Symfony Framework with Existing Code ● Install Separately ● Move Directories ● Combine composer.json ○ scripts ○ extra ○ autoload
  30. 30. Sonata Admin
  31. 31. Install Sonata Admin $ php composer require "sonata-project/admin-bundle" $ php composer require "sonata-project/doctrine-orm-admin-bundle"
  32. 32. Enable Sonata Admin Bundle //AppKernel.php public function registerBundles () { return array( [...] new SymfonyBundleSecurityBundle SecurityBundle (), new SonataCoreBundleSonataCoreBundle (), new SonataBlockBundleSonataBlockBundle (), new KnpBundleMenuBundleKnpMenuBundle(), new SonataDoctrineORMAdminBundle SonataDoctrineORMAdminBundle (), new SonataAdminBundleSonataAdminBundle () ); }
  33. 33. Configure Sonata Admin Bundle sonata_block: default_contexts: [cms] blocks: sonata.admin.block.admin_list: contexts: [admin]
  34. 34. Sonata Admin Bundle Routing admin: resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml' prefix: /admin _sonata_admin: resource: . type: sonata_admin prefix: /admin
  35. 35. Configure Sonata Admin Bundle $ php app/console assets:install web $ php app/console cache:clear
  36. 36. Admin Class <?php namespace DemoAppBundleAdmin; use SonataAdminBundleAdminAdmin; use SonataAdminBundleDatagridListMapper; use SonataAdminBundleDatagridDatagridMapper ; use SonataAdminBundleFormFormMapper; class CourseAdmin extends Admin { }
  37. 37. Admin Class - Create/Edit Form // Fields to be shown on create/edit forms protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('title', 'text', ['label' => 'Course Title']) ->add('author', 'entity', ['class' => 'DemoAppBundleEntityUser']) ->add('description', null, ['required' => false]) ->add('categories') ->add('cost'); }
  38. 38. Admin Class - List // Fields to be shown on lists protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('title') ->add('author') ->add('cost') ->add('categories'); }
  39. 39. Admin Class - Datagrid Filters // Fields to be shown on filter forms protected function configureDatagridFilters( DatagridMapper $datagridMapper) { $datagridMapper ->add('title') ->add('author') ->add('categories') ; }
  40. 40. Admin Service # Acme/DemoBundle/Resources/config/admin.yml services: sonata.admin.course: class: DemoAppBundleAdminCourseAdmin tags: - { name: sonata.admin, manager_type: orm, group: "Course Management", label: "Courses" } arguments: - ~ - DemoAppBundleEntityCourse - ~ calls: - [ setTranslationDomain, [AppBundle]]
  41. 41. Admin Services - Add to Config # app/config/config.yml imports: - { resource: parameters.yml } - { resource: security.yml } - { resource: services.yml } - { resource: @AppBundle/Resources/config/admin.yml }
  42. 42. Done!
  43. 43. Optimization
  44. 44. Symfony Debug Toolbar
  45. 45. Symfony Profiler
  46. 46. Admin Class - Custom Query (List) public function createQuery($context = 'list') { $queryBuilder = $this->getModelManager() ->getEntityManager('modelsCourse') ->createQueryBuilder(); $queryBuilder->select('course', 'categories') ->from('modelsCourse', 'course') ->leftJoin('course.categories', 'categories'); $proxyQuery = new ProxyQuery($queryBuilder); return $proxyQuery; }
  47. 47. Admin Class - Custom Query (Edit Page) public function getObject($id) { $dql = "SELECT course, categories FROM modelsCourse course LEFT JOIN course.categories categories WHERE course.id = :id"; $query = $this->getModelManager() ->getEntityManager('modelsCourse') ->createQuery($dql); $query->setParameter('id', $id); $course = $query->getOneOrNullResult(); return $course; }
  48. 48. API
  49. 49. Install FOS Rest Bundle $ php composer require "friendsofsymfony/rest-bundle" $ php composer require "jms/serializer-bundle" $ php composer require "nelmio/api-doc-bundle"
  50. 50. Enable FOS Rest Bundle and Serializer Bundle //AppKernel.php public function registerBundles () { return array( [...] new FOSRestBundleRestBundle(), new JMSSerializerBundle JMSSerializerBundle (), new NelmioApiDocBundleNelmioApiDocBundle () ); }
  51. 51. Configuration # app/config/routing.yml NelmioApiDocBundle: resource: "@NelmioApiDocBundle/Resources/config/routing.yml" prefix: /api/doc # app/config/config.yml nelmio_api_doc: ~ framework: templating: engines: ['twig']
  52. 52. API Controller <?php use FOSRestBundleControllerFOSRestController ; use FOSRestBundleControllerAnnotationsGet; class UsersController extends FOSRestController { /** @Get("/users/") */ public function getUsersAction () { $data = $this->getDoctrine()->getRepository('modelsUser')- >findAll(); $view = $this->view($data, 200) -> setTemplate("AppBundle:Basic:json.twig" ) -> setTemplateVar ('users'); return $this->handleView($view); } }
  53. 53. Add Doc Blocks with Annotation to API Controller /** * @Get("/users/") * @ApiDoc( * resource=true, * description="List of Users", * output="modelsUser" * ) */ public function getUsersAction () { $data = $this->getDoctrine()->getRepository('modelsUser')->findAll(); $view = $this->view($data, 200) -> setTemplate("AppBundle:Basic:json.twig" ) -> setTemplateVar ('users'); return $this->handleView($view); }
  54. 54. Dependency Injection VS. Service Location
  55. 55. Dependency Injection Service Location Configure Dependencies Outside of Class Class Requests Dependencies From Container
  56. 56. Service Location ● Messy, unclear ● Not Unit-Testable public function getUsersAction() { $users = $this->getDoctrine() ->getRepository('modelsUser') ->findAll(); [...] }
  57. 57. Defining Services services: appbundle.message.factory: class: DemoAppBundleFactoryMessageFactory
  58. 58. Defining Services services: appbundle.message.factory: class: DemoAppBundleFactoryMessageFactory appbundle.repositories.user: class: DemoAppBundleEntityRepositoriesUserRepository factory_service: doctrine.orm.entity_manager factory_method: getRepository arguments: - 'modelsUser'
  59. 59. Defining Services services: [...] appbundle.command.register: class: DemoAppBundleCommandRegisterCommand calls: - [ setMessageFactory, [@appbundle.message.factory]] - [ setUserRepository, [@appbundle.repositories.user]]
  60. 60. Current Project Status It's stable! ● New Symfony based Admin was complete after about 6 months (thanks developers!) ● Had a few bugs, took about 3 more months to be stable. ● Over past year, close to 0 regressions (Thanks Behat!) ● Very limited downtime (Thanks Amazon, Elastic Beanstalk!)
  61. 61. Technical Goals Happy Developers! ● Maintainable Code: Check ● Quality Code: Check ● Documentation: Check ● Rapid Development: Oh Yeah ● Easy Deployment: So Easy! ● Zero Regressions: Close Enough!
  62. 62. Rebuilding Our Foundation How We Used Symfony To Rewrite Our Application @jessicamauerhan | Symfony Live! | https://joind.in/16052
  63. 63. Resources Gitflow: https://github.com/nvie/gitflow PSR-2: http://www.php-fig.org/psr/psr-2/ PHPMD: http://phpmd.org/ Pre-commit hook: https://gist.github.com/jmauerhan/d18e7c232acb3986134d Doctrine: http://www.doctrine-project.org/ Doctrine Migrations Bundle: http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html Doctrine Data Fixtures Bundle: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html Behat: http://docs.behat.org/en/v2.5/ XDebug Wizard: http://xdebug.org/wizard.php PHP Unit Code Coverage: https://github.com/sebastianbergmann/php-code-coverage Sonata Project: https://sonata-project.org/bundles/admin/2-3/doc/index.html FOS Rest Bundle: http://symfony.com/doc/master/bundles/FOSRestBundle/index.html Nelmio API Doc Bundle: https://github.com/nelmio/NelmioApiDocBundle/blob/master/Resources/doc/index.md

This talk is about how my company took a broken e-commerce and LMS site written in an older style MVC framework and re-wrote a significant portion of it in Symfony and related tools (Doctrine, FOS Bundles, Sonata) over 6 months and created a stable, well-tested application. I’ll cover the approach we took to rewriting the admin panel in Symfony, writing an API, introducing Behat and PHPUnit tests for both new and legacy code (still in a separate framework) and setting up Continuous Integration. I’ll discuss how we optimized the site as we went, by identifying weak spots in the code and how we addressed them. I’ll also cover what we would do differently now that we’ve done it once.

Views

Total views

202

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

2

Shares

0

Comments

0

Likes

0

×