PHPFlickr script...could this be cleaner/leaner? - php

OK, here's my dilemma:
I've read all over about how many guys want to be able to display a set of images from Flickr using PHPFlickr, but lament on how the API for PhotoSets does not put individual photo descriptions. Some have tried to set up their PHP so it will pull the description on each photo as the script assembles the gallery on the page. However, the method has shown how slow and inefficient it can be.
I caught an idea elsewhere of creating a string of comma separated values with the photo ID and the description. I'd store it on the MySQL database and then call upon it when I have my script assemble the gallery on the page. I'd use explode to create an array of the photo ID and its description, then call on that to fill in the gaps...thus less API calls and a faster page.
So in the back-end admin, I have a form where I set up the information for the gallery, and I hand a Set ID. The script would then go through and make this string of separated values ("|~|" as a separation). Here's what I came up with:
include("phpFlickr.php");
$f = new phpFlickr("< api >");
$descArray = "";
// This will create an Array of Photo ID from the Set ID.
// $setFeed is the set ID brought in from the form.
$photos = $f->photosets_getPhotos($setFeed);
foreach ($photos['photoset']['photo'] as $photo) {
$returnDesc = array();
$photoID = $photo['id'];
$rsp = $f->photos_getInfo($photoID);
foreach ($rsp as $pic) {
$returnDesc[] = htmlspecialchars($pic['description'], ENT_QUOTES);
}
$descArray .= $photoID."|~|".$returnDesc[0]."|~|";
}
The string $descArray would then be placed in the MySQL string that puts it into the database with other information brought in from the form.
My first question is was I correct in using a second foreach loop to get those descriptions? I tried following other examples all over the net that didn't use that, but they never worked. When I brought on the second foreach, then it worked. Should I have done something else?
I noticed the data returned would be two entries. One being the description, and the other just an "o"...hence the array $returnDesc so I could just get the one string I wanted and not the other.
Second question is if I made this too complicated or not. I like to try to learn to write cleaner/leaner code, and was looking for opinions.
Suggestions on improvement are welcome. Thank you in advance.

I'm not 100% sure as I've just browsed the source for phpFlickr, and looked the the Flickr API for the getInfo() call. But let me have a go anyway :)
First off, it looks like you shouldn't need that loop, like you mention. What does the output of print_r($rsp); look like? It could be that $rsp is an array with 1 element, in which case you could ditch the inner loop and replace it with something like $pic = $rsp[0]; $desc = $pic['description'];
Also, I'd create a new "description" column in your database table (that has the photo id as the primary key), and store the description in their on its own. Parsing db fields like that is a bit of a nightmare. Lastly, you might want to force htmlspecialchars to work in UTF8 mode, cause I don't think it does by default. From memory, the third parameter is the content encoding.
edit: doesn't phpFlickr have its own caching system? Why not use that and make the cache size massive? Seems like you might be re-inventing the wheel here... maybe all you need to do is increase the cache size, and make a getDescription function:
function getDescription ($id)
{
$rsp = $phpFlickr->photos_getInfo ($id);
$pic = $rsp[0];
return $pic['description'];
}

Related

Storing multiple artist info from API into file (PHP)

I really need help. I'm using an API to gather artist information depending on the artist name ($artist_name = $_GET['artistname']).
I need to add the API results into an array and store it into a file (NOT a database). This file will be ever growing as more and more artist entries are added to it.
Once I have an array in the file, I need to be able to read it and parse it. That way I can display the information without repeatedly using the API.
I have figured out how to add an array to a file with one entry, but how can I add more keys into the same array?
This is what I'm using now...
//ARRAY
$artist_info_location_array = array($artist_name => $location_entry);
//FILE
$artist_location_file = get_template_directory()."/Database/Artists/info-location.json";
//GET ARRAY FILE
$get_location_array[] = json_decode(file_get_contents($artist_location_file), true);
if (is_array($get_location_array)) {
if (!array_key_exists($artist_name, $get_location_array)) {
file_put_contents($artist_location_file, json_encode($artist_info_location_array));
}
}
It prints this to the file:
{"Imagine Dragons":"Las Vegas, NV, US"}
That's cool, but I need to be able to add more artists to this SAME ARRAY. So the result should look like this with another artist added:
{"Imagine Dragons":"Las Vegas, NV, US", "Adele":"London, UK"}
That shows Imagine Dragons and Adele both added to the same array.
Can someone help me "append" or add extra keys and values to the same array as they are added to the file?
Thanks.
EDIT 1 (In response to Martin):
I have a panel on the side of the page in question. This panel will show relevant information about the artist that has been searched for. Let's say you search for the artist "Adele". $artist_name would = Adele.
Lets say I'd like to store all artist locations, I would use the example I posted to store each artist location in the file called info-location.json ($artist_location_file).
So every time an artist page is loaded, the artist name and location would be added to the array in the file.
If my example doesn't make any sense, please show me an example on how to add multiple entries into ONE ARRAY. I am using an API and would like to cache this information to use instead of requesting the API on each load.
Hope this makes sense. :)
I might be misunderstanding your question, but if you just want to read in a json file, add an associative array key to it if it does not exist and then put it back into the json file why dont you do something like this:
if (is_array($get_location_array)) {
if (!array_key_exists($artist_name, $get_location_array)) {
$get_location_array[$artist_name] = $location;
file_put_contents($artist_location_file, json_encode($artist_info_location_array));
}
}
file_put_contents will overwrite an existing file (pretty sure). But your best option is to use a database. If you can't do that, then I suggest to prevent writing to the file while you are doing this I suggest you use fopen, flock, and fwrite and then fclose

pass a value from one page to another outside querystring and without javascript?

One solution to automatically building navigation for a site is by scanning a folder for documents like this:
foreach(glob('pages/*.pg.php') as $_SITE_NAV_filePath):
$_SITE_NAV_filePath = explode('.pg',pathinfo($_SITE_NAV_filePath,PATHINFO_FILENAME));
$_SITE_NAV_fileName = $_SITE_NAV_filePath[0];
$_SITE_NAV_qv = preg_replace('/([A-Z])/','-$1',$_SITE_NAV_fileName); $_SITE_NAV_qv = trim($_SITE_NAV_qv,'-');
$_SITE_NAV_name = preg_replace('/([A-Z])/',' $1',$_SITE_NAV_fileName);
?>
<li><?=$_SITE_NAV_name?></li>
<?php
endforeach;
This code will turn "AnAwesomePage.pg.php" into a menu item like this :
<li>An Awesome Page</li>
This might be bad practice (?).
Anyway; I don't use this method very often since most of the time the sites have a database, and with that comes better solutions...
But my question is this:
Is there a way to prefix the filename with a integer followed by and underscore (3_AnAwesomePage.pg.php), for sorting order purposes, and pass it somehow to the destination page outside of the querystring and without any async javascript?
I could just explode the filename once again on "_" to get the sort order and store it somewhere, somehow?
This is the code for handeling the page query request:
$_SITE_PAGE['qv'] = $_GET['page'];
if (empty($_SITE_PAGE['qv'])){ $_SITE_PAGE['qv'] = explode('-','Home'); }
else { $_SITE_PAGE['qv'] = explode('-',$_GET['page']); }
$_SITE_PAGE['file'] = 'pages/'.implode($_SITE_PAGE['qv']).'.pg.php';
This code turns "An-Awesome-Page" back into "AnAwesomePage.pg.php" so it's possible to include it with php.
But with a prefix, it's not so easy.
The probliem is; Now there's no way to know what prefix number there was before since it has been stripped away from the query string. So I need to send it somehow along in the "background".
One very bad solution I came up with was to transform the navigation link into a form button and just _POST the prefix interger along with the form. At fist it sounded like a nice solution, but then I realized that once a user refreshes their page, it didn't look very good. And after all, that's not what forms are for either...
Any good solutions out there?
Or some other and better way for dealing with this?
There are two ways to keep that number saved, you can use cookies or php session variables.
But in this case, if user first enter the url in the browser or in a new browser, then he should be taken to default number.
Like you have:
1_first-page.php
2_first-page.php
3_first-page.php
If user enter the url like: domain.com/?page=first-page, you have to take him to 1_first-page.php to any number which you want to be default.

How to store search conditions with php and Codeigniter?

I have small problem.
I've coded a full website in php using CodeIgniter framework. One of my modules is search module, it contains text input with keyword and three select lists with filtering criterias.
That's ok, when I'm searching something - result's listing pagination is done via URL like that:
mysite.com/$keyword/$criteria1/$criteria2/$criteria3/$offset
works like a charm.
But when I'm entering into one of my images (it's image gallery) I want to have an option to go into NEXT and PREVIOUS image from my search results - the ones which I entered this image from.
I'm solving this case now in this way - I have session table called 'search_conditions' and I'm storing values of keyword and my three criterias there, but that's quite not comfortable, because why if someone opens second window and search something else there?
Then all of his searches in another windows or tabs are getting the same criteria - because with every new search, user overwrite the session value.
My next and previous functions:
public function next($count)
{
$search = $this->session->userdata('search_conditions'); //getting session table and overwriting it
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count, 1);
}
public function previous($count)
{
$search = $this->session->userdata('search_conditions');
$catid = isset($search['catid'])?$search['catid']:'0';
$brandid = isset($search['brandid'])?$search['brandid']:'0';
$prodid = isset($search['prodid'])?$search['prodid']:'0';
$keyword = isset($search['keyword'])?$search['keyword']:'';
$res = $this->search_model->main_search($keyword, $catid, $brandid, $prodid, $count-2, 1);
}
Can you recommend me some other, more comfortable solution, because this seems not to be good...
: )
Thank you!
Add an index to the $search_conditions variable:
$search_conditions[1]['catid']
$search_conditions[1]['brandid']
...
then refer to it with a controller's or config variable. This way you can allow one session to store multiple search conditions.
But I would recommend you drop storing the search condition in session. Instead, just pass it with the URI. Session data, in the case you describe, work as an intermediary; you don't need it. Use the Pagination Class and pass the search page number, not the direction (next or previous) to the URI.
Do not worry that the URI may look ugly - it only depends on what user searches for, and it's still friendly to share. Your only concern is if the GET string does not extend the limited length.
Pull the segments from the URI in your next() and previous() functions. Use the codeigniter URL helper. That should allow you to pass the different search criterion as variables to the next page, this would also remove your need to use the session.

How to convert from one by one to a mass output using PHP

I am trying to find a way how to get the twitter ID from a list of users. I found the following link that works pretty well, you just replace ABC with the username you want
http://www.idfromuser.com/getID.php?username=ABC
What you get is the id from that user. Using "View Page Source" there is only the ID, no format or stuff.
What I want to do and do not know how, is how can I load a list of usernames and get/save the IDs. No one by one.
Thank you. I have a knowledge in PHP
Update
I have a list of usernames saved in a .txt file. The output with the IDs may be printed or screen or saved in a txt. I know that this is a solution with a get file contents but I need some guide/example
Why don't you use the twitter API?
This returns the user IDalong with other details
GET https://api.twitter.com/1/users/lookup.jsonscreen_name=ABC&include_entities=true
Return up to 100 users worth of extended information, specified by
either ID, screen name, or combination of the two. The author's most
recent status (if the authenticating user has permission) will be
returned inline.
It's pretty powerful, with only two requests you can get as much as 200 user ID's max.
https://dev.twitter.com/docs/api/1/get/users/lookup
It is better you concatenate (comma-separated) as much as 100 user ID's to the lookup URL, because it would return a max of 100 for each query. Unauthenticated users are rate limited so:
Example Code:
$lookupString = ""; //usernames seperated by new line character in text file
foreach ($notf as $key => $value) {
$lookupString .= $value.","; //concatenating, comma separated.
}
$lookupStringUrl = "http://api.twitter.com/1/users/lookup.json?user_id=".$lookupString;
$namejson = json_decode(file_get_contents($lookupStringUrl));
foreach ($namejson as $key => $value) {
echo $value->id."\n";
}

add a name value pair to posted data for joomla to consume and insert into DB

I'm trying to use the Joomla framework to make a create in the main content table.[http://docs.joomla.org/How_to_use_the_JTable_class] This works fine except that some data comes from posted variables and some from logic that happens when a file is uploaded moments before (store the random image name of a jpg)
$data=&JRequest::get('post');
this takes a ref to the posted values and I want to add to this Array or Object my field. The code I have makes the new record but the column images, doesnt get my string inserted.
I am trying to do something like$data=&JRequest::get('post');
$newdata=(array)$data;
array_push($newdata,"images"=>"Dog");
i make newdata as data is a ref to the posted variables and i suspect wont there fore allow me to add values to $data.
I'm a flash guy normally not a php and my knowledge is letting me down here.
Thanks for any help
Right, first thing:
$data=&JRequest::get('post');
$data is an array, you do not have to cast it. To add another element to the array as described in the comments do this:
$data['images'] = 'cats';
If you are using normal SQL to do the insert then you would do something like this to get the last inserted id e.g. the id of the row you just inserted:
$db = $this->getDBO();
$query = 'Some sql';
$db->setQuery($query);
if (!$db->query()) {
JError::raiseWarning(100, 'Insert failed - '.$db->getErrorMsg());
}
$id = $db->insertid();
If you are developing in Joomla I suggest you use the db functions provided to you rather than mysql_insert_id();
[EDIT]
If you want to use store then you can get the last inserted id like so:
$row->bind($data);
$row->check();
$row->store();
$lastId = $row->id;

Categories