T
T
Twist2015-01-11 15:04:51
symfony
Twist, 2015-01-11 15:04:51

How do you build applications on Symfony2?

This topic has always been very interesting, let's share our experience!
For example, how do you organize thin controllers when developing regular sites?
, how do you organize thin controllers when developing a REST API sites? What project structure do you follow ? What "life hacks" can you recommend ? In the case of building "regular" sites, i.e. with twig rendering and other things, I try to leave only the handle for the form in the controller, but I'm also looking for all sorts of ways to get rid of it. I read PS best practices, watched popular bundles, but even in them very often the code does not look the most pleasant way and sometimes it seems that all the beauty of OOP sometimes passes by php PS vol. 2 if there are links to projects on git written (in your opinion) in a good style, it would be cool to post them here Added 9.2.15


In my case, when building a REST API on Symfony2, I use JMSSerializer, FOSRest, NelmioApi. In controllers, all Actions go in one line (example return $this->managerEntity->action(Entity $entity); ) In Actions, I never accept the Request $request parameter, because I usually get all the data I need in annotations and I fill the object with them. I do this using ParamConverter, QueryParam. This approach, in my opinion, gives a clearer understanding of what you have to work with. As for the managers (code example above), I have them redirecting to the service (sometimes packing data into the required formats), that is, they receive data from the controller and call the necessary services / repositories to manage or save data. Thus, I get a level of abstraction that is convenient for me, very subtle methods and quite readable code (sometimes the annotations grow, though). Also, when developing a REST API, I don’t use forms at all, the data is validated by the built-in validator from Symfony + the rules described in the entity itself



-------------------- --------------------------------
Here I will add examples of "well" written bundles / sites on Symfony2, so that take as an example
https://github.com/orocrm/platform
Added on 12.2.15
E-commerce solution build on top of symfony
https://github.com/elcodi/elcodi

Answer the question

In order to leave comments, you need to log in

4 answer(s)
T
Twist, 2015-01-13
@bboytiwst

Well, since no one writes anything interesting, I'll write it myself :) Maybe the solution is quite obvious, but I constantly see code duplicates for uploading files in Symfony2 when something complex like Gaufrette or Doctrine Uploadable is not required, you can use traits.

<?php


namespace YouBundle\Traits;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;

trait UploadTrait {

    /**
     * @Assert\File(
     * maxSize="2M",
     * mimeTypes={
     *     "image/png",
     *     "image/jpeg",
     *     "image/gif",
     *     "image/jpg"
     * }
     * )
     *
     */
    private $file;

    private $temp;

    /**
     * @return mixed
     */
    public function getFile()
    {
        return $this->file;
    }
    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file = null)
    {
        $this->file = $file;

        if (isset($this->path)) {
            $this->temp = $this->path;
            $this->path = null;
        } else {
            $this->path = 'initial';
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {

        if (null !== $this->getFile()) {

            $filename = sha1(uniqid(mt_rand(), true));
            $this->path = $filename.'.'.$this->getFile()->guessExtension();
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->getFile()) {
            return;
        }

        $this->getFile()->move($this->getUploadRootDir(), $this->path);


        if (isset($this->temp)) {

            unlink($this->getUploadRootDir().'/'.$this->temp);

            $this->temp = null;

        }
        $this->file = null;
    }

    public function getAbsolutePath()
    {
        return null === $this->path
            ? null
            : $this->getUploadRootDir().'/'.$this->path;
    }

    public function getWebPath()
    {
        return null === $this->path
            ? null
            : $this->getUploadDir().'/'.$this->path;
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }
}

and in the entity itself, you need to set the $path property
/**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $path;

and determine the folder in which we will upload all this stuff
protected function getUploadDir()
    {
        return 'images/courts/photos';
    }

PS I provide the solution as a basic one, which does not pretend to be something serious, the code is taken from the official documentation and simply wrapped in a trait that can be reused. If there is a need for improvement on the project, then I will finish it and post here also an updated version

A
Alexey Romanenko, 2015-01-15
@slimus

About thin controllers. I understood one project, there were about 50 services written for it. The controllers also turned out to be approximately one-line, but all the logic in the services was hellishly confusing. But you can understand such code, and it took me only a couple of hours to understand the naming of services and files.
Share your experience how do you build requests for api where there is sorting + pager + many filters? What logic are you taking out? What do repositories look like?
Thank you!

S
Sergey, 2015-01-28
@ta1isman

G
GrizliK1988, 2015-12-24
@GrizliK1988

In the team for the implementation of thin controllers, we use an additional BusinessCase layer, which pulls services to get the necessary data and gives it to the controller in a form ready for conversion in Respone.
I also want to note that the JMSSerializer is very slow due to the reflection used inside it. Therefore, we use our own solution (which is not yet available in open source).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question