An entity is a basic class that holds data, here is how you would create a simple Car class
// src/My/HelloBundle/Entity/Car.php
namespace My\HelloBundle\Entity;
class Car
{
protected $id;
protected $model;
protected $color;
protected $year;
}
This class doesn't persist to a database, it doesn't do CRUD operations, if you wan to let Doctrine do that here is the way to create this entity:
php app/console doctrine:generate:entity --entity="MyHelloBundle:Car"
Create all fields with their types (interget,string,smallint,datetime,etc...)
And answer:
Do you want to generate empty repository class? yes
The primary key id will be added by default
use Doctrine\ORM\Mapping as ORM;
/**
* My\HelloBundle\Entity\Car
*
* @ORM\Table()
* @ORM\Entity
*/
class Car
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $model
*
* @ORM\Column(name="model", type="string", length=255)
*/
private $model;
/**
* @var string $color
*
* @ORM\Column(name="color", type="string", length=255)
*/
private $color;
/**
* @var integer $year
*
* @ORM\Column(name="year", type="integer")
*/
private $year;
/**
* Get id
*
* @return integer */
public function getId()
{
return $this->id;
}
// All the getters and setters ...
}
You can launch php app/console doctrine:generate:entity --entity="MyHelloBundle:Car" and anwser all the questions to add the fields
But this class is not linked to any database table, so change * @ORM\Table() by * @ORM\Table(name="car") which is the table name, if you don't do that the table name will be picked up from the class name.
Create a table with Doctrine
To print the sql query without executing it
php app/console doctrine:schema:update --dump -sql
To force the update and execute it
php app/console doctrine:schema:update --force
This command is very powerful because is going to create/update your database based on the mapping information of your entities
Persisting objects to the database
Or how to save an entity to the database, to do so add a method inside a Controller
// src/My/HelloBundle/Controller/DefaultController.php
use My\HelloBundle\Entity\Car;
/**
* @Route("/test/", name="test")
*/
public function testAction()
{
$car = new Car();
$car->setModel("Ford");
$car->setColor("White");
$car->setYear("2010");
$em = $this->getDoctrine()->getEntityManager();
$em->persist($car);
$em->flush();
print 'Created car id '.$car->getId();
exit();
}
Then browse to /app_dev.php/test and you will see: Created car id 1
Get an object from the database
Let's say that you need to find a car in your database, usually you will do it with a query like "SELECT * FROM car WHERE id=1. Where are going to fetch a car object based on its id
Create a method show Action in the controller
/**
* @Route("/show/", name="show")
*/
public function showAction()
{
$id=1;
$car = $this->getDoctrine()
->getRepository('MyHelloBundle:Car')
->find($id);
if (!$car)
{
throw $this->createNotFoundException('No car found for id '.$id);
}
print 'Car model: '.$car->getModel();
exit();
}
A repository is a PHP class that will fetch entities and store queries related to an entity, to find all cars int the table
$car = $this->getDoctrine()
->getRepository('MyHelloBundle:Car')
->findAll();
Create a Custom Repository Class
For the entity "Car" a repository class will have more complex query method inside, for example the method: findAllOrderedByName.
The repository class extends from the EntityRepository class we are going to use annotation to create, first, modify the annontation method Entity in the class "Car"
* @ORM\Entity(repositoryClass="My\HelloBundle\Repository\CarRepository")
Then let Doctrine generate the repository for you:
php app/console doctrine:generate:entities My/HelloBundle/Entity/Car
// src/MyHelloBundle/Repository/CarRepository.php
namespace My\HelloBundle\Repository;
use Doctrine\ORM\EntityRepository;
class CarRepository extends EntityRepository
{
// Define custom methods here
}
Create the Entity Manager
Entity Managers will help us to format data before passing it to controllers and call methods from the Repository.
We will create this manager with a basic method to persist objects in the database:
// Base class manager
namespace My\HelloBundle\Manager;
abstract class BaseManager
{
protected function persistAndFlush($entity)
{
$this->em->persist($entity);
$this->em->flush();
}
}
// Car manager class
namespace My\HelloBundle\Manager;
use Doctrine\ORM\EntityManager;
use My\HelloBundle\Manager\BaseManager;
use My\HelloBundle\Entity\Car;
class CarManager extends BaseManager
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function loadCar($carId) {
return $this->getRepository()
->findOneBy(array('id' => $carId));
}
/**
* Save Car entity
*
* @param Car $car
*/
public function saveCar(Car $car)
{
$this->persistAndFlush($car);
}
public function getPreviousCar($carId) {
return $this->getRepository()
->getAdjacentCar($carId, false)
->getQuery()
->setMaxResults(1)
->getOneOrNullResult();
}
public function getNextCar($carId) {
return $this->getRepository()
->getAdjacentCar($carId, true)
->getQuery()
->setMaxResults(1)
->getOneOrNullResult();
}
public function isAuthorized(Car $car, $memberId)
{
return ($car->getMember()->getId() == $memberId) ?
true:
false;
}
public function getPreviousAndNextCar($car)
{
return array(
'prev' => $this->getPreviousCar($car->getId()),
'car' => $car,
'next' => $this->getNextCar($car->getId())
);
}
public function getRepository()
{
return $this->em->getRepository('MyHelloBundle:Car');
}
}
The Service Container in Symfony 2
Service Container is a new concept in Symfony 2. A service is a task of function with a global scope in the whole framework. All services are available via the Service Container which is an object in the core of Symfony 2.
Services will allow us to get the object responsable for the email seinding for exemple.
Let's create a service for our CarManager, to do we need to declare the service in the service XML file in the folder: My/HelloBundle/Resources/config/services.xml
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
My\HelloBundle\Manager\CarManager
Later on we can call the service from our code like this: $car = $this->get('my.car_manager')->loadCar($carId)
Dependency Injection
The main advantage of all this is flexibility, let's say that one day you want to change the Manager class to handle Cars and user a CarNewManager class instead.
All you will have to do is to change the parameter
My\HelloBundle\Manager\CarNewManager
And it will be operational right away whithout changes on the controllers or nothing.
Please read the full article here: http://symfony.com/doc/current/cookbook/bundles/extension.html