Part # 11 Symfony2 How to Create a Service

How to create a service with Symfony and separate business model from Data Access Objects

[Back to Learn Symfony 2]

So many people are asking where is the model in symfony? because object persistance is the Data Access layer is not the bussiness logic model, so we are going to see how to create a service with symfony and separate the Data Access Objects from the logic Model. We are going to create a service called Sending that we can use to send campaigns to users.
We've got these items:

  • A database table called sending
  • A bundle : Acme\SendingBundle

 

1. Generate XML metadata from your table

The first step is to generate ORM metadata from our table:

CREATE TABLE IF NOT EXISTS `sending` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `campaign_name` varchar(255) NOT NULL,

  `sending_date` datetime NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDBDEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;


Import to generate xml metadata files:

php app/console doctrine:mapping:import AcmeDemoBundle xml


We'll get the file:

/src/Acme/DemoBundle/Resources/config/doctrine/Sending.orm.xml

2. Generate entities from database

We want to generate entities to handle Data Access Objects and our model will be coded in somewhere else in a different class, so:
Rename the file:

/src/Acme/DemoBundle/Resources/config/doctrine/Sending.orm.xml

to

/src/Acme/DemoBundle/Resources/config/doctrine/SendingDAO.orm.xml


Open the file and do the change marked in red:




 

   

     

   

   

   
 

Now generate the entity with getters and setters:

php app/console doctrine:generate:entities AcmeDemoBundle

This generates the object to persists inside the Entity folder, this code is automatically generated here from the xml metadata configuration file: SendingDAO.orm.xml you don't need to write or modify anything inside, if you need to do so modify the xml file and regenerate the entity:


// src/Acme/DemoBundle/Entity/SendingDAO.php

namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * Acme\DemoBundle\Entity\SendingDAO
 */
class SendingDAO
{
    /**
     * @var string $campaignName
     */
    private $campaignName;
   
/**
* @var \DateTime $sendingDate

     */
    private $sendingDate;

    /**
     * @var integer $id

     */

    private $id;
// more automatic generated code here...

 

3. Create the Model class

This model class will be our service, we can call it anything and save it almost anywhere, in this case we will do it in the Model folder so create a file here:
src/Acme/DemoBundle/Model/Sending.php

It is empty for now, we will write the code later

4. Configure a new service

Now we need to tell Symfony that there is a new service ready to be used, so open the file:

/src/Acme/DemoBundle/Resources/config/services.xml

and edit the new changes like this:



   
        Acme\DemoBundle\Model\Sending
   

   
       
        
       
   

We are injecting  Doctrine as a service to our service so we can  use Doctrine inside, so we are saying that our service Sending uses the Doctrine service.

5. Create an Extension

The extension loads the service.xml configuration file and if you created the bundle with the automatic structure option you've got nothing to do, but if you didn't here is what you should write:

// src/Acme\DemoBundle\DependencyInjection
namespace Acme\DemoBundle\DependencyInjection/AcmeDemoExtension.php;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Config\FileLocator;

class AcmeDemoExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.xml');
    }
}

 

6. Code the model logic

/**
* file: src/Acme/DemoBundle/Model/Sending.php
* Handles sending functions
*
*/


namespace Acme\DemoBundle\Model;

use Doctrine\ORM\EntityManager;
use Acme\DemoBundle\Entity\SendingDAO;

use \DateTime;

class Sending
{
protected $em;
// Doctrine service was passed as a parameter to the service, remember?
public function __construct(EntityManager $em)
{
$this->em = $em;
}

public function add()
{
// persists test
$persistObj=new SendingDAO();

$persistObj->setCampaignName("Hello world!");
$persistObj->setSendingDate(new \DateTime('now'));

$this->em->persist($persistObj);
$this->em->flush();
}

// Some more logic code here...
}

 

6. Access the service

Now the service is ready and can be accessed from the controller: 


$objSending=$this->get('acme.demo.sending');
$objSending->add();

That's it!


[Back to Learn Symfony 2]