Reputation: 3612
Hey guys i'm trying to build a little app that pulls in the users profile picture, allows them to manipulate the image and then publish the modified image to their profile pictures album (ideally set as their profile pic, but i don't think this is possible???).
The problem I'm having is that the javascript i'm using to alter the image will not work unless the image is local
i.e. <img src="http://profile.ak.fbcdn.net/hprofile-ak-snc4/[some_user_id].jpg" />
will not work, but <img src="img/image.jpg" />
will...
Is there any way of achieving this?
The method I am using to get hold of the user picture is this:
To connect to facebook:
<?php
require_once 'library/facebook.php';
$app_id = "###";
$app_secret = "###";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
if(is_null($facebook->getUser()))
{
header("Location:{$facebook->getLoginUrl(array('req_perms' => 'user_status,publish_stream,user_photos'))}");
exit;
}
Then to display the image:
<?php
$aResponse = $facebook->api('/me', array(
'fields' => 'picture',
'type' => 'large'
));
echo "<img src='".$aResponse["picture"]."' />";
?>
Many thanks!
Upvotes: 2
Views: 1443
Reputation: 31
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
function curl_redir_exec($ch)
{
static $curl_loops = 0;
static $curl_max_loops = 20;
if ($curl_loops++ >= $curl_max_loops)
{
$curl_loops = 0;
return FALSE;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
@list($header, $data) = @explode("\n\n", $data, 2);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302)
{
$matches = array();
preg_match('/Location:(.*?)\n/', $header, $matches);
$url = @parse_url(trim(array_pop($matches)));
if (!$url)
{
//couldn't process the url to redirect to
$curl_loops = 0;
return $data;
}
$last_url = parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL));
if (!$url['scheme'])
$url['scheme'] = $last_url['scheme'];
if (!$url['host'])
$url['host'] = $last_url['host'];
if (!$url['path'])
$url['path'] = $last_url['path'];
$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . (@$url['query']?'?'.$url['query']:'');
return $new_url;
} else {
$curl_loops=0;
return $data;
}
}
function get_right_url($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
return curl_redir_exec($curl);
}
$url = 'http://graph.facebook.com/' . $fbid . '/picture?type=large';
$file_handler = fopen('/img/avatar/'.$fbid.'.jpg', 'w');
$curl = curl_init(get_right_url($url));
curl_setopt($curl, CURLOPT_FILE, $file_handler);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_exec($curl);
curl_close($curl);
fclose($file_handler);
// Happy Coding
Upvotes: 0
Reputation: 3612
Thanks Jim for your response, I had seen someone doing something very similar to that, but again (just my luck) I was having problems with it. Anyway the way I managed to solve it was:
function save_image($inPath,$outPath)
{ //Download images from remote server
$in= fopen($inPath, "rb");
$out= fopen($outPath, "wb");
while ($chunk = fread($in,8192))
{
fwrite($out, $chunk, 8192);
}
fclose($in);
fclose($out);
}
// This is just pulling the user id to use for the filename
$id = $get_id['id'];
save_image($aResponse['picture'],'tmp/'.$id.'.jpg');
Upvotes: 0
Reputation: 6930
Write yourself a proxy image server which which takes the the image you want to manipulate as a query parameter and just outputs the image content. It's a little slower than directly accessing the user's picture, but if you get creative you could cache that image locally to make subsequent loads faster.
a simple way to do this would be something like this:
front end:
<img src="image_server.php?img=<?= urlencode($aResponse['picture']); ?>">
back end:
<?php
if (!empty($_GET['img']))
{
//make sure this is a file on the facebook content delivery network
//and not our /etc/passwd or database connection config, or something
//else completely malicious.
if (preg_match("#^https?://profile\.ak\.fbcdn\.net/#i", $_GET['img']))
{
$img_path = $_GET['img'];
}
else
{
//do something with someone that entered a bad image, probably just
//display a "no image" image.
die('bad user. bad.');
}
readfile($img_path);
exit;
}
else
{
//no image was specified. output an anonymous/no image image.
die('an image file must be specified.');
}
You might want to get a little more complex than that...but that's the basic gist.
note: The php code assumes you have fopen wrappers enabled in your php.ini (so you can include web urls).
Upvotes: 1