How to paginate through joined records on laravel? - php

I'm using Laravel 4.1.x and I have a Has Many and Belongs To Many relationship between Tags and Photos (A photo belongs to many tags, a tag belongs to many photos). I'm using a pivot table with tag_id and photo_id
I know how to paginate the tags, using:
Tag::paginate($limit);
I'm able to fetch one tag with all the related photos using:
Tag::find($id);
But what I want to do now, is to retrieve all the photos that belongs to a tag , but paginating them. So, its something like the second code that I show, but with a page and limit parameter.
For example, I would want to see the first 15 photos that belongs to the tag with id=1, and be able to after that select the second 15.
Update:
Based on the answer provided, I tried with ->photos()->paginate(), but using this, it doesn't returns the rest of the informaton from the tag (Name, description, etc).
I've been able to get everything using:
$tag = Tag::findOrFail($id)->toArray();
$tag['photos'] = Tag::findOrFail($id)->photos()->paginate($limit)->toArray();
But I'm not sure if there is any other way to do this, and if this is generating an extra query.

Have you tried...
Tag::find(1)->photos()->paginate(15);
If you need to display information on the tag, there are a few ways. Eager loading is usually best but in this case because we know the tag id, we aren't being faced with the n+1 problem so it may look a bit more confusing than it needs to be.
$limit = 15;
$tag = Tag::with(array('photos' => function($q) use ($limit)
{
$q->paginate($limit);
}))->find(1);
// Use
echo $tag->name;
foreach($tag->photos as $photo) {
echo $photo->description;
}
Or you can just do what we did earlier except split it up a bit to save the individual parts.
$tag = Tag::find(1);
$photos = $tag->photos()->paginate(15);
// use
echo $tag->name;
foreach($photos as $photo) {
echo $photo->description;
}

Related

if statement bug in php and html

<img id="post_like_btn_<?php echo $post_info['id']; ?>" class="post_like_btn"
<?php $like_result = data_like($dbc, $user_info['id']);
while($like_info = mysqli_fetch_assoc($like_result)){
if($post_info['id'] == $like_info['post_id'])
{ echo 'src="img/like/like_active.png"';
} else{echo 'src="img/like/like_dark.png"'}?>>
I have this code to change the icon image on the like button when the post id exists in likes table but when there are no values in the table, else statement does not work and shows no image. I tried to add '&& !== null' to if condition but it does not work either.
If there's no data in the likes tables for the user, the while loop has nothing to iterate over. That means the if condition never actually gets executed.
It's also worth noting another issue: It looks like your while loop will iterate over all results for all posts. If your user has liked other posts (besides the one being displayed) then your else clause will be executed multiple times, giving you multiple src attributes in your img tag (most or all of them referring to like_dark.png).
Ideally, what you need to do is make your database query search only for the user's likes on the ID of the post being displayed. That way you won't need a while loop at all. You just need to check if any result was found. If so, output like_active.png, otherwise output like_dark.png.
If you're not able to modify the query for some reason (or if you want to avoid multiple queries when displaying several posts on a page), your loop will need to go through each record and just set a boolean variable to true if it sees a like matching the current post ID. After the while loop, check that boolean variable in an if condition and only output the src attribute then. That way, you'll only output one src attribute, no matter how many records you've iterated over.
missing closing bracket on the while loop:
while($like_info = mysqli_fetch_assoc($like_result)){
if($post_info['id'] == $like_info['post_id'])
{ echo ' src="img/like/like_active.png"';}
else{echo ' src="img/like/like_dark.png"';}
}?>>
also since the following is common:
src="img/like/like"
you could remove that out of the if statement and just switch between the active and dark.png states.

Access a column in a database Eloquent Laravel4

I need to be able to access all the data in one of the columns of my table. My initial approach was to do something like this. The column i am trying to access in my database is called 'Tags'
//get all posts
$post = Post::get();
//get all post tags
$post_tags = $post['tags'];
but this returns null. I know there will be an extremely simple way to do it, i am just not seeing it!
EDIT
The reason i am doing this is i have a tagging system in place when something is posted you can add 3 tags which relate to that post. What i am trying to do in the long run is when a tag is clicked it will filter out all the posts with that set tag.
The way this works is when a tag is clicked the user will be redirect to a url like so
//test-site.com/posts/tags/{tag}
so ill be using that tag to then query the database for the results. I have managed to confuse myself in a task i thought would be farily simple!
If your tags are stored in the same table, the problem may be that you are getting a full result set:
Post::get();
When you should get only one row:
Post::first();
So this one might do the trick in this case:
$post = Post::first();
$post_tags = $post->tags;
If you use Post::get() or Post::all(), you'll have to iterate trough the result set to get your info:
foreach(Post::all() as $post)
{
echo $post->tags;
}

Is there a way to combine independent functions of a page into single and query once to distribute fetched data individually

First of all, it's an idea, need to share because its solution is not present to me. But if applicable, it can help many PHP developer as well.
I'm developing a WordPress Ad Manager Plugin. Very simple thought, get an image URL into db with an id, and fetch the URL and show them with <img> tag. In my show ad function I did something like this:
<?php
function show_ad($id){
global $wpdb;
$table = $wpdb->prefix . "my_ad";
$query = $wpdb->get_results(
"SELECT *
FROM $table
WHERE id = $id;
");
$output = echo '<img src="'. $query[0]->img_url .'"/>';
return $output;
}
?>
The ad can be shown by any of these ways: PHP Function in Template (<?php show_ad($); ?>), Shortcode, Sidebar Widget. In all the cases the image showing process will be the same function.
Suppose, I have a site, where I added 20 ads into the plugin db. Now I want to show 10 of them into 10 different places, 10 different <div>s. in the same page. So what the function is doing, using the same function in 10 different places means 10 Individual db Queries. And 10 db Queries means 10 times hit to db.
So, I'm seeking a way to combine all the function into one and execute a single db query to fetch data. I'm dreaming something like the following. Assuming there are 10 different ad places in my page:
<?php
// A TOTAL FICTIONOUS CODE BLOCK
if( function_in_this_page_exists( 'show_ad' ) ) {
$function_array = make_them_array_with_vallues();
//so function_array looks like: array( '2','4','1','5','8','10','15', ... )
//execute the combined query function
//and query the db once
$query_result_array = combined_query_function();
//so the $query_result_array looks like: array('2'=>'http://url2.com','4'=>'http://url4.com','1'=>'http://url1.com', ...)
//now, distribute the data to the individual function where they are
//by executing another function that distribute fetched data where their id belongs
distribute_array_data_to_functions($query_result_array);
}
?>
Though it's a fictionous code block, but [if possible], with this way a simple db query can do all the individual queries instead. I don't think such a function-fetching-with-parameter thing is present now in PHP. Any idea?
Firstly, you might use the MySQL keyword IN to fetch more than one id.
Secondly, just write your processing function for the returned data-set as you imagined.
In other words, build the content, insert image URL for each for the ids.
After that, you might think about caching the query and caching the generated content.
$array_with_ids = array('1','2','3');
$sql = 'SELECT *
FROM `table`
WHERE `id` IN (' . implode(',', array_map('intval', $array)) . ')';

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";
}

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

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'];
}

Categories