Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public function getConfigTreeBuilder()

$rootNode
->children()
->scalarNode("entity_class")->isRequired()->end()
->enumNode("driver")->values(array('orm', 'odm'))->isRequired()->end()
->scalarNode("model")->isRequired()->end()
->end()
;

Expand Down
9 changes: 6 additions & 3 deletions DependencyInjection/WhiteOctoberSwiftMailerDBExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ class WhiteOctoberSwiftMailerDBExtension extends Extension
*/
public function load(array $configs, ContainerBuilder $container)
{
$this->loadDriver($container, $configs[0]['driver']);
$this->setupConfiguration($configs, $container);
}

// Service config
protected function loadDriver(ContainerBuilder $container, $driver)
{
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
$loader->load($driver.'.xml');
}

/**
Expand All @@ -38,7 +41,7 @@ protected function setupConfiguration(array $configs, ContainerBuilder $containe
$configuration = new Configuration();
$config = $processor->processConfiguration($configuration, $configs);

$container->setParameter("white_october.swiftmailer_db.spool.entity_class", $config["entity_class"]);
$container->setParameter("white_october.swiftmailer_db.spool.model", $config["model"]);
}

/**
Expand Down
42 changes: 27 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
This bundle faciliates using a database to spool messages to with SwiftMailer and Symfony2.
This bundle facilitates using a database to spool messages to with SwiftMailer and Symfony2.

At present, it only works with the Doctrine EntityManager and entities managed with this.
You can choose from either Doctrine ORM or ODM (MongoDB) depending on your projects db.

Installation
============

First of all, get the bundle into your project.

**Via Composer**:
Using Composer:
-------------

1. Add the following line to your composer.json require section:

Expand All @@ -21,7 +22,8 @@ First of all, get the bundle into your project.

$ php composer.phar update whiteoctober/swiftmailerdbbundle

**Via the deps files**:
Using the deps files:
-------------------

1. Add the following lines in your ``deps`` file:

Expand All @@ -40,8 +42,11 @@ First of all, get the bundle into your project.
'WhiteOctober' => __DIR__.'/../vendor/bundles',
));

Configuration
=============

Once you've got the bundle downloaded in your Symfony project, you'll need to add it to the kernel,
and add some configuration parameters, so that it knows which entity you want to use.
and add some configuration parameters, so that it knows which entity/document you want to use.

1. Add the bundle to your application's kernel:

Expand All @@ -57,10 +62,19 @@ and add some configuration parameters, so that it knows which entity you want to

2. Configure the `white_october_swift_mailer_db` service in your config.yml:

a. Using Doctrine ORM:

white_october_swift_mailer_db:
entity_class: Full\Path\To\Mail\Entity
driver: orm
model: Full\Path\To\Email\Entity

Read below about how to construct this entity.
b. Using Doctrine ODM (MongoDB):

white_october_swift_mailer_db:
driver: odm
model: Full\Path\To\Email\Document

Read below about how to construct your entity or document class.

3. Tell SwiftMailer to use the database spooler:

Expand All @@ -70,14 +84,12 @@ and add some configuration parameters, so that it knows which entity you want to

That's it for bundle installation and configuration.

Mail entity
===========
Email Entity/Document
========================

You will need to create an entity that can be persisted and that extends from the
`EmailInterface` interface in the bundle. At the moment, the bundle expects a
property to be available on your entity called 'status', since this field is queried.
You will need to create an entity or document that can be persisted and that implements the
`EmailInterface` interface in the bundle. At the moment, the bundle expects a property to be
available on your entity or document called 'status', since this field is queried.

Once you have your entity all set up, use the full namespaced path in your `config.yml`
Once you have your entity or document all set up, use the full namespaced path in your `config.yml`
configuration as detailed above.


20 changes: 20 additions & 0 deletions Resources/config/odm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="white_october.swiftmailer_db.spool.class">WhiteOctober\SwiftMailerDBBundle\Spool\MongoDBSpool</parameter>
</parameters>

<services>
<service id="white_october.swiftmailer_db.spool" class="%white_october.swiftmailer_db.spool.class%">
<argument type="service" id="doctrine.odm.mongodb.document_manager" />
<argument>%white_october.swiftmailer_db.spool.model%</argument>
</service>

<service id="swiftmailer.spool.db" alias="white_october.swiftmailer_db.spool" />
<service id="swiftmailer.mailer.default.spool.db" alias="white_october.swiftmailer_db.spool" />
</services>

</container>
4 changes: 2 additions & 2 deletions Resources/config/services.xml → Resources/config/orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="white_october.swiftmailer_db.spool.class">WhiteOctober\SwiftMailerDBBundle\Spool\DatabaseSpool</parameter>
<parameter key="white_october.swiftmailer_db.spool.class">WhiteOctober\SwiftMailerDBBundle\Spool\ORMSpool</parameter>
</parameters>

<services>
<service id="white_october.swiftmailer_db.spool" class="%white_october.swiftmailer_db.spool.class%">
<argument type="service" id="doctrine.orm.entity_manager" />
<argument>%white_october.swiftmailer_db.spool.entity_class%</argument>
<argument>%white_october.swiftmailer_db.spool.model%</argument>
</service>

<service id="swiftmailer.spool.db" alias="white_october.swiftmailer_db.spool" />
Expand Down
120 changes: 120 additions & 0 deletions Spool/MongoDBSpool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace WhiteOctober\SwiftMailerDBBundle\Spool;

use Doctrine\ODM\MongoDB\DocumentManager;
use WhiteOctober\SwiftMailerDBBundle\EmailInterface;

class MongoDBSpool extends \Swift_ConfigurableSpool
{
/**
* @var DocumentManager
*/
protected $dm;

/**
* @var string
*/
protected $modelClass;

public function __construct(DocumentManager $dm, $modelClass)
{
$this->dm = $dm;

$obj = new $modelClass;
if (!$obj instanceof EmailInterface) {
throw new \InvalidArgumentException("The document class '{$modelClass}'' does not extend from EmailInterface");
}

$this->modelClass = $modelClass;
}

/**
* Starts this Spool mechanism.
*/
public function start()
{
}

/**
* Stops this Spool mechanism.
*/
public function stop()
{
}

/**
* Tests if this Spool mechanism has started.
*
* @return boolean
*/
public function isStarted()
{
return true;
}

/**
* Queues a message.
*
* @param \Swift_Mime_Message $message The message to store
* @return boolean Whether the operation has succeeded
* @throws \Swift_IoException if the persist fails
*/
public function queueMessage(\Swift_Mime_Message $message)
{
$mailObject = new $this->modelClass;
$mailObject->setMessage(serialize($message));
$mailObject->setStatus(EmailInterface::STATUS_READY);
try {
$this->dm->persist($mailObject);
$this->dm->flush();
} catch (\Exception $e) {
throw new \Swift_IoException("Unable to persist object for enqueuing message");
}

return true;
}

/**
* Sends messages using the given transport instance.
*
* @param \Swift_Transport $transport A transport instance
* @param string[] &$failedRecipients An array of failures by-reference
*
* @return int The number of sent emails
*/
public function flushQueue(\Swift_Transport $transport, &$failedRecipients = null)
{
if (!$transport->isStarted())
{
$transport->start();
}

$repoClass = $this->dm->getRepository($this->modelClass);
$limit = $this->getMessageLimit();
$limit = $limit > 0 ? $limit : null;
$emails = $repoClass->findBy(array("status" => EmailInterface::STATUS_READY), null, $limit);
if (!count($emails)) {
return 0;
}

$failedRecipients = (array) $failedRecipients;
$count = 0;
$time = time();
foreach ($emails as $email) {
$email->setStatus(EmailInterface::STATUS_PROCESSING);
$this->dm->flush();

$message = unserialize($email->getMessage());
$count += $transport->send($message, $failedRecipients);
$this->dm->remove($email);
$this->dm->flush();

if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) {
break;
}
}

return $count;
}
}
2 changes: 1 addition & 1 deletion Spool/DatabaseSpool.php → Spool/ORMSpool.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Doctrine\ORM\EntityManager;
use WhiteOctober\SwiftMailerDBBundle\EmailInterface;

class DatabaseSpool extends \Swift_ConfigurableSpool
class ORMSpool extends \Swift_ConfigurableSpool
{
/**
* @var EntityManager
Expand Down