Youtube library for CodeIgniter

It has been almost a year that I’m using CodeIgniter and I can tell you that the thing missing with this framework is libraries. Today I’m gonna share with you this youtube library which basically return an array of video for a keywords, very useful if you need to illustrate a article or whatever you want actually.
In this library I use methods chaining like the highchart library. There for you have to return the current object in each method (return $this). let’s have a look.
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* @file system/application/libraries/Youtube_Lib.php
* @version 1.0
* @author Maxime
*/
class Youtube_Lib{
protected $url = 'http://gdata.youtube.com/feeds/api/videos?';
protected $a_options;
function Youtube_Lib(){
$this->a_options = array();
}
In the constructor I’m just initializing the array of option that will use to build the request URL. As you can see I’ve declare 2 protected (can be set to private) variables, “$url” which is the base URL for the search request.
public function result_array(){
$return = array();
# Build the URL
if(!empty($this->a_options)){
$this->url .= '&'.implode('&', $this->a_options);
}
$o_xml = $this->get_oxml();
if(is_object($o_xml) && isset($o_xml->entry)){
foreach($o_xml->entry as $video){
$tmp = $this->parse_video($video);
if(!empty($tmp)){
$return[] = $tmp;
}
}
}
return $return;
}
This is the main method of the library. It returns the results of the query into a PHP array that you can send to your view and organise the result as you wish. In this method we first start to initialize the $return variable as an empty array (I always did that into my function to be sure of the type of data I’m returning). The second thing I’m doing is to build the request URL using the options array after what I’m calling the get_oxml() methods. This method is returning a simpleXMLElement object. After what I’m just browsing the array to parse the video elements using “parse_video()” method which return an array of information about the video.
/**
* Create a simple XML Object with the XML String received and return it
*
* @return Mixed
*/
private function get_oxml(){
$s_xml = $this->get_curl();
try {
$obj_xml = @new SimpleXMLElement($s_xml, LIBXML_NOCDATA);
}
catch (Exception $e){
//if ($this->debug) echo 'Invalid XML string: ' , $e->getMessage() , "";
$obj_xml = FALSE;
}
return $obj_xml;
}
/**
* curl function to call the API
*
* @param string $s_url
* @return xml result
*/
private function get_curl(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; EN-US; RV:1.9.0.3) GECKO/2008092417 FIREFOX/3.0.3");
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // timeout de 10 sec.
# we get the xml file contening the ads
$str_xml = curl_exec($ch);
$error = curl_error($ch);
$info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
# we close the curl connexion
curl_close($ch);
return $str_xml;
}
This 2 previous methods are used to request the the XML feed and build the simpleXMLElement. In each of the library that I’m building I like to build clear function which are going only one thing and not several. That’s why there is one function using cURL to do the HTTP request to google and get back the XML Feed (which could be used in different way) and an other function to transform this XML response into a simpleXMLElement object. We could imagine a cache system into the get_oxml() method to avoid to request to Google always the same query (Update: cache system has been added).
Now we will have a look to the others methods which allow us to specify filters into the request that we will send to google.
/**
* Add the keyword to the search query
*
* @param String $keyword
* @return $this
*/
public function search($keyword=FALSE){
$return = array();
if($keyword !== FALSE && trim($keyword) != ''){
$this->a_options[] = 'q='.urlencode(trim($keyword));
}
return $this;
}
This function is to specify the keyword to search. I take this exemple because it’s the method that you will probably use the most and all the other method are built on the same base. Here we just add to the option array. There is a bunch of options that we can specify requesting Youtube Video, I just picked up the most used one and create methods for them. You can add has much method as you wish according your need. I won’t explain the following methods as there working like the one I’ve just explained but I’m gonna list them and tell you what they are used for.
# Add a ordering filter to the results function orderby(['relevance','published','viewCount,'rating']) # Add a video format filter to the results function format(['h263','swf','mpeg4']) # Add a developer key to the query (this method is compulsory) function key($str='') # Add a location filter to the results function location($str='') # Add a location_radius filter to the results function location_radius($str='') # Add a restrictions filter to the results function restriction($str='') # Limit the number of results and offset function limit($str=10, $offset=0) # Add an offset to the result function offset($str=0) # Specified a safesearch parameter to the query (no idea what this is) function safeSearch(['none','moderate','strict']) # Specify a time range for the result function time(['today','this_week','this_month','all_time']) # This method is used to parse the video element function parse_video(&$o_xml_video)
Now let’s see how to use this library. Basically we have to load it and build the chain of methods before to return whatever we want (XML or an array or what ever you wish to return). Here is the sample of code:
# Search on youtube
$this->load->library('Youtube_Lib');
$a_vid = $this->youtube_lib
->orderby('viewCount')
->search('ken block')
->limit(3)
->format('h263')
->result_array();
Firstly we are loading the Codeigniter library. After what I’m asking to order the results by number of view (most viewed video first), I want to get a result related to the keyword “Ken Block”, I want only 3 results to the H263 format and I want the result into an array. And here we go, we got our list of video into an array which is affected to the $a_vid variable.
And here is the results:
KEN BLOCK GYMKHANA TWO THE INFOMERCIALDCSHOES.COM/GYMKHANATWO Riding on the success of the first Gymkhana Practice video that grabbed the attention of over 20 million viewers worldwide, the Gymkhana TWO video takes infomercials to the next level…
Ken Block Gymkhana PracticeKen Block Gymkhana Practice www.kenblockracing.com
Gymkhana THREE, Part 2; Ultimate Playground; l’Autodrome, FranceShot just south of Paris, France in Linas at l’Autodrome de Linas –Montlhéry, this 1.58 mile oval track, built in 1924, features banks as steep as 51 degrees, which is more than double the standard incline of most NASCAR ovals. Chosen by Ken for this specific reason, the ramp-like banking proved to be a unique and exciting challenge…
And finally, here is the full source code of the library.
a_options = array();
}
/**
* Return an array of results
*
* @param Boolean $b_cache
* @return Array
*/
public function result_array($b_cache=FALSE){
$return = array();
# Build the URL
if(!empty($this->a_options)){
$this->url .= '&'.implode('&', $this->a_options);
}
$o_xml = $this->get_oxml($b_cache);
if(is_object($o_xml) && isset($o_xml->entry)){
foreach($o_xml->entry as $video){
$tmp = $this->parse_video($video);
if(!empty($tmp)){
$return[] = $tmp;
}
}
}
return $return;
}
/**
* Execute the query and return the XML result
*
* @param Boolean $b_cache
* @return XMLString
*/
public function result_xml($b_cache=FALSE){
# Build the URL
if(!empty($this->a_options)){
$this->url .= '&'.implode('&', $this->a_options);
}
# reset the options
$this->a_options = array();
return $this->get_curl($b_cache);
}
/**
* Add the keyword to the search query
*
* @param String $keyword
* @return $this
*/
public function search($keyword=FALSE){
$return = array();
if($keyword !== FALSE && trim($keyword) != ''){
$this->a_options[] = 'q='.urlencode(trim($keyword));
}
return $this;
}
/**
* Add a ordering filter to the results
*
* @param String $str
* @return $this
*/
public function orderby($str=''){
if($str!=''){
switch (trim(strtolower($str))){
case 'relevance':$this->a_options[] = 'orderby=relevance';break;
case 'published':$this->a_options[] = 'orderby=published';break;
case 'viewCount':$this->a_options[] = 'orderby=viewCount';break;
case 'rating':$this->a_options[] = 'orderby=rating';break;
}
}
return $this;
}
/**
* Add a video format filter to the results
*
* @param String $str
* @return $this
*/
public function format($str=''){
if($str!=''){
switch (trim(strtolower($str))){
case 'h263':$this->a_options[] = 'format=1';break;
case 'swf':$this->a_options[] = 'format=5';break;
case 'mpeg4':$this->a_options[] = 'format=6';break;
}
}
return $this;
}
/**
* Add a developer key to the query
*
* @param String $str
* @return $this
*/
public function key($str=''){
if($str!=''){
$this->a_options[] = 'key='.$str;
}
return $this;
}
/**
* Add a location filter to the results
*
* @param String $str
* @return $this
*/
public function location($str=''){
if($str!=''){
$this->a_options[] = 'location='.$str;
}
return $this;
}
/**
* Add a location_radius filter to the results
*
* @param String $str
* @return $this
*/
public function location_radius($str=''){
if($str!=''){
$this->a_options[] = 'location-radius='.$str;
}
return $this;
}
/**
* Add a restriction filter to the results
*
* @param String $str
* @return $this
*/
public function restriction($str=''){
if($str!=''){
$this->a_options[] = 'restriction='.$str;
}
return $this;
}
/**
* Limit the number of results
*
* @param Integer $str
* @return $this
*/
public function limit($str=10, $offset=0){
if(is_numeric($str)){
$this->a_options[] = 'max-results='.$str;
}
if(is_numeric($offset) && $offset > 0){
$this->offset($offset);
}
return $this;
}
/**
* Limit the number of results
*
* @param Integer $str
* @return $this
*/
public function offset($str=0){
if(is_numeric($str) && $str > 0){
$str++;
$this->a_options[] = 'start-index='.$str;
}
return $this;
}
/**
* Add a safeSearch filter to the results
*
* @param String $str
* @return $this
*/
public function safeSearch($str=''){
if($str!=''){
switch (trim(strtolower($str))){
case 'none':$this->a_options[] = 'safeSearch=none';break;
case 'moderate':$this->a_options[] = 'safeSearch=moderate';break;
case 'strict':$this->a_options[] = 'safeSearch=strict';break;
}
}
return $this;
}
/**
* Add a time filter to the results
*
* @param String $str
* @return $this
*/
public function time($str=''){
if($str!=''){
switch (trim(strtolower($str))){
case 'today':$this->a_options[] = 'time=today';break;
case 'this_week':$this->a_options[] = 'time=this_week';break;
case 'this_month':$this->a_options[] = 'time=this_month';break;
case 'all_time':$this->a_options[] = 'time=all_time';break;
}
}
return $this;
}
/**
* Create a simple XML Object with the XML String received and return it
*
* @param Boolean $b_cache
* @return Mixed
*/
private function get_oxml($b_cache=FALSE){
$s_xml = $this->get_curl($b_cache);
try {
$obj_xml = @new SimpleXMLElement($s_xml, LIBXML_NOCDATA);
}
catch (Exception $e){
//if ($this->debug) echo 'Invalid XML string: ' , $e->getMessage() , "";
$obj_xml = FALSE;
}
return $obj_xml;
}
/**
* curl function to call the API
*
* @param string $s_url
* @param boolean $b_cache
* @return xml result
*/
private function get_curl($b_cache=FALSE){
$request = TRUE;
# If the user decide to use the cache, we check that we have the data into the cache
if($b_cache === TRUE){
$md5_cache = 'itunes_'.md5($this->url).'.cache';
# The cache folder is always located at the same place system/cache
$cache_dir = dirname(__FILE__).'/../../cache/libraries';
$cache_file = $cache_dir.'/'.$md5_cache;
# We check that the folder exist, if not create it
if(!file_exists($cache_dir)){
mkdir($cache_dir);
}else{
# Now we check the file exists and is not out of date
if(file_exists($cache_file)){
$filemtime = @filemtime($cache_file);
# If the cache still up to date
if ($filemtime !== FALSE && (time() - $filemtime < $this->cache_life)){
$request = FALSE;
$str_xml = file_get_contents($cache_file);
}else{
@unlink($cache_file);
}
}
}
}
if($request === TRUE){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "MOZILLA/5.0 (WINDOWS; U; WINDOWS NT 5.1; EN-US; RV:1.9.0.3) GECKO/2008092417 FIREFOX/3.0.3");
// curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // timeout de 10 sec.
# we get the xml file contening the ads
$str_xml = curl_exec($ch);
$error = curl_error($ch);
$info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
# we close the curl connexion
curl_close($ch);
# If the cache is enabled, we save the response into the cache
if($b_cache === TRUE){
$fp = fopen($cache_file, 'w+');
fwrite($fp, $str_xml);
fclose($fp);
}
}
return $str_xml;
}
private function parse_video(&$o_xml_video){
$return = array();
if(isset($o_xml_video->id)){
$return['id'] = (string)$o_xml_video->id;
$return['title'] = (string)$o_xml_video->title;
$return['desc'] = (string)$o_xml_video->content;
$return['author'] = (string)$o_xml_video->author->name;
$return['author_link'] = (string)$o_xml_video->author->uri;
$return['published_date'] = (integer)strtotime((string)$o_xml_video->published);
$return['updated_date'] = (integer)strtotime((string)$o_xml_video->updated);
$return['category'] = array();
if(isset($o_xml_video->category)){
foreach($o_xml_video->category as $cat){
if(isset($cat->attributes()->label)){
$return['category'][] = (string)$cat->attributes()->label;
}
}
}
if(isset($o_xml_video->link)){
foreach($o_xml_video->link as $link){
if((string)$link->attributes()->rel == 'alternate'){
$return['url'] = (string)$link->attributes()->href;
}
}
}
# Get the data from the media namespace
$media = $o_xml_video->children('http://search.yahoo.com/mrss/');
if(is_object($media)){
$return['keyword'] = (string)$media->group->keywords;
$return['images']['small'] = array();
$return['images']['large'] = array();
if(isset($media->group->thumbnail)){
foreach($media->group->thumbnail as $img){
$height = (string)$img->attributes()->height;
if($height == '90'){
$return['images']['small'][] = (string)$img->attributes()->url;
}elseif($height == '240'){
$return['images']['large'][] = (string)$img->attributes()->url;
}
}
}
}
}
return $return;
}
}
Excellent! Thanks for the library! Why not post it all in a single easy download though… I thought Frameworks were meant to be cushions for the lazy?