Selaa lähdekoodia

Patch to fix several bugs in Zend_Gdata_YouTube and Zend_Gdata multipart MIME support.

ZF-7075: Update Zend_Gdata URL constants to include 'api' projection.
ZF-7076: User specified URLs are now preferred over edit links when working with Zend_Gdata media entries.
ZF-7077: Rewrite Zend_Gdata MIME streaming support to correct erratic behavior.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@16229 44c647ce-9c0f-0410-b52a-842ac1e357ba
tjohns 16 vuotta sitten
vanhempi
commit
38035ca90e

+ 1 - 1
library/Zend/Gdata/App.php

@@ -513,7 +513,7 @@ class Zend_Gdata_App
             }
             if ($method == 'PUT' || $method == 'DELETE') {
                 $editLink = $data->getEditLink();
-                if ($editLink != null) {
+                if ($editLink != null && $url == null) {
                     $url = $editLink->getHref();
                 }
             }

+ 5 - 2
library/Zend/Gdata/HttpAdapterStreamingSocket.php

@@ -95,13 +95,16 @@ class Zend_Gdata_HttpAdapterStreamingSocket extends Zend_Http_Client_Adapter_Soc
 
 
         //read from $body, write to socket
-        while ($body->hasData()) {
-            if (! @fwrite($this->socket, $body->read(self::CHUNK_SIZE))) {
+        $chunk = $body->read(self::CHUNK_SIZE);
+        while ($chunk !== FALSE) {
+            if (! @fwrite($this->socket, $chunk)) {
                 require_once 'Zend/Http/Client/Adapter/Exception.php';
                 throw new Zend_Http_Client_Adapter_Exception(
                     'Error writing request to server');
             }
+            $chunk = $body->read(self::CHUNK_SIZE);
         }
+        $body->closeFileHandle();
         return 'Large upload, request is not cached.';
     }
 }

+ 50 - 374
library/Zend/Gdata/MediaMimeStream.php

@@ -21,6 +21,17 @@
  */
 
 /**
+*  @see Zend_Gdata_MimeFile
+*/
+require_once 'Zend/Gdata/MimeFile.php';
+
+/**
+* @see Zend_Gdata_MimeBodyString
+*/
+require_once 'Zend/Gdata/MimeBodyString.php';
+
+
+/**
  * A streaming Media MIME class that allows for buffered read operations.
  *
  * @category   Zend
@@ -33,63 +44,13 @@ class Zend_Gdata_MediaMimeStream
 {
 
     /**
-     * The Content-Type section that precedes the XML data in the message.
-     *
-     * @var string
-     */
-    // TODO (jhartmann) Add support for charset [ZF-5768]
-    const XML_HEADER = "Content-Type: application/atom+xml\r\n\r\n";
-
-    /**
-     * A constant indicating the xml string part of the message
-     *
-     * @var integer
-     */
-    const PART_XML_STRING = 0;
-
-    /**
-     * A constant indicating the file binary part of the message
-     *
-     * @var integer
-     */
-    const PART_FILE_BINARY = 1;
-
-    /**
-     * A constant indicating the closing boundary string of the message
-     *
-     * @var integer
-     */
-    const PART_CLOSING_XML_STRING = 2;
-
-    /**
-     * The maximum buffer size that can be used.
-     *
-     * @var integer
-     */
-    const MAX_BUFFER_SIZE = 8192;
-
-    /**
-     * A valid MIME boundary including a linefeed.
-     *
-     * @var string
-     */
-    protected $_boundaryLine = null;
-
-    /**
-     * A valid MIME boundary without a linefeed for use in the header.
+     * A valid MIME boundary.
      *
      * @var string
      */
     protected $_boundaryString = null;
 
     /**
-     * A valid MIME closing boundary including a linefeed.
-     *
-     * @var string
-     */
-    protected $_closingBoundaryLine = null;
-
-    /**
      * A handle to the file that is part of the message.
      *
      * @var resource
@@ -97,76 +58,25 @@ class Zend_Gdata_MediaMimeStream
     protected $_fileHandle = null;
 
     /**
-     * The headers that preceed the file binary including linefeeds.
-     *
-     * @var string
-     */
-    protected $_fileHeaders = null;
-
-    /**
-     * The internet media type of the enclosed file.
-     *
-     * @var string
-     */
-    protected $_fileContentType = null;
-
-    /**
-     * The file size.
-     *
-     * @var integer
-     */
-    protected $_fileSize = null;
-
-    /**
-     * The total size of the message.
-     *
-     * @var integer
-     */
-    protected $_totalSize = null;
-
-    /**
-     * The XML string that typically represents the entry to be sent.
-     *
-     * @var string
-     */
-    protected $_xmlString = null;
-
-    /**
-     * The number of bytes that have been read so far.
-     *
+     * The current part being read from.
      * @var integer
      */
-    protected $_bytesRead = 0;
+    protected $_currentPart = 0;
 
     /**
-     * Enumeration indicating the part of the message that is currently being
-     * read. Allowed values are: 0, 1 and 2, corresponding to the constants:
-     * PART_XML_STRING, PART_FILE_BINARY, PART_CLOSING_XML_STRING
-     *
+     * The size of the MIME message.
      * @var integer
      */
-    protected $_currentPart = 0;
+    protected $_totalSize = 0;
 
     /**
-     * A nested array containing the message to be sent. Each element contains
-     * an array in the format:
-     *
-     * [integer (size of message)][string (message)]
-     *
-     * Note that the part corresponding to the file only contains a size.
-     *
+     * An array of all the parts to be sent. Array members are either a
+     * MimeFile or a MimeBodyString object.
      * @var array
      */
     protected $_parts = null;
 
     /**
-     * A boolean to be set immediately once we have finished reading.
-     *
-     * @var boolean
-     */
-    protected $_doneReading = false;
-
-    /**
      * Create a new MimeMediaStream object.
      *
      * @param string $xmlString The string corresponding to the XML section
@@ -180,290 +90,67 @@ class Zend_Gdata_MediaMimeStream
     public function __construct($xmlString = null, $filePath = null,
         $fileContentType = null)
     {
-        $this->_xmlString = $xmlString;
-        $this->_filePath = $filePath;
-        $this->_fileContentType = $fileContentType;
-
         if (!file_exists($filePath) || !is_readable($filePath)) {
             require_once 'Zend/Gdata/App/IOException.php';
             throw new Zend_Gdata_App_IOException('File to be uploaded at ' .
                 $filePath . ' does not exist or is not readable.');
         }
 
-        $this->_fileHandle = fopen($filePath, 'rb', true);
-        $this->generateBoundaries();
-        $this->calculatePartSizes();
-    }
-
-    /**
-     * Generate the MIME message boundary strings.
-     *
-     * @return void
-     */
-    private function generateBoundaries()
-    {
+        $this->_fileHandle = fopen($filePath, 'rb', TRUE);
         $this->_boundaryString = '=_' . md5(microtime(1) . rand(1,20));
-        $this->_boundaryLine = "\r\n" . '--' . $this->_boundaryString . "\r\n";
-        $this->_closingBoundaryLine = "\r\n" . '--' . $this->_boundaryString .
-            '--';
-    }
-
-    /**
-     * Calculate the sizes of the MIME message sections.
-     *
-     * @return void
-     */
-    private function calculatePartSizes()
-    {
-        $this->_fileHeaders = 'Content-Type: ' . $this->_fileContentType .
-            "\r\n" . 'Content-Transfer-Encoding: binary' . "\r\n\r\n";
-        $this->_fileSize = filesize($this->_filePath);
+        $entry = $this->wrapEntry($xmlString, $fileContentType);
+        $closingBoundary = new Zend_Gdata_MimeBodyString("\r\n--{$this->_boundaryString}--\r\n");
+        $file = new Zend_Gdata_MimeFile($this->_fileHandle);
+        $this->_parts = array($entry, $file, $closingBoundary);
 
-        $stringSection = $this->_boundaryLine . self::XML_HEADER .
-            $this->_xmlString . "\r\n" . $this->_boundaryLine .
-            $this->_fileHeaders;
-        $stringLen = strlen($stringSection);
-        $closingBoundaryLen = strlen($this->_closingBoundaryLine);
+        $fileSize = filesize($filePath);
+        $this->_totalSize = $entry->getSize() + $fileSize
+          + $closingBoundary->getSize();
 
-        $this->_parts = array();
-        $this->_parts[] = array($stringLen, $stringSection);
-        $this->_parts[] = array($this->_fileSize);
-        $this->_parts[] = array($closingBoundaryLen,
-            $this->_closingBoundaryLine);
-
-        $this->_totalSize = $stringLen + $this->_fileSize + $closingBoundaryLen;
-    }
-
-    /**
-     * A wrapper around fread() that doesn't error when $length is 0.
-     *
-     * @param integer $length Number of bytes to read.
-     * @return string Results of byte operation.
-     */
-    private function smartfread($length)
-    {
-        if ($length < 1) {
-            return '';
-        } else {
-            return fread($this->_fileHandle, $length);
-        }
     }
 
     /**
-     * A non mbstring overloadable strlen-like function.
+     * Sandwiches the entry body into a MIME message
      *
-     * @param string $string The string whose length we want to get.
-     * @return integer The length of the string.
+     * @return void
      */
-    private function strlen2($string)
+    private function wrapEntry($entry, $fileMimeType)
     {
-        return array_sum(char_count($string));
+        $wrappedEntry = "--{$this->_boundaryString}\r\n";
+        $wrappedEntry .= "Content-Type: application/atom+xml\r\n\r\n";
+        $wrappedEntry .= $entry;
+        $wrappedEntry .= "\r\n--{$this->_boundaryString}\r\n";
+        $wrappedEntry .= "Content-Type: $fileMimeType\r\n\r\n";
+        return new Zend_Gdata_MimeBodyString($wrappedEntry);
     }
 
     /**
      * Read a specific chunk of the the MIME multipart message.
      *
-     * This function works by examining the internal 'parts' array. It
-     * expects that array to consist of basically a string, a file handle
-     * and a closing string.
-     *
-     * An abbreviated version of what this function does is as follows:
-     *
-     * - throw exception if trying to read bigger than the allocated max buffer
-     * - If bufferSize bigger than the entire message: return it and exit.
-     *
-     * - Check how far to read by looking at how much has been read.
-     * - Figure out whether we are crossing sections in this read:
-     *   i.e. -> reading past the xml_string and into the file ?
-     *   - Determine whether we are crossing two sections in this read:
-     *     i.e. xml_string, file and half of the closing string or
-     *     possibly file, closing string and next (non-existant) section
-     *     and handle each case.
-     *   - If we are NOT crossing any sections: read either string and
-     *     increment counter, or read file (no counter needed since fread()
-     *     stores it's own counter.
-     *   - If we are crossing 1 section, figure out how much remains in that
-     *     section that we are currently reading and how far to read into
-     *     the next section. If the section just read is xml_string, then
-     *     immediately unset it from our 'parts' array. If it is the file,
-     *     then close the handle.
-     *
      * @param integer $bufferSize The size of the chunk that is to be read,
      *                            must be lower than MAX_BUFFER_SIZE.
-     * @throws Zend_Gdata_App_InvalidArgumentException if buffer size too big.
      * @return string A corresponding piece of the message. This could be
      *                binary or regular text.
      */
-    public function read($bufferSize)
+    public function read($bytesRequested)
     {
-        if ($bufferSize > self::MAX_BUFFER_SIZE) {
-            require_once 'Zend/Gdata/App/InvalidArgumentException.php';
-            throw new Zend_Gdata_App_InvalidArgumentException('Buffer size ' .
-                'is larger than the supported max of ' . self::MAX_BUFFER_SIZE);
-        }
-
-        // handle edge cases where bytesRead is negative
-        if ($this->_bytesRead < 0) {
-            $this->_bytesRead = 0;
-        }
-
-        $returnString = null;
-        // If entire message is smaller than the buffer, just return everything
-        if ($bufferSize > $this->_totalSize) {
-            $returnString = $this->_parts[self::PART_XML_STRING][1];
-            $returnString .= fread($this->_fileHandle, $bufferSize);
-            $returnString .= $this->_closingBoundaryLine;
-            $this->closeFileHandle();
-            $this->_doneReading = true;
-            return $returnString;
-        }
-
-        // increment internal counters
-        $readTo = $this->_bytesRead + $bufferSize;
-        $sizeOfCurrentPart = $this->_parts[$this->_currentPart][0];
-        $sizeOfNextPart = 0;
-
-        // if we are in a part past the current part, exit
-        if ($this->_currentPart > self::PART_CLOSING_XML_STRING) {
-            $this->_doneReading = true;
-            return;
-        }
-
-        // if bytes read is bigger than the current part and we are
-        // at the end, return
-        if (($this->_bytesRead > $sizeOfCurrentPart) &&
-            ($this->_currentPart == self::PART_CLOSING_XML_STRING)) {
-                $this->_doneReading = true;
-                return;
-        }
-
-        // check if we have a next part
-        if ($this->_currentPart != self::PART_CLOSING_XML_STRING) {
-            $nextPart = $this->_currentPart + 1;
-            $sizeOfNextPart = $this->_parts[$nextPart][0];
+        if($this->_currentPart >= count($this->_parts)) {
+          return FALSE;
         }
 
-        $readIntoNextPart = false;
-        $readFromRemainingPart = null;
-        $readFromNextPart = null;
+        $activePart = $this->_parts[$this->_currentPart];
+        $buffer = $activePart->read($bytesRequested);
 
-        // are we crossing into multiple sections of the message in
-        // this read?
-        if ($readTo > ($sizeOfCurrentPart + $sizeOfNextPart)) {
-            if ($this->_currentPart == self::PART_XML_STRING) {
-                // If we are in XML string and have crossed over the file
-                // return that and whatever we can from the closing boundary
-                // string.
-                $returnString = $this->_parts[self::PART_XML_STRING][1];
-                unset($this->_parts[self::PART_XML_STRING]);
-                $returnString .= fread($this->_fileHandle,
-                    self::MAX_BUFFER_SIZE);
-                $this->closeFileHandle();
-
-                $readFromClosingString = $readTo -
-                    ($sizeOfCurrentPart + $sizeOfNextPart);
-                $returnString .= substr(
-                    $this->_parts[self::PART_CLOSING_XML_STRING][1], 0,
-                    $readFromClosingString);
-                $this->_bytesRead = $readFromClosingString;
-                $this->_currentPart = self::PART_CLOSING_XML_STRING;
-                return $returnString;
-
-            } elseif ($this->_currentPart == self::PART_FILE_BINARY) {
-                // We have read past the entire message, so return it.
-                $returnString .= fread($this->_fileHandle,
-                    self::MAX_BUFFER_SIZE);
-                $returnString .= $this->_closingBoundaryLine;
-                $this->closeFileHandle();
-                $this->_doneReading = true;
-                return $returnString;
-            }
-        // are we just crossing from one section into another?
-        } elseif ($readTo >= $sizeOfCurrentPart) {
-            $readIntoNextPart = true;
-            $readFromRemainingPart = $sizeOfCurrentPart - $this->_bytesRead;
-            $readFromNextPart = $readTo - $sizeOfCurrentPart;
-        }
-
-        if (!$readIntoNextPart) {
-            // we are not crossing any section so just return something
-            // from the current part
-            switch ($this->_currentPart) {
-                case self::PART_XML_STRING:
-                    $returnString = $this->readFromStringPart(
-                        $this->_currentPart, $this->_bytesRead, $bufferSize);
-                    break;
-                case self::PART_FILE_BINARY:
-                    $returnString = fread($this->_fileHandle, $bufferSize);
-                    break;
-                case self::PART_CLOSING_XML_STRING:
-                    $returnString = $this->readFromStringPart(
-                        $this->_currentPart, $this->_bytesRead, $bufferSize);
-                    break;
-            }
-        } else {
-            // we are crossing from one section to another, so figure out
-            // where we are coming from and going to
-            switch ($this->_currentPart) {
-                case self::PART_XML_STRING:
-                    // crossing from string to file
-                    $returnString = $this->readFromStringPart(
-                        $this->_currentPart, $this->_bytesRead,
-                        $readFromRemainingPart);
-                    // free up string
-                    unset($this->_parts[self::PART_XML_STRING]);
-                    $returnString .= $this->smartfread($this->_fileHandle,
-                            $readFromNextPart);
-                    $this->_bytesRead = $readFromNextPart - 1;
-                    break;
-                case self::PART_FILE_BINARY:
-                    // skipping past file section
-                    $returnString = $this->smartfread($this->_fileHandle,
-                            $readFromRemainingPart);
-                    $this->closeFileHandle();
-                    // read closing boundary string
-                    $returnString = $this->readFromStringPart(
-                        self::PART_CLOSING_XML_STRING, 0, $readFromNextPart);
-                    // have we read past the entire closing boundary string?
-                    if ($readFromNextPart >=
-                        $this->_parts[self::PART_CLOSING_XML_STRING][0]) {
-                        $this->_doneReading = true;
-                        return $returnString;
-                    }
-
-                    // Reset counter appropriately since we are now just
-                    // counting how much of the final string is being read.
-                    $this->_bytesRead = $readFromNextPart - 1;
-                    break;
-                case self::PART_CLOSING_XML_STRING:
-                    // reading past the end of the closing boundary
-                    if ($readFromRemainingPart > 0) {
-                        $returnString = $this->readFromStringPart(
-                            $this->_currentPart, $this->_bytesRead,
-                            $readFromRemainingPart);
-                        $this->_doneReading = true;
-                    }
-                    return $returnString;
-            }
-            $this->_currentPart++;
+        while(strlen($buffer) < $bytesRequested) {
+          $this->_currentPart += 1;
+          $nextBuffer = $this->read($bytesRequested - strlen($buffer));
+          if($nextBuffer === FALSE) {
+            break;
+          }
+          $buffer .= $nextBuffer;
         }
-        $this->_bytesRead += $bufferSize;
-        return $returnString;
-    }
 
-    /**
-     * Convenience method to shorthand the reading of non-file parts of the
-     * message.
-     *
-     * @param integer $part The part from which to read (supports only 0 or 2).
-     * @param integer $start The point at which to read from.
-     * @param integer $length How many characters to read.
-     * @return string A string of characters corresponding to the requested
-     *                section.
-     */
-    private function readFromStringPart($part, $start, $length)
-    {
-        return substr($this->_parts[$part][1], $start, $length);
+        return $buffer;
     }
 
     /**
@@ -477,22 +164,11 @@ class Zend_Gdata_MediaMimeStream
     }
 
     /**
-     * Check whether we have data left to read.
-     *
-     * @return boolean True if there is data remaining in the mime message,
-     *                 false, otherwise.
-     */
-    public function hasData()
-    {
-        return !($this->_doneReading);
-    }
-
-    /**
      * Close the internal file that we are streaming to the socket.
      *
      * @return void
      */
-    protected function closeFileHandle()
+    public function closeFileHandle()
     {
         if ($this->_fileHandle !== null) {
             fclose($this->_fileHandle);
@@ -506,7 +182,7 @@ class Zend_Gdata_MediaMimeStream
      */
     public function getContentType()
     {
-        return 'multipart/related; boundary="' .
+        return 'multipart/related;boundary="' .
             $this->_boundaryString . '"' . "\r\n";
     }
 

+ 91 - 0
library/Zend/Gdata/MimeBodyString.php

@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @subpackage Gdata
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * A wrapper for strings for buffered reading.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata_MimeBodyString
+ * @subpackage Gdata
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_MimeBodyString
+{
+
+    /**
+     * The source string.
+     *
+     * @var string
+     */
+    protected $_sourceString = '';
+
+    /**
+     * The size of the MIME message.
+     * @var integer
+     */
+    protected $_bytesRead = 0;
+
+    /**
+     * Create a new MimeBodyString object.
+     *
+     * @param string $sourceString The string we are wrapping.
+     */
+    public function __construct($sourceString)
+    {
+        $this->_sourceString = $sourceString;
+        $this->_bytesRead = 0;
+    }
+
+    /**
+     * Read the next chunk of the string.
+     *
+     * @param integer $bytesRequested The size of the chunk that is to be read.
+     * @return string A corresponding piece of the string.
+     */
+    public function read($bytesRequested)
+    {
+      $len = strlen($this->_sourceString);
+      if($this->_bytesRead == $len) {
+          return FALSE;
+      } else if($bytesRequested > $len - $this->_bytesRead) {
+          $bytesRequested = $len - $this->_bytesRead;
+      }
+
+      $buffer = substr($this->_sourceString, $this->_bytesRead, $bytesRequested);
+      $this->_bytesRead += $bytesRequested;
+
+      return $buffer;
+    }
+
+    /**
+     * The length of the string.
+     *
+     * @return int The length of the string contained in the object.
+     */
+    public function getSize()
+    {
+      return strlen($this->_sourceString);
+    }
+
+
+}

+ 65 - 0
library/Zend/Gdata/MimeFile.php

@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata
+ * @subpackage Gdata
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+/**
+ * A wrapper for strings for buffered reading.
+ *
+ * @category   Zend
+ * @package    Zend_Gdata_MimeFile
+ * @subpackage Gdata
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Gdata_MimeFile
+{
+
+    /**
+     * A handle to the file that is part of the message.
+     *
+     * @var resource
+     */
+    protected $_fileHandle = null;
+
+    /**
+     * Create a new MimeFile object.
+     *
+     * @param string $fileHandle An open file handle to the file being
+     *               read.
+     */
+    public function __construct($fileHandle)
+    {
+        $this->_fileHandle = $fileHandle;
+    }
+
+    /**
+     * Read the next chunk of the file.
+     *
+     * @param integer $bytesRequested The size of the chunk that is to be read.
+     * @return string A corresponding piece of the message. This could be
+     *                binary or regular text.
+     */
+    public function read($bytesRequested)
+    {
+      return fread($this->_fileHandle, $bytesRequested);
+    }
+
+}

+ 4 - 4
library/Zend/Gdata/YouTube.php

@@ -87,10 +87,10 @@ class Zend_Gdata_YouTube extends Zend_Gdata_Media
     const AUTH_SERVICE_NAME = 'youtube';
     const CLIENTLOGIN_URL = 'https://www.google.com/youtube/accounts/ClientLogin';
 
-    const STANDARD_TOP_RATED_URI = 'http://gdata.youtube.com/feeds/standardfeeds/top_rated';
-    const STANDARD_MOST_VIEWED_URI = 'http://gdata.youtube.com/feeds/standardfeeds/most_viewed';
-    const STANDARD_RECENTLY_FEATURED_URI = 'http://gdata.youtube.com/feeds/standardfeeds/recently_featured';
-    const STANDARD_WATCH_ON_MOBILE_URI = 'http://gdata.youtube.com/feeds/standardfeeds/watch_on_mobile';
+    const STANDARD_TOP_RATED_URI = 'http://gdata.youtube.com/feeds/api/standardfeeds/top_rated';
+    const STANDARD_MOST_VIEWED_URI = 'http://gdata.youtube.com/feeds/api/standardfeeds/most_viewed';
+    const STANDARD_RECENTLY_FEATURED_URI = 'http://gdata.youtube.com/feeds/api/standardfeeds/recently_featured';
+    const STANDARD_WATCH_ON_MOBILE_URI = 'http://gdata.youtube.com/feeds/api/standardfeeds/watch_on_mobile';
 
     const STANDARD_TOP_RATED_URI_V2 =
         'http://gdata.youtube.com/feeds/api/standardfeeds/top_rated';