Moving from CakePHP to Lithium: Helpers
I love CakePHP and I love Lithium. I imagine many other people will also love both or one or the other or parts from one or the other or neither or enough already. I also suspect that many people will find themselves moving from CakePHP to Lithium. I believe it will be a somewhat common and natural transition. However, we're missing something. Oh right, tons of helpers and other classes!
But wait! There already exists a few helpers for Lithium that act like CakePHP's helpers! So the whole point of this blog post is to say, "Hey! Migration might not be as bad as you think after all." Ok, ok, a few helpers is really not a solution for alllll of the tools CakePHP has but these are, well, helpful. I think Alexander Morland (alkemann) did an amazing job re-writing some helpers for Lithium. You can grab the helpers from his Github repository here. So I wanted to share my discovery and spread the word.
Combine & Minify Assets with Lithium
li3_assets is a nice Lithium library that I've been working on for the Lithium php framework. It is a very easy to configure (and use) library that will combine and optimize your assets all into one file. How does this impact your web site? Well really, it's how traffic won't impact your web server. What happens is instead of say 5 or 6 JavaScript files if you're using jQuery and a handful of plugins, you'll have just one and it will be minified or packed for you. So you don't even need to be using a minified or packed version of the script. In my test here, I saw 12 requests go down to 5 requests and 302Kb page size drop to 187Kb. The numbers really can be staggering depending on how many scripts (and css files) and whether or not they were originally minified or packed or not. This helps overall performance in a website and helps when you have large amounts of traffic coming to your website. The server will serve out less requests and smaller amounts of data so it can handle more visitors.
For JavaScript you have the choice of using JSMin or Packer and for CSS you have the choice of using CSSTidy or a simple whitespace and new line removal. This removal code is very simple, but also very safe. The reason I left a few options for both is because sometimes when you start minifying and packing code, things break. It's rare, but possible. Some of these tools have options and those can be passed as well in the configuration.
As an added bonus, this library also will run less files through phpless. Less is a CSS shorthand syntax that will be converted into actual CSS files. The idea is to speed up your development time. After the files are run through phpless and converted, they are then run through CSSTidy and combined into the single CSS file.
These single combined and condensed assets will live in a directory of your choice and be named with a hash string. This hash was generated from all of the assets used. This way every page that has different assets (JavaScript and for the CSS), will have a different combined hash and therefore different file. Updates? If you have an update to a CSS or JavaScript file, you'll have to remove this hashed file so it can be regenerated. In other words, you may not want to enable all this until you're live with your site.
What's this about images? Images can be "optimized" as well. All images placed with the Html image helper on any given template can be output as base64 data URI's if you so choose. The major drawback to using data URI's is that they don't work on IE 6 and IE 7. You can find some JavaScript solution to this problem, ignore this problem, or don't use data URIs. The benefit? Well, if you're caching your view templates, you've now just embedded all images within the HTML code of your view template. So you can probably take a page down to about 3 requests. One for the JS, one for the CSS, and one for the HTML code plus images within. Now you're really starting to save the server quite a bit of work.
So how easy is this to use? How do you use it? Lithium makes this simple. You will run the Libraries::add() method and add li3_assets. Within the same call, you'll pass all of the configuration options. Then in your layout you'll call $this->optimize->styles() and $this->optimize->scripts() instead of $this->styles() and $this->scripts(). So it runs based on the "scripts for layout" feature. Where any script you place within any of your view templates that contain the array option "inline" as false, you will have those be put into the layout template up top within your head section (or wherever you chose in your layout template). The li3_assets library's helper basically intercepts these assets and runs the magic. It then simply returns the HTML code for the assets to be embedded into the page. Simple. So this makes it nice when you want to turn off the optimization. It also makes it flexible so you can have certain layouts that optimize and others that do not. Here's the code all formatted. First, the library configuration.
Libraries::add('li3_assets', array(
'config' => array(
'js' => array(
'compression' => 'packer', // possible values: 'jsmin', 'packer', false (true uses jsmin)
'output_directory' => 'optimized', // directory is from webroot/css if full path is not defined
'packer_encoding' => 'Normal', // level of encoding (only used for packer), possible values: 0,10,62,95 or 'None', 'Numeric', 'Normal', 'High ASCII'
'packer_fast_decode', => true, // default: true
'packer_special_chars' => false // default: false
),
'css' => array(
'compression' => 'tidy', // possible values: true, 'tidy', false
'tidy_template' => 'highest_compression',
'less_debug' => false, // debugs lessphp writing messages to a log file, possible values: true, false
'output_directory' => 'optimized' // directory is from webroot/css if full path is not defined
),
'image' => array(
'compression' => true, // uses base64/data uri, possible values: true, false
'allowed_formats' => array('jpeg', 'jpg', 'jpe', 'png', 'gif') // which images to base64 encode
)
)
));
This shows all of the options, but there are defaults. Then in your layout template put the following within the head section of your template:
echo $this->optimize->scripts(); echo $this->optimize->styles();
That should do it. Now any script in any template using that layout defined like this:
echo $this->html->script('scriptname', array('inline' => false));
...Will be sent to the layout and intercepted and added to the list of scripts to be processed. The same goes for CSS as well.
To convert all images within a template using the Html::image() helper method, you'll simple put at the top of the view template:
$this->optimize->images();
This doesn't output anything, but it does trigger a method that will apply a filter to the Html::image() method. Filters are a real nice feature with Lithium. Now any call to the image() method will be intercepted and the data will be converted to a base64 data URI and returned. I think the use of images as data URI's is limited, but can be a nice feature to have. I think it's especially handy on certain pages where you know a lot of traffic will hit and also helpful for mobile devices. Remember that making another request (connection) takes time and while we don't notice it on high-speed internet, mobile devices will notice it. It also changes when images get loaded and rendered in a browser as well. So I feel it's an under used trick of the trade.
Again, you can grab this library from the repository on the rad-dev site. http://rad-dev.org/li3_assets.
Using Swiftmailer with Lithium
The Lithium framework is a very flexible framework and it gets along quite well with other classes. It has auto-loading features and utilizes namespaces in PHP 5.3. So any class or library of classes is typically pretty easy to use. Take for example the wonderful Swiftmailer project. This library makes sending mail via mail, sendmail, or any smtp server (including Gmail) very easy.
So how does one get it working with Lithium? Quite easy. You can simply move all of the Swiftmailer files into a folder under your app's libraries folder, named something like "swiftmailer" ... Why not? Obvious enough. Under there you should have a lib folder with all of Swiftmailer's classes and it's auto-loader.
Great. You're actually half done. The next half is to include the Swiftmailer library and auto-loader in your bootstrap. You could of course also just follow the directions on the Swiftmailer site and run require_once(...); somewhere in your method of some class, but we want to do things the Lithium way. So use Libraries:add('swiftmailer'); instead. Though, we will need to pass some options to bootstrap that auto-loader.
Libraries::add('swiftmailer', array(
'bootstrap' => 'lib/swift_required.php'
)
);
That's all there is to it. Now you can use Swiftmailer anywhere in your application. You just should note that you're working with namespaces in Lithium and the Swiftmailer class doesn't use a namespace within your application. So you'll need to call its classes like so:
$transport = \Swift_MailTransport::newInstance();
$mailer = \Swift_Mailer::newInstance($transport);
$message = \Swift_Message::newInstance()
//Give the message a subject
->setSubject('Test Message')
//Set the From address with an associative array
->setFrom(array('your@email.com' => 'Your Name'))
//Set the To addresses with an associative array
->setTo(array('to@email.com'))
//Give it a body
->setBody('Here is the message itself')
//And optionally an alternative body
->addPart('Here is the message itself', 'text/html');
$result = $mailer->send($message);
This would send a message using mail(). You can refer to the Swiftmailer documentation for other usages, but you'll just need to remember to add the first \ slash so you're in the proper namespace. You can also put the "use" command at the top of your class like this:
namespace whatever\may\have;
use \Swift_Mailer;
use \Swift_Message;
use \Swift_MailTransport;
class whatever extends something {
}
Then you won't have to remember the beginning slash to use the classes and when you follow (or copy and paste) from the Swiftmailer documentation, you won't have to really adjust much or think about it. I don't mind adding the slash personally, I don't like to put "use" up top in this case because you're talking about a few different classes that you will be using (the "Mailer", "Message", and "MailTransport") and I just find it a hassle and just makes me write more. Additionally, I may only have one method that actually uses those classes.
Anyway, I hope this helps someone out there with using Swiftmailer with Lithium. I'm sure it's fairly obvious, but that bootstrap feature is really cool and I wanted to put it out there for those not familiar with the framework or those who didn't take advantage of the auto-loader with Swiftmailer and Lithium. There are actually several ways you can use Swiftmailer (and other 3rd party classes for that matter) with Lithium. I just really like how Lithium keeps things consistent with the Libraries::add(); method.




Social Networks