├── .gitignore └── classes ├── youtube.php └── youtube ├── video.php ├── playlist.php ├── playlist ├── video.php ├── result.php ├── data.php ├── item.php └── video │ └── data.php ├── video ├── result.php └── item.php ├── user.php ├── core.php ├── item.php ├── result.php └── data.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /classes/youtube.php: -------------------------------------------------------------------------------- 1 | _items[] = new YouTube_Video($item->video); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /classes/youtube/playlist/result.php: -------------------------------------------------------------------------------- 1 | _items[] = new YouTube_Playlist_Item($item); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /classes/youtube/user.php: -------------------------------------------------------------------------------- 1 | _playlists = new YouTube_Playlist($this->_user); 12 | } 13 | 14 | public function playlists() 15 | { 16 | return $this->_playlists; 17 | } 18 | } -------------------------------------------------------------------------------- /classes/youtube/playlist/data.php: -------------------------------------------------------------------------------- 1 | _url = YouTube::API_URL.'users/'.$user.'/playlists?v=2&alt=jsonc'; 8 | 9 | $this->_result_type = YouTube::PLAYLIST_RESULT; 10 | 11 | parent::__construct('yt_user_'.$user); 12 | } 13 | } -------------------------------------------------------------------------------- /classes/youtube/playlist/item.php: -------------------------------------------------------------------------------- 1 | _videos = new YouTube_Playlist_Video_Data($this->id); 12 | } 13 | 14 | public function videos() 15 | { 16 | return $this->_videos; 17 | } 18 | } -------------------------------------------------------------------------------- /classes/youtube/core.php: -------------------------------------------------------------------------------- 1 | _meta = array( 20 | 'id' => $data->id, 21 | 'title' => $data->title, 22 | 'description' => $data->description 23 | ); 24 | } 25 | 26 | /** 27 | * Handles retrieval of metadata. 28 | * 29 | * @param string meta name 30 | * @return mixed 31 | */ 32 | public function __get($name) 33 | { 34 | if (array_key_exists($name, $this->_meta)) 35 | { 36 | return $this->_meta[$name]; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /classes/youtube/playlist/video/data.php: -------------------------------------------------------------------------------- 1 | _playlist_id = $id; 12 | 13 | $this->_url = YouTube::API_URL.'playlists/'.$id.'?v=2&alt=jsonc&orderby='.$order_by; 14 | 15 | $this->_result_type = YouTube::VIDEO_RESULT; 16 | 17 | parent::__construct($id); 18 | } 19 | 20 | public function __sleep() 21 | { 22 | return Arr::merge(array('_playlist_id', '_meta'), parent::__sleep()); 23 | } 24 | 25 | protected function _initialize() 26 | { 27 | $data = parent::_initialize(); 28 | 29 | $this->_meta = array( 30 | 'id' => $data->id, 31 | 'title' => $data->title, 32 | 'description' => $data->description 33 | ); 34 | 35 | return $data; 36 | } 37 | } -------------------------------------------------------------------------------- /classes/youtube/video/item.php: -------------------------------------------------------------------------------- 1 | viewCount; 16 | } catch (Exception $e) { 17 | $view_count = 0; 18 | } 19 | 20 | // initialize video properties 21 | $meta = array( 22 | 'duration' => $this->sec2hms($data->duration, true), 23 | 'views' => $view_count 24 | ); 25 | 26 | // merge extended meta properties with base meta 27 | $this->_meta = Arr::merge($this->_meta, $meta); 28 | 29 | $this->_thumbnails = array( 30 | 'small' => $data->thumbnail->sqDefault, 31 | 'large' => $data->thumbnail->hqDefault 32 | ); 33 | $this->_timestamp = strtotime($data->uploaded); 34 | } 35 | 36 | /** 37 | * Get thumbnail for video 38 | * 39 | * @param string thumb size (small|large) 40 | * @return string thumb url 41 | */ 42 | public function thumb($size = 'large') 43 | { 44 | if ($size != 'large') 45 | { 46 | // default to small thumb 47 | $size = 'small'; 48 | } 49 | 50 | return $this->_thumbnails[$size]; 51 | } 52 | 53 | /** 54 | * Get link for video player 55 | * 56 | * @param string type of link: short or embed 57 | * @return string url to video 58 | **/ 59 | public function link($type = false) 60 | { 61 | switch ($type) 62 | { 63 | case 'short': 64 | return 'http://youtu.be/'.$this->id; 65 | break; 66 | case 'embed': 67 | return 'http://www.youtube.com/embed/'.$this->id; 68 | break; 69 | default: 70 | return 'http://www.youtube.com/watch?v='.$this->id; 71 | } 72 | } 73 | 74 | /** 75 | * Format the uploaded timestamp 76 | * 77 | * @return string date 78 | **/ 79 | public function uploaded($format = false) 80 | { 81 | if ( ! $format) 82 | { 83 | $format = 'F jS, Y g:i a T'; 84 | } 85 | 86 | return date($format, $this->_timestamp); 87 | } 88 | 89 | /** 90 | * Convert time in seconds to hh:mm:ss 91 | * 92 | * @return string time 93 | **/ 94 | private function sec2hms ($sec, $padHours = false) 95 | { 96 | $hms = ""; 97 | 98 | $hours = intval(intval($sec) / 3600); 99 | 100 | if ($hours > 0) 101 | { 102 | $hms .= ($padHours) 103 | ? str_pad($hours, 2, "0", STR_PAD_LEFT). ":" 104 | : $hours. ":"; 105 | } 106 | 107 | $minutes = intval(($sec / 60) % 60); 108 | 109 | $hms .= str_pad($minutes, 2, "0", STR_PAD_LEFT). ":"; 110 | 111 | $seconds = intval($sec % 60); 112 | 113 | $hms .= str_pad($seconds, 2, "0", STR_PAD_LEFT); 114 | 115 | return $hms; 116 | } 117 | } -------------------------------------------------------------------------------- /classes/youtube/result.php: -------------------------------------------------------------------------------- 1 | _items); 24 | } 25 | 26 | /** 27 | * the current position index in the array of items. 28 | * 29 | * @var int index 30 | */ 31 | private $_position; 32 | 33 | /** 34 | * Implements [Iterator::current], returns the current item. 35 | * 36 | * echo current($result); 37 | * 38 | * @return integer 39 | */ 40 | public function current() 41 | { 42 | return $this->_items[$this->_position]; 43 | } 44 | 45 | /** 46 | * Implements [Iterator::key], returns the current item number. 47 | * 48 | * echo key($result); 49 | * 50 | * @return integer 51 | */ 52 | public function key() 53 | { 54 | return $this->_position; 55 | } 56 | 57 | /** 58 | * Implements [Iterator::next], moves to the next item. 59 | * 60 | * next($result); 61 | * 62 | * @return $this 63 | */ 64 | public function next() 65 | { 66 | ++$this->_position; 67 | return $this; 68 | } 69 | 70 | /** 71 | * Implements [Iterator::rewind], sets the current item to zero. 72 | * 73 | * rewind($result); 74 | * 75 | * @return $this 76 | */ 77 | public function rewind() 78 | { 79 | $this->_position = 0; 80 | return $this; 81 | } 82 | 83 | /** 84 | * Implements [Iterator::valid], checks if the current item exists. 85 | * 86 | * [!!] This method is only used internally. 87 | * 88 | * @return boolean 89 | */ 90 | public function valid() 91 | { 92 | return isset($this->_items[$this->_position]); 93 | } 94 | 95 | /** 96 | * Implements [ArrayAccess::offsetExists], determines if item exists. 97 | * 98 | * @return boolean 99 | */ 100 | public function offsetExists($offset) 101 | { 102 | return isset($this->_items[$offset]); 103 | } 104 | 105 | /** 106 | * Implements [ArrayAccess::offsetGet], gets a given item. 107 | * 108 | * @return mixed 109 | */ 110 | public function offsetGet($offset) 111 | { 112 | return isset($this->_items[$offset]) ? $this->_items[$offset] : null; 113 | } 114 | 115 | /** 116 | * Implements [ArrayAccess::offsetSet], throws an error. 117 | * 118 | * [!!] You cannot modify a result. 119 | * 120 | * @return void 121 | * @throws Kohana_Exception 122 | */ 123 | final public function offsetSet($offset, $value) 124 | { 125 | throw new Kohana_Exception('YouTube results are read-only'); 126 | } 127 | 128 | /** 129 | * Implements [ArrayAccess::offsetUnset], throws an error. 130 | * 131 | * [!!] You cannot modify a result. 132 | * 133 | * @return void 134 | * @throws Kohana_Exception 135 | */ 136 | final public function offsetUnset($offset) 137 | { 138 | throw new Kohana_Exception('YouTube results are read-only'); 139 | } 140 | } -------------------------------------------------------------------------------- /classes/youtube/data.php: -------------------------------------------------------------------------------- 1 | _cache_key = $name; 33 | 34 | // Initialize data 35 | $data = $this->_initialize(); 36 | 37 | // set meta properties 38 | $this->_pagination = array( 39 | 'total_items' => $data->totalItems, 40 | 'items_per_page' => $data->itemsPerPage, 41 | 'offset' => $data->startIndex - 1, 42 | 'limit' => $data->totalItems 43 | ); 44 | } 45 | 46 | /** 47 | * Initialize the data for the class 48 | * Makes an API call if needed 49 | * 50 | * @return mixed 51 | */ 52 | protected function _initialize() 53 | { 54 | // check if a result type is set 55 | if ($this->_result_type === NULL) 56 | { 57 | throw new Exception('No result type set.'); 58 | } 59 | 60 | // check to see if data is cached first 61 | $data = Kohana::cache($this->_cache_key); 62 | 63 | // Get fresh feed 64 | if ($data === NULL OR ! YouTube::$use_cache) 65 | { 66 | try { 67 | // Request the feed url 68 | $request = Request::factory($this->_url)->method('GET'); 69 | $feed = $request->execute(); 70 | } catch (Exception $e) { 71 | // Do nothing for now 72 | // @todo some error checking 73 | return FALSE; 74 | } 75 | 76 | $json = json_decode($feed); 77 | 78 | if ($json !== NULL) 79 | { 80 | $data = $json->data; 81 | } 82 | else 83 | { 84 | return FALSE; 85 | } 86 | } 87 | 88 | // cache the data 89 | Kohana::cache($this->_cache_key, $data, 300); 90 | 91 | return $data; 92 | } 93 | 94 | /** 95 | * Handles retrieval of metadata. 96 | * 97 | * @param string meta name 98 | * @return mixed 99 | */ 100 | public function __get($name) 101 | { 102 | if (array_key_exists($name, $this->_meta)) 103 | { 104 | return $this->_meta[$name]; 105 | } 106 | else if (array_key_exists($name, $this->_pagination)) 107 | { 108 | return $this->_pagination[$name]; 109 | } 110 | } 111 | 112 | public function __sleep() 113 | { 114 | return array('_pagination', '_url', '_cache_key', '_result_type'); 115 | } 116 | 117 | public function __wakeup() 118 | { 119 | $this->_initialize(); 120 | } 121 | 122 | public function offset($num) 123 | { 124 | $this->_pagination['offset'] = $num; 125 | 126 | return $this; 127 | } 128 | 129 | public function limit($count) 130 | { 131 | $this->_pagination['limit'] = $count; 132 | 133 | return $this; 134 | } 135 | 136 | /** 137 | * Find all related items 138 | * 139 | * @return YouTube_Result class (depends on result type of this class) 140 | */ 141 | public function find_all() 142 | { 143 | $result_type = $this->_result_type; 144 | 145 | $data = $this->_initialize(); 146 | 147 | // paginate items 148 | $items = array_slice( 149 | $data->items, 150 | $this->_pagination['offset'], 151 | $this->_pagination['limit'] 152 | ); 153 | 154 | return new $result_type($items); 155 | } 156 | 157 | /** 158 | * Find a specific item 159 | * 160 | * @param string $id 161 | * @return YouTube_Item (depends on result type of this class) 162 | */ 163 | public function find($id) 164 | { 165 | $search_ids = array(); 166 | 167 | $data = $this->_initialize(); 168 | 169 | foreach ($data->items as $item) 170 | { 171 | $search_ids[] = ($this->_result_type === YouTube::VIDEO_RESULT) ? 172 | $item->video->id : $item->id; 173 | } 174 | 175 | $index = (is_int($id)) ? $id : array_search($id, $search_ids); 176 | 177 | $result_type = $this->_result_type; 178 | 179 | $results = new $result_type($data->items); 180 | 181 | return ($index !== FALSE) ? $results[$index] : $index; 182 | } 183 | } 184 | --------------------------------------------------------------------------------