Tag Archives: Web 2.0

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.

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.

Zend_Validate_Alnum Doesn’t Work Correctly

Zend Framework’s Zend_Validate

I’m used to validate the form in a typical Zend Framework application with Zend_Validate or course. It gives you the absolute power to use the build in classes for standard validation, as well as write your custom validation classes.

The problem I had was a bit odd! Zend_Validate_Alnum is supposed to filter all characters and numbers, but what about non Latin symbols!? The project I’m working on is multilingual and there are eight languages, including Arabic, Chinese and Russian! All these were incorrectly !not validated by Zend_Validate_Alnum, although there were only letters and numbers!

In fact whatever the string encoding was – it doesn’t seem to work! Perhaps I’m wrong, but so far this is the situation.

Recent Update

After few test I figured out the problem was not in Zend_Validate at all! My mistake the solution is:

iconv_set_encoding('input_encoding', 'UTF-8');
iconv_set_encoding('output_encoding', 'UTF-8');
iconv_set_encoding('internal_encoding', 'UTF-8');

Send Mail with Zend Framework

Simple, but Doesn’t Work!

It may sound strange, because all this is quite well documented in the Zend Framework documentation. Indeed it’s very very simple and all is done only by few lines of code.

$mail = new Zend_Mail();
$mail->setFrom('sender@example.com');
$mail->setBodyHtml('some message - it may be html formatted text');
$mail->addTo('recipient@example.com', 'recipient');
$mail->setSubject('subject');
$mail->send();

Even it look simple though, it may not work on your localhost while you’re trying to make it work! Because you’ve to have sendmail setup. And in Zend Framework sendmail is the default transport protocol for sending mails.

What You Have to Do to Make it Work?

Actually you’ve simply to add a transport protocol, just like that:

$tr = new Zend_Mail_Transport_Smtp('smtp.example.com',
                    array('auth' => 'login',
                             'username' => 'username',
                             'password' => 'password'));
Zend_Mail::setDefaultTransport($tr);

Where Did I Get These?

Well look at your favorite mail account you probably use every day. It may be hosted in GMail or wherever, but there are some configurations you have to port under Zend’s code and everything will be just fine until you develop the app!

Modyfing Response Headers with Zend Framework

Response Headers

You’ve probably seen that you can track the server response headers with Firebug – a wonderful extension to Firefox.

But have you ever asked yourself how to change a response header with Zend Framework.

header()

Typically this is done with the built in PHP function header, where you can setup the header the page must return, but how to make it with Zend Framework?

It’s pretty simple of course, it’s Zend Framework in fact. To be more precise I’ll post a snippet:

$response = $this->getResponse();
$response->setHeader('content-type', 'application/x-javascript; charset=utf-8');
$response->sendResponse();