Archive for the ‘cakephp’ Category

CakePHP Email component

Tuesday, October 20th, 2009

This is quite a simple component that integrates PHPMailer with CakePHP. Save the following code to /app/controllers/components/email.php

<?php 

App::import('Vendor', 'PhpMailer', array('file' => 'phpmailer' . DS . 'class.phpmailer.php'));

/*
    Depends on "unhtml"
*/

class EmailComponent extends PHPMailer
{
	// phpmailer
	var $Mailer = 'sendmail'; // choose 'sendmail', 'mail', 'smtp'
	var $unhtml_bin = '/usr/bin/unhtml';

	// component
	var $controller;

	function startup( &$controller )
	{
		$this->controller = &$controller;
	}

	function renderBody($view)
	{
		// render the view and use its output to set the body text of the email
		$this->Body = $this->controller->render('emails/' . $view, 'email');

		// reset the output of the controller
		$this->controller->output = '';

		// create plain text version of the email
		//
		// create temporary files
		$htmlfile = tempnam(TMP, 'htmlfile');
		$textfile = tempnam(TMP, 'textfile');

		// write html to temporary file
		file_put_contents($htmlfile, $this->Body);

		// convert the html file to plain text
		$cmd = "cat $htmlfile | $this->unhtml_bin > $textfile";
		system($cmd);

		// set the plain text body of the email
		$this->AltBody = file_get_contents($textfile);

		// remove temporary files
		unlink($htmlfile);
		unlink($textfile);
	}
}

?>

In addition to that, make sure phpmailer is installed in /app/vendors/phpmailer. I just extracted the phpmailer archive in /app/vendors/ and created a symlink:

$ tar xzf PHPMailer_v5.0.2.tar.gz
$ ln -s PHPMailer_v5.0.2 phpmailer

Usage
In your controller code, make sure the component is included by adding it to the components array:

var $components = array('Email');

In app/views/layouts, create a new layout called email.ctp. It should contain something like:

<html>
<body>
<?php echo $content_for_layout; ?>
</body>
</html>

Let’s send some emails!
In controller snippet, the renderBody(‘test’) call will create a html email from the view in app/views/users/emails/test.ctp. Additionally, a plain text version will be generated using ‘unhtml’. Unhtml has a package in the Ubuntu / Debian repository.
The action works just like rendering a normal view. The $this->Email object is just an instance of PHPMailer and all PHPMailers’ methods and properties apply.

function testmail()
{
	// *Some notes*
	// Email methods:    http://phpmailer.worxware.com/index.php?pg=methods
	// Email properties: http://phpmailer.worxware.com/index.php?pg=properties
	//
	// Email configuration is done in /app/controllers/components/email.php

	$this->set(compact('some', 'vars'));

	// the email content is just a (html) view in app/views/{controller}/emails/testmail.ctp
	$this->Email->renderBody('test');

	// subject
	$this->Email->Subject = 'Test from example.com';

	// sender
	$this->Email->SetFrom('test@example.com', 'Test');

	// recipients
	$this->Email->AddAddress('joe@example.com', 'Joe');
	$this->Email->AddAddress('jane@example.com', 'Jane');

	// send!
	$this->Email->Send();
}

Cakephp ThumbnailHelper

Tuesday, April 7th, 2009

This thumbnail helper is based on the one published by Studio Canaria. Additional features are multiple size caching and an extra method which is a truly drop-in replacement for $html->image().
Usage:

<?php

echo $thumbnail->image('picture.jpg', array(
 	'alt' => 'test thumbnail',
 	'width' => '100',
 	'height' => '75'
 	)
 );

// result:
// <img src="/img/thumbs/100x75/picture.jpg"
//	alt="test thumbnail" height="75" width="100">

?>

Installation:

  • Download thumbnail.txt
  • Rename it to thumbnail.php and place it in /app/views/helpers/
  • download phpThumb()
  • Extract the phpThumb archive in a directory named /app/vendors/phpthumb/
  • Add ‘Thumbnail’ to the ‘helpers’ array your controller
  • Create a directory named ‘thumbs’ in /app/webroot/img/. Make sure it’s writable for the webserver.

That’s it!
In the above example, the thumb helper will first check if there is a file named /app/webroot/img/thumbs/100×75/picture.jpg. If it isn’t there yet, it will instantiate phpThumb and create the thumbnail.
For more advanced usage, there’s also the render() method. It will give you the flexibility to use images located outside /app/webroot/img and also make use of most of the phpThumb options.
Advanced example:

<?php

$thumb = $thumbnail->render(
	$data['Picture']['path'],
	array(
		'w' => 320,
		'h' => 200,
		'ra' => 10
	),
	'5271a9e66c99c84c092d7fd81cebcd57'
);

echo $html->image($thumb);

?>

This will generate a picture named /app/webroot/img/thumbs/320×200/5271a9e66c99c84c092d7fd81cebcd57.jpg, which is a 10 degrees rotated thumbnail of the original image specified with $data['Picture']['path'].

explorerTree demo files

Monday, April 6th, 2009

tree.png
To save you some typing, this archive contains a working example of the tree helper code described in the bakery. The archive includes cake 1.2, three images and jquery. In the js-code, some hard-coded paths were corrected. It also contains a file named tree.sql which contains a dump of the database including some sample data.

cakephp, user_dir and mod_rewrite

Thursday, April 2nd, 2009

Here’s a little note on getting a cakephp app working in your public_html directory. In order to get the mod_rewrite configuration working, add a RewriteBase rule to the .htaccess files in the cakephp source. If your app is located in /home/me/public_html/cakesite/ and the URL to the site is http://host/~me/cakesite you’ll need to change the following .htaccess files:

/home/me/public_html/cakesite/.htaccess
/home/me/public_html/cakesite/app/webroot/.htaccess

Add the following line to these files, just below the line stating “RewriteEnginge On”:

RewriteBase /~me/cakesite/

For example, the first .htaccess file will look like:

<ifModule mod_rewrite.c>
	RewriteEngine on
	RewriteBase /~me/cakesite/
	RewriteRule    ^$ app/webroot/    [L]
	RewriteRule    (.*) app/webroot/$1 [L]
</ifModule>

Bonus notes with instructions for Debian/Ubuntu systems
You should have mod_rewrite enabled:

$ sudo a2enmod rewrite
$ sudo /etc/init.d/apache2 force-reload

To make sure the use of .htaccess files is actually allowed. In the Directory section of your apache configuration, there should be a line like:

AllowOverride FileInfo

Also, be sure to force-reload Apache after making this change.

Combining Modalbox & CakePHP

Thursday, February 28th, 2008

demo included!I’m pretty sure this can be implemented more elegantly, but I’ll describe my attempt to unite Modalbox with CakePHP 1.2.

First example – a modal box view
This example shows the steps I’ve taken to flavour a freshly baked cake app with modalbox. The starting point is a customer model, a controller and some basic index, view and edit views.
Showing a cakephp view in a modalbox, is just a few snippets away. Just make sure you include prototype, scriptaculous and the modalbox javascript and the modalbox css file in the default layout…

/app/views/layouts/default.ctp:
echo $html->css('modalbox');
echo $javascript->link('prototype');
echo $javascript->link('scriptaculous.js?load=effects');
echo $javascript->link('modalbox');

Then create the appropiate link to the view you want to load inside the modalbox. For example, if you want to show customer details from the customers/index.ctp view:

# ...somewhere in the loop that lists customers:
echo $html->link('View', array('action' => 'view', $customer['Customer']['id']), array('title' => 'Customer details', 'onclick' => "Modalbox.show(this.href, {title: this.title, width: 400}); return false;"));

Make sure you use the RequestHandler component so that the customer view is displayed in the ajax.ctp instead of the default.ctp layout. You can do this by making sure the following line is in /app/app_controller.php:

var $components = array('RequestHandler');

And… there you go! When you click the view link, the modalbox slides in, while the rest of the page dims to gray. When you hit the escape button, click the little ‘X’ or click anywhere in the gray area, the modal box slides back where it came from.

Ok, now forms!
(more…)

Howto start your CakePHP project in Subversion

Thursday, December 6th, 2007

This howto will demonstrate how to start your cakephp project from scratch, taking advantage of subversions “externals definition”. The result will be a basic CakePHP directory structure with only the “/app” part under your svn control and the other directories linked to a specified revision of cakephp. Once setup, if you do a ’svn chekout’ of your project, you will get all the files at the right location, so no need to merge your ‘/app ‘ with the contents of a tarbal which you downloaded from the CakePHP website.

Let’s get started!

First, we create a temporary directory structure, just for the purpose of importing it:

$ mkdir temp
$ mkdir temp/mynewproject
$ mkdir temp/mynewproject
$ svn import -m "New import" temp file:///home/me/subversion/
# remove the temporary directory structure
$ rm -rf temp

Now, we checkout a working copy:

$ cd ~/src
$ svn checkout file:///home/me/subversion/mynewproject

Ok, this just bought us an empty directory managed by subversion!! Let’s fill it with the use of some magic: Externals. We will create an externals definition for the directory. It will point to the current cakephp1.2 release, which is 5875 at time of writing.

$ cd mynewproject
$ svn propedit svn:externals .

This will fire up your text editor with an empty text file. Type the following line, save and quit:

third-party/cake_1.2.0.5875 -r 5875 https://svn.cakephp.org/repo/trunk/cake/1.2.x.x/

Since this is an actual change to the current directory, we should commit it back to the repository:

$ svn commit -m "Added externals definition for CakePHP 1.2 rev. 5875"

By updating our working copy, the cakephp files will be downloaded to the in the property specified directory:

$ svn update

Wow, that’s nice, isn’t it! Oh… and btw, don’t forget to donate some change to the project!

Let’s go and make some symlinks and a copy of the ‘app’ directory:

$ ln -s third-party/cake_1.2.0.5875/.htaccess
$ ln -s third-party/cake_1.2.0.5875/cake
$ ln -s third-party/cake_1.2.0.5875/index.php
# now create your own copy of the app directory
$ cp -r third-party/cake_1.2.0.5875/app .

Since we don’t need the .svn directories from the cakephp svn checkout. We find and delete them:

$ find app -type d | grep \.svn | sort -r | xargs rm -rf

Finally, add the ‘/app’ directory and the simlinks to our own subversion repository

$ svn add .htaccess app cake index.php
$ svn commit

That should be it!

Remember, when you want to upgrade your CakePHP version. It should be a matter of (a) editing the externals definition on the myproject directory. And (b) re-linking the symbolic links.

‘Compact’ bash prompt

Monday, July 30th, 2007

Especially when working with cakephp, the following line in your .bash_profile script might come in handy:

HOSTCOLOR="31m"
PS1="\u@\[\e[${HOSTCOLOR}\]\h\[\e[0m\]:\w\n\[\e[33m\]\!\[\e[0m\] \$ "

It will print out the current working directory on the first line and the actual bash prompt on the second line. Making it less likely that your command will wrap lines after the first few typed characters.
It changes the command prompt from:

command line long

….into:

command line 'short'

The login prompt now shows the following info:

  • username
  • hostname in red (in my bash script, it will print red for one group of servers and blue for other servers)
  • current working directory
  • command history number, ie: use !520 to execute the previous command

CakePHP radio button example

Friday, January 26th, 2007

cakephp radio buttons.png
Thanks Ronnie, for the example! It looks like this useful hint won’t appear in the cakephp documentation any time soon. I think is’t “nerdnoteworthy”:

echo $html->radio(
	'User/admin',
	array(
		'no' => 'No',
		'yes' => 'Yes'),
	null,
	array('value' => 'no')
);

www.hiddenspiral.net/node/23

Monday, December 18th, 2006

This is a comment that I would have posted on this blog entry, if the author was willing to receive it without me signing up. It’s about retrieving the keys and values of an enum field in CakePHP:

This version returns the original mysql key values and returns false if the enum is not found:

function generateEnumArray($enum)
{
  if (!is_string($enum)) {
    return false;
  }

  foreach($this->_tableInfo->value as $field)
  {
    // found matching field, check for type enum and field name
    if(substr($field['type'], 0 ,4) == 'enum' && $field['name'] == $enum)
    {
      $enum_array = array();
      foreach(split("','", substr($field['type'], 6, -2)) as $key => $value)
      {
        $enum_array[$key]=$value;
      }
      return $enum_array;
    }
  }

  // enum not found
  return false;
}