Can you view a friendship relationship's data (the "You and a friend" page) via the Facebook API? [duplicate] - api

How can I get a friendship detail for two people? So for example in the web it will be:
http://www.facebook.com/<my_id>?and=<friend_id>
Is there any way I can do this in Graph API? Furthermore can I get specific items such as photos together, wall posts between us, etc? (Not documented AFAIK, but many Graph API features aren't anyway...)
EDIT: I think it should be possible with Graph API. For example getting family details (brother, sister, parents, etc) is not documented yet I still able to do it.

You can simulate a friendship query by doing multiple FQL queries. For example, to get all the photos between two friends A and B, you can:
Get all photos (p) from A
Get all tags of B in p (query on the photo_tags table)
Get all comments made by B on p (query on the comments table)
Repeat, this time selecting photos from B.
You can apply the same concept on other things such as posts, likes, videos etc.

Yes, I think you can also do the same thing phillee answered with the Graph API instead of FQL:
Get user's photos https://graph.facebook.com/USERID/photos
Get each photo's tags https://graph.facebook.com/PHOTOID/tags
Sort through the list of photo tags, and grab all photos with the Friend in them
Get each photo's comments https://graph.facebook.com/PHOTOID/comments
Sort through the list of photo comments, and grab all comments left by the friend
As the other answer also said: rinse and repeat for all data you want
https://graph.facebook.com/USERID/feed
https://graph.facebook.com/USERID/posts
etc etc, see all connections here: http://developers.facebook.com/docs/reference/api/user/
For the interests, movies, activities, etc just make an API call for both (https://graph.facebook.com/ONEUSER/music and https://graph.facebook.com/OTHERUSER/music) and find the intersection of the two sets of data (loop through each list and save all matches to a separate list of mutual Likes)
There are no specific API calls for friendships though, so you will have to build your own. My guess is that Facebook is doing exactly this on their Friendship pages :)
It should be just as easy with FQL as with the REST API... maybe even easier with FQL since you can add WHERE conditions and get back just the data you need (SELECT * FROM comments WHERE fromid = FRIENDID), instead of sorting through the big list returned by the API (unless there is a way to add conditions to API request URLs?).

If I understand properly you want to "View Friendship"
This type of query is not directly possible using the Graph API (at the moment). You would need to gather the information from each resource endpoint and then do some relating on your own part to "View Friendship"

This is what I have been using:
<?php
function main()
{
global $Fb;
$Fb = new Facebook(array('appId'=>FB_API_ID,'secret'=>FB_API_SECRET));
$logoutUrl = $Fb->getLogoutUrl();
$loginUrl = $Fb->getLoginUrl();
$user = fb_loguser($Fb);
if ($user)
{
$txt .= "<p align=\"center\">Logout</p>";
$txt .= "<h3 align=\"center\">You</h3>";
$access_token = $Fb->getAccessToken();
$user_profile = $Fb->api('/me');
$txt .= "<p align=\"center\">
<img src=\"https://graph.facebook.com/".$user."/picture\"></p>";
$txt .= fb_friends_list($user_profile,$access_token);
}
}
function fb_loguser($facebook)
{
global $Fb;
$Fb = $facebook;
$user = $Fb->getUser();
if ($user)
{
try
$user_profile = $Fb->api('/me');
catch (FacebookApiException $e)
{
error_log($e);
$user = null;
}
}
return($user);
}
function fb_friends_list($access_token)
{
global $Sess,$Fb;
$friends = $Fb->api('/me/friends'); // return an array [data][0 to n][name]/[id]
$siz = sizeof($friends['data']);
$txt = "<h3>Your FRIENDS on FACEBOOK</h3>";
$txt .= "<table>";
for ($i=0; $i<$siz; $i++)
{
$fid = $friends['data'][$i]['id'];
$src = "http://graph.facebook.com/".$fid."/picture";
$txt .= "<tr><td><img src=\"".$src."\" /></td>";
$txt .= "<td>".$friends['data'][$i]['name'] . "</td>";
$txt .= "<td>" . $fid . "</td></tr>";
}
$txt .= "</table>";
return($txt);
}
?>
Call main()!

Getting the photos where two (or more) users are tagged in:
SELECT pid, src_big FROM photo
WHERE pid IN(
SELECT pid FROM photo_tag WHERE subject=me())
AND pid IN(
SELECT pid FROM photo_tag WHERE subject=FRIEND_ID)
AND pid IN(
SELECT pid FROM photo_tag WHERE subject=ANOTHER_FRIEND_ID)
...

http://bighnarajsahu.blogspot.in/2013/03/facebook-graph-api-to-get-user-details.html
This is the complete code to get the friendlist in Fb.

Related

Why filter 'posts_join', 'posts_where', and 'posts_fields' not affect on single post request?

I created some custom query use filter above, but why not affected on single posts? The filter work well in posts loop.
Here example code.
add_filter( 'posts_join', 'my_join' );
function my_join( $join ) {
$join .= " some sql ";
return $join;
}

How to get top 10 videos from your channel with the views count included in the response

So I have a ouath web app that connects to youtube. I use the youtube analytics calls to get information like number of subscribers from my channel. But right now I try to make a top 10 videos from my channel with the views count for every video included in the response. I use this documentation:
Top videos for subscribed or unsubscribed viewers
My call looks like this:
$command = 'curl -H "Authorization: Bearer ' . $access_token . '" "https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=' . date('Y-m-d', strtotime('-31 days')) . '&end-date=' . date('Y-m-d', strtotime('today')). '&metrics=views&dimensions=video&sort=views"';
But I get an error message as a response:
"The query is not supported. Check the documentation at https://developers.google.com/youtube/analytics/v1/available_reports for a list of supported queries."
I also tried this call with YoTube data API:
$videos_url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&forMine=true&order=viewCount&type=video&access_token=' . $access_token;
But it provides this response:
["kind"]=>
string(26) "youtube#searchListResponse"
["etag"]=>
string(57) ""######""
["nextPageToken"]=>
string(112) "#######"
["pageInfo"]=>
object(stdClass)#267 (2) {
["totalResults"]=>
int(1)
["resultsPerPage"]=>
int(5)
}
["items"]=>
array(1) {
[0]=>
object(stdClass)#270 (4) {
["kind"]=>
string(20) "youtube#searchResult"
["etag"]=>
string(57) ""#####""
["id"]=>
object(stdClass)#269 (2) {
["kind"]=>
string(13) "youtube#video"
["videoId"]=>
string(11) "####"
}
["snippet"]=>
object(stdClass)#273 (6) {
["publishedAt"]=>
string(24) "2016-09-14T14:49:49.000Z"
["channelId"]=>
string(24) "#####"
["title"]=>
string(12) "My Slideshow"
["description"]=>
string(87) "I created this video with the YouTube Slideshow Creator (http://www.youtube.com/upload)"
This response provides no views count. I need for every video to get the views count as well.
Any ideas on how to accomplish this? Any help is welcomed! Thank you all for your time!
The issue with your youtube analytics api request is sort parameter. Try using value -views instead of views. You can double check the API link you provided. Also set the max-results
Example URL :
https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3Dmine&start-date=2016-05-01&end-date=2016-09-01&metrics=views&dimensions=video&max-results=10&sort=-views&key={YOUR_API_KEY}

Codeigniter populate nested associations

this is the results i need from the database
{comment: 'hello there', user: [{name: 'sahan', id: 1}], id: 2}
function used to get comments
public function get_comments(){
$query = $this->db->get('comments');
return $query->result_array();
}
I have a comments table and a users table, When a user comments on something the
comment is saved as follows
comment > Comment text
user: userid
So when the data is shown I need codeigniter to populate the user field with the user data found from the users table
Does anyone know how to do this ?
I used this functionality in SailsJS but dont know how to do it here in CodeIG
Sails.js populate nested associations
Codeigniter 's active record is not as advanced as SailJS active record, but you can achieve what you are asking for with two queries within the same method.
I'm assuming the comments table has a foreign key to the users table through a user_id field.
public function get_comments() {
/* Get all the comments */
$query = $this->db->get('comments');
$comments = $query->result_array();
/* Loop through each comment, pulling the associated user from the db */
foreach $comments as &$comment {
$query = $this->db->get_where('users', array('id' => $comment['user_id']));
$user = $query->result_array();
/* Put the user's data in a key called 'user' within the comment array */
$comment['user'] = $user;
/* Remove the unnecessary user_id and $user variable */
unset($comment['user_id']);
unset($user);
}
return $comments;
}

Symfony2 + Doctrine - Filtering

I've got a OneToMany relationship where one football team has many players. I want to list all football teams and display the name of the captain for each team.
Each player entity has a foreign key (team_id) and a field 'captain' which is set to 0 or 1. I'm currently running the following query:
$teams = $this
->getDoctrine()
->getRepository('FootballWebsiteBundle:Team')
->createQueryBuilder('t')
->setFirstResult(($pageNumber * $resultPerPage) - $resultPerPage)
->setMaxResults($resultPerPage)
->add('where','t.deleted = 0')
->add('orderBy', 't.name DESC')
->getQuery()->getResult();
Then when I loop through each team in twig I run team.getTeamCaptain().getName() which is a filter within my Team entity:
public function getTeamCaptain() {
$them = $this->players->filter(function($p) {
return $p->getCaptain() == 1;
});
return $them->first();
}
Is there a better way to run this query?
First of all, you may want to fetch-join the players of each retrieved team to avoid having them lazy loaded during rendering of the template. Here's the DQL:
SELECT
t, p
FROM
FootballWebsiteBundle:Team t
LEFT JOIN
t.players p
WHERE
t.deleted = 0
ORDER BY
t.name DESC
Which can be built with following query builder API calls:
$teamsQuery = $this
->getDoctrine()
->getRepository('FootballWebsiteBundle:Team')
->createQueryBuilder('t')
->addSelect('p')
->leftJoin('t.players', 'p')
->add('where','t.deleted = 0')
->add('orderBy', 't.name DESC')
->getQuery()
Then you wrap this query into a Paginator object (since setMaxResults and setFirstResult cannot be trusted when fetch-joining):
$paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($teamsQuery, true);
$teamsQuery
->setFirstResult(($pageNumber * $resultPerPage) - $resultPerPage)
->setMaxResults($resultPerPage)
In your view you can then iterate on the teams like following pseudo-code:
foreach ($paginator as $team) {
echo $team->getTeamCaptain() . "\n";
}
You can also gain some extra performance in your getTeamCaptain method by using the Selectable API:
public function getTeamCaptain() {
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->andWhere($criteria->expr()->eq('captain', 1));
return $this->players->matching($criteria)->first();
}
The advantage here is mainly relevant when the association players is not yet initialized, since this will avoid loading it entirely. This is not the case, but I consider it a good practice (instead of re-inventing collection filtering logic).

Youtube api get latest upload thumbnail

I am looking to returning the video-thumbnail of the latest uploaded video from my channel, and display it on my website.
Anyone know how I can do a minimal connection trough api and get only the thumbnail?
Thanks!
-Tom
REVISED!!
Using Cakephp, this is how I did it (thanks dave for suggestions using zend);
controller:
App::import('Xml');
$channel = 'Blanktv';
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads?v=2&max-results=1&orderby=published';
$parsed_xml =& new XML($url);
$parsed_xml = Set::reverse($parsed_xml);
//debug($parsed_xml);
$this->set('parsed_xml',$parsed_xml);
View;
$i=0;
foreach ($parsed_xml as $entry)
{
echo '<a href="/videokanalen" target="_self">
<img width="220px" src="'.$entry['Entry']['Group']['Thumbnail'][1]['url'] .'">
</a>';
}
Now the only thing remaining is to cache the feed call someway.. Any suggestions???
-Tom
here is a quick dirty way of doing it without really touching the api at all.
I'm not suggesting it's best practice or anything and I'm sure there are smarter ways but it definitely works with the current Youtube feed service.
My solution is PHP using the Zend_Feed_Reader component from Zend Framework, if you need a hand setting this up if you're not familiar with it let me know.
Essentially you can download version 1.11 from Zend.com here and then make sure the framework files are accessible on your PHP include path.
If you are already using Zend Framework in an MVC pattern you can do this in your chosen controller action:
$channel = 'Blanktv'; //change this to your channel name
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads';
$feed = Zend_Feed_Reader::import($url);
$this->view->feed = $feed;
Then you can do this in your view:
<h1>Latest Video</h1>
<div>
<?php
$i=0;
foreach ($this->feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
echo '<h3>' . $entry->getTitle() . '</h3>';
echo '<p>Uploaded on: '. $entry->getDateCreated() .'</p>';
echo '<a href="http://www.youtube.com/watch?v=' . $videoId .'" target="_blank">
<img src="http://img.youtube.com/vi/' . $videoId .'/hqdefault.jpg">
</a>';
$i++;
if($i==1) break;
}
?>
</div>
otherwise you can do:
<?php
$channel = 'Blanktv'; //change this to your channel
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads';
$feed = Zend_Feed_Reader::import($url);
?>
<h1>Latest Video</h1>
<div>
<?php
$i=0;
foreach ($feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
echo '<h3>' . $entry->getTitle() . '</h3>';
echo '<p>Uploaded on: '. $entry->getDateCreated() .'</p>';
echo '<a href="http://www.youtube.com/watch?v=' . $videoId .'" target="_blank">
<img src="http://img.youtube.com/vi/' . $videoId .'/hqdefault.jpg">
</a>';
$i++;
if($i==1) break;
}
?>
</div>
With the latter method you'll likely need to use a php require statement for the Zend_Feed_Reader files etc....
Hope this helps, like I say let me know if you need a hand.
All the best,
Dave
UPDATE: In response to your comments about caching
Hi Tom, here is another quick and dirty solution which doesn't use cache but may be very quick to implement.
The reason I didn't go with a caching component is because I figured a simple db solution would suffice under the circumstances. I also thought having to pull the feed to compare whether it was new or not wouldn't be the most economical for you.
You could automate this process to be run automatically at specified times but if you don't want to automate the process and don't mind clicking a link to update the video manually you could trigger it that way.
My solution is again based on ZF but since you were ok hacking it into something useful with cakephp you should have no problem doing the same here.
First set up a new table (assuming a MySQL db):
CREATE TABLE `yourdbname`.`latestvid` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Unique identifier',
`videoId` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video id',
`videoTitle` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video title',
`uploadDate` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video upload date'
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO `yourdbname`.`latestvid` (`id`, `videoId`, `videoTitle`, `uploadDate`) VALUES (NULL, '--', '--', '--');
This will create a table for your latest video info for use in your template however the default values I've set up will not work with your template for obvious reasons.
You could then do something similar to this:
public function updateAction()
{
$this->_helper->viewRenderer->setNoRender(); // disable view
$this->_helper->layout()->disableLayout(); // disable layout
$user = 'Blanktv'; // insert your channel name
$url = 'https://gdata.youtube.com/feeds/api/users/'.$user.'/uploads';
$feed = Zend_Feed_Reader::import($url);
if(!$feed)
{
die("couldn't access the feed"); // Note: the Zend component will display an error if the feed is not available so this wouldn't really be necessary for ZF
}
else
{
$i=0;
foreach ($feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
$videoTitle = $entry->getTitle();
$uploadDate = $entry->getDateCreated();
// use your preferred method to update the db record where the id = 1
$i++;
if($i==1) break;
}
}
}
Maybe have a go and let me know how you get on?
You'd just need to tweak the template so you'd get the variables from the database instead of Youtube with the exception of the thumbnail.
I suppose you could always take that approach further and actually store images etc since the thumbnail is still being pulled from Youtube and may slow things down.
You could set up a script to copy the thumbnail to your own server and store the path in the db or use a standard thumbnail if you are running a series of videos for which you require standard branding - anyway hope it helps.
:-D
Dave