Category Archives: zend framework

Extending the art & spirit of PHP, Zend Framework is based on simplicity, object-oriented best practices, corporate friendly licensing, and a rigorously tested agile codebase. Zend Framework is focused on building more secure, reliable, and modern Web 2.0 applications & web services, and consuming widely available APIs from leading vendors like Google, Amazon, Yahoo!, Flickr, as well as API providers and cataloguers like StrikeIron and ProgrammableWeb.

Default Error Handling in Zend Framework

Zend_Controller_Action_Exception

There’s a cool feature in Zend Framework when a controller or action doesn’t exists. That’s really useful, because you simply write an ErrorController.php in you default module and every action’s exception sends the user to this controller/action and the job is done for you. What is important here is to show the error message at least on the development stage. Actually the request stores it as a parameter. Here’s some source:

<?php
 
class ErrorController extends Zend_Controller_Action
{
    public function errorAction()
    {
        $errorHandler = $this->getRequest()->getParam('error_handler');
        /* @var $error Zend_Controller_Action_Exception */
        $error = $errorHandler->exception;
        echo $error->getMessage();
    }
}

Zend Framework: Simple Acl Front Controller Plugin

access with Zend_Acl

Almost every web site need some abstraction over the access control list (ACL) to grant access of its users. As usual Zend Framework has quite good mechanism to deal with this – Zend_Acl.

Out in the web there are a lot of resources about Zend_Acl’s usage, so I ain’t going to cover it one more time, but simply copy/paste a very small front controller plugin implementing the basic usage of Zend_Acl.

Note that instead of defining the __construct() here is called preDispatch where the request is passed as a parameter. However only by copy pasting not every answer will be given. That’s why I’m going to write more about Zend_Acl in my future posts, for now only the source code:

<?php
 
class AclInit extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // create new acl object
        $acl = new Zend_Acl();
 
        // define resources. typically there are
        // only four resources from the CRUD functionality
        // but there can be added more resources
        $acl->add(new Zend_Acl_Resource('index'))
            ->add(new Zend_Acl_Resource('create'))
            ->add(new Zend_Acl_Resource('read'))
            ->add(new Zend_Acl_Resource('update'))
            ->add(new Zend_Acl_Resource('delete'));
 
        // define roles
        $acl->addRole(new Zend_Acl_Role('guest'))
            ->addRole(new Zend_Acl_Role('admin'));
 
        // define privileges
        $acl->allow('guest', array('index', 'read'))
            ->allow('admin');
 
        // setup acl in the registry for more
        Zend_Registry::set('acl', $acl);
 
        // check permissions
        if (!$acl->isAllowed('guest', $request->getActionName())) {
            $request->setControllerName('error');
            $request->setActionName('error');
        }
    }
}

Zend_View_Helper_InlineScript Appends Scripts Twice

Double Trouble

duplicate
This is a well known problem, which is well described as a bug in Zend Framework’s issue tracker. Once you add some scripts with the inlineScript helper you’ll receive them twice in the code. This makes the page slower and leads to some crashes.

$scripts->appendFile('my-file1.js')
        ->appendFile('my-file2.js')
        ->appendScript('alert("test")');

This will print the alert twice.

<script src="my-file1.js"></script>
<script src="my-file2.js"></script>
<script>
//<!--
alert("test");
//-->
</script>
<script>
//<!--
alert("test");
//-->
</script>

Quick Solution

Although this is the worst solution I’ve ever made – it works! There is a check for duplicates in the HeadScript helper around line 240:

if (!$this->_isDuplicate($content)) {
...

and then a check in the _isDuplicate method(), ~ line 270:

if (($item->source === null)
    && array_key_exists('src', $item->attributes)
    && ($file == $item->attributes['src']))
{
    return true;
}

The thing you’ve to do is to add such a check for the appendScript() and not only for appendFile() method – again ~ line 230:

case 'script':
	if (!$this->_isDuplicate($content)) {
	    $item = $this->createData($type, $attrs, $content);
	    if ('offsetSet' == $action) {
	        $this->offsetSet($index, $item);
	    } else {
	        $this->$action($item);
	    }
	}
	break;

And then slightly modify the _isDuplicate method:

foreach ($this->getContainer() as $item) {
    if (($item->source === null)
        && array_key_exists('src', $item->attributes)
        && ($file == $item->attributes['src']))
    {
        return true;
    }
    if ($item->source == $file) {
        return true;
    }
}
return false;

Send Authenticated POST Request with Zend_Http_Client


There is an easy way to send requests with Zend_Http_Client either in GET and POST. Actually you can request not only with GET and POST methods, but with any other http request method.

$httpClient = new Zend_Http_Client('http://....');
// request via post
$response = $httpClient->request(Zend_Http_Client::POST);
// or get
$response = $httpClient->request(Zend_Http_Client::GET);

However the interesting and useful thing is that you can perform authenticated requests:

$httpClient = new Zend_Http_Client('http://username:password@example.com');
// or define it later
$httpClient = new Zend_Http_Client('http://example.com');
$httpClient->setAuth('username', 'password');

That’s an opportunity to send/receive authenticated POST requests.

$httpClient = new Zend_Http_Client('http://username:password@example.com');
// now post
$httpClient->request(Zend_Http_Client::POST);

Zend Framework: Inject JavaScript Code in a Action/View

There is a view helper that can inject a head or inline script into your code.

Simply by putting some JavaScript code into the view script wont do the job, because the .phtml file is grabbed and parsed by the Zend Framework and thus the code there wont be parsed as JavaScript and it wont be executed as well by the browser.

The Most Simple Way …

is to put some place holder into the layout .phtml file and than from the controller’s action you can assign some JS code:

// layout.phtml
<?php
...
echo $this->layout()->scriptTags;
...
<?php
 
class IndexController extends Zend_Controller_Action
{
	public function indexAction() 
	{
		$this->view->layout()->scriptTags = '<script src="my.js"></script>';	
	}	
}

Solution No. 2

Although the first solution is correct it’s not the most clearest way, because you put the JavaScript code into the PHP, and this sooner or later becomes a mess.

<?php
 
class IndexController extends Zend_Controller_Action
{
	public function indexAction() 
	{
		$this->view->layout()->scriptTags = '<script src="my.js"></script>';
						  . '<script>alert("here\'s my" + "test")</script>';
	}	
}

The IDE is not highlighting the code, and you’ve to deal with too many quotes, which is bad! There is a better solution however – the inline script:

// script tags
/* @var $scripts Zend_View_Helper_InlineScript */
$scripts = $this->view->inlineScript();
$scripts->appendFile('my.js');

Simply the Best

Yeah, the best solution is something even better than the second one. Although the solution I’ve just mentioned is fine for including JS files, when you’ve to add some JS code you’ll have to put it again into the PHP.

$msg = 'some dynamically generated message';
 
// script tags
/* @var $scripts Zend_View_Helper_InlineScript */
$scripts = $this->view->inlineScript();
$scripts->appendFile('my.js');
$scripts->appendScript('alert("' . $msg . '")');

If there’s no relation between JavaScript and PHP you can simply put all this code into a separate .js file and load it from there. This is by the way the best solution because the file is cached by the browser, if the cache is enabled. But most of the time you perhaps have to send some variables from PHP to the JavaScript code.

It would be perfect if you had some kind of a variable placeholders – exactly as you have it in the Zend Framework’s view scripts!

Another View

This is completely possible – just forget about the default view – it renders the view script and it’s bind to the /views/scripts folder. You can make another, completely new, view instead! Here’s some source:

$view = new Zend_View();
$view->setBasePath('path_to_the_js_folder');
 
$view->msg = 'Some dynamically generated message';
 
// script tags
/* @var $scripts Zend_View_Helper_InlineScript */
$scripts = $this->view->inlineScript();
$scripts->appendFile('my.js');
$scripts->appendScript($view->render('inline.js'));

Thus now in the JS file you can have some placeholders!

// inline.js
 
// some js code
// ...
alert('<?php echo $this->msg ?>');