Draven Draven - 4 months ago 28
PHP Question

YouTube API v3: How to get returned 404 (not found) error from PlaylistItems?

I know I can loop through the playlists to compare if the playlist exists on Youtube but that is making two calls (example below) and since I already know the playlist ID I should just be able to make one call.

Two calls to YouTube to loop through playlists (not the way I want to do it):

# Playlist ID from URL
$playlist=$_GET['playlist'];

# Playlists from YoUtube
$playlists=$yt->PlaylistsListFeed();

# Loop through the playlists.
foreach($playlists as $playlist_feed)
{
if($playlist_feed['id']==$playlist)
{
# This is a playlist
$this->setIsPlaylist(TRUE);

# Assign the Playlist Items to a variable.
$video_search=$yt->PlaylistItems($playlist_feed['id']);
break;
}
}

# If $video_search is not set then playlist does not exist.
if(!isset($video_search))
{
return $display='That playlist doesn\'t exist. Please choose another.';
}


I have the code working for the single call but I can't figure out how to get the 404 error it returns if the playlist ID does not exist (results from YouTube below).

YouTube method (
PlaylistItems
):

/**
* PlaylistItems
*
* Retrieves videos from a playlist.
*
* @param int $playlist_id The ID of the playlist.
* @param string $part The part parameter specifies a comma-separated list of
* one or more playlistItem resource properties that the API
* response will include. The part names that you can include
* in the parameter value are id, snippet, and contentDetails.
* @access public
*/
public function PlaylistItems($playlist_id, $part='snippet')
{
# Set the Database instance to a variable.
$doc=Document::getInstance();
try
{
# Bring $youtube_service into the scope
global $youtube_service;

$playlistsItems_optParams=array('maxResults' => 50, 'playlistId' => $playlist_id);
$playlistsItems=$youtube_service->playlistItems->listPlaylistItems($part, $playlistsItems_optParams);

$new_array=$this->rebuildArray($playlistsItems, TRUE);

# Instantiate a new Utility object.
$utility=new Utility();
# Sort the playlist array by date.
$items=$utility->sortByDate($new_array, 'publishedAt');

return $items;
}
catch(Exception $e)
{
# Print Results (below)
print_r($e); exit;

if($e->getCode()==404)
{
$doc->setError('That playlist doesn\'t exist. Please choose another.');
}
}
} #==== End -- PlaylistItems


Single call code:

# Playlist ID from URL
$playlist=$_GET['playlist'];

# Assign the Playlist Items to a variable.
$video_search=$yt->PlaylistItems($playlist);


Return from
PlaylistItems
method

Google_ServiceException Object
(
[errors:protected] => Array
(
[0] => Array
(
[domain] => youtube.playlistItem
[reason] => playlistNotFound
[message] => Not Found
[locationType] => parameter
[location] => playlistId
)

)

[message:protected] => Error calling GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLD2D6E64D9CD49E1&key=AIzaSyDVGJhk7DfKKJAaciX14aqyw_YbPaT4fp4: (404) Not Found
[string:Exception:private] =>
[code:protected] => 404
[file:protected] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Social/Google/io/Google_REST.php
[line:protected] => 66
[trace:Exception:private] => Array
(
[0] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Social/Google/io/Google_REST.php
[line] => 36
[function] => decodeHttpResponse
[class] => Google_REST
[type] => ::
[args] => Array
(
[0] => Google_HttpRequest Object
(
[batchHeaders:Google_HttpRequest:private] => Array
(
[Content-Type] => application/http
[Content-Transfer-Encoding] => binary
[MIME-Version] => 1.0
[Content-Length] =>
)

[url:protected] => https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLD2D6E64D9CD49E1&key=AIzaSyDVGJhk7DfKKJAaciX14aqyw_YbPaT4fp4
[requestMethod:protected] => GET
[requestHeaders:protected] => Array
(
)

[postBody:protected] =>
[userAgent:protected] => google-api-php-client/0.6.0
[responseHttpCode:protected] => 404
[responseHeaders:protected] => Array
(
[content-type] => application/json; charset=UTF-8
[date] => Thu, 18 Jul 2013 05:11:11 GMT
[expires] => Thu, 18 Jul 2013 05:11:11 GMT
[cache-control] => private, max-age=0
[x-content-type-options] => nosniff
[x-frame-options] => SAMEORIGIN
[x-xss-protection] => 1; mode=block
[server] => GSE
[transfer-encoding] => chunked
)

[responseBody:protected] => {
"error": {
"errors": [
{
"domain": "youtube.playlistItem",
"reason": "playlistNotFound",
"message": "Not Found",
"locationType": "parameter",
"location": "playlistId"
}
],
"code": 404,
"message": "Not Found"
}
}

[accessKey] =>
)

)

)

[1] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Social/Google/service/Google_ServiceResource.php
[line] => 186
[function] => execute
[class] => Google_REST
[type] => ::
[args] => Array
(
[0] => Google_HttpRequest Object
(
[batchHeaders:Google_HttpRequest:private] => Array
(
[Content-Type] => application/http
[Content-Transfer-Encoding] => binary
[MIME-Version] => 1.0
[Content-Length] =>
)

[url:protected] => https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLD2D6E64D9CD49E1&key=AIzaSyDVGJhk7DfKKJAaciX14aqyw_YbPaT4fp4
[requestMethod:protected] => GET
[requestHeaders:protected] => Array
(
)

[postBody:protected] =>
[userAgent:protected] => google-api-php-client/0.6.0
[responseHttpCode:protected] => 404
[responseHeaders:protected] => Array
(
[content-type] => application/json; charset=UTF-8
[date] => Thu, 18 Jul 2013 05:11:11 GMT
[expires] => Thu, 18 Jul 2013 05:11:11 GMT
[cache-control] => private, max-age=0
[x-content-type-options] => nosniff
[x-frame-options] => SAMEORIGIN
[x-xss-protection] => 1; mode=block
[server] => GSE
[transfer-encoding] => chunked
)

[responseBody:protected] => {
"error": {
"errors": [
{
"domain": "youtube.playlistItem",
"reason": "playlistNotFound",
"message": "Not Found",
"locationType": "parameter",
"location": "playlistId"
}
],
"code": 404,
"message": "Not Found"
}
}

[accessKey] =>
)

)

)

[2] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Social/Google/contrib/Google_YoutubeService.php
[line] => 425
[function] => __call
[class] => Google_ServiceResource
[type] => ->
[args] => Array
(
[0] => list
[1] => Array
(
[0] => Array
(
[part] => snippet
[maxResults] => 50
[playlistId] => PLD2D6E64D9CD49E1
)

)

)

)

[3] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Media/YouTube.php
[line] => 412
[function] => listPlaylistItems
[class] => Google_PlaylistItemsServiceResource
[type] => ->
[args] => Array
(
[0] => snippet
[1] => Array
(
[maxResults] => 50
[playlistId] => PLD2D6E64D9CD49E1
)

)

)

[4] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/application/modules/Media/Video.php
[line] => 1130
[function] => PlaylistItems
[class] => YouTube
[type] => ->
[args] => Array
(
[0] => PLD2D6E64D9CD49E1
)

)

[5] => Array
(
[file] => /Volumes/Coding/WebDev/CWIS/cwis.org/public/media/video/index.php
[line] => 59
[function] => displayVideoFeed
[class] => Video
[type] => ->
[args] => Array
(
)

)

)

[previous:Exception:private] =>
)


As you an see everything is either
protected
or
private
so how am I supposed to know if there was an error or not?

Answer

I ended up just listing the videos from YouTube and getting their statuses. This runs as a cron script, every 10 minutes.

# Get new uploaded videos from the database.
$get_new_videos=$db->get_results('SELECT `id`, `file_name`, `api` FROM `'.DBPREFIX.'videos` WHERE `new` IS NULL');

# If there are new videos...
if($get_new_videos>0)
{
    # Loop through the new videos
    foreach($get_new_videos as $new_video)
    {
        # Decode the `api` field.
        $api_decoded=json_decode($new_video->api);
        # Get the YouTube Video ID.
        $video_yt_id=$api_decoded->youtube_id;

        if(isset($new_video->file_name))
        {
            # Set the path to the video on the server.
            $video_path='videos'.DS.$new_video->file_name;
        }

        $to=TO_USER;
        $reply_to=FROM_SERVER;
        $subject="Video status from ".DOMAIN_NAME;
        $body='';

        # Check the video status.
        $check_status=$yt->listVideos('status', array('id' => $video_yt_id));

        # Did YouTube return results?
        if(!empty($check_status['items']))
        {
            # Has the video been processed? Default is TRUE. will be changed to FALSE if the video still has "uploaded" status.
            $processed=TRUE;

            # Loop through the videos from YouTube.
            foreach($check_status['items'] as $status)
            {
                if($status['status']['uploadStatus']=="uploaded")
                {
                    # The video has not been processed yet so do not send an email.
                    $processed=FALSE;
                }
                # Check to see if the YouTube upload was a success.
                elseif($status['status']['uploadStatus']=="processed")
                {
                    # Tell the user the video was uploaded.
                    $body.='Your video has been uploaded to YouTube and can be viewed at http://'.FULL_DOMAIN.'media/videos/?video='.$new_video->id;
                }
                # Check if the uploaded video status is rejected.
                elseif($status['status']['uploadStatus']=="rejected")
                {
                    if(isset($new_video->file_name))
                    {
                        # Get the Upload class.
                        require_once MODULES.'Form'.DS.'Upload.php';
                        # Instantiate an Upload object.
                        $upload=new Upload($video_path);
                        # Delete video file from server.
                        $upload->deleteFile($video_path);
                        # Remove extention from filename.
                        $name_no_ext=substr($new_video->file_name, 0, strrpos($new_video->file_name, '.'));
                        # Delete the thumbnails from the server.
                        $upload->deleteFile(IMAGES_PATH.'videos'.DS.'original'.DS.$name_no_ext.'.jpg');
                        $upload->deleteFile(IMAGES_PATH.'videos'.DS.$name_no_ext.'*.jpg', TRUE);

                        # Delete rejected video from YouTube
                        $delete_response=$yt->deleteVideo($video_yt_id);
                    }

                    # Need to delete the entry from the database as well.
                    $db->query('DELETE FROM `'.DBPREFIX.'videos` WHERE `id` = '.$db->quote($new_video->id).' LIMIT 1');

                    # Check if the rejection status was a duplicate.
                    if($status['status']['rejectionReason']=="duplicate")
                    {
                        # Tell the user the video was a duplicate.
                        $body.='Your video was rejected because it was a duplicate video';
                    }
                }
            }
        }
        else
        {
            $body.='Your video was not found on YouTube';
            $processed=TRUE;
        }

        # Update database if the video has been "processed".
        if($processed===TRUE)
        {
            # Get the PHPMailer class.
            require_once MODULES.'Email'.DS.'Email.php';
            # Instantiate a new PHPMailer object.
            $mail=new Email();

            $mail->sendEmail($subject, $to, $body, $reply_to);

            # Set new videos to old.
            $db->query('UPDATE `'.DBPREFIX.'videos` SET `new` = 0 WHERE `id` = '.$db->quote($new_video->id).' LIMIT 1');
        }
    }
}