$30 off During Our Annual Pro Sale. View Details »

PFZ workshopday symfony2 slides

Joshua Thijssen
May 17, 2014
58

PFZ workshopday symfony2 slides

Joshua Thijssen

May 17, 2014
Tweet

Transcript

  1. 1
    PFZ Workshopdag - 17 mei 2014
    Symfony2 Workshop

    View Slide

  2. 2
    Joshua Thijssen
    Freelance consultant, developer and trainer
    @ NoxLogic / TechAdemy
    Founder of the Dutch Web Alliance.
    Author of “Mastering the SPL Library”
    Blog: http://adayinthelifeof.nl
    Email: [email protected]
    Twitter: @jaytaph
    TechAdemy.nl

    View Slide

  3. ➡ 4 avonden (19:00 - 22:00)
    ➡ dinsdag 10 - 17 - 24 june & 1 july
    ➡ 300 euro early bird, 400 euro normaal
    ➡ https://www.eventbrite.nl/e/tickets-
    introductie-symfony2-webinar-
    nederlands-11668148747
    3
    Symfony2 introduction webinar

    View Slide

  4. Introduction
    in
    Symfony2
    4

    View Slide

  5. Downloading
    & Installing
    symfony2
    5

    View Slide

  6. 6

    View Slide

  7. $ curl -s https://getcomposer.org/installer | php
    $ php composer.phar create-project symfony/framework-
    standard-edition dir/ ~2.4
    7

    View Slide

  8. 8

    View Slide

  9. .
    !"" app
    # !"" AppCache.php
    # !"" AppKernel.php
    # !"" autoload.php
    # !"" bootstrap.php.cache
    # !"" cache
    # !"" check.php
    # !"" config
    # !"" console
    # !"" logs
    # !"" phpunit.xml.dist
    # !"" Resources
    # %"" SymfonyRequirements.php
    !"" composer.json
    !"" composer.lock
    !"" LICENSE
    !"" README.md
    !"" src
    # %"" Acme
    !"" UPGRADE.md
    !"" vendor
    # !"" autoload.php
    # !"" bin
    # !"" composer
    # !"" doctrine
    # !"" jms
    # !"" kriswallsmith
    # !"" monolog
    # !"" sensio
    # !"" swiftmailer
    # !"" symfony
    # %"" twig
    %"" web
    !"" app_dev.php
    !"" apple-touch-icon.png
    !"" app.php
    !"" bundles
    !"" config.php
    !"" favicon.ico
    %"" robots.txt
    9

    View Slide

  10. 10

    View Slide

  11. 11

    View Slide

  12. Routing
    12

    View Slide

  13. /my/url?q=a controller/action
    ?
    13

    View Slide

  14. ➡ Routing starts in app/config/routing.yml (or
    xml, or php)
    14

    View Slide

  15. # app/config/routing.yml
    blog_index:
    pattern: /blog
    defaults: { _controller: AcmeBlogBundle:Blog:index }
    15

    View Slide

  16. # app/config/routing.yml
    blog_index:
    pattern: /blog
    defaults: { _controller: AcmeBlogBundle:Blog:index }
    blog_show:
    pattern: /blog/{slug}
    defaults: { _controller: AcmeBlogBundle:Blog:show }
    16

    View Slide

  17. TWIG
    17

    View Slide

  18. namespace Noxlogic\GuestbookBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    class DefaultController extends Controller
    {
    public function indexAction($name)
    {
    return $this->render('NoxlogicGuestbookBundle:Default:index.html.twig', array('name' => $name));
    }
    }
    Template name
    Format
    Engine
    Parameters
    This template can be found at:
    /src/Noxlogic/GuestbookBundle/views/Default/index.html.twig
    18

    View Slide

  19. ➡ Output something {{ }}
    ➡ Do something {% %}
    ➡ Comments {# #}
    19

    View Slide

  20. ➡ Like most things in symfony2, don’t hardcode
    URLs.
    ➡ Use “path” and/or “url”
    20

    View Slide

  21. {% foreach user in users %}
    {{ user.name | capitalize }}
    {% endfor %}
    Go back to the homepage
    Use path() for relative URLs
    Use url() for absolute URLs
    21

    View Slide

  22. FORMS
    22

    View Slide

  23. namespace Noxlogic\GuestbookBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Noxlogic\GuestbookBundle\Form\CommentType;
    class CommentController extends Controller
    {
    public function indexAction()
    {
    $form = $this->createFormBuilder()
    ->add('name', 'text')
    ->add('email', 'email')
    ->add('comment', 'textarea')
    ->getForm();
    return $this->render('NoxlogicGuestbookBundle:Comment:index.html.twig', array('form' => $form->createView()));
    }
    }
    23

    View Slide

  24. namespace Noxlogic\GuestbookBundle\Form;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    class CommentType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $builder->add('name');
    $builder->add('email', 'email');
    $builder->add('comment', 'textarea');
    }
    public function getName()
    {
    return 'comment';
    }
    }
    src/Noxlogic/GuestbookBundle/Form/
    CommentType.php
    24
    Move the form to its own class

    View Slide

  25. namespace Noxlogic\GuestbookBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Noxlogic\GuestbookBundle\Form\CommentType;
    class CommentController extends Controller
    {
    public function indexAction()
    {
    $form = $this->createForm(new CommentType());
    return $this->render('NoxlogicGuestbookBundle:Comment:index.html.twig', array('form' => $form->createView()));
    }
    }
    src/Noxlogic/GuestbookBundle/Controller/CommentController.php
    25
    Keeps the controllers small and clean.

    View Slide

  26. 26
    http://webmozarts.com/2012/03/06/symfony2-form-architecture/
    default available in the form extension
    added by extensions

    View Slide

  27. Form validation
    27

    View Slide

  28. ➡ We can add validators to our form(entries).
    ➡ isValid() will check form values, and create
    errors which can be displayed with the
    form_errors() twig function.
    28

    View Slide

  29. namespace Noxlogic\GuestbookBundle\Form;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Validator\Constraints;
    class CommentType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $builder->add('name', 'text', array(
    'constraints' => new Constraints\NotBlank(),
    ));
    $builder->add('email', 'email');
    $builder->add('comment', 'textarea', array(
    'constraints' => array(
    new Constraints\NotBlank(),
    new Constraints\Length(array('min' => 10, 'max' => 50)),
    )
    ));
    }
    public function getName()
    {
    return 'comment';
    }
    }
    29

    View Slide

  30. ➡ NotBlank
    ➡ Blank
    ➡ NotNull
    ➡ Null
    ➡ True
    ➡ False
    ➡ Type
    ➡ Email
    ➡ MinLength
    ➡ MaxLength
    ➡ Length
    ➡ Url
    ➡ Regex
    ➡ Ip
    ➡ Max
    ➡ Min
    ➡ Range
    ➡ Date
    ➡ DateTime
    ➡ Time
    ➡ Choice
    ➡ Collection
    ➡ Count
    ➡ UniqueEntity
    ➡ Language
    ➡ Locale
    ➡ Country
    ➡ File
    ➡ Image
    ➡ Callback
    ➡ All
    ➡ UserPasswor
    d
    ➡ Valid
    30

    View Slide

  31. namespace Noxlogic\GuestbookBundle\Form;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Validator\Constraints;
    class CommentType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $builder->add('name', 'text', array(
    'constraints' => new Constraints\NotBlank(),
    ));
    $builder->add('email', 'email');
    $builder->add(‘country’, ‘country’);
    $builder->add('comment', 'textarea', array(
    'constraints' => array(
    new Constraints\NotBlank(),
    new Constraints\Length(array('min' => 10, 'max' => 50)),
    )
    ));
    }
    public function getName()
    {
    return 'comment';
    }
    }
    31

    View Slide

  32. ➡ Validations etc can be added to configuration
    to simplify things.
    ➡ Normally, validation is done on “entities”.
    32

    View Slide

  33. 33
    ➡ As with (almost) anything, you can write
    your custom validators as well.
    ➡ Check for valid customer-id, ISBN, VAT
    numbers etc..

    View Slide

  34. Using entities
    34

    View Slide

  35. ➡ Form data is usually coupled to models/
    entities
    ➡ Doctrine2, but standalone models are
    possible too.
    35

    View Slide

  36. namespace NoxLogic\GuestbookBundle\Entity;
    class Comment {
    protected $name;
    protected $email;
    protected $comment;
    // getters and setters getName(), setName() etc..
    }
    36

    View Slide

  37. namespace Noxlogic\GuestbookBundle\Controller;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Noxlogic\GuestbookBundle\Form\CommentType;
    use Noxlogic\GuestbookBundle\Entity\Comment;
    class CommentController extends Controller
    {
    public function indexAction()
    {
    $comment = new Comment();
    $form = $this->createForm(new CommentType(), $comment);
    $request = $this->getRequest();
    if ($request->getMethod() == "POST") {
    $form->handleRequest($request);
    // $comment is now filled with our form values
    if ($form->isValid()) {
    $this->get("session")->setFlash("notice", "Thank you for posting your comment!");
    $url = $this->generateUrl("noxlogic_guestbook_homepage", array("name" => $comment->getName()));
    return $this->redirect($url);
    }
    }
    return $this->render('NoxlogicGuestbookBundle:Comment:index.html.twig', array(
    'form' => $form->createView())
    );
    }
    }
    37

    View Slide

  38. Doctrine2
    38

    View Slide

  39. class User {
    protected $id;
    protected $firstname;
    protected $lastname;
    protected $email;
    protected $birthdate;
    }
    39

    View Slide

  40. use Doctrine\ORM\Mapping AS ORM;
    /** @ORM\Entity */
    class User {
    /**
    * @ORM\Id
    * @ORM\GeneratedValue
    * @ORM\Column(type=”integer”)
    */
    protected $id;
    /** @ORM\Column(type=”string”, length=25);
    protected $firstname;
    /** @ORM\Column(type=”string”, length=25);
    protected $lastname;
    /** @ORM\Column(type=”string”, length=50);
    protected $email;
    /** @ORM\Column(type=”date”);
    protected $birthdate;
    }
    40

    View Slide

  41. ➡ The entitymanager takes care of loading
    and saving your entities (through
    repositories).
    41

    View Slide

  42. public function indexAction() {
    $user = new User();
    $user->setFirstName(“John”);
    $user->setLastName(“Doe”);
    $user->setBirthdate(new \DateTime(“1 august 1980”));
    $em = $this->getDoctrine()->getManager();
    $em->persist($user);
    $em->flush();
    }
    42

    View Slide

  43. public function indexAction() {
    $user = $this->getDoctrine()
    ->getRepository(“NoxlogicBundle:User”)
    ->find(1);
    if (!$user) {
    throw new \HttpNotFoundException();
    }
    $this->render(“myview.html”, array(“user” => $user));
    }
    43

    View Slide

  44. $usersNamedJohn = $this->getDoctrine()
    ->getRepository(“NoxlogicBundle:User”)
    ->findAllByFirstName(“John”);
    $usersNamedDoe = $this->getDoctrine()
    ->getRepository(“NoxlogicBundle:User”)
    ->findAllByLastName(“Doe”);
    $em = $this->getDoctrine()->getManager();
    foreach ($usersNamedDoe as $doe) {
    $em->remove($doe);
    }
    $em->flush();
    44

    View Slide

  45. ➡ Repositories provides ways to find /
    query for your entities.
    ➡ Standard repository:
    ➡ fetchAll, fetchOne, fetchAllBy*,
    fetchOneBy*
    45

    View Slide