How do I temporarily store facebook profile picture? - php

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!

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).

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');

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

Related

Laravel google images search

In my application users creating articles and adding images to it if user wont add a image, that application must search for it in google images. I'm googling it quite long but still can't find which tools do I need to achieve this.
EDIT
I tried Mimos approach but now something going wrong and now I get:
NotReadableException in AbstractDecoder.php line 302:
Image source not readable
When i tried to save the image from url
ArticlesController store method:
public function store(ArticleRequest $request)
{
if ($request->hasFile('file')) {
$file = Input::file('file');
$imgTitle = $request->title;
$imagePath = 'uploads/' . $imgTitle . '.jpg';
$request->image_path = $imagePath;
Article::create(array('title' => $request->title,
'body' => $request->body,
'image_path' => $imagePath));
Image::make($file)->resize(300, 200)->save($imagePath);
} else {
// $file = Input::file('file');
$imgTitle = $request->title;
$query = $imgTitle;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" . urlencode($query));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = json_decode(curl_exec($ch));
// $file = file_get_contents($output);
curl_close($ch);
$imagePath = 'uploads/' . $imgTitle . '.jpg';
$request->image_path = $imagePath;
Article::create(array('title' => $request->title,
'body' => $request->body,
'image_path' => $imagePath));
Image::make($output)->resize(300, 200)->save($imagePath);
}
}
<?php
$query = 'Foobar';
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=".urlencode($query));
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string as json
$output = json_deocde(curl_exec($ch));
// close curl resource to free up system resources
curl_close($ch);
But I don't recommend to let a program decide what image it should take. You will maybe get a problem with copyright. Better set a default pic.

How to get bigger size picture of Instagram user

I'm writing an application to get all the relevant media based to a user or a tag.
I was able to the media but the resolution of the user's profile picture found under data/user/profile_picture is quite poor (around 150*150px).
So my question is : is there anyway to get a user profile's picture in a bigger size ? Here are the queries I use to retrieve the media :
https://api.instagram.com/v1/users/3/media/recent/?access_token=ACCESS-TOKEN
https://api.instagram.com/v1/tags/snow/media/recent?access_token=ACCESS-TOKEN
This gets the 600x600 profile picture:
function Request($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function get_value($username, $att, $accesstoken) {
$url = "https://api.instagram.com/v1/users/search?q=" . $username . "&access_token=" . $accesstoken;
if($result = json_decode(Request($url), true)) {
if ($att == "full_name") {
return preg_replace("/[^A-Za-z0-9 ]/", '', $result['data'][0][$att]);
} elseif ($att == "profile_picture") {
$res = str_replace("s480x480", "s600x600", $result['data'][0][$att]);
$res = str_replace("s320x320", "s600x600", $res);
$res = str_replace("s150x150", "s600x600", $res);
return $res;
} else {
return $result['data'][0][$att];
}
}
}
Example Usage:
$profile_picture = get_value("USERNAME","profile_picture", "ACCESS_TOKEN");

HTTP Requests made with file_get_contents() share the same session data?

I've got a problem...
I've a MVC-like framework and the redirect mechanism allows me too get snippets of HTML code generated by PHP on a remote host.
I'm getting these snippets by using the file_get_contents() function, with allow_url_fopen turned on.
The problem is the fact I use session data inside these code fragments and the session data is being lost every time. I'm assuming this new request is not sharing the same session data and therefore I need a way to get these fragments without losing my session data.
Any suggestions?
If the files your accessing are on the same server as the calling file then you might as well use include(); like #user574632's answer.
But if not, to keep the session you will need to handle the cookies the server sends;
Sessions are cookie based, server sets the session cookie your browser picks it up and uses it for all subsequent requests.
By default file_get_contents wont handle cookies, so your need to grab the header from the server by accessing $http_response_header array and then match with regex the Set-Cookie: header then store that and on following requests use the cookie and create a stream context with the cookie added to the header and pass that to fgc:
<?php
function get_cookies() {
//check cookies folder - or make it
if(!file_exists('./cookies/')){
mkdir('./cookies/', 0755, true);
}
$return = null;
foreach(glob("./cookies/*.txt") as $file) {
$return .= file_get_contents($file).';';
}
return $return;
}
function save_cookies($http_response_header) {
print_r($http_response_header);
foreach($http_response_header as $header) {
if(substr($header, 0, 10) == 'Set-Cookie'){
if(preg_match('#Set-Cookie: (([^=]+)=[^;]+)#i', $header, $matches)) {
$fp = fopen('./cookies/'.$matches[2].'.txt', 'w');
fwrite($fp, $matches[1]);
fclose($fp);
}
}
}
}
$opts = array('http' =>
array('header'=>'Cookie: '.get_cookies()."\r\n")
);
$context = stream_context_create($opts);
$contents = file_get_contents('http://mywebsite.com/snippets/', false, $context);
save_cookies($http_response_header);
echo $contents;
?>
Alternatively you should use curl instead its faster and handles cookies fine.
So something like the following, use curl and then revert to fgc if curl is not present, all wrapped up with cookie support in a class, so the 3 functions are contained:
<?php
//example usage
echo new curl_get_contents('http://example.com/page_that_needs_sessions');
class curl_get_contents{
public $result;
function __construct($url){
$this->curl_rev_fgc($url);
}
function __toString(){
return $this->result;
}
private function get_cookies() {
$return = null;
foreach(glob("./cookies/*.txt") as $file) {
$return .= file_get_contents($file).';';
}
return $return;
}
private function save_cookies($http_response_header) {
foreach($http_response_header as $header) {
if(substr($header, 0, 10) == 'Set-Cookie'){
if(preg_match('#Set-Cookie: (([^=]+)=[^;]+)#i', $header, $matches)) {
$fp = fopen('./'.$matches[2].'.txt', 'w');
fwrite($fp, $matches[1]);
fclose($fp);
}
}
}
}
private function curl_rev_fgc($url){
//check cookies folder - or make it
if(!file_exists('./cookies')){
mkdir('./cookies/', 0755, true);
}
$usragent = 'Mozilla/5.0 (compatible; Yourbot/0.1; +https://yoursite/bot.html)';
//Check curl is installed or revert to file_get_contents()
$curl = function_exists('curl_init') ? true : false;
if($curl){
$opts = array(
'http' => array(
'method' => "GET",
'header' => 'Cookie: '.$this->get_cookies().'\r\n', // cookie in fgc support
'user_agent' => $usragent)
);
$context = stream_context_create($opts);
$result = #file_get_contents($url, false, $context);
$this->save_cookies($http_response_header);
if(empty($result)){
$this->result = 'Error fetching: '.htmlentities($url);
}else{
$this->result = $result;
}
return;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_USERAGENT, $usragent);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
if(!file_exists('./cookies/curl.txt')){
file_put_contents('./cookies/curl.txt',null);
}
curl_setopt($curl, CURLOPT_COOKIEFILE, './cookies/curl.txt');
curl_setopt($curl, CURLOPT_COOKIEJAR, './cookies/curl.txt');
$result = curl_exec($curl);
if(empty($result)){
$this->result = 'Error fetching: '.htmlentities($url);
}else{
$this->result = $result;
}
curl_close($curl);
return;
}
}
?>
Use include instead. If you need to read the output into a variable to display later/elsewhere in the code, as suggested in the comments, use the output buffer:
ob_start();
include('path/to/file.php');
$included = ob_get_clean();
//nothing has been output to the browser yet
//later on
echo $included;

How save Facebook user display picture to the disk Without using file_get_contents()`?

Hello I am trying to get the user profile picture and then merge into an existing image as per my Facebook app requirement. For that I need to check its mime time etc. But I am having difficulty in retrieving and saving the picture.
$facebook = new Facebook($config);
$user = $facebook -> getUser();
if ($user) {
$user_profile = $facebook -> api('/me');
}
//User Info. Variables:
try {
$userPpicture = $user_profile[picture];
}
Now we I have retrieved this I want to save this image on disk so I could check its mime time etc. for further processing, how can I achieve this?
p.s. due to my hosting server restrictions I can’t use the function file_get_contents(). So I need a solution except this.
Kindly help.
thank-you.
cURL try:
//Create image instances
$url = "http://graph.facebook.com/{$userId}/picture?type=large";
$dpImage = 'temp/' . $userId . '_dpImage_' . rand().'.jpg';
echo $dpImage;
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$returned_content = get_data($url);
file_put_contents($dpImage, $returned_content);
echo "Type: " . exif_imagetype($dpImage);
getting this error while checking the mime type of the image:
Notice: exif_imagetype(): Read error! in
Are you allowed to use CURL ?
If so, just follow http://phpsense.com/2007/php-curl-functions/

PHP: Check if URL redirects?

I have implemented a function that runs on each page that I want to restrict from non-logged in users. The function automatically redirects the visitor to the login page in the case of he or she is not logged in.
I would like to make a PHP function that is run from a exernal server and iterates through a number of set URLs (array with URLs that is for each protected site) to see if they are redirected or not. Thereby I could easily make sure if protection is up and running on every page.
How could this be done?
Thanks.
$urls = array(
'http://www.apple.com/imac',
'http://www.google.com/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
$headers = explode("\n", $out);
foreach($headers as $header) {
if( substr($header, 0, 10) == "Location: " ) {
$target = substr($header, 10);
echo "[$url] redirects to [$target]<br>";
continue 2;
}
}
echo "[$url] does not redirect<br>";
}
I use curl and only take headers, after I compare my url and url from header curl:
$url="http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if(curl_getinfo($ch)['url'] == $url){
echo "not redirect";
}else {
echo "redirect";
}
You could always try adding:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
since 302 means it moved, allow the curl call to follow it and return whatever the moved url returns.
Getting the headers with get_headers() and checking if Location is set is much simpler.
$urls = [
"https://example-1.com",
"https://example-2.com"
];
foreach ($urls as $key => $url) {
$is_redirect = does_url_redirect($url) ? 'yes' : 'no';
echo $url . ' is redirected: ' . $is_redirect . PHP_EOL;
}
function does_url_redirect($url){
$headers = get_headers($url, 1);
if (!empty($headers['Location'])) {
return true;
} else {
return false;
}
}
I'm not sure whether this really makes sense as a security check.
If you are worried about files getting called directly without your "is the user logged in?" checks being run, you could do what many big PHP projects do: In the central include file (where the security check is being done) define a constant BOOTSTRAP_LOADED or whatever, and in every file, check for whether that constant is set.
Testing is great and security testing is even better, but I'm not sure what kind of flaw you are looking to uncover with this? To me, this idea feels like a waste of time that will not bring any real additional security.
Just make sure your script die() s after the header("Location:...") redirect. That is essential to stop additional content from being displayed after the header command (a missing die() wouldn't be caught by your idea by the way, as the redirect header would still be issued...)
If you really want to do this, you could also use a tool like wget and feed it a list of URLs. Have it fetch the results into a directory, and check (e.g. by looking at the file sizes that should be identical) whether every page contains the login dialog. Just to add another option...
Do you want to check the HTTP code to see if it's a redirect?
$params = array('http' => array(
'method' => 'HEAD',
'ignore_errors' => true
));
$context = stream_context_create($params);
foreach(array('http://google.com', 'http://stackoverflow.com') as $url) {
$fp = fopen($url, 'rb', false, $context);
$result = stream_get_contents($fp);
if ($result === false) {
throw new Exception("Could not read data from {$url}");
} else if (! strstr($http_response_header[0], '301')) {
// Do something here
}
}
I hope it will help you:
function checkRedirect($url)
{
$headers = get_headers($url);
if ($headers) {
if (isset($headers[0])) {
if ($headers[0] == 'HTTP/1.1 302 Found') {
//this is the URL where it's redirecting
return str_replace("Location: ", "", $headers[9]);
}
}
}
return false;
}
$isRedirect = checkRedirect($url);
if(!$isRedirect )
{
echo "URL Not Redirected";
}else{
echo "URL Redirected to: ".$isRedirect;
}
You can use session,if the session array is not set ,the url redirected to a login page.
.
I modified Adam Backstrom answer and implemented chiborg suggestion. (Download only HEAD). It have one thing more: It will check if redirection is in a page of the same server or is out. Example: terra.com.br redirects to terra.com.br/portal. PHP will considerate it like redirect, and it is correct. But i only wanted to list that url that redirect to another URL. My English is not good, so, if someone found something really difficult to understand and can edit this, you're welcome.
function RedirectURL() {
$urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/');
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// chiborg suggestion
curl_setopt($ch, CURLOPT_NOBODY, true);
// ================================
// READ URL
// ================================
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
echo $out;
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr(strtolower($header), 0, 9) == "location:") {
// read URL to check if redirect to somepage on the server or another one.
// terra.com.br redirect to terra.com.br/portal. it is valid.
// but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid.
// what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page.
// if contains http, we will check if changes url or not.
// some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden
// only execute if have http on location
if ( strpos(strtolower($header), "http") !== false) {
$address = explode("/", $header);
print_r($address);
// $address['0'] = http
// $address['1'] =
// $address['2'] = www.terra.com.br
// $address['3'] = portal
echo "url (address from array) = " . $url . "<br>";
echo "address[2] = " . $address['2'] . "<br><br>";
// url: terra.com.br
// address['2'] = www.terra.com.br
// check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here.
if(strpos(strtolower($address['2']), strtolower($url)) !== false) {
echo "URL NOT REDIRECT";
} else {
// not the same. (areiaebrita)
echo "SORRY, URL REDIRECT WAS FOUND: " . $url;
}
}
}
}
}
}
function unshorten_url($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
$real_url = $url;//default.. (if no redirect)
if (preg_match("/location: (.*)/i", $out, $redirect))
$real_url = $redirect[1];
if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
$real_url = unshorten_url($real_url);
return $real_url;
}
I have just made a function that checks if a URL exists or not
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
function url_exists($url, $ch) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
//echo $out."====<br>";
$headers = explode("\n", $out);
//echo "<pre>";
//print_r($headers);
foreach($headers as $header) {
//echo $header."---<br>";
if( strpos($header, 'HTTP/1.1 200 OK') !== false ) {
return true;
break;
}
}
}
Now I have used an array of URLs to check if a URL exists as following:
$my_url_array = array('http://howtocode.pk/result', 'http://google.com/jobssss', 'https://howtocode.pk/javascript-tutorial/', 'https://www.google.com/');
for($j = 0; $j < count($my_url_array); $j++){
if(url_exists($my_url_array[$j], $ch)){
echo 'This URL "'.$my_url_array[$j].'" exists. <br>';
}
}
I can't understand your question.
You have an array with URLs and you want to know if user is from one of the listed URLs?
If I'm right in understanding your quest:
$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
echo 'FROM ARRAY';
} else {
echo 'NOT FROM ARR';
}

Categories