Tag Archives: controller

Zend_Controller_Router_Route_Regex – the Power of Regular Expressions

I posted once of custom URLs within Zend Framework, but back than I wasn’t quite sure enough there isn’t a better, more elegant way to do this job. Of course as it appears, there is! With no need to is to use the power of regular expressions with Zend_Controller_Router_Route_Regex. Thus you can match dynamically the URL.

Let’s assume you’d like to have a link with something like www.example.com/3939-some-title-here. This is really very common. So to proceed you’d have to have some regex like:

$pattern = '/\d+-.*/;

So what about Zend Framework

Here the things are going naturally more OOP.

$route = new Zend_Controller_Router_Route_Regex('(\d+)-?(.*)',
                       array('controller' => 'controller_name', 'action' => 'action_name'),
                       array(1 => 'id'));
 
$ctrl->addRoute('my-route', $route);

Iterate over YouTube Channel with Zend_Gdata_YouTube

Read YouTube’s Feed in Zend App

The task is to read the entire Gdata from a YouTube’s channel. It may sound easy, but as you may know Gdata is based on the Atom publishing protocol, and it naturally gives you only the latest few items.

Of course Zend Framework has a large set of classes dealing with Google’s Gdata services, one of them is the Zend_Gdata_YouTube.

It gives you the power to iterate/paginate over the entire set of YouTube user’s/channel’s videos. In that example let’s assume you have a protected function doing the reading of a single portion:

protected function _process(Zend_Gdata_YouTube_VideoFeed $videoFeed)
{
 
    /* @var $entry Zend_Gdata_YouTube_VideoEntry */
    foreach ($videoFeed as $entry) {
        /* @var $published Zend_Gdata_App_Extension_Published */
        $published = $entry->getPublished();
        $thumbnails = $entry->getVideoThumbnails();
 
        // set date format
        $date = new Zend_Date($published->getText());
 
        // array
        $tags = $entry->getVideoTags();
 
        $data['title'] = $entry->getVideoTitle();
        $data['description'] = $entry->getVideoDescription();
        $data['date'] = $date->get('Y-MM-d hh:mm:ss');
        $data['thumb'] = @$thumbnails[3]['url'];
        $data['id'] = $entry->getVideoId();
        $data['flash_player'] = $entry->getFlashPlayerUrl();
        $data['tags'] = implode(',', $tags) . ', ' . $entry->getVideoCategory();
        // do whatever you want with the data
    }
 
}

The only thing left is to iterate over the “pages” of the feed. This can be done with getNextFeed() method.

public function readRssAction()
{
    $userId = 'some_user';
    $client = new Zend_Http_Client();
    $gdata = new Zend_Gdata_YouTube($client, 'my-app', null, $this->_apiKey);
    $videoFeed = $gdata->getUserUploads($userId);
 
    // save the last items
    $this->_process($videoFeed);
 
    try {
        while ($videoFeed = $videoFeed->getNextFeed()) {
            $this->_process($videoFeed);
        }
    } catch (Zend_Gdata_App_Exception $e) {
        echo $e->getMessage();
    }
}

You’ll get an exception when there is no more feeds to process!

To combine all this into a single controller and to complete the code here’s the entire source:

class YoutubeController extends Zend_Controller_Action
{
    protected $_apiKey = 'your_api_key_goes_here';
 
    protected function _process(Zend_Gdata_YouTube_VideoFeed $videoFeed)
    {
 
        /* @var $entry Zend_Gdata_YouTube_VideoEntry */
        foreach ($videoFeed as $entry) {
            /* @var $published Zend_Gdata_App_Extension_Published */
            $published = $entry->getPublished();
            $thumbnails = $entry->getVideoThumbnails();
 
            // set date format
            $date = new Zend_Date($published->getText());
 
            // array
            $tags = $entry->getVideoTags();
 
            $data['title'] = $entry->getVideoTitle();
            $data['description'] = $entry->getVideoDescription();
            $data['date'] = $date->get('Y-MM-d hh:mm:ss');
            $data['thumb'] = @$thumbnails[3]['url'];
            $data['id'] = $entry->getVideoId();
            $data['flash_player'] = $entry->getFlashPlayerUrl();
            $data['tags'] = implode(',', $tags) . ', ' . $entry->getVideoCategory();
            // do whatever you want with the data
        }
    }
 
    public function readRssAction()
    {
        $userId = 'some_user';
        $client = new Zend_Http_Client();
        $gdata = new Zend_Gdata_YouTube($client, 'my-app', null, $this->_apiKey);
        $videoFeed = $gdata->getUserUploads($userId);
 
        // save the last items
        $this->_process($videoFeed);
 
        try {
            while ($videoFeed = $videoFeed->getNextFeed()) {
                $this->_process($videoFeed);
            }
        } catch (Zend_Gdata_App_Exception $e) {
            echo $e->getMessage();
        }
    }
}

Note: here you’ve to substitute the API key with the one you’ve for your development.

Setting a Zend Framework _redirect Referer

Seems to be impossible, just because the only parameters you can set are far less than setting a referrer. Thus you’ve to rely on your browser capabilities. However the most reliable way is to redirect with referrer in mind. Something like _GET parameters.

$this->_redirect('/url/return-to/1');

Once this parameter is processed by the controller/action you can return to the referrer!

Custom Routes with Zend_Controller_Router_Route

Rewrite The Url?

Actually this is really a common task to do. You’ve to rewrite the url to be more “user friendly”. To be more clear I’ll give you an example. Let’s imagine you have a index controller and an index action. Thus if you have to load an Id from the database at least with the build in Zend Framework capabilities, you’ve to use this link:

www.example.com/index/index/id/33949

This is not good. It’s really bad. It will be great if you can use something like this:

www.example.com/33949

The solution in Zend Framework is called Zend_Controller_Router_Route. In a short snippet this will look like so:

$frontController->addRoute("my-route", new Zend_Controller_Router_Route("/:id",
    array("controller" => "index", "action" => "index", 'id' => 1),
    array('id' => '\d+')));

Here as you can see id is set to be 1. But don’t worry that’s not a hard code. The real work is done by the last parameter where the id is matched against a number value. Thus www.example.com/3 will be OK, but www.example.com/3a won’t.

Important Note

Don’t forget to add this rewrite rule in the .htaccess file.

Escaping strings in a Zend Framework view. Prevent unclosed tags!

In most of the tutorials about Zend Framework the simple theory is described how all these MVC things may work together. However beyond that the things become more and more tricky and not everything is done by the MVC pattern itself.

What I mean is that reading most of the tutorials about ZF I found describing the simple relationship between controllers and views just by setting up a view member variable in the controller and than simply call that variable in the view of that particular controller action.

Setup controller’s view variable. In this example I used the default ZF IndexController – indexAction:

public IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->view->greeting = ‘Hello World!’;
    }
}

where afterwards you can call this member variable in the index.phtml view in the index view scripts.

Note: In a typical Zend Framework installation all this is setup into the application folder (either web visible or not), where the IndexController.php file containing the code above is placed into the application/controllers and its indexAction stores its view in the application/views/scripts/index/index.phtml

In that situation the view file, the previously mentioned index.phtml should access this “greeting” variable in something like:

<div><?php echo $this->greeting ?></div>

Note that here you miss the ->view-> part of the chain. That’s because the view’s parsed and now this contains everything that the controller’s view member object contains.

All that is pretty cool and it works great until you start accessing and working with different type of data escaped or not, coming from various sources.

Natively comes the problem of escaping bad strings and the single question is why should I do that? To give you a simple example I’ll describe the above code in a different manner.

Imagine you should setup a browser specific title depending of the controller/action you call. To do that is simple but there comes the tricky part. In the example above we can just change the code a bit.

In the controller you can setup the browserTitle variable:

<?php
class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->view->browserTitle = “Welcome”;
    }
}

Than normally in the view you may have something like that:

<html>
<head>
<title><?php echo $this->browserTitle ?></title>
...

Everything until that looks normal and you don’t need to escape whatever as it appears. Even if the browserTitle contains something with quotes:

...
$this->view->browserTitle = ‘Hello ”World”’;
...

This will result in the browser’s source view as:

...
<title>Hello “World”</title>
...

see the image below:


But what if you setup a meta title tag:

<meta name=”title” content=”Hello “World”” />

for the browser that’s an error as shown on the image:

There’s why you simply should be careful when dumping variables all over the page and to use the native ZF escape function.

$this->escape()

In the example above you simply can call the escape function into the view:

<html>
<head>
<title><?php echo $this->browserTitle ?></title>
<meta name=”title” content=”<?php echo $this->escape($this->browserTitle) ?>” />

That will prevent the browser to “crash” and of course and more important will improve the site’s SEO.