I'm trying to get images from flickr using the Flickr API and I'm having trouble figuring out how to get only unique images. I've already reviewed the arguments for the specific method that I'm using and here's what I came up with:
<?php
class Flickr {
private $flickr_key;
private $flickr_secret;
private $format = 'json';
public function __construct( $flickr_key, $flickr_secret ) {
$this->flickr_key = $flickr_key;
$this->flickr_secret = $flickr_secret;
}
public function searchPhotos( $query = '', $tags = '' ) {
$urlencoded_tags = array();
$tags_r = explode(',', $tags);
foreach($tags_r as $tag){
$urlencoded_tags[] = urlencode($tag);
}
$url = 'http://api.flickr.com/services/rest/?';
$url .= 'method=flickr.photos.search';
$url .= '&text=' . urlencode($query);
$url .= '&tags=' . implode(',', $urlencoded_tags);
$url .= '&sort=relevance';
$url .= '&safe_search=1';
$url .= '&content_type=4';
$url .= '&api_key=' . $this->flickr_key;
$url .= '&format=' . $this->format;
$url .= '&per_page=10';
$url .= '&media=photos';
$url .= '&privacy_filter=1';
$result = #file_get_contents( $url );
$json = substr( $result, strlen( "jsonFlickrApi(" ), strlen( $result ) - strlen( "jsonFlickrApi(" ) - 1 );
$photos = array();
$data = json_decode( $json, true );
if($data['stat'] != 'fail'){
$photos = $data['photos']['photo'];
return $photos;
}else{
return false;
}
}
}
And I'll just call it in like:
$flickr = new Flickr($flickr_key, $flickr_secret);
$query = 'Kaspersky Internet Security 2013';
$tags = 'software';
$results = $flickr->searchPhotos($query, $tags);
foreach($results as $img){
$src = "http://farm" . $img['farm'] . ".static.flickr.com/" . $img['server'] . '/' . $img['id'] . '_' . $img['secret'] . '_m.jpg';
?>
<img src="<?php echo $src; ?>"/>
<?php
}
The problem here is that I'm getting duplicate images from time to time.
I also tried using the phpflickr library. But I'm still having the same issues:
$flickr = new phpFlickr($api_key);
$args = array(
'text' => 'Kaspersky Internet Security 2013',
'tags' => 'software',
'per_page' => '10',
'safe_search' => '1',
'content_type' => '4',
'media' => 'photos',
'sort' => 'relevance',
'privacy_filter' => '1'
);
$results = $flickr->photos_search($args);
$hashes = array();
$sources = array();
$images = $results['photo'];
foreach($images as $img){
$src = "http://farm" . $img['farm'] . ".static.flickr.com/" . $img['server'] . '/' . $img['id'] . '_' . $img['secret'] . '_m.jpg';
$current_hash = sha1_file($src);
if(!in_array($current_hash, $hashes)){
?>
<img src="<?php echo $src; ?>" alt="">
<?php
}
$hashes[] = $current_hash;
}
As you can see from the above code I've used sha1_file method to compare the hashes of each of the images returned from flickr. But that's a big performance hit:
without sha1_file: 0.81311082839966
with sha1_file: 6.8974900245667
Any ideas what else can I do to prevent flickr from returning duplicates? As you can see I'm only returning 10 images and that's all I need. I've also tried to add as many arguments that matches my needs but still no luck. Thanks in advance!
try on API explorer, will this give you the same result?
I tried using the param you specified, it returns 34 result in total..
Related
please help me with the blow code on where am having error, i have two php function, one copies an external image from and website in any string that has [img]here is the image link[/img]. and the other function returns the image downloaded in our sever and set to the previous external link which was copied from.
here is the two functions
function covertContentToHTML($title, $content)
{
$regex = '#\[img( alt="(.+?)\")?( caption="(.+?)\")?](.+?)\[\/img\]#is';
$content = preg_replace_callback($regex, function ($matches) use ($title) {
$imageAlt = $matches[2];
$caption = $matches[4];
$imageUrl = $matches[5];
$caption = trim(preg_replace('/\s+/', ' ', $caption));
$imageUrlToLocalPath = copyimage($imageUrl);
return '<figure class="center"><img src="' . $imageUrlToLocalPath . '" alt="' . (empty($imageAlt) ? $title : $imageAlt) . '" title="' . $title . '">
' . (!empty($caption) ? '<br><figcaption><span class="help">Inset:</span> <strong>' . $caption . '</strong></figcaption>' : '') . '
</figure>';
}, $content);
return $content;
}
function copyimage($content) {
$content = preg_replace('#<img(.*?)src="(.*?)"(.*?)>#is', '[img]\\2[/img]', $content);
preg_match_all('#\[img( alt="(.+?)\")?( caption="(.+?)\")?](.+?)\[\/img\]#is', $content, $matches);
$images = $matches[5];
$i = 0;
$im = [];
foreach ($images as $image) {
array_push($im, $image);
$i++;
$encodeImageUrl = base64_encode($image);
$imageBasename = pathinfo($image, PATHINFO_BASENAME);
$imageLocalPath = "images/hsi/" . $encodeImageUrl . "/images";
if ( !is_dir( $imageLocalPath ) ) {
mkdir($imageLocalPath, 0755, true );
}
copy($image, $imageLocalPath.'/'.$imageBasename);
}
}
the problem am having is that the function convertContentToHtml Does not return the downloaded image and set them to the return figure class..
example i have a string or content like this
$content = 'HELLO WORLD <p> [img]http://www.stackoverflow/images/newimage.jpg[/img] testing this content [img]http://www.stackoverflow.com/images/newimage2.jpg'[/img]';
the code function convertContentToHtml will download the the stackoverflow newimage.jpg and newimage2.jpg to my server and then replace with the stackoverflow/images/newimage.jpg and stackoverflow.com/images/newimage2.jpg to to my link to the image downloaded using the copyimage function.
please help. thanks.
I have a theme that I edited causing very high load on my server,
First i used this code to get only text from content
$response = get_the_content();
$content = $response;
$content = preg_replace("/(<)([img])(\w+)([^>]*>)/", "", $content);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
Then i wanted to fetch all images inside my post content so i used "DOMDocument" Code:
$document = new DOMDocument();
libxml_use_internal_errors(true);
$document->loadHTML($response);
libxml_clear_errors();
$images = array();
$imgsq = $document->getElementsByTagName('img');
I have every post contains a static part than is in all photo pages so i used that code to get it
function findit($mytext,$starttag,$endtag) {
$posLeft = stripos($mytext,$starttag)+strlen($starttag);
$posRight = stripos($mytext,$endtag,$posLeft+1);
return substr($mytext,$posLeft,$posRight-$posLeft);
}
$project = #findit($content , '-projectinfostart-' , '-projectinfoend-');
$check = str_replace('ializer-buttons clearfix">', '', $project);
if($project != $check) $project = '';
$replace = array('-projectinfostart-' , '-projectinfoend-' , $project , '<p> </p>');
$content = str_replace( $replace, '', $content);
Then at last i wanted to get all photos in thumb size so i used that code:
foreach($imgsq as $key => $img) :
// Extract what we want
$image = array('src' => $img->getAttribute('src') );
if( ! $image['src'])
continue;
if($key == $page) :
echo '<center><img style="height: auto !important;max-height:450px;" class="responsiveMe" src=" ' . $image['src'] . '" /> ';
endif;
$srcs[$key] = array();
$srcs[$key]['src'] = wp_get_attachment_thumb_url(get_attachment_id_by_url($image['src']));
$srcs[$key]['full'] = $image['src'];
if(!empty($project)) $description = '<p>' . $project . '</p>';
else $description = '';
endforeach;
My server is 16 GB Ram and can't work with 1500 online users on single post page ! any ideas about what is causing this high load ?
Thanks.
I'm using simple_html_dom [ http://sourceforge.net/projects/simplehtmldom/ ] to parse through HTML.
I'm trying to get all of the <script> urls, grab the contents, and then replace it in the $html variable... I have this and it almost works like I want:
$html_elements = str_get_html( $html );
$current_src = array( );
$new_src = array( );
foreach($html_elements->find('script') as $element) {
if( $element->src != '' )
{
$script_url = $element->src;
$script_data = get_script( $script_url );
$current_src[] = $element->outertext;
$new_src[] = "<script>" . $element->innertext . "\n" . $script_data . "</script>";
}
}
$html = str_replace( $current_src, $new_src, $html );
function get_script( $url )
{
$data = file_get_contents( $url );
return $data;
}
The problem is that it seems to be turning the plus signs in the javascript files in to spaces when it's all said and done?
Please refer to the comment section above.
After further debugging, I was parsing the data one to many times through urldecode() later on in the code.
I'm in the process of creating a photo uploader that uploads photos directly to a personal flickr account... right now I'm trying to call all my photosets (by title) and populate my select dropdown with them. Unfortunately everything I've been trying hasn't worked... so I'm here for some help from you experienced people! ;)
Here's the code I'm working with:
From my file called class.flickr.php
// Code being used for the purpose of calling photoset titles
public function getPhotosets() {
// Function specific variables
$flickr_api_call = "http://api.flickr.com/services/rest/";
$method = "flickr.photosets.getList";
$nsid = 'my user id';
$url_parameters = array(
'method' =>$method,
'oauth_consumer_key' =>$this->flickr_key,
'user_id' =>$nsid,
'format' =>$this->format,
'nojsoncallback' =>'1',
'oauth_nonce' =>$this->nonce,
'oauth_timestamp' =>$this->timestamp,
'oauth_version' =>'1.0',
);
$parameters_string = "";
foreach ( $url_parameters as $key=>$value ) $parameters_string .= "$key=" . urlencode( $value ) . "&";
$url = $flickr_api_call . "?" . $parameters_string;
$photosets = array();
$data = json_decode(file_get_contents($url), true);
if ( $data['stat'] != 'fail' ) {
$photosets = $data['photosets']['photoset'];
return $photosets;
} else {
return false;
}
var_dump( $photosets );
} // end getPhotosets
The code being used to call the getPhotosets method within my main document:
<select class="categorize-options">
<?php
require_once( 'class.flickr.php' );
$flickr = new Flickr( 'api key', 'api shared secret' );
$results = $flickr->getPhotosets();
if ( !empty( $results )):
foreach( $results as $photoset ):?>
<option><?php echo $photoset['title']; ?></option>
<?php endforeach;
else:
echo "This isn't working!!! :)";
endif;
?>
</select>
The thing that is really confusing me is that both the var_dump() and the else statement are not displaying... but, neither is anything else. Would be a great help to get some experienced input... thanks!
First, though flickr documentation says you don't need authorization for the method flickr.photosets.getList... it is wrong. You will need to run an authorization function something like this:
// Get list of photosets (for their titles)
public function getPhotosets() {
// Function specific variables
$flickr_api_call = $this->flickr_rest_call;
$method = "flickr.photosets.getList";
$nsid = 'user_id';
$access_token = "access_token";
$access_token_secret = "access_token_secret";
$url = "format=" . $this->format;
$url .= "&method=" . $method;
$url .= "&nojsoncallback=1";
$url .= "&oauth_consumer_key=" . $this->flickr_key;
$url .= "&oauth_nonce=" . $this->nonce;
$url .= "&oauth_signature_method=" . $this->sig_method;
$url .= "&oauth_timestamp=" . $this->timestamp;
$url .= "&oauth_token=" . $access_token;
$url .= "&oauth_version=1.0";
$url .= "&user_id=" . urlencode( $nsid );
$baseurl = "GET&" . urlencode( $flickr_api_call ) . "&" . urlencode( $url );
$hashkey = $this->flickr_secret . "&" . $access_token_secret;
$oauth_signature = base64_encode( hash_hmac( 'sha1', $baseurl, $hashkey, true ));
$url_parameters = array(
'method' =>$method,
'oauth_consumer_key' =>$this->flickr_key,
'user_id' =>$nsid,
'format' =>$this->format,
'nojsoncallback' =>'1',
'oauth_nonce' =>$this->nonce,
'oauth_timestamp' =>$this->timestamp,
'oauth_signature_method'=>$this->sig_method,
'oauth_version' =>'1.0',
'oauth_token' =>$access_token,
'oauth_signature' =>$oauth_signature
);
/* Now that we have encoded the parameters for our ouath_signature
* and have reformated them for the url we need to send... we must
* re-urlencode them too. */
$parameters_string = "";
foreach ( $url_parameters as $key=>$value )
$parameters_string .= "$key=" . urlencode( $value ) . "&";
$url = $flickr_api_call . "?" . $parameters_string;
NOTE: any time you use nsid you need to urlencode the value twice! Reason: the #, if only encoded once will return like this %40, but in order to keep the % you MUST encode twice resulting in this: %2540
Secondly, change your call from the json response from this: <option><?php echo $photoset['title']; ?></option> to this: <option><?php echo $photoset['title']['_content']; ?></option>
This is how I was able to accomplish this... if there is a better, more efficient way of doing this I'd love to hear about it.
I have a PHP file (Region.php) and an excerpt of my code is:
<?php
/** Create HTTP POST */
$country = 'Australia';
$area = htmlspecialchars($_POST["area"]);
$seek = '<parameters>
<row><param>COUNTRY</param><value>'. $country .'</value></row>
<row><param>AREA</param><value>'. $area .'</value></row>
</parameters>';
$postdata = http_build_query(
array(
'DistributorKey' => '201201100935',
'CommandName' => 'GetCities',
'CommandParameters' => $seek)
);
$opts = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata)
);
/** Get string output of XML (In URL instance) */
$context = stream_context_create($opts);
$result = file_get_contents('http://national.atdw.com.au/soap/AustralianTourismWebService.asmx/CommandHandler?', false, $context);
/** Change encoding from UTF-16 to Unicode (UTF-8)
Parse unstructured tags */
$result = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $result);
$result = str_replace('<string xmlns="http://tempuri.org/soap/AustralianTourismWebService">', '', $result);
$result = str_replace('</string>', '', $result);
$result = str_replace('utf-16', 'utf-8', $result);
$result = simplexml_load_string(trim(html_entity_decode($result)), 'SimpleXMLElement');
/** Instantiate Loop */
foreach ($result->area as $entry) {
echo $entry->attributes()->area_name . "<br /><br />";
}
foreach ($result->area->city as $entry) {
$pna = htmlspecialchars_decode($entry->attributes()->suburb_city_postal_code, ENT_QUOTES);
$pna = str_replace("'", "''", $pna);
$str = htmlspecialchars_decode($entry->attributes()->attribute_id_status, ENT_QUOTES);
$str = str_replace("'", "''", $str);
echo $pna. "<br />";
echo $str . "<br />";
echo (string)$entry . "<br /><br />";
}
?>
I have another PHP file (Houses.php) but I need only the value of $entry->attributes()->area_name in the Houses.php file. Excerpt of my code in Houses.php:
<?php
require_once 'Region.php';
/** Create HTTP POST */
$accomm = 'ACCOMM';
$region = '('$entry->attributes()->area_name')';
$page = '10';
---- some code ---
?>
I keep getting errors because it is executes the entire Region.php file whereas I only need the value of the attribute().
Please how can I fix this.
Thanks
I can interpret comments as this, as you cannot include only part of a PHP file:
Create a file header.inc.php, not header.inc for security, as one can download a .inc as source file by bad config, but not .php, as executed by apache2 :
<?php
/** Create HTTP POST */
$country = 'Australia';
$area = htmlspecialchars($_POST["area"]);
$seek = '<parameters>
<row><param>COUNTRY</param><value>'. $country .'</value></row>
<row><param>AREA</param><value>'. $area .'</value></row>
</parameters>';
$postdata = http_build_query(
array(
'DistributorKey' => '201201100935',
'CommandName' => 'GetCities',
'CommandParameters' => $seek)
);
$opts = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata)
);
/** Get string output of XML (In URL instance) */
$context = stream_context_create($opts);
$result = file_get_contents('http://national.atdw.com.au/soap/AustralianTourismWebService.asmx/CommandHandler?', false, $context);
/** Change encoding from UTF-16 to Unicode (UTF-8)
Parse unstructured tags */
$result = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $result);
$result = str_replace('<string xmlns="http://tempuri.org/soap/AustralianTourismWebService">', '', $result);
$result = str_replace('</string>', '', $result);
$result = str_replace('utf-16', 'utf-8', $result);
$result = simplexml_load_string(trim(html_entity_decode($result)), 'SimpleXMLElement');
?>
Shorten the Region.php file:
<?php
require_once "header.inc.php";
/** Instantiate Loop */
foreach ($result->area as $entry) {
echo $entry->attributes()->area_name . "<br /><br />";
}
foreach ($result->area->city as $entry) {
$pna = htmlspecialchars_decode($entry->attributes()->suburb_city_postal_code, ENT_QUOTES);
$pna = str_replace("'", "''", $pna);
$str = htmlspecialchars_decode($entry->attributes()->attribute_id_status, ENT_QUOTES);
$str = str_replace("'", "''", $str);
echo $pna. "<br />";
echo $str . "<br />";
echo (string)$entry . "<br /><br />";
}
?>
In House.php:
<?php
require_once 'header.inc.php';
/** Create HTTP POST */
$accomm = 'ACCOMM';
$region = "";
foreach ($result->area as $entry) {
$region = $entry->attributes()->area_name;
break;
}
$page = '10';
---- some code ---
?>
All the tree files must reside in the same directory/folder.
Organize your code into functions:
myfuncts.php
function fn1() {
...stuff...
...stuff...
} // fn1()
function fn2() {
...things...
...things...
} // fn2()
Then you can use them by simply calling:
require("functions.php");
fn1();
fn3();