Dieses Blog durchsuchen

Sonntag, 17. Juli 2016

symfony 3: use custom repositories instead of entities

Its allways a good idea, not to use entitiyobject like $user= new User();

Symfony allows to implement the repositorypattern. Its well documented and a good way, to extend the entities without to couple the entityclass and the manager

In the next example I want to show you not only to implement the repository. I have implemented an AbstractRepository and a repositoryInterface too to setup an extendable abstract repositorymechanismto


1) first thing to do is creating a folder "Entities" in your Bundle
2) Save a File called "UserRepository.php"
3) Save a FIle EntityRepositoryAbstract.php
4) Save a File IEntityRepository.php

My abstract repository implements 2 methods to make saving objects easier, when requests come from an api controller

<?php
/**
* Created by PhpStorm.
* User: root
* Date: 17.07.16
* Time: 07:49
*/
namespace Check\BlogBundle\Repositories;
use Check\BlogBundle\Entity\IEntity;
use Doctrine\ORM\EntityRepository;
/**
* Class EntityRepositoryAbstract
* @package Check\BlogBundle\Repositories
*/
class EntityRepositoryAbstract extends EntityRepository implements IEntityRepository
{
/**
* @param IEntity $entity
* @param array $data
* @return array
*/
public function save(IEntity $entity, $data = array())
{
try
{
$properties = $this->getProperties($entity);
foreach ($properties as $propertyName)
{
if (property_exists($data, $propertyName))
{
$setter = 'set' . ucfirst($propertyName);
$entity->{$setter}($data->{$propertyName});
}
}
$response = $this->_em->persist($entity);
$this->_em->flush();
}
catch (\Exception $e)
{
return array('error' => $e->getMessage(), 'code'=>$e->getCode());
}
return array('success'=>array('id'=>$entity->getId()));
}
/**
* @param IEntity $entity
* @return mixed
*/
public function getProperties(IEntity $entity)
{
$metadata = $this->_em->getClassMetadata(get_class($entity));
$properties = [];
foreach ($metadata->fieldMappings as $name=>$value)
{
$properties[] = $name;
}
return $properties;
}
}
At next we implement the interface:
<?php
/**
* Created by PhpStorm.
* User: root
* Date: 17.07.16
* Time: 07:57
*/
namespace Check\BlogBundle\Repositories;
use Check\BlogBundle\Entity\IEntity;
interface IEntityRepository {
/**
* @param IEntity $entity
* @return mixed
*/
public function getProperties(IEntity $entity)
public function save(IEntity $entity, $data = array());
}

At next we implement a UserRepository. This Class is empty for now. Because the current save implementation can be used abstract
<?php
/**
* Created by PhpStorm.
* User: root
* Date: 17.07.16
* Time: 07:49
*/
namespace Check\BlogBundle\Repositories;
class UserRepository extends EntityRepositoryAbstract
{
}
To make this work, we have to tell the entity, that it has to use our new repositories. This can be done by setting the right annotations.
Here is my entityclas. As you can see we have extended the Anntotation ORM\ENTITY with the link to our new repository
* @ORM\Entity(repositoryClass="Check\BlogBundle\Repositories\UserRepository")
<?php
namespace Check\BlogBundle\Entity;
use Check\BlogBundle\Repositories\UserRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* User
* @ORM\Entity(repositoryClass="Check\BlogBundle\Repositories\UserRepository")
* @ORM\Table(name="user", uniqueConstraints={@ORM\UniqueConstraint(name="UNIQ_8D93D649F85E0677", columns={"username"})})
*/
class User extends BaseEntity implements IEntity
{
/**
* @var string
*
* @ORM\Column(name="username", type="string", length=255, nullable=false)
*/
private $username;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255, nullable=false)
*/
private $email;
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=255, nullable=false)
*/
private $password;
/**
* @var string
*
* @ORM\Column(name="firstname", type="string", length=255, nullable=false)
*/
private $firstname;
/**
* @var string
*
* @ORM\Column(name="lastname", type="string", length=255, nullable=false)
*/
private $lastname;
/**
* @var string
*
* @ORM\Column(name="created", type="string", length=255, nullable=false)
*/
private $created;
/**
* @var string
*
* @ORM\Column(name="updated", type="string", length=255, nullable=false)
*/
private $updated;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* Set username
*
* @param string $username
*
* @return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set email
*
* @param string $email
*
* @return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set password
*
* @param string $password
*
* @return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set firstname
*
* @param string $firstname
*
* @return User
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* @return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* @param string $lastname
*
* @return User
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* @return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set created
*
* @param string $created
*
* @return User
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* @return string
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated
*
* @param string $updated
*
* @return User
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* @return string
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
view raw User.php hosted with ❤ by GitHub

At next you have to delete all genereated .orm files under src//Resoucres/config/doctrine and clear your appcache,otherwise it want work.
At last we can use our new UserRepository like that in a controller. This apicontroller takes a request and saves the body as a new user directly via calling a save() method in our new repository
<?php
/**
* Created by PhpStorm.
* User: root
* Date: 16.07.16
* Time: 15:34
*/
namespace AppBundle\Controller\Api;
use Check\BlogBundle\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class UserController extends Controller
{
/**
* @Route("/api/user")
* @Method("POST")
*/
public function newAction(Request $request)
{
try
{
$data = json_decode($request->getContent());
$user = new User();
$em = $this->getDoctrine()->getManager();
$className = get_class($user);
$response = $em->getRepository($className)->save($user, $data);
}
catch (Exception $e)
{
return new Response($e->getMessage());
}
return new Response(json_encode($response));
}
}

Keine Kommentare:

Kommentar veröffentlichen