Your own cakephp file-browser for ckeditor: part 3 – youtube videos

Here we are. The basics are still the same of the first part – making you own file explorer popup and using CKEditor.insertHtml to inject the desired generated code into ckeditor.

Of course, the same may be applied to webservices; including data form external sources is not harder than inserting your uploaded files.

At the times, I found this class – it was the best usable php youtube api wrapper, if not the only. Probably there is something new on github – but php5Tube does the job, and does it well. You may use your own choice, of course.

Here is my fork – a sligthly modified version with some features I needed

  1. <?php
  2.  
  3. /**
  4.  * Project: Php5tube: A PHP class for using the Youtube API<br />
  5.  * File: Php5tube.php<br />
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or any later version.<br /><br />
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15.  * Lesser General Public License for more details.<br /><br />
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br /><br />
  20.  *
  21.  * Any modifications to the library should be indicated clearly in the source code
  22.  * to inform users that the changes are not a part of the original software.<br /><br />
  23.  *
  24.  * @link http://www.debuggeddesigns.com/open-source-projects/php5tube Php5tube Youtube API Wrapper
  25.  * @link http://sourceforge.net/projects/php5tube/ Download Latest Version
  26.  * @link http://www.debuggeddesigns.com/open-source-projects/php5tube/docs Online Documentation
  27.  * @copyright 2008 Debugged Interactive Designs
  28.  * @author debuggeddesigns <info@debuggeddesigns.com>
  29.  * @version 0.0.3 (October 07, 2008)
  30.  *
  31.  */
  32.  
  33. /**
  34.  *
  35.  * Fork by Stefano Manfredini
  36.  *
  37.  * added getVideosByKeyword and getVideosByCategory methods, and tweaked some other code
  38.  *
  39.  * this is not intended as a full and all-purpose version of the class;
  40.  * it's mainly a fast add-on to use it for my needs at the moment
  41.  * ..but you can use it and build on it
  42.  *
  43.   ChangeLog
  44.   0.4
  45.   - Suppressed warning messages from bad feed returns and checks for empty results. If there was a problem
  46.   the user will recieve empty arrays out of the methods
  47.   -Added private method parse_multi_video() to reduced the size of php5tube by reducing reused code
  48.   -Author array entry in multi-video search is now a string and no longer a simple_xml_object
  49.  
  50.   0.3
  51.   - Added ability to get a list of the most viewed videos on youtube [getMostViewed()]
  52.  
  53.   0.2
  54.   - Added ability to get a video's information, given the video's youtube id [getVideoInfo()]
  55.   - Added ability to get a video's comments, given the video's youtube id [getVideoComments()]
  56.  
  57.   0.1
  58.   - Added ability to get a user's information, given the user's account name [getUserInfo()]
  59.   - Added ability to get a user's videos, give the user's account name [getUserVideos()]
  60.  
  61. */
  62.  
  63. /**
  64.  * Php5tube Class.
  65.  *
  66.  * Php5tube is a class written by Debugged Interactive Designs in PHP5
  67.  * to act as a wrapper for Youtube's API.
  68.  *
  69.  * Methods process the response XML and return a friendly array of data
  70.  * to make development simple and intuitive.
  71.  *
  72.  */
  73.  
  74. class Php5tube {
  75.  
  76. /*
  77. * Current Working functions
  78. *
  79. * getVideoInfo()
  80. * getUserVideos()
  81. * getUserInfo()
  82. * getMostViewed()
  83. * getVideoComments()
  84. *
  85. * Functions Under Production
  86. *
  87. * getVideosByKeywords($start,$max,$order)
  88. * getVideosByCategory($start,$max,$order)
  89. *
  90. *
  91. */
  92.  
  93. //CLASS VARIABLES
  94.  
  95. /**
  96. * The video object name in the returned array
  97. *
  98. * @var string
  99. */
  100. var $video_object = null;
  101.  
  102. /**
  103. * The user object name in the returned array
  104. *
  105. * @var string
  106. */
  107. var $user_object = null;
  108.  
  109. /**
  110. * The comment object name in the returned array
  111. *
  112. * @var string
  113. */
  114. var $comment_object = null;
  115.  
  116. /**
  117. * Set to the next index in the query
  118. * or -1, if there are no more videos left
  119. *
  120. * @var int
  121. */
  122. var $next_index = -1;
  123.  
  124. var $previous_index = -1;
  125.  
  126. //CLASS CONSTRUCTOR
  127.  
  128. /**
  129. * Class constructor.
  130. *
  131. * <code>
  132. * <?php
  133. * include 'Php5tube.php';
  134. * $php5tube = new Php5tube('Video','User','Comment');
  135. * ?>
  136. * </code>
  137. *
  138. * @param string $video The video object name in the returned array.
  139. * @param string $user The user object name in the returned array
  140. * @param string $comment The comment object name in the returned array
  141. */
  142. function Php5tube($video, $user, $comment) {
  143. $this->video_object = $video;
  144. $this->user_object = $user;
  145. $this->comment_object = $comment;
  146. }
  147.  
  148. //CLASS FUNCTIONS
  149.  
  150. /**
  151. * Returns all youtube videos that belong to the corresponding user.
  152. *
  153. * <code>
  154. * <?php
  155. * include 'Php5tube.php';
  156. * $php5tube = new Php5tube('Video','User','Comment');
  157. * $user_vids = $php5tube->getUserVideos('rickrolled','',1,10);
  158. * ?>
  159. * </code>
  160. *
  161. * @param string $user The account name of the youtube user.
  162. * @param string $category The category to search.
  163. * @param integer $start_index The first video id you want to grab. The default is 1.
  164. * @param integer $max The maximum number of videos returned.
  165. *
  166. * @return array array[<numbered_index>][$this->video_object][<field_name>] where <field_name> =<br />
  167. * {'youtube_id', 'author', 'title', 'description', 'keywords', 'url', 'thumbnail1', 'thumbnail2', 'thumbnail3', 'thumbnail4', 'length', 'view_count', 'favorite_count', 'comments_count'}
  168. */
  169.  
  170. function getUserVideos($user, $category = null, $start_index = 1, $max = 25) {
  171. //set up the url to the feed
  172. $feedURL = 'http://gdata.youtube.com/feeds/api/videos?author=' . $user . '&start-index=' . $start_index . '&max-results=' . $max;
  173.  
  174. //add category variable to feed url, if it exists
  175. if ($category != null) {
  176. $feedURL = $feedURL . '&category=' . $category;
  177. }
  178.  
  179. $videos = array();
  180. //read the feed and place it in an simple_xml object
  181. $xml = @ simplexml_load_file($feedURL);
  182. if (!empty ($xml)) {
  183.  
  184. //get the next start index.
  185. if (isset ($xml->link[4])) {
  186. $this->next_index = (int) preg_replace('/&max-results=' . $max . '/', '', preg_replace('/http:\/\/gdata.youtube.com\/feeds\/api\/videos\?author=' . $user . '&start-index=/', '', (string) $xml->link[4]->attributes()->href));
  187. } //if empty, then set $this->nex_index to -1 to let the user know they have reached the end of the list
  188. else {
  189. $this->next_index = -1;
  190. }
  191.  
  192. $videos = $this->parse_multi_video($xml);
  193. }
  194.  
  195. return $videos;
  196. }
  197.  
  198. /**
  199. * Returns the account information of a youtube user.
  200. *
  201. * <code>
  202. * <?php
  203. * include 'Php5tube.php';
  204. * $php5tube = new Php5tube('Video','User','Comment');
  205. * $user_info = $php5tube->getUserInfo('rickrolled');
  206. * ?>
  207. * </code>
  208. *
  209. * @param string $user - The account name of the youtube user.
  210. *
  211. * @return array array[$this->user_object][<field_name>] where <field_name> =<br />
  212. * {'username', 'first_name', 'last_name', 'age', 'hobbies', 'relationship', 'occupation', 'music','movies', 'location', 'hometown', 'gender', 'description'}
  213. *
  214. */
  215. function getUserInfo($user) {
  216.  
  217. $authorURL = 'http://gdata.youtube.com/feeds/api/users/' . $user;
  218.  
  219. $xml = @simplexml_load_file($authorURL);
  220. $author_array = array ();
  221. if (!empty ($xml)) {
  222. $author = $xml->children('http://gdata.youtube.com/schemas/2007');
  223. //user's user name'
  224. $author_array[$this->user_object]['username'] = (string) $author->username;
  225. //users first name (if supplied)
  226. $author_array[$this->user_object]['first_name'] = (string) $author->firstName;
  227. //users last name (if supplied)
  228. $author_array[$this->user_object]['last_name'] = (string) $author->lastName;
  229. //users age (if supplied)
  230. $author_array[$this->user_object]['age'] = (string) $author->age;
  231. //users hobbies (if supplied)
  232. $author_array[$this->user_object]['hobbies'] = (string) $author->hobbies;
  233. //users relationship (if supplied) ie single, married, etc...
  234. $author_array[$this->user_object]['relationship'] = (string) $author->relationship;
  235. //users occupation
  236. $author_array[$this->user_object]['occupation'] = (string) $author->occupation;
  237. //favorite music
  238. $author_array[$this->user_object]['music'] = (string) $author->music;
  239. //favorite movies (not youtube videos) ... the rest are pretty obvious
  240. $author_array[$this->user_object]['movies'] = (string) $author->movies;
  241. $author_array[$this->user_object]['location'] = (string) $author->location;
  242. $author_array[$this->user_object]['hometown'] = (string) $author->hometown;
  243. $author_array[$this->user_object]['gender'] = (string) $author->gender;
  244. $author_array[$this->user_object]['description'] = (string) $author->description;
  245. }
  246. return $author_array;
  247. }
  248.  
  249. /**
  250. * Returns a list of the most frequently viewed videos on youtube.
  251. *
  252. * <code>
  253. * <?php
  254. * include 'Php5tube.php';
  255. * $php5tube = new Php5tube('Video','User','Comment');
  256. * $most_viewed = $php5tube->getMostViewed(1,10);
  257. * ?>
  258. * </code>
  259. *
  260. * @param int $start_index Start at the nth most viewed video. The default is to start the number 1 most viewed video.
  261. * @param int $max The maximum number of videos returned in list. The default is 25 videos.
  262. *
  263. * @return array array[<numbered_index>][$this->video_object][<field_name>] where <field_name> =<br />
  264. * {'youtube_id', 'author', 'title', 'description', 'keywords', 'url', 'thumbnail1', 'thumbnail2', 'thumbnail3', 'thumbnail4', 'length', 'view_count', 'favorite_count', 'comments_count'}
  265. *
  266. */
  267. function getMostViewed($start_index = 1, $max = 25) {
  268. $feedURL = 'http://gdata.youtube.com/feeds/api/standardfeeds/most_viewed?start-index=' . $start_index . '&max-results=' . $max;
  269. $xml = @simplexml_load_file($feedURL);
  270.  
  271. $videos = array();
  272.  
  273. if(!empty($xml))
  274. {
  275. $videos = $this->parse_multi_video($xml);
  276. }
  277.  
  278. return $videos;
  279. }
  280.  
  281. /**
  282. * Returns the video comments of a youtube video.<br />
  283. * Note: this function does not set the next starting index instance variable in the class.
  284. *
  285. * <code>
  286. * <?php
  287. * include 'Php5tube.php';
  288. * $php5tube = new Php5tube('Video','User','Comment');
  289. * $vid_comments = $php5tube->getVideoComments('oHg5SJYRHA0',1,10);
  290. * ?>
  291. * </code>
  292. *
  293. * @param string $id The video's youtube id.
  294. * @param int start_index The first entry returned.
  295. * @param int max The number of results returned.
  296. *
  297. * @return array array[<numbered_index>][$this->video_object][<field_name>] where <field_name> =<br />
  298. * {'youtube_id', 'author','title','content','updated','published'}
  299. *
  300. */
  301.  
  302. function getVideoComments($id, $start_index = 1, $max = 25) {
  303. $commentURL = 'http://gdata.youtube.com/feeds/api/videos/' . $id . '/comments?start-index=' . $start_index . '&max-results=' . $max;
  304. $xml = @ simplexml_load_file($commentURL);
  305.  
  306. $comment_array = array ();
  307. $i = 0;
  308. //check to see if we've reached the end of the feed pages
  309. //if there is no link to the next set of comments we are done.
  310. //so either set this->next_index to the next start_index or set it to -1 to notify the user we are done.
  311. /*
  312. if(!empty($xml->link[6]))
  313. {
  314. $this->next_index = $start_index + $max;
  315. }
  316. else
  317. {
  318. $this->next_index = -1;
  319. }
  320. */
  321. foreach ($xml->entry as $entry) {
  322. $comment_array[$i][$this->comment_object]['youtube_id'] = $id;
  323. //get the author's name
  324. $comment_array[$i][$this->comment_object]['author'] = (string) $entry->author->name;
  325. //get title of the comment
  326. $comment_array[$i][$this->comment_object]['title'] = (string) $entry->title;
  327. //get comment content
  328. $comment_array[$i][$this->comment_object]['content'] = (string) $entry->content;
  329. //get the last time the comment was updated
  330. $comment_array[$i][$this->comment_object]['updated'] = $entry->updated;
  331. //get the time the comment was published
  332. $comment_array[$i][$this->comment_object]['published'] = $entry->published;
  333. $i++;
  334. }
  335.  
  336. return $comment_array;
  337. }
  338.  
  339. /**
  340. * Returns the information of a youtube video.
  341. *
  342. * <code>
  343. * <?php
  344. * include 'Php5tube.php';
  345. * $php5tube = new Php5tube('Video','User','Comment');
  346. * $vid_info = $php5tube->getVideoInfo('oHg5SJYRHA0');
  347. * ?>
  348. * </code>
  349. *
  350. * @param string $id - The video's youtube id.
  351. *
  352. * @return array array[$this->video_object][<field_name>] where <field_name> =<br />
  353. * {'youtube_id', 'author', 'title', 'description', 'keywords', 'url', 'thumbnail1', 'thumbnail2', 'thumbnail3', 'thumbnail4', 'length', 'view_count', 'favorite_count', 'comments_count'}
  354. *
  355. */
  356.  
  357. function getVideoInfo($id) {
  358. //set up the feed url
  359. $feedURL = 'http://gdata.youtube.com/feeds/api/videos/' . $id;
  360. //read the feed and place it in an simple_xml object
  361. $xml = @ simplexml_load_file($feedURL);
  362. //create an empty array to deal with foreach loops incase nothing is returned from the feed query
  363. $video_array = array ();
  364.  
  365. //if the query returned a value and the xml object is not empty
  366. if (!empty ($xml)) {
  367.  
  368. //store the youtube_id in the object.
  369. $video_array[$this->video_object]['youtube_id'] = $id;
  370. //get the authors name
  371. $video_array[$this->video_object]['author'] = $xml->author->name;
  372. $video = $xml->children('http://search.yahoo.com/mrss/');
  373.  
  374. $player = $video->group->player->attributes();
  375. $thumbnail1 = $video->group->thumbnail[0]->attributes(); //get value for first thumbnail variable
  376. $thumbnail2 = $video->group->thumbnail[1]->attributes(); //get value for first thumbnail variable
  377. $thumbnail3 = $video->group->thumbnail[2]->attributes(); //get value for first thumbnail variable
  378. $thumbnail4 = $video->group->thumbnail[3]->attributes(); //get value for first thumbnail variable
  379. //get the url to the thumbnails for the video
  380. $video_array[$this->video_object]['thumbnail_url1'] = (string) $thumbnail1['url'];
  381. $video_array[$this->video_object]['thumbnail_url2'] = (string) $thumbnail2['url'];
  382. $video_array[$this->video_object]['thumbnail_url3'] = (string) $thumbnail3['url'];
  383. $video_array[$this->video_object]['thumbnail_url4'] = (string) $thumbnail4['url'];
  384.  
  385. //get the video's title
  386. $video_array[$this->video_object]['title'] = (string) $video->group->title;
  387. //get the video's description
  388. $video_array[$this->video_object]['description'] = (string) $video->group->description;
  389. //get the video's category
  390. $video_array[$this->video_object]['category'] = (string) $video->group->category;
  391. //get the video's tags/keywords
  392. $video_array[$this->video_object]['keywords'] = (string) $video->group->keywords;
  393. //get the url to the video
  394. $video_array[$this->video_object]['url'] = (string) $player['url'];
  395.  
  396. $yt = $video->children('http://gdata.youtube.com/schemas/2007');
  397. $length = $yt->duration->attributes();
  398. //get the video length in seconds
  399. $video_array[$this->video_object]['length'] = (string) $length['seconds'];
  400. $video = $xml->children('http://gdata.youtube.com/schemas/2007');
  401. //get the number of times the video has been viewed and marked as favorite
  402. $views = $video->statistics->attributes();
  403.  
  404. //if results were returned - removes php warning
  405. if (!empty ($video)) {
  406. //number of times the video has been viewed
  407. if ($views['viewCount'] == '') {
  408. $video_array[$this->video_object]['view_count'] = '0';
  409. } else {
  410. $video_array[$this->video_object]['view_count'] = (string) $views['viewCount'];
  411. }
  412. //number of times the video has been set as favorite
  413. if ($views['favoriteCount'] == '') {
  414. $video_array[$this->video_object]['favorite_count'] = '0';
  415. } else {
  416. $video_array[$this->video_object]['favorite_count'] = (string) $views['favoriteCount'];
  417. }
  418. } else { //results were not returned
  419. $video_array[$this->video_object]['view_count'] = '0';
  420. $video_array[$this->video_object]['favorite_count'] = '0';
  421. }
  422.  
  423. $video = $xml->children('http://schemas.google.com/g/2005');
  424.  
  425. //check to see if there are any comments/any information about the comments
  426. //if there is get the feedlink and number of comments
  427. if ($video->comments->feedLink) {
  428. $comments = $video->comments->feedLink->attributes();
  429. //get the number of comments for the video
  430. $video_array[$this->video_object]['comments_count'] = (string) $comments['countHint'];
  431. }
  432. }
  433.  
  434. //return the current video array
  435. return $video_array;
  436.  
  437. }
  438.  
  439. ///*
  440. function getVideosByKeywords($keywords, $start_index = 1 ,$max_results = 25, $order = 'ViewCount', $category = null)
  441. {
  442.  
  443. $feedURL = 'http://gdata.youtube.com/feeds/api/videos?q=' . $keywords . '&start-index=' . $start_index . '&max-results=' . $max_results; //.'&v=2';
  444.  
  445. //add category variable to feed url, if it exists
  446. if ($category != null) {
  447. $feedURL = $feedURL . '&category=' . $category;
  448. }
  449.  
  450. $videos = array();
  451. //read the feed and place it in an simple_xml object
  452. $xml = @ simplexml_load_file($feedURL);
  453. //debug($xml);
  454. if (!empty ($xml)) {
  455.  
  456. //get the next start index.
  457. if (isset ($xml->link[5])) {
  458. if($xml->link[5]->attributes()->rel == 'next') $this->next_index = $start_index + $max_results;
  459. }
  460. if (isset ($xml->link[4])) {
  461. if($xml->link[4]->attributes()->rel == 'next') $this->next_index = $start_index + $max_results;
  462. if($xml->link[4]->attributes()->rel == 'previous') $this->previous_index = $start_index - $max_results;
  463. //$this->next_index = (int) preg_replace('/&max-results=' . $max_results . '/', '', preg_replace('/http:\/\/gdata.youtube.com\/feeds\/api\/videos\?q=' . $keywords . '&start-index=/', '', (string) $xml->link[4]->attributes()->href));
  464. //http://gdata.youtube.com/feeds/api/videos?q=volontariato+ferrara&start-index=11&max-results=10
  465. } //if empty, then set $this->nex_index to -1 to let the user know they have reached the end of the list
  466. else {
  467. $this->next_index = -1;
  468. }
  469. //debug($this->next_index);debug($this->previous_index);
  470. $videos = $this->parse_multi_video($xml);
  471. }
  472.  
  473. return $videos;
  474. }
  475.  
  476. /**
  477. * function getVideosByCategory
  478. * returns a list of videos which fall under a certain category
  479. *
  480. *$category - category of videos you want to see (can be the url or the category)
  481. *
  482. * @return an array structured like array[<numbered_index>][$this->video_object][<field_name>]
  483. *
  484. * <field_name> = {'id','title','description','keywords','url','thumbnail','length','views','comments_url','comments_count'}
  485. */
  486. function getVideosByCategory($category,$max = 25, $order) {
  487. //pull out the category incase the user gave us the whole url..
  488. //this is to make it easier for the user to use data from one query to launch this one
  489. $feedURL = 'http://gdata.youtube.com/feeds/api/videos/-/' . $category . '?max-results=' . $max;
  490. $xml = @simplexml_load_file($feedURL);
  491. $video_array = array ();
  492. $i = 0;
  493. foreach ($xml->entry as $entry) {
  494. //id is the full url to get the video feed. the characters after the last slash is the actual video id
  495. //so id here could be 'http://gdata.youtube.com/feeds/api/videos/2jkExrrm_sQ' with the actual video id being 2jkExrrm_sQ
  496. $video_array[$i][$this->video_object]['id'] = (string) $entry->id;
  497. $video = $entry->children('http://search.yahoo.com/mrss/');
  498. $player = $video->group->player->attributes();
  499. $thumbnail = $video->group->thumbnail[0]->attributes();
  500.  
  501. $video_array[$i][$this->video_object]['title'] = (string) $video->group->title;
  502. $video_array[$i][$this->video_object]['description'] = (string) $video->group->description;
  503. //keywords are a number of keywords in one string separated by commas
  504. $video_array[$i][$this->video_object]['keywords'] = (string) $video->group->keywords;
  505. //url is the actual url to the videos page
  506. $video_array[$i][$this->video_object]['url'] = (string) $player['url'];
  507. //url to the first thumbnail image
  508. $video_array[$i][$this->video_object]['thumbnail'] = (string) $thumbnail['url'];
  509.  
  510. $yt = $video->children('http://gdata.youtube.com/schemas/2007');
  511. $length = $yt->duration->attributes();
  512. //videos length in seconds
  513. $video_array[$i][$this->video_object]['length'] = (string) $length['seconds'];
  514.  
  515. $video = $entry->children('http://gdata.youtube.com/schemas/2007');
  516. $views = $video->statistics->attributes();
  517.  
  518. //number of times the video has been watched
  519. $video_array[$i][$this->video_object]['views'] = (string) $views['viewCount'];
  520.  
  521. $video = $entry->children('http://schemas.google.com/g/2005');
  522.  
  523. //check to see if there are any comments/any information about the comments
  524. //if there is get the feedlink and number of comments
  525. if ($video->comments->feedLink) {
  526. $comments = $video->comments->feedLink->attributes();
  527. //number of comments the video has
  528. $video_array[$i][$this->video_object]['comments_count'] = (string) $comments['countHint'];
  529. }
  530.  
  531. $i++;
  532. }
  533. return $video_array;
  534. }
  535.  
  536. //*/
  537.  
  538. /*
  539. * Start Helper code reduction methods.
  540. */
  541.  
  542. private function parse_multi_video($xml) {
  543. $video_array = array (); //holds the video objects
  544. $i = 0;
  545. foreach ($xml->entry as $entry) {
  546. $temp_video = array (); //reset memory for temp video object
  547. //extract youtube id from url
  548. $temp_video_array[$this->video_object]['youtube_id'] = preg_replace('/http:\/\/gdata.youtube.com\/feeds\/api\/videos\//', '', (string) $entry->id);
  549. $temp_video_array[$this->video_object]['author'] = (string) $entry->author->name;
  550.  
  551. $video = array (); //reset variable
  552. //magically gets new variables for each video
  553. $video = $entry->children('http://search.yahoo.com/mrss/');
  554. $player = $video->group->player->attributes(); //get value for player variable
  555. $thumbnail1 = $video->group->thumbnail[0]->attributes(); //get value for first thumbnail variable
  556. $thumbnail2 = $video->group->thumbnail[1]->attributes(); //get value for first thumbnail variable
  557. $thumbnail3 = $video->group->thumbnail[2]->attributes(); //get value for first thumbnail variable
  558. $thumbnail4 = $video->group->thumbnail[3]->attributes(); //get value for first thumbnail variable
  559.  
  560. $temp_video_array[$this->video_object]['title'] = (string) $video->group->title;
  561. $temp_video_array[$this->video_object]['description'] = (string) $video->group->description;
  562. //keywords are a number of keywords in one string separated by commas
  563. $temp_video_array[$this->video_object]['keywords'] = (string) $video->group->keywords;
  564. //category is a single keyword
  565. $temp_video_array[$this->video_object]['category'] = (string) $video->group->category;
  566. //url is the actual url to the videos page
  567. $temp_video_array[$this->video_object]['url'] = (string) $player['url'];
  568. //urls to thethumbnail images
  569. $temp_video_array[$this->video_object]['thumbnail_url1'] = (string) $thumbnail1['url'];
  570. $temp_video_array[$this->video_object]['thumbnail_url2'] = (string) $thumbnail2['url'];
  571. $temp_video_array[$this->video_object]['thumbnail_url3'] = (string) $thumbnail3['url'];
  572. $temp_video_array[$this->video_object]['thumbnail_url4'] = (string) $thumbnail4['url'];
  573.  
  574. //magically get the duration for video in seconds
  575. $yt = $video->children('http://gdata.youtube.com/schemas/2007');
  576. $duration = $yt->duration->attributes(); //extract from xml
  577. $temp_video_array[$this->video_object]['duration'] = (string) $duration['seconds'];
  578.  
  579. $video = array (); //reset variable
  580. //magically get the duration for video in seconds
  581. $video = $entry->children('http://gdata.youtube.com/schemas/2007');
  582. $views = $video->statistics->attributes();
  583.  
  584. //if results were returned - removes php warning
  585. if (!empty ($video)) {
  586. //number of times the video has been viewed
  587. if ($views['viewCount'] == '') {
  588. $temp_video_array[$this->video_object]['view_count'] = '0';
  589. } else {
  590. $temp_video_array[$this->video_object]['view_count'] = (string) $views['viewCount'];
  591. }
  592. //number of times the video has been set as favorite
  593. if ($views['favoriteCount'] == '') {
  594. $temp_video_array[$this->video_object]['favorite_count'] = '0';
  595. } else {
  596. $temp_video_array[$this->video_object]['favorite_count'] = (string) $views['favoriteCount'];
  597. }
  598. } else { //results were not returned
  599. $temp_video_array[$this->video_object]['view_count'] = '0';
  600. $temp_video_array[$this->video_object]['favorite_count'] = '0';
  601. }
  602. /*
  603. $video = array();
  604. $video = $entry->children('http://schemas.google.com/g/2005');
  605. $ratings = array();
  606. //$ratings = $video->rating->attributes();
  607. $rating = $video->rating;
  608.  
  609. print_r($i);
  610. print_r($rating);
  611.  
  612. if(!empty($video)){
  613. if(isset($rating)){
  614. if(!empty($rating)){
  615. if($ratings['min']==''){ $c[$this->video_object]['min_rating'] = '0'; }
  616. else{ $c[$this->video_object]['min_rating'] = (string) $ratings['min']; }
  617. if($ratings['max']==''){ $c[$this->video_object]['max_rating'] = '0'; }
  618. else{ $c[$this->video_object]['max_rating'] = (string) $ratings['max']; }
  619. if($ratings['average']==''){ $c[$this->video_object]['avg_rating'] = '0.00'; }
  620. else{ $c[$this->video_object]['avg_rating'] = (string) $ratings['average']; }
  621. if($ratings['numRaters']){ $c[$this->video_object]['num_raters'] = '0'; }
  622. else{ $c[$this->video_object]['num_raters'] = (string) $ratings['numRaters']; }
  623. } else {
  624. $c[$this->video_object]['min_rating'] = '0';
  625. $c[$this->video_object]['max_rating'] = '0';
  626. $c[$this->video_object]['avg_rating'] = '0.00';
  627. $c[$this->video_object]['num_raters'] = '0';
  628. }
  629. } else {
  630. $c[$this->video_object]['min_rating'] = '0';
  631. $c[$this->video_object]['max_rating'] = '0';
  632. $c[$this->video_object]['avg_rating'] = '0.00';
  633. $c[$this->video_object]['num_raters'] = '0';
  634. }
  635. }
  636.  
  637. //check to see if there are any comments/any information about the comments
  638. //if there is get the feedlink and number of comments
  639. if ($video->comments->feedLink) {
  640. $comments = $video->comments->feedLink->attributes();
  641. //number of comments the video has
  642. $c[$this->video_object]['comments_count'] = (string) $comments['countHint'];
  643. }
  644. */
  645. $video_array[$i] = $temp_video_array;
  646. $i++;
  647. }
  648.  
  649. //set the array to instance variable $user_videos
  650. return $video_array;
  651. }
  652. }
  653. ?>

Basically, I added the search videos by keywords and category functions. (not only by user, as it was originally)
And added some tweaks to adapt it to my needs.

  1. ///*
  2. function getVideosByKeywords($keywords, $start_index = 1 ,$max_results = 25, $order = 'ViewCount', $category = null)
  3. {
  4.  
  5. $feedURL = 'http://gdata.youtube.com/feeds/api/videos?q=' . $keywords . '&start-index=' . $start_index . '&max-results=' . $max_results; //.'&v=2';
  6.  
  7. //add category variable to feed url, if it exists
  8. if ($category != null) {
  9. $feedURL = $feedURL . '&category=' . $category;
  10. }
  11.  
  12. $videos = array();
  13. //read the feed and place it in an simple_xml object
  14. $xml = @ simplexml_load_file($feedURL);
  15. //debug($xml);
  16. if (!empty ($xml)) {
  17.  
  18. //get the next start index.
  19. if (isset ($xml->link[5])) {
  20. if($xml->link[5]->attributes()->rel == 'next') $this->next_index = $start_index + $max_results;
  21. }
  22. if (isset ($xml->link[4])) {
  23. if($xml->link[4]->attributes()->rel == 'next') $this->next_index = $start_index + $max_results;
  24. if($xml->link[4]->attributes()->rel == 'previous') $this->previous_index = $start_index - $max_results;
  25. //$this->next_index = (int) preg_replace('/&max-results=' . $max_results . '/', '', preg_replace('/http:\/\/gdata.youtube.com\/feeds\/api\/videos\?q=' . $keywords . '&start-index=/', '', (string) $xml->link[4]->attributes()->href));
  26. //http://gdata.youtube.com/feeds/api/videos?q=volontariato+ferrara&start-index=11&max-results=10
  27. } //if empty, then set $this->nex_index to -1 to let the user know they have reached the end of the list
  28. else {
  29. $this->next_index = -1;
  30. }
  31. //debug($this->next_index);debug($this->previous_index);
  32. $videos = $this->parse_multi_video($xml);
  33. }
  34.  
  35. return $videos;
  36. }

Having this class in the vendors folder is half the work.

Let’s see the action and the popup view.

in our asset_controller.php

  1. function admin_youtubebrowser($opener_instance, $start_index = 1,$max_results = 10, $order = 'Relevance', $category = null) {
  2.  
  3. $category = null;
  4.  
  5. //gets named parameters like posted variables - useful for filtered pagination
  6. $this->_clean_params();
  7.  
  8. if(isset($this->data['Asset'])) {
  9. if (isset($this->data['Asset']['keyword']) && $this->data['Asset']['keyword'] != '') $keyword = $this->data['Asset']['keyword']; else $keyword = 'volontariato';
  10. if (isset($this->data['Asset']['category']) && $this->data['Asset']['category'] != '') $category = $this->data['Asset']['category'];
  11. if (isset($this->data['Asset']['author']) && $this->data['Asset']['author'] != '') $youtube_user = $this->data['Asset']['author'];
  12. if (isset($this->data['Asset']['page']) && $this->data['Asset']['page'] != '') $page = $this->data['Asset']['page'];
  13. } else {
  14. $keyword = 'volontariato ferrara';
  15. }
  16.  
  17. //set the ckeditor instance id
  18. $this->set('opener_instance', $opener_instance);
  19.  
  20. //create php5tube object and get videos
  21. if(App::import("Vendor", "Php5tube", array('file' => '../vendors/Php5tube.php'))) { //, array('file' => '../vendors/Php5tube.php')
  22. $php5tube = new Php5tube('Video','User','Comment');
  23.  
  24. //here we are
  25. if($keyword)
  26. $videos = $php5tube->getVideosByKeywords($keyword, $start_index, $max_results, $order, $category);
  27. else if ($user)
  28. $videos = $php5tube->getUserVideos($youtube_user, $category, $start_index, $max_results);
  29.  
  30. $this->set('videos', $videos);
  31.  
  32. //paginate returned videos- create urls for next and previous N videos request to youtube
  33. if($php5tube->next_index != -1) {
  34. $next_index = $php5tube->next_index;
  35. $this->set('next_index', $next_index);
  36. $url = array('controller' => 'assets', 'action' => 'youtubebrowser',
  37. $opener_instance,
  38. $next_index,
  39. $max_results
  40. );
  41. if (isset($keyword)) $url['keyword'] = $keyword;
  42. if (isset($category)) $url['category'] = $category;
  43. if (isset($author)) $url['author'] = $author;
  44.  
  45. $this->set('next_url', $url);
  46. }
  47.  
  48. if($php5tube->previous_index != -1) {
  49. $previous_index = $php5tube->previous_index;
  50. $this->set('previous_index', $previous_index);
  51. $url = array('controller' => 'assets', 'action' => 'youtubebrowser',
  52. $opener_instance,
  53. $previous_index,
  54. $max_results
  55. );
  56. if (isset($keyword)) $url['keyword'] = $keyword;
  57. if (isset($category)) $url['category'] = $category;
  58. if (isset($author)) $url['author'] = $author;
  59.  
  60. $this->set('previous_url', $url);
  61. }
  62. }
  63. else {
  64. $this->Session->setFlash(__('Problem: cannot import Php5tube Vendor class',true));
  65. }
  66. $this->render('admin_youtubebrowser', 'basic');
  67.  
  68. }

The actions gets the filters (keywords, category or author) from the form or url parameters (preserving filters in pagination); calls the appropriate method from the php5Tube class -retieving videos data from youtube-, and then sets the variables for the view (including urls for paginated requests to youtube)

Here is the _clean_params method:

  1. function _clean_params() {
  2. if(is_array($this->params['named'])) {
  3.  
  4. foreach ($this->params['named'] as $key => $value) {
  5.  
  6. if(strpos($key, 'Asset.') === 0) {
  7. $short_key = str_replace('Asset.', '', $key);
  8. $this->params['named']['Asset'][$short_key] = $value;
  9. //unset($this->params['named'][$key] );
  10. } else {
  11. $this->params['named']['Asset'][$key] = $value;
  12. }
  13. //debug($this->params['named']);debug($this->params['named']);
  14. };
  15.  
  16. if(isset($this->params['named']['Asset'])) {
  17. if(isset($this->data['Asset']))
  18. $this->data['Asset'] = array_merge($this->data['Asset'],$this->params['named']['Asset']);
  19. else
  20. $this->data['Asset'] = $this->params['named']['Asset'];
  21. }
  22.  
  23. }
  24.  
  25. }

Then the view: the popup. like the image one in the previous article, prepares the code to be injected back to ckeditor.

The view, admin_youtubebrowser.ctp

  1. <script type="text/javascript">
  2. <!--
  3. function InsertHTML(passed)
  4. {
  5. var oEditor = opener.CKEDITOR.instances.<?php echo $opener_instance ?>;
  6. // Check the active editing mode.
  7. if ( oEditor.mode == 'wysiwyg' )
  8. {
  9. // Insert the desired HTML.
  10. oEditor.insertHtml( passed ) ;
  11. }
  12. else
  13. alert('<?php echo __('You must be on WYSIWYG mode!', true); ?>') ;
  14.  
  15. window.close();
  16. }
  17. -->
  18. </script>
  19. <div class="pannello">
  20. <h2><?php __('Video');?></h2>
  21. <div class="art-Block">
  22. <div class="art-Block-body">
  23. <div class="art-BlockHeader">
  24. <div class="l"></div>
  25. <div class="r"></div>
  26. <div class="art-header-tag-icon">
  27. <div class="t"><?php
  28. echo __('Search youtube videos');
  29. ?></div>
  30. </div>
  31. </div><div class="art-BlockContent">
  32. <div class="art-BlockContent-body">
  33. <?php echo $form->create('Asset',
  34. array('url'=>array('action'=>'youtubebrowser', $opener_instance)
  35. , 'type' => 'post'));?>
  36.  
  37. <table border="0" cellpadding="10">
  38. <tbody>
  39. <tr>
  40. <td>
  41. <?php echo $html->image('social_me/big/youtube.png', array('align' => 'absmiddle', 'hspace' => '2'));; ?>
  42. </td>
  43. <td valign="middle">
  44. <?php
  45. echo $form->input('keyword', array('class' => 'size120', 'label' => __('Keywords', true)));
  46. ?></td>
  47. <td valign="middle"><?php
  48. echo $form->input('category', array('class' => 'size120', 'label' => __('Category',true) ));
  49. ?></td>
  50. <td valign="middle"><?php
  51. echo $form->input('author', array('class' => 'size120', 'label' => __('Author',true) ));
  52. ?></td>
  53. </tr>
  54. </tbody>
  55. </table>
  56. <?php echo $form->hidden('page', array('value' => $session->read('page')));
  57. echo '<br>'. $form->submit(__('Search',true), array('div' => false, 'class' => 'art-button')); ?>
  58. <?php echo $form->end(); ?>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. <div style="clear:both"></div>
  64. <h2><?php
  65. if(isset($previous_url)) echo $html->link('<<', $previous_url). ' | ';
  66. if(isset($next_url)) echo $html->link('>>', $next_url); ?>
  67. </h2>
  68. <table cellpadding="0" cellspacing="0">
  69. <?php if (isset($videos)) {
  70. foreach($videos as $video) { ?>
  71. <tr> <!--
  72. <td>
  73. <div style="padding:2px;"><img src="<?php //echo $video['Video']['thumbnail_url2']; ?>"></div>
  74.  
  75. </td> -->
  76. <td>
  77. <div style="padding:10px;">
  78. <object width="280" height="170"><param name="movie" value="http://www.youtube.com/v/<?php echo $video['Video']['youtube_id']; ?>&hl=it_IT&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/<?php echo $video['Video']['youtube_id']; ?>&hl=it_IT&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="280" height="170"></embed></object>
  79.  
  80. </div>
  81. </td>
  82. <td>
  83. <div class="box_right">
  84. <?php
  85.  
  86. // generated HTML to be embedded in CKeditor
  87. $insert_big = '<object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/'.$video['Video']['youtube_id'].'&hl=it_IT&fs=1&color1=0x3a3a3a&color2=0x999999"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/'.$video['Video']['youtube_id'].'&hl=it_IT&fs=1&color1=0x3a3a3a&color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object>';
  88. $insert_small = '<object width="320" height="265"><param name="movie" value="http://www.youtube.com/v/'.$video['Video']['youtube_id'].'&hl=it_IT&fs=1&color1=0x3a3a3a&color2=0x999999"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/'.$video['Video']['youtube_id'].'&hl=it_IT&fs=1&color1=0x3a3a3a&color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="320" height="265"></embed></object>';
  89.  
  90. $insert_left =
  91. $html->div('imageleft',
  92. "<p>".
  93. $insert_small ."</p><p><em>".htmlentities($video['Video']['title'], ENT_QUOTES)."</em></p>",null,false). ' &nbsp;'
  94. ;
  95.  
  96. $insert_right =
  97. $html->div('imageright',
  98. "<p>".
  99. $insert_small ."</p><p><em>".htmlentities($video['Video']['title'], ENT_QUOTES)."</em></p>",null,false). ' &nbsp;'
  100. ;
  101.  
  102. $insert_center =
  103. $html->div('imagecenter',
  104. "<p>".$insert_big
  105. ."</p><p><em>".htmlentities($video['Video']['title'], ENT_QUOTES)."</em></p>",null,false). ' &nbsp;'
  106. ;
  107.  
  108. echo $html->link($html->image('icons_big/Youtube_Embed_left.png',
  109. array('alt' => __('embed video',true), 'title' => __('embed video from youtube (small, left)', true), 'border' => 0, 'align' => 'absmiddle')),
  110. //'javascript:;',
  111. 'javascript:InsertHTML(\''. $insert_left .'\');',
  112. array('escape' => false,
  113. //'onclick' => "javascript:InsertHTML('". $insert_left ."'); return false;"
  114. ),
  115. null, false
  116. );
  117.  
  118. echo $html->link($html->image('icons_big/Youtube_Embed_right.png',
  119. array('alt' => __('embed video',true), 'title' => __('embed video from youtube (small, right)', true), 'border' => 0, 'align' => 'absmiddle')),
  120. //'javascript:;',
  121. 'javascript:InsertHTML(\''. $insert_right .'\');',
  122. array('escape' => false,
  123. //'onclick' => "javascript:InsertHTML('". $insert_right ."'); return false;"
  124. ),
  125. null, false
  126. );
  127.  
  128. echo '<div>';
  129. echo $html->link($html->image('icons_big/Youtube_Embed.png',
  130. array('alt' => __('embed video',true), 'title' => __('embed video from youtube (big)', true), 'border' => 0, 'align' => 'absmiddle')),
  131. //'javascript:;',
  132. 'javascript:InsertHTML(\''. $insert_center .'\');',
  133. array('escape' => false,
  134. //'onclick' => "javascript:InsertHTML('". $insert_center ."'); return false;"
  135. ),
  136. null, false
  137. );
  138. echo '</div>';
  139.  
  140. ?>
  141. </div>
  142. <div style="font-size:16px;"><?php echo $video['Video']['title']; ?></div>
  143. <div><b><?php __('Category'); ?></b> = <?php echo $video['Video']['category']; ?> </div>
  144. <!-- <div><b>Tags</b> = <?php //echo $video['Video']['keywords']; ?> </div> -->
  145. <div><b><?php __('Description'); ?></b> = <?php echo $video['Video']['description']; ?></div>
  146. <div><b><?php __('Views'); ?></b> = <?php echo $video['Video']['view_count']; ?> times</div>
  147. <div><b><?php __('Marked as favorite'); ?></b> = <?php echo $video['Video']['favorite_count']; ?> times</div>
  148.  
  149. </td>
  150.  
  151. </tr>
  152. <?php }
  153. } ?>
  154. </table>
  155. <h2><?php
  156. if(isset($previous_url)) echo $html->link('<<', $previous_url). ' | ';
  157. if(isset($next_url)) echo $html->link('>>', $next_url); ?>
  158. </h2>
  159. </div>

Like we did for images, there is a choiche for different sizes and align for the video to be inserted.

With a few lines of code we have a functional browser (and search by keyword, category or author) of yuotube videos, with thumbnails and the chance to preview the actual video, integrated in our application.

It’s easy with cakephp.


youtube_browser

This – extended form the first article- is the relevant excerpt of the view calling the popups:

  1. <?php
  2. $javascript->link('ckeditor/ckeditor', false);
  3. ?>
  4. [..]
  5. <?php
  6. echo $form->input('summary', array('type' => 'textarea','label'=> false)); //, 'class'=>'ckeditor')
  7. ?>
  8.  
  9. <!-- Show the image / links foropening the "browser" popups -->
  10. <h5>
  11. <?php
  12. echo $html->link($html->image('icons_big/attachment.png', array('align' => 'absmiddle'))
  13. . __(' Files ', true),
  14. 'javascript:;',
  15. array('escape' => false,
  16. 'onclick' => "javascript:window.open('".$html->url(array(
  17. 'controller' => 'assets',
  18. 'action'=>'filebrowser',
  19. $Type.'Summary' // or ContentWholeContent
  20. )
  21. )."','_blank', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=800,height=680'); return false;"
  22. ),
  23. null, false
  24. );
  25.  
  26. echo " | ";
  27. echo $html->link($html->image('icons_big/attach_image.png', array('align' => 'absmiddle')).
  28. __('Images', true),
  29. 'javascript:;',
  30. array('escape' => false,
  31. 'onclick' => "javascript:window.open('".$html->url(array(
  32. 'controller' => 'assets',
  33. 'action'=>'imagebrowser',
  34. $Type.'Summary' // or ContentWholeContent
  35. )
  36. )."','_blank', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=800,height=680'); return false;"
  37. ),
  38. null, false
  39. );
  40. echo " | ";
  41. echo $html->link($html->image('icons_big/Youtube_browser.png', array('align' => 'absmiddle')).
  42. __(' YT Video', true),
  43. 'javascript:;',
  44. array('escape' => false,
  45. 'onclick' => "javascript:window.open('".$html->url(array(
  46. 'controller' => 'assets',
  47. 'action'=>'youtubebrowser',
  48. $Type.'Summary' // or ContentWholeContent
  49. )
  50. )."','_blank', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=800,height=680'); return false;"
  51. ),
  52. null, false
  53. );
  54.  
  55. echo " | ";
  56. echo $html->link($html->image('social_me/medium/flickr.png', array('align' => 'absmiddle')).
  57. __(' Flickr (slides)', true),
  58. 'javascript:;',
  59. array('escape' => false,
  60. 'onclick' => "javascript:window.open('".$html->url(array(
  61. 'controller' => 'assets',
  62. 'action'=>'flickrbrowser',
  63. $Type.'Summary' // or ContentWholeContent
  64. )
  65. )."','_blank', 'toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,width=800,height=680'); return false;"
  66. ),
  67. null, false
  68. );
  69.  
  70. ?>
  71. </h5>
  72. [..]
  73. <script type="text/javascript">
  74. var editor = CKEDITOR.replace( "<?php echo $Type ?>Summary" , {customConfig : "/js/ckeditor/alternate_config.js", height : "150px"});
  75. CKEDITOR.add
  76. CKEDITOR.config.contentsCss = '<?php echo $html->webroot('/js/ckeditor/mycontents.css') ?>' ;
  77. </script>


That’s all – please feel free to comment for info, doubts or anything.

Next (last) time, a flickr browser: search, browse and embed images or photoset slideshows form flickr.