Skip to content

Commit

Permalink
Merge pull request #261 from CakeDC/email-refactoring
Browse files Browse the repository at this point in the history
Email refactoring based on 3.1 email improvements
  • Loading branch information
steinkel committed Oct 23, 2015
2 parents 3705f63 + 1863dc7 commit 705366d
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 176 deletions.
99 changes: 99 additions & 0 deletions src/Email/EmailSender.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
/**
* Copyright 2010 - 2015, Cake Development Corporation (http://cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2015, Cake Development Corporation (http://cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace CakeDC\Users\Email;

use Cake\Datasource\EntityInterface;
use Cake\Mailer\Email;
use Cake\Mailer\MailerAwareTrait;

/**
* Email sender class
*
*/
class EmailSender
{
use MailerAwareTrait;

/**
* Send validation email
*
* @param EntityInterface $user User entity
* @param Email $email instance, if null the default email configuration with the
* @return void
*/
public function sendValidationEmail(EntityInterface $user, Email $email = null)
{
$this
->getMailer(
'CakeDC/Users.Users',
$this->_getEmailInstance($email)
)
->send('validation', [$user, __d('Users', 'Your account validation link')]);
}

/**
* Send the reset password email
*
* @param EntityInterface $user User entity
* @param Email $email instance, if null the default email configuration with the
* @param string $template email template
* Users.validation template will be used, so set a ->template() if you pass an Email
* instance
* @return array email send result
*/
public function sendResetPasswordEmail(EntityInterface $user, Email $email = null, $template = 'CakeDC/Users.reset_password')
{
$this
->getMailer(
'CakeDC/Users.Users',
$this->_getEmailInstance($email)
)
->send('resetPassword', [$user, $template]);
}

/**
* Send social validation email to the user
*
* @param EntityInterface $socialAccount social account
* @param EntityInterface $user user
* @param Email $email Email instance or null to use 'default' configuration
* @return mixed
*/
public function sendSocialValidationEmail(EntityInterface $socialAccount, EntityInterface $user, Email $email = null)
{
if (empty($email)) {
$template = 'CakeDC/Users.social_account_validation';
} else {
$template = $email->template()['template'];
}
$this
->getMailer(
'CakeDC/Users.Users',
$this->_getEmailInstance($email)
)
->send('socialAccountValidation', [$user, $socialAccount, $template]);
}

/**
* Get or initialize the email instance. Used for mocking.
*
* @param Email $email if email provided, we'll use the instance instead of creating a new one
* @return Email
*/
protected function _getEmailInstance(Email $email = null)
{
if ($email === null) {
$email = new Email('default');
$email->emailFormat('both');
}
return $email;
}
}
80 changes: 80 additions & 0 deletions src/Mailer/UsersMailer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
/**
* Copyright 2010 - 2015, Cake Development Corporation (http://cakedc.com)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2010 - 2015, Cake Development Corporation (http://cakedc.com)
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace CakeDC\Users\Mailer;

use Cake\Datasource\EntityInterface;
use Cake\Mailer\Email;
use Cake\Mailer\Mailer;

/**
* User Mailer
*
*/
class UsersMailer extends Mailer
{
/**
* Send the templated email to the user
*
* @param EntityInterface $user User entity
* @param string $subject Subject, note the first_name of the user will be prepended if exist
* @param string $template string, note the first_name of the user will be prepended if exists
*
* @return array email send result
*/
protected function validation(EntityInterface $user, $subject, $template = 'CakeDC/Users.validation')
{
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
$this
->to($user['email'])
->subject($firstName . $subject)
->viewVars($user->toArray())
->template($template);
}

/**
* Send the reset password email to the user
*
* @param EntityInterface $user User entity
* @param string $template string, note the first_name of the user will be prepended if exists
*
* @return array email send result
*/
protected function resetPassword(EntityInterface $user, $template = 'CakeDC/Users.reset_password')
{
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
$subject = __d('Users', '{0}Your reset password link', $firstName);

$this
->to($user['email'])
->subject($subject)
->viewVars($user->toArray())
->template($template);
}

/**
* Send account validation email to the user
*
* @param EntityInterface $user User entity
* @param EntityInterface $socialAccount SocialAccount entity
*
* @return array email send result
*/
protected function socialAccountValidation(EntityInterface $user, EntityInterface $socialAccount)
{
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
//note: we control the space after the username in the previous line
$subject = __d('Users', '{0}Your social account validation link', $firstName);
$this
->to($user['email'])
->subject($subject)
->viewVars(compact('user', 'socialAccount'));
}
}
42 changes: 0 additions & 42 deletions src/Model/Behavior/Behavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,13 @@

use Cake\Datasource\EntityInterface;
use Cake\I18n\Time;
use Cake\Mailer\Email;
use Cake\ORM\Behavior as BaseBehavior;

/**
* Covers the user registration
*/
class Behavior extends BaseBehavior
{

/**
* Send the templated email to the user
*
* @param EntityInterface $user User entity
* @param string $subject Subject, note the first_name of the user will be prepended if exists
* @param Email $email instance, if null the default email configuration with the
* Users.validation template will be used, so set a ->template() if you pass an Email
* instance
*
* @return array email send result
*/
protected function _sendEmail(EntityInterface $user, $subject, Email $email = null)
{
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
$emailInstance = $this->_getEmailInstance($email)
->to($user['email'])
->subject($firstName . $subject)
->viewVars($user->toArray());
if (empty($email)) {
$emailInstance->template('CakeDC/Users.validation');
}
return $emailInstance->send();
}

/**
* Get or initialize the email instance. Used for mocking.
*
* @param Email $email if email provided, we'll use the instance instead of creating a new one
* @return Email
*/
protected function _getEmailInstance(Email $email = null)
{
if ($email === null) {
$email = new Email('default');
$email->emailFormat('both');
}

return $email;
}

/**
* DRY for update active and token based on validateEmail flag
*
Expand Down
36 changes: 13 additions & 23 deletions src/Model/Behavior/PasswordBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CakeDC\Users\Model\Behavior;

use CakeDC\Users\Email\EmailSender;
use CakeDC\Users\Exception\UserAlreadyActiveException;
use CakeDC\Users\Exception\UserNotFoundException;
use CakeDC\Users\Exception\WrongPasswordException;
Expand All @@ -25,6 +26,17 @@
*/
class PasswordBehavior extends Behavior
{
/**
* Constructor hook method.
*
* @param array $config The configuration settings provided to this behavior.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->Email = new EmailSender();
}
/**
* Resets user token
*
Expand Down Expand Up @@ -63,7 +75,7 @@ public function resetToken($reference, array $options = [])
$saveResult = $this->_table->save($user);
$template = !empty($options['emailTemplate']) ? $options['emailTemplate'] : 'CakeDC/Users.reset_password';
if (Hash::get($options, 'sendEmail')) {
$this->sendResetPasswordEmail($saveResult, null, $template);
$this->Email->sendResetPasswordEmail($saveResult, null, $template);
}
return $saveResult;
}
Expand All @@ -79,28 +91,6 @@ protected function _getUser($reference)
return $this->_table->findAllByUsernameOrEmail($reference, $reference)->first();
}

/**
* Send the reset password email
*
* @param EntityInterface $user User entity
* @param Email $email instance, if null the default email configuration with the
* @param string $template email template
* Users.validation template will be used, so set a ->template() if you pass an Email
* instance
* @return array email send result
*/
public function sendResetPasswordEmail(EntityInterface $user, Email $email = null, $template = 'CakeDC/Users.reset_password')
{
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
$subject = __d('Users', '{0}Your reset password link', $firstName);
return $this->_getEmailInstance($email)
->template($template)
->to($user['email'])
->subject($subject)
->viewVars($user->toArray())
->send();
}

/**
* Change password method
*
Expand Down
4 changes: 3 additions & 1 deletion src/Model/Behavior/RegisterBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CakeDC\Users\Model\Behavior;

use CakeDC\Users\Email\EmailSender;
use CakeDC\Users\Exception\TokenExpiredException;
use CakeDC\Users\Exception\UserAlreadyActiveException;
use CakeDC\Users\Exception\UserNotFoundException;
Expand Down Expand Up @@ -40,6 +41,7 @@ public function initialize(array $config)
parent::initialize($config);
$this->validateEmail = (bool)Configure::read('Users.Email.validate');
$this->useTos = (bool)Configure::read('Users.Tos.required');
$this->Email = new EmailSender();
}

/**
Expand All @@ -63,7 +65,7 @@ public function register($user, $data, $options)
$this->_table->isValidateEmail = $validateEmail;
$userSaved = $this->_table->save($user);
if ($userSaved && $validateEmail) {
$this->_sendEmail($user, __d('Users', 'Your account validation link'), $emailClass);
$this->Email->sendValidationEmail($user, $emailClass);
}
return $userSaved;
}
Expand Down
16 changes: 4 additions & 12 deletions src/Model/Behavior/SocialAccountBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CakeDC\Users\Model\Behavior;

use ArrayObject;
use CakeDC\Users\Email\EmailSender;
use CakeDC\Users\Exception\AccountAlreadyActiveException;
use CakeDC\Users\Exception\AccountNotActiveException;
use CakeDC\Users\Exception\MissingEmailException;
Expand Down Expand Up @@ -45,6 +46,7 @@ public function initialize(array $config)
'joinType' => 'INNER',
'className' => Configure::read('Users.table')
]);
$this->Email = new EmailSender();
}

/**
Expand Down Expand Up @@ -77,18 +79,8 @@ public function afterSave(Event $event, Entity $entity, $options)
*/
public function sendSocialValidationEmail(EntityInterface $socialAccount, EntityInterface $user, Email $email = null)
{
$emailInstance = $this->_getEmailInstance($email);
if (empty($email)) {
$emailInstance->template('CakeDC/Users.social_account_validation');
}
$firstName = isset($user['first_name'])? $user['first_name'] . ', ' : '';
//note: we control the space after the username in the previous line
$subject = __d('Users', '{0}Your social account validation link', $firstName);
return $emailInstance
->to($user['email'])
->subject($subject)
->viewVars(compact('user', 'socialAccount'))
->send();
$this->Email = new EmailSender();
$this->Email->sendSocialValidationEmail($socialAccount, $user, $email);
}

/**
Expand Down
Loading

0 comments on commit 705366d

Please sign in to comment.