Welcome Guest, Not a member yet? Register   Sign In
Templated Emails
#1

[eluser]meglio[/eluser]
For my own need I have developed Emailx library and I'm going to share this class with everyone because it is of use for long time now.

Why this class is better then do all things manually?

* it autoloads email template from database (only once even if you send email many times)
* it uses associative array to replace variables in email template
* it uses associative array to fully configure email (from, to, cc, bb etc) - so you do not need to call methods of standard Email class and you can put your configuration in config/

First at all, this class uses table in database named "templates". This table name is hardcoded just because I'm always using "templates" table for email templates, but of course you can change this easily in the code.

Here is structure of table:

Code:
CREATE TABLE `templates` (
  `name` varchar(150) collate utf8_unicode_ci NOT NULL,
  `subject` varchar(255) collate utf8_unicode_ci NOT NULL,
  `body` text collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


Also you can put test template to play with it while reading documentation:
Code:
INSERT INTO `templates` (`name`, `subject`, `body`) VALUES
('Account Registered', 'Your Account has been created!', '<p><b>Dear [name]</b></p>\r\n\r\n<p>\r\nYour Account has been created and your login details are:<br/>\r\nemail: <b>[email]</b><br/>\r\npassword: <b>[password]</b><br/>\r\n</p>\r\n\r\n<p>\r\nYou can log in here to view your profile page at any time:<br/>\r\n<a href="[link]">{unwrap}[link]{/unwrap}</a>\r\n</p>\r\n\r\n<p>\r\n<i>\r\nThank you<br/>\r\n<a href="http://yourcompany.com">\r\nYourCopmany\r\n</a>\r\n</i>\r\n</p>');



Now take a look to my custom configuration file in system/application/config/. You can create your own configuration file and put it to config/ folder, for example:
config/emailx.php

Code:
$config['emailDebug'] = true;

$config['emailConfig'] = array(
    'protocol' => 'smtp',
    'smtp_host' => 'outmail.voliacable.com',
    'smtp_port' => '25',
    'smtp_user' => '...',
    'smtp_pass' => '...',
    'mailtype' => 'html',
    'nnewline' => '\r\n'
);

$config['emailNoreplyFrom'] = array(
    'email' => '[email protected]',
    'name' => 'Example Company Title'
);

$config['emailDebug'] serves to turn on/off debugging output

$config['emailConfig'] serves to configure email server and other email configuration. This is useful because you can create different configurations and use them in initialize (see below). For example, you can create one configuration for your local development server and another configuration for your live server.

$config['emailNoreplyFrom'] serves to configure "from" email. As you know it is useful because usually you will need to send from different emails, for example:
* [email protected]
* [email protected]
* [email protected]
* [email protected]

Now when you configured all your emailing options, lets send some emails...

The library can be loaded normally (and it requires standard db and email to be loaded too)

Code:
$this->load-database();
$this->load->library('email');
$this->load->library('emailx');

Next we can initialize emailx by passing to it associative array with configuration:

Code:
$this->emailx->initialize($this->config->item('emailConfig'));


Now lets set 2 arrays before to send email: vars and params.
Params will be used to specify from/to values.
Vars will be used to replace variables in template; for example, [email]

Code:
// User registered and we got some variables:
// $email, $name, $newPassword

$params = array(
                'from' => $this->config->item('emailNoreplyFrom'),
                'to' => $email
            );
            $vars = array(
                'name' => $name,
                'email' => $email,
                'password' => $newPassword,
                'link' => base_url() . 'userlogin'
            );
            $sentEmail = $this->emailx->email($params, 'Account Registered', $vars);

// If you want to ouput email debugging information then use
// $this->emailx->print_debugger
// In my code I'm using PHPTAL (http://phptal.motion-twin.com/), but you can simply "echo"

if (!$sentEmail && $this->config->item('emailDebug'))
                $this->phptal->emailDebug = "Email failure information: " .
                    $this->emailx->print_debugger;


I hope this class will do good work for somebody and I will be happy to see some comments from who tried this class.

Thanks,
Anton
#2

[eluser]Phil Sturgeon[/eluser]
You could package this nicely as an extension to the standard email class. Would stop the requirement for the double load, and if your class needs the database library running, load it! Smile.

If you just add a single public method template() to email class, this would work nicely and have a lot less duplicated code.

The config arrays you have set up are surely just an over-complication of what is already handled by config/Email.php ?
#3

[eluser]meglio[/eluser]
>> You could package this nicely as an extension to the standard email class.

Yes I know, but email sending logic and templates generation logic are totally different, so I decided to not join them together using extension to standard email class.


>> if your class needs the database library running, load it

I like to create objects separately, or even multiple instances if I need them, and I do not like to have all instances to be properties of some main class (some instances can be function-scope for one-time execution - this is right OOP politics when you create huge application, and this comes from Pascal and c# ideology).

In contrary, the DB connection is unique for the site, so as for me it is not right to load "db" library in the class. The db loading workflow is up to the main controller method which holds the business logic.

In other words, you can't force db loading inside small objects, you must do it in the main business logic objects (in our case, controller's method).


>> nicely and have a lot less duplicated code

What code is duplicated?


>> he config arrays you have set up are surely just an over-complication of what is already handled by config/Email.php ?

If you read my post with explanations, you will see that config arrays are there to allow you to manage multiple email configurations + to configure different "from" addresses. Why this is bad? Well you can create arrays directly in the code when you need it, just to avoid 100 parameters for the function. But as for me config arrays makes it more declarative (which is always better and more readable).


Hope makes sense for you.
Anton
#4

[eluser]Phil Sturgeon[/eluser]
Config groups would be a handy one, but it seemed your config arrays were justy doing the same thing we can do right now. If you have a way to set up groups in the config file thats great.

I see where you are coming from with no autoloading database within your object, but I feel that if something needs something, it should ask for it. In C++ and older languages, if you did it this way it would obviously end up loading things multiple times. The joy of CI is that it will only load it once. If several things require the same object, they all ask for it and get the same one. Good stuff.
#5

[eluser]meglio[/eluser]
Well I agree, database can be loaded in Emailx constructor then.

P.S. I do not like C++ and I use c# which does it the same way as CodeIgniter - it loads library once. But what I wanted to tell is that there is business logic - more general then small objects - and I do not like to load library in each small object which requires it. As for me it is not right. For example, what if I want to load database once in my business logic and work up all exceptions (if something goes wrong) BEFORE to do something else? In this way I know already that DB is loaded already if I'm going to create small object somewhere.

Well it seems that we are both right, but with different concept of programming big image of application Smile
#6

[eluser]miss_amylee[/eluser]
hy!i used code above..but why its says 'Unable to load the requested class: emailx'..sory..im new in CI.tQ
#7

[eluser]meglio[/eluser]
Have you putted Emailx class to your libraries folder?




Theme © iAndrew 2016 - Forum software by © MyBB