Amptools.Net

simplify your life.

Zend Framework

Zend Framework Image Captcha

No Gravatar

The Zend Framework documentation lacks when it comes to showing the ins of out of some of its components, the seems to fall under that category. You would think there would be a ton of useful blog posts and if there are useful posts, I don’t think google is catching them. I did find some useful code on this blog, . It does make some decent notes, so please go read this post first (and thank him, cause so far he has the best notes on the ZF captcha thus far), but the code did not seem to work with the current version of Zend that I have which is currently version 1.7.8. The other post is using some kind of Iterator and expecting the zend namespace to have a getIterator method, for some reason this was not working for me.

Here is the modified/refactored version that creates a static wrapper Captcha class using the image captcha. To reiterate what the other blog says, Make sure you have GD enabled, make sure you have a font file, make sure you have the file paths pointing to the right place, and make sure you have the right permissions for the folders that contain the images and font file.

PHP Captcha Class

class Capatcha
{

	/**
	 * validates the last image captcha that was created
	 * and put into the current session.
	 *
	 * @param string $postPrefix  the prefix of the post value i.e. 'captcha[id]'
	 * @return boolean
	 */
	public static function validate($postPrefix = "captcha")
	{
		$captcha = $_POST[$postPrefix];
        	$captchaId = $captcha['id'];
        	$captchaInput = $captcha['input'];
        	$captchaSession = new Zend_Session_Namespace('Zend_Form_Captcha_' . $captchaId);

        	$captchaWord =   $captchaSession->word;
        	if( $captchaWord )
        		return $captchaInput == $captchaWord;
       		return false;
	}

	/**
	 * generates the captcha image and returns the image id.
	 *
	 * @param string $postPrefix  the prefix of the post value i.e. 'captcha[id]'
	 * @return string
	 */
	public static function generate($postPrefix = "captcha")
	{
		// replace the path/to with the correct path...
		// same with /images/captcha
		$captcha = new Zend_Captcha_Image(array(
		    'name' => $postPrefix,
		    'wordLen' => 6,
		    'timeout' => 600,
			'font' => "path/to/IMPACT.TTF",
			'imgdir' => "path/to/images/captcha",
			'imgurl' => "/images/captcha"
		));

		return $captcha->generate();
	}
}

PHP ZF Controller

// in your action in the controller,
// it would look like some variation of this
if($this->getRequest()->isPost())
{
	if(!Capatcha::validate())
        {
        	$id = Capatcha::generate();
        	$this->view->captcha = $id;
        	$this->view->message = "captcha was invalid";
        	return;
        } else {
               $this->view->message = "saved!";
        }
}
else
{
        $this->view->message ="";
        $id = Capatcha::generate();
        $this->view->captcha = $id;
}

XHTML View


<!-- above your form using with short tags on -->
<div class="error"><?= $this->message ?></div>

<!-- somewhere in your form -->
	<img src="/images/captcha/<?= $this->captcha ?>.png" alt="captcha" />
	<input type="text" name="captcha[input]" value="" />
	<input type="hidden" name="captcha[id]" value="<?= $this->captcha ?>" />

Tags: , ,

Wednesday, June 24th, 2009 Blog Comments

HTTP GET vs POST in the Zend Framework

No Gravatar

As most web developers know there is a difference between HTTP GET and HTTP POST and sometimes you end up using a combination of these items and take precedence depending on what are you are trying to accomplish. In the Zend Framework, when working with controllers there is a object used in conjunction with controllers. The object has useful methods like determining what kind of HTTP Request it is (isPost, isXmlHttpRequest, isGet, etc), getting various request variables (_getParam, getParams, getPost,etc).

While working on a search page for a client, I came across a need to get POST values which could sometimes also be in the query string already, but needed the HTTP POST variables to take precedence in being loaded. When using $this->_request->_getParam() inside of the controller, the HTTP GET values were taking precedence. The reason why: there is no $this->_request->getGet() method on the request object, HTTP GET data must be acquired through $this->_request->_getParam() or by calling for the property (which invokes the magic method __get on the request object). The _getParam() method always checks GET data first. However there is a $this->_request->getPost() method which can be used to retrieved the post values.

PHP

// in the controller action method....
// too long to use a ternary.

// TIP:
// technically $this->_request->search should be the same as
// $this->_request->getPost('search');
if($this->_request->isPost())
	$params = $this->_request->getPost('search'); // HTTP POST
else
	$params = $this->_getParam("search", array()); // HTTP GET

// there is no $this->getGet('search')

Tags: ,

Thursday, June 11th, 2009 Blog Comments

Fun Times with Partial Loops in Zend Framework

No Gravatar

While working with the Zend Framework and partial loops, I ran into a few issues. One was not getting the data to load, which was easily solved after looking at . Make sure you set the object key in the controller for the partial loop. The other issue of trying to pass local variables into the partial loop took time to see there was really no current answer without extending or creating a new helper, or the evil global.

PHP

// in the action method
global $otherVariable;
$otherVariable = "should be the same through each iteration";
$this->view->partialLoop()->setObjectKey('model');
$this->view->paginator = Zend_Paginator::factory($array); //etc

// in the view
<?= $this->partialLoop('path/to/_partial.phtml', $this->paginator) ?>

// in the _partial.phtml
<?php
      $model = $this->model
      global $otherVariable; // just seems so hackish to have to do this.
?>

I have already added a task to to extend the Partial Loop Helper to overcome the lack of the ability to pass in local variables to the partial loop.

Tags: , ,

Thursday, June 11th, 2009 Blog Comments