How to get all comments from a Youtube video - php

Firstly, I looked all of other title. All of them out of date. I mean, they are use old api.
I write a code to list all comments with their nextPageToken
<?php
$url = "SE0wDh_pILk"; // Youtube video ID
$ytkey = "IzaSyCaRXmJ9XDC4XucAZCzXx7hisCtYEH0mNs"; //"IzaSyBuu-rnbmPAj1DjR6WmyxGmpmQKz8aTXbw" Your api key
$nextPage = ""; // Next Page Token for get comments of next Page.
//$i =0; // DO NOT CHANGE
for ($i = 0; $i < 5; $i++) {
$str = file_get_contents("https://www.googleapis.com/youtube/v3/commentThreads?key=" . "$ytkey" . "&textFormat=plainText&part=snippet&videoId=" . "$url" . "&maxResults=100&nextPagetoken=" . "$nextPage");
$json = json_decode($str, true); // decode the JSON into an associative array
//echo '<pre>' . print_r($json, true) . '</pre>'; // Print json data as array structer ..
echo "$i - " . "Next Page Token : " . $json['nextPageToken']; // Take the next Page Token for get next 100 comment...
echo "<hr>"; // Divider
$nextPage = $json['nextPageToken']; // Take token for next query
// print comments.
foreach ($json['items'] as $val) { // Loop for list comments...
$author = $val['snippet']['topLevelComment']['snippet']['authorDisplayName']; //Get Comment Author Name.
//$author_url = $val['snippet']['topLevelComment']['snippet']['authorChannelUrl']; //Get Comment Author URL.
//$author_thumbnail_url = $val['snippet']['topLevelComment']['snippet']['authorProfileImageUrl']; //Get Comment Author Thumbnail URL.
$comment = $val['snippet']['topLevelComment']['snippet']['textDisplay']; //Get Comment Content.
echo "<span style='color:red';>" . "$author" . "</span>" . " --> " . "$comment"; // Author and comment
echo "<hr>"; // Divider
}
}
echo "Process over. ";
?>
I learn how to parse json and how to show them on php from stackoverflow.
Now, there is no problem with taking nextPageTokens. But I can't get comments.
When I run the script, It returns different nextPageToken but comments are same, they come from the first page.
I try to add enough comment line.
Sorry I can't color the php codes.

You are calling commentThreads with the parameter &nextPagetoken=.
The correct parameter to use is &pageToken=.

Here is a recursive,bare bones function to return all comments from a video
public function getAllComments($videoId,$pageToken=null,$maxResults){
$url = "https://www.googleapis.com/youtube/v3/commentThreads";
static $all =[];
$params =[
'key' => 'your-key',
'part' => 'snippet',
'maxResults' => $maxResults,
'videoId' => $videoId,
'pageToken' => $pageToken
];
$call = $url.'?'.http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $call);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$data = NULL;
$data = json_decode($output,true);
$all[] = $data;
if(isset($data['nextPageToken'])){
if($data['nextPageToken'] != NULL ){
$pageToken = $data['nextPageToken'];
getAllComments($videoId,$pageToken,$maxResults);
}
}
curl_close($ch);
return $all;
}

Finally I found a site that does what I want to do.
If you have to collect all comments of a video and take one of them randomly for lottery etc. , use these sites ->
https://www.randomcommentpicker.com
http://commentpicker.com/youtube.html

Related

How to dynamically repeat for all children of a JSON array, that may have children (PHP)

I'm trying to code a website that takes the comments of a Reddit page and shows them. However, the comments have replies, and I want to show those too, but a comment can have none, one or more replies, and those replies can have replies. Is there a way to repeat the same code for all of the replies with minor differences (indentation)? I'm using the reddit json feature, and am getting the JSON from something like here: https://www.reddit.com/r/pcmasterrace/comments/dln0o3/foldinghome_and_pcmr_team_up_use_your_pc_to_help/.json.
I have:
$url = ('https://www.reddit.com/r/pcmasterrace/comments/dln0o3/foldinghome_and_pcmr_team_up_use_your_pc_to_help/.json');
$json = file_get_contents($url);
$obj = json_decode($json, true);
$comment_array = array_slice($obj[1]['data']['children'], 0, 50);
echo '<div class="comments">';
foreach ($comment_array as $c) {
echo "<p>(".$c['data']['author'].") ". $c['data']['score'] . " Points<br>".$c['data']['body']."</p>";
if (!($c['data']['replies'] == "")) {
$r1_array = $c['data']['replies']['data']['children'];
foreach ($r1_array as $r1) {
echo "<p> (".$r1['data']['author'].") ". $r1['data']['score'] . " Points<br> ".$r1['data']['body']."</p>";
if (!($r1['data']['replies'] == "")) {
$r2_array = $r1['data']['replies']['data']['children'];
foreach ($r2_array as $r2) {
echo "<p> (".$r2['data']['author'].") ". $r1['data']['score'] . " Points<br> ".$r2['data']['body']."</p>";
}
}
}
}
}
}
This produces the desired result, with replies to replies and such. However, it's a bit messy, and if there is a really long reply chain, it won't catch it. Is there a way to make it repeat somehow or should I just copy and paste it a bunch of times?
Thanks very much!
I think you're looking for a concept called recursion.
The basic idea is that a function will call itself as many times as needed (as opposed to using a fixed number of loops).
Something like this:
<?php
function output($data, $level = 0) {
$spaces = str_repeat(' ', $level);
foreach ($data as $post) {
echo "<p>(".$spaces.$post['data']['author'].") ". $post['data']['score'] . " Points<br>".$post['data']['body']."</p>\r\n";
if ($post['data']['replies']) {
// Notice that we are calling the function again, this time increasing the level
// This is the "recursive" part of the function
output($post['data']['replies']['data']['children'], $level + 1);
}
}
}
$url = ('https://www.reddit.com/r/pcmasterrace/comments/dln0o3/foldinghome_and_pcmr_team_up_use_your_pc_to_help/.json');
$json = file_get_contents($url);
$data = json_decode($json, true);
$comment_array = array_slice($data[1]['data']['children'], 0, 50);
output($comment_array);
?>

CSE Google Custom Page api show 50 results PHP?

I'm trying to get the first 50 results of the Google CSE API with the following PHP code.
The problem is that it combines the two pages sow the results are getting messed up like the first position is the one of the first page and the second position is the second of the second page and so on. Can someone tell me what I am doing wrong here?
What I actually want to do is get the first 50 results in a array, but the code below gives me mixed results.
$apiKey = "theapikey";
$query = "news";
for ($i = 1; $i <= 5; $i++) {
$ch = curl_init();
$request = "https://www.googleapis.com/customsearch/v1?q=" . urlencode( "$query" ) . "&cx=013594553343653397533:q-qkkaltmay" ."&key=" . $apiKey . "&start=" . $i;
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$output = curl_exec($ch);
$output = json_decode($output);
foreach( $output->items as $result ) {
$url = $result->link;
${"items" . $i}[] = $url;
}
}
echo json_encode($items1);
It looks like you are adding each set of 10 results into a separate array, so $items1 has the first 10 results, $items2 has the next 10, etc. If you want all 50 results in a single array, there is no need to use an index in the array's name.
Also, the "start" parameter is the number of the result you want, not the number of the result set - so you want the first query to start at 1, the second to start at 11, the third at 21, etc.
You may also want to check that there is something in the result before adding it to your array.
I might do something more like so:
$apiKey = "theapikey";
$query = "news";
$items = array();
for ($i = 1; $i <= 5; $i++) {
$ch = curl_init();
$request = "https://www.googleapis.com/customsearch/v1?" .
"q=" . urlencode( "$query" ) .
"&cx=013594553343653397533:q-qkkaltmay" .
"&key=" . $apiKey .
"&start=" . ( ($i - 1)*10 + 1 );
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$output = curl_exec($ch);
$output = json_decode($output);
foreach( $output->items as $result ) {
if ($url = $result->link && trim($url)) $items[] = $url;
}
}
echo json_encode($items);
Finally, a couple caveats:
There is an existing question about whether this JSON api is deprecated and possibly going away.
Each query for the next 10 results counts against your quota. If you are worried about running out of queries each month, or if you are paying for quota increases, you may want to consider only retrieving what you need.

(PHP) Grabbing AccessToken and feed without permission. (sorta)

I'm beginning a blog and I wanted to make a 'FacebookStatusApp' for the blog.
All it has to do is get my latest status and get request it to my translator page.
I can get my latest feed but the problem is the accesstoken.
I found a way to keep refreshing my access_token every 9 minutes. It's a site called:
https://mywebcron.com/
This site will call your url every X minutes. I chose 9 minutes.
My renew code is pretty simple:
<?php
$file = file_get_contents("fbat.txt");
$token = $file;
$token_url = "https://graph.facebook.com/oauth/access_token?client_id=100000280644272&client_secret=secret&grant_type=fb_exchange_token&fb_exchange_token=".$token;
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_URL, $token_url);
$contents = curl_exec($c);
$err = curl_getinfo($c,CURLINFO_HTTP_CODE);
curl_close($c);
$paramsfb = null;
//parse_str($contents, $paramsfb);
echo $contents;
?>
"Fbat.txt" contains the current AccessToken.
But I need a client_secret for my account.
And I can't get a AccessToken for my facebook account :/
So my solution was creating a new app using MY ClientID and HIS ClientSecret with the 'GRAPH EXPLORER' to generate a access_token.
So my question is:
How can I get MY latest status AND MY access_token. ?
If there is a good alternative (Ex. Using an APP) I could do that too.
Well, I hope you understand my question :P
First of all, your feed needs to be public. The below code should do the rest:
function fb_setup(){
$app_id = 'APP_ID';
$app_secret = 'APP_SECRET';
$response = file_get_contents('https://graph.facebook.com/oauth/access_token?type=client_cred&client_id='.$app_id.'&client_secret='.$app_secret);
$token = str_replace('access_token=', '', $response);
$node = "PAGE_ID(if not a page just use 'me')";
$fields = array();
$fields[] = 'feed';
$fields[] = 'likes';
$response = file_get_contents('https://graph.facebook.com/'.$node.'?fields='.implode(',', $fields).'&access_token='.$token.'');
$arr = json_decode($response);
$data['node'] = $node;
$data['arr'] = $arr;
return $data;
}
function last_post(){
$ret = fb_setup();
$arr = $ret['arr'];
$node = $ret['node'];
$feed = $arr->feed->data;
$ret = "";
$ret .= "<div id='last-fb-post'>";
$item = $feed[0];
$message = str_replace("\n","</p><p>",$item->message);
$likes = (!$item->likes->count) ? '0' : $item->likes->count;
$coms = $item->comments->count;
$ex_id = explode('_',$item->id);
$id = $ex_id[1];
$href = 'http://www.facebook.com/permalink.php?story_fbid='.$id.'&id='.$node;
$ret .= '<a class="title" target="_blank" href="'.$href.'">Last Update: <u>' . date("F j, Y",strtotime($item->created_time)) . '</u></a>';
if($item->type == 'photo'){
$ret .= '<div class="fb_img"><a target="_blank" href="'.$href.'"><img src="'.$item->picture.'"/></a></div>';
}
$ret .= "<p class=\"msg\">";
$ret .= $message;
$ret .= "</p>";
$ret .= "<p class='likes'><a htarget=\"_blank\" href=\"$href\">$likes</p>";
$ret .= "</div>";
return $ret;
}

Parsing XML in PHP DOM via cURL - can't get nodeValue if it is url address or date

I have this strange problem parsing XML document in PHP loaded via cURL. I cannot get nodeValue containing URL address (I'm trying to implement simple RSS reader into my CMS). Strange thing is that it works for every node except that containing url addresses and date ( and ).
Here is the code (I know it is a stupid solution, but I'm kinda newbie in working with DOM and parsing XML documents).
function file_get_contents_curl($url) {
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
curl_setopt($ch, CURLOPT_TIMEOUT, 4); // times out after 4s
$result = curl_exec($ch); // run the whole process
return $result;
}
function vypis($adresa) {
$html = file_get_contents_curl($adresa);
$doc = new DOMDocument();
#$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName('title');
$desc = $doc->getElementsByTagName('description');
$ctg = $doc->getElementsByTagName('category');
$pd = $doc->getElementsByTagName('pubDate');
$ab = $doc->getElementsByTagName('link');
$aut = $doc->getElementsByTagName('author');
for ($i = 1; $i < $desc->length; $i++) {
$dsc = $desc->item($i);
$titles = $nodes->item($i);
$categorys = $ctg->item($i);
$pubDates = $pd->item($i);
$links = $ab->item($i);
$autors = $aut->item($i);
$description = $dsc->nodeValue;
$title = $titles->nodeValue;
$category = $categorys->nodeValue;
$pubDate = $pubDates->nodeValue;
$link = $links->nodeValue;
$autor = $autors->nodeValue;
echo 'Title:' . $title . '<br/>';
echo 'Description:' . $description . '<br/>';
echo 'Category:' . $category . '<br/>';
echo 'Datum ' . gmdate("D, d M Y H:i:s",
strtotime($pubDate)) . " GMT" . '<br/>';
echo "Autor: $autor" . '<br/>';
echo 'Link: ' . $link . '<br/><br/>';
}
}
Can you please help me with this?
To read RSS you shouldn't use loadHTML, but loadXML. One reason why your links don't show is because the <link> tag in HTML ignores its contents. See also here: http://www.w3.org/TR/html401/struct/links.html#h-12.3
Also, I find it easier to just iterate over the <item> tags and then iterate over their children nodes. Like so:
$d = new DOMDocument;
// don't show xml warnings
libxml_use_internal_errors(true);
$d->loadXML($xml_contents);
// clear xml warnings buffer
libxml_clear_errors();
$items = array();
// iterate all item tags
foreach ($d->getElementsByTagName('item') as $item) {
$item_attributes = array();
// iterate over children
foreach ($item->childNodes as $child) {
$item_attributes[$child->nodeName] = $child->nodeValue;
}
$items[] = $item_attributes;
}
var_dump($items);

is there a PHP library that handles URL parameters adding, removing, or replacing?

when we add a param to the URL
$redirectURL = $printPageURL . "?mode=1";
it works if $printPageURL is "http://www.somesite.com/print.php", but if $printPageURL is changed in the global file to "http://www.somesite.com/print.php?newUser=1", then the URL becomes badly formed. If the project has 300 files and there are 30 files that append param this way, we need to change all 30 files.
the same if we append using "&mode=1" and $printPageURL changes from "http://www.somesite.com/print.php?new=1" to "http://www.somesite.com/print.php", then the URL is also badly formed.
is there a library in PHP that will automatically handle the "?" and "&", and even checks that existing param exists already and removed that one because it will be replaced by the later one and it is not good if the URL keeps on growing longer?
Update: of the several helpful answers, there seems to be no pre-existing function addParam($url, $newParam) so that we don't need to write it?
Use a combination of parse_url() to explode the URL, parse_str() to explode the query string and http_build_query() to rebuild the querystring. After that you can rebuild the whole url from its original fragments you get from parse_url() and the new query string you built with http_build_query(). As the querystring gets exploded into an associative array (key-value-pairs) modifying the query is as easy as modifying an array in PHP.
EDIT
$query = parse_url('http://www.somesite.com/print.php?mode=1&newUser=1', PHP_URL_QUERY);
// $query = "mode=1&newUser=1"
$params = array();
parse_str($query, $params);
/*
* $params = array(
* 'mode' => '1'
* 'newUser' => '1'
* )
*/
unset($params['newUser']);
$params['mode'] = 2;
$params['done'] = 1;
$query = http_build_query($params);
// $query = "mode=2&done=1"
Use this:
http://hu.php.net/manual/en/function.http-build-query.php
http://www.addedbytes.com/php/querystring-functions/
is a good place to start
EDIT: There's also http://www.php.net/manual/en/class.httpquerystring.php
for example:
$http = new HttpQueryString();
$http->set(array('page' => 1, 'sort' => 'asc'));
$url = "yourfile.php" . $http->toString();
None of these solutions work when the url is of the form:
xyz.co.uk?param1=2&replace_this_param=2
param1 gets dropped all the time
.. which means it never works EVER!
If you look at the code given above:
function addParam($url, $s) {
return adjustParam($url, $s);
}
function delParam($url, $s) {
return adjustParam($url, $s);
}
These functions are IDENTICAL - so how can one add and one delete?!
using WishCow and sgehrig's suggestion, here is a test:
(assuming no anchor for the URL)
<?php
echo "<pre>\n";
function adjustParam($url, $s) {
if (preg_match('/(.*?)\?/', $url, $matches)) $urlWithoutParams = $matches[1];
else $urlWithoutParams = $url;
parse_str(parse_url($url, PHP_URL_QUERY), $params);
if (strpos($s, '=') !== false) {
list($var, $value) = split('=', $s);
$params[$var] = urldecode($value);
return $urlWithoutParams . '?' . http_build_query($params);
} else {
unset($params[$s]);
$newQueryString = http_build_query($params);
if ($newQueryString) return $urlWithoutParams . '?' . $newQueryString;
else return $urlWithoutParams;
}
}
function addParam($url, $s) {
return adjustParam($url, $s);
}
function delParam($url, $s) {
return adjustParam($url, $s);
}
echo "trying add:\n";
echo addParam("http://www.somesite.com/print.php", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1&fee=0", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?newUser=1&fee=0&", "mode=3"), "\n";
echo addParam("http://www.somesite.com/print.php?mode=1", "mode=3"), "\n";
echo "\n", "now trying delete:\n";
echo delParam("http://www.somesite.com/print.php?mode=1", "mode"), "\n";
echo delParam("http://www.somesite.com/print.php?mode=1&newUser=1", "mode"), "\n";
echo delParam("http://www.somesite.com/print.php?mode=1&newUser=1", "newUser"), "\n";
?>
and the output is:
trying add:
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?newUser=1&mode=3
http://www.somesite.com/print.php?newUser=1&fee=0&mode=3
http://www.somesite.com/print.php?newUser=1&fee=0&mode=3
http://www.somesite.com/print.php?mode=3
now trying delete:
http://www.somesite.com/print.php
http://www.somesite.com/print.php?newUser=1
http://www.somesite.com/print.php?mode=1
You can try this:
function removeParamFromUrl($query, $paramToRemove)
{
$params = parse_url($query);
if(isset($params['query']))
{
$queryParams = array();
parse_str($params['query'], $queryParams);
if(isset($queryParams[$paramToRemove])) unset($queryParams[$paramToRemove]);
$params['query'] = http_build_query($queryParams);
}
$ret = $params['scheme'].'://'.$params['host'].$params['path'];
if(isset($params['query']) && $params['query'] != '' ) $ret .= '?'.$params['query'];
return $ret;
}

Categories