diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 79a9cbd..6dbc413 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -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() ; diff --git a/DependencyInjection/WhiteOctoberSwiftMailerDBExtension.php b/DependencyInjection/WhiteOctoberSwiftMailerDBExtension.php index c07bcab..6c754c6 100644 --- a/DependencyInjection/WhiteOctoberSwiftMailerDBExtension.php +++ b/DependencyInjection/WhiteOctoberSwiftMailerDBExtension.php @@ -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'); } /** @@ -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"]); } /** diff --git a/README.md b/README.md index 821a0c5..9999891 100644 --- a/README.md +++ b/README.md @@ -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: @@ -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: @@ -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: @@ -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: @@ -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. - - diff --git a/Resources/config/odm.xml b/Resources/config/odm.xml new file mode 100644 index 0000000..fefcfb0 --- /dev/null +++ b/Resources/config/odm.xml @@ -0,0 +1,20 @@ + + + + + WhiteOctober\SwiftMailerDBBundle\Spool\MongoDBSpool + + + + + + %white_october.swiftmailer_db.spool.model% + + + + + + + diff --git a/Resources/config/services.xml b/Resources/config/orm.xml similarity index 84% rename from Resources/config/services.xml rename to Resources/config/orm.xml index 9ae728f..6c5826b 100644 --- a/Resources/config/services.xml +++ b/Resources/config/orm.xml @@ -4,13 +4,13 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - WhiteOctober\SwiftMailerDBBundle\Spool\DatabaseSpool + WhiteOctober\SwiftMailerDBBundle\Spool\ORMSpool - %white_october.swiftmailer_db.spool.entity_class% + %white_october.swiftmailer_db.spool.model% diff --git a/Spool/MongoDBSpool.php b/Spool/MongoDBSpool.php new file mode 100644 index 0000000..fc7aa16 --- /dev/null +++ b/Spool/MongoDBSpool.php @@ -0,0 +1,120 @@ +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; + } +} diff --git a/Spool/DatabaseSpool.php b/Spool/ORMSpool.php similarity index 98% rename from Spool/DatabaseSpool.php rename to Spool/ORMSpool.php index 48a47b0..4191cd6 100644 --- a/Spool/DatabaseSpool.php +++ b/Spool/ORMSpool.php @@ -5,7 +5,7 @@ use Doctrine\ORM\EntityManager; use WhiteOctober\SwiftMailerDBBundle\EmailInterface; -class DatabaseSpool extends \Swift_ConfigurableSpool +class ORMSpool extends \Swift_ConfigurableSpool { /** * @var EntityManager