retrieving rows based on another rows laravel - laravel

I am working over a basic system where blogs retrieve the image from other database table but it shows the posts not the photos
here is my controller:
$bloginfo=bloginfo::where('blog_name','=',$name)->first();
$blogposts=pageposts::where('p_id','=',$bloginfo->id)->orderBy('id','desc')->get();
foreach($blogposts as $posts){
$photoscount=pagephotos::where('b_id','=',$posts->id)->count();
$blogphotos=pagephotos::where('b_id','=',$posts->id)->get();
}
return View::make('myblog')
->with('bloginfo',$bloginfo)
->with('blogposts',$blogposts)
->with('blogphotos',$blogphotos)
->with('photoscount',$photoscount);
and here is my view:
#foreach($blogposts as $posts)
<div class="panel panel-default">
<div class="panel-body">
#if($photoscount==0)
{{ null }}
#elseif($photoscount==1)
//a bunch of code here
#else
//a bunch of code here
#endif
<h4>{{ $posts->title }}</h4>
<p>{{ $posts->description }}</p>
</div>
</div>
#endforeach

Might i suggest you looking into to relationships, this could also be your answer.
You can eager load all the data within one query.
bloginfo::with('posts', 'posts.images')->where('blog_name','=',$name)->first();
This will load the blog posts with all the information that relates to it, i.e. the posts, and their images. Look here for setting them up. HERE
As your current problem is within your for loop you overwrite the variables you are setting n times, i.e. by the amount of posts there are. So potentially you will always have different results.

Related

Laravel: How to create link buttons on a view dynamically?

I'm making a College Administration website where a professor can log in.
I have a dashboard, where my dynamically generated button should be placed: (right now it just has dummy buttons!)
Generated by this view file, which I will have to modify soon:
<div class="container d-flex flex-column align-items-center justify-content-center">
<h1>IA DASHBOARD</h1>
<br>
<div class="grid2">
SUBCODE 1</button>
SUBCODE 2</button>
SUBCODE 3</button>
</div>
Tables in the Database:
the table iamarks contains the data (student info, and marks) that is to be displayed after /subcode/{subcode} narrows it down to records of just the students that are in the class assigned to current logged-in professor.
classroom_mappers is a table used to map a professor to a classroom with a subject. It makes sure that one classroom only has one professor for a particular subject.
the routes currently in my web.php:
route::get('/ia', 'IAController#show')->middleware('auth');
Route::get('/subcode/{subcode}', 'IAController#showTable')->middleware('auth');
...and these are the methods inside my controller:
//shows buttons to the user:
public function show(){
$subcodes = DB::table('classroom_mappers')
->select('subcode')
->where([['PID','=', auth()->user()->PID]])
->get();
return view('ia',compact('subcodes'));
}
//when user clicks a button, subcode is to be generated and a table is to be shown:
//it works, I tried it by manually typing in subcode value in URL.
public function showTable($subcode){
$sem = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['subcode','=',$subcode]])
->pluck('semester');
$division = DB::table('classroom_mappers')
->where([['PID','=', auth()->user()->PID],
['semester','=',$sem],
['subcode','=',$subcode]])
->pluck('division');
$data = DB::table('iamarks')
->where([['semester','=',$sem],
['division','=',$division],
['subcode','=',$subcode]])
->get();
return view('subcode',compact('data'));
}
My Problem:
To be able to generate the {subcode} in the URL dynamically, I want to create buttons in the dashboard using the data $subcodes. The controller hands over the $subcodes (an array of subject codes which belong to logged in professor) which are to be made into buttons from the show() method.
The buttons should have the name {subcode} and when clicked, should append the same subject code in the URL as {subcode}.
How do I make use of $subcodes and make the buttons dynamically?
How do I make sure the buttons made for one user are not visible to another user?
I managed to find the solution, thanks to Air Petr.
Apparently, you can't nest blade syntax like {{some_stuff {{ more_stuff }} }} and it generates a wrong php code. I modified the solution by Air Petr to:
<div class="grid2">
#foreach ($subcodes as $subcode)
<a href="<?php echo e(url('/subcode/'.$subcode->subcode));?>">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">
<?php
echo e($subcode->subcode);
?>
</button>
</a>
#endforeach
</div>
It generates the buttons perfectly. The buttons for one user are not visible to another, since I'm using PID constraint in a query (['PID','=', auth()->user()->PID]).
Pass the passcodes array to view:
$subcodes = []; // Array retrieved from DB
return view('subcode', compact('subcodes'));
And in subcode.blade.php, loop through each subcode:
<div class="grid2">
#foreach($subcodes as $subcode)
<a href="{{ url('/subcode/' . $subcode->subcode) }}">
<button class="btn btn-outline-primary btn-custom-outline-primary btn-custom">SUBCODE {{ $subcode->subcode }}</button>
</a>
#endforeach
</div>
You can loop your codes to create buttons. Something like this (it's for "blade" template engine):
<div class="grid2">
#foreach ($subcodes as $subcode)
{{ $subcode->subcode }}</button>
#endforeach
</div>
Since you're using PID constrain in a query (['PID','=', auth()->user()->PID]), you'll get buttons for that specific PID. So there's no problem.

Pagination is not showing

I'm trying to get pagination into my view. I don't know where is the problem, the code doesn't show any errors.
Here is my controller function
public function apakskategorijas($id)
{
$apakskat = apakskategorijas::with('prece')->where('id',$id)->paginate(2);
return view ('kategorijas.apakskategorijas',compact('apakskat'));
}
View
#section('content')
#foreach($apakskat as $apk)
#foreach($apk->prece as $prec)
<div class="col-md-4 kat">
<a href="{{ url('kategorija/apakskategorija/preces/'.$prec->id) }}">
<div>
<img src="{{ URL::to($prec->path) }}">
</div>
<div class="nos">
<p>{{$prec->nosaukums}}</p>
</div></a>
<div class="price-box-new discount">
<div class="label">Cena</div>
<div class="price">{{ $prec->cena }} €</div>
</div>
<div><span>Ielikt grozā</span></div>
</div>
#endforeach
#endforeach
<center>{{$apakskat->links()}}</center> <--pagination
#endsection
dd($apakskat)
UPDATE
when i changed code in my controller to $apakskat = apakskategorijas::paginate(1); then it showed me pagination, but this doesn't work for me since i need to display items in each subcategory, with this code it just displays every item i have,it doesn't filter which subcategory is selected.
This is why i need this $apakskat = apakskategorijas::with('prece')->where('id',$id)->paginate(1); with is a function that i call which creates a relation between tables, so that it would display every item with its related subcategory.
That's the behavior of paginator in current Laravel version. When you have just one page, pagination links are not displayed.
To test this, just change the code to something like this to get more pages:
$apakskat = apakskategorijas::paginate(1);
If you want to show the first page if there is only one page, you need to customize pagination views. Just publish pagination views and remove this #if/#endif pair from the default.blade.php but keep the rest of the code as is:
#if ($paginator->hasPages())
....
#endif

Retrieve unique entries from DB using Eloquent Laravel 4

I am using Laravel-4 to build an application. I am trying to make the best use of Eloquent ORM. Currently I am displaying a list of db entries which all have a number of tags associated with them
To the right I display a grid of all the tags however it is showing duplicate tags. I would only like to show unique tags
This is my code:
<div class="tags-panel">
<div class="tags-title"><h1>Tags</h1></div>
<div class="tags-cloud">
#foreach(Tag::distinct()->get() as $tag)
<span class="num"> {{ Tag::getAmount($tag->id) }} </span> {{$tag->name}}
#endforeach
</div>
</div>
Does Eloquent provide a way of only retrieving distinct entries from the db?
Try using Tag::groupBy('field_name')->get()
<div class="tags-panel">
<div class="tags-title"><h1>Tags</h1></div>
<div class="tags-cloud">
#foreach(Tag::groupBy('field_name')->get() as $tag)
<span class="num"> {{ Tag::getAmount($tag->id) }} </span> {{$tag->name}}
#endforeach
</div>
</div>
To use the distinct()-function you have either have a select() in your chain, or use a field as an argument in your get()-function. For example:
$tags = Tag::distinct()->get(array('field'));
or
$tags = Tag::select('field')->distinct()->get();
You could also instead use groupBy('field') if you don't want to supply field names:
$tags = Tag::groupBy('field')->get();

How can I solve issue with One to One relationship using foreign keys

I've been using eloquent in my models. I've got the following two tables:
Singlecard
->id
->card_id
Card
->id
->card_id
My Singlecard Model has the following function:
public function info()
{
return $this->hasOne('Card', 'card_id', 'card_id');
}
I used this to get the card (there's only one card in the deck for my test).
$cards = Singlecard::where('deck_id', '=', $deck)->get();
foreach ($cards as $card)
{
$cards_array[] = $card;
}
It got the correct card and using var_dump I verified that. However, here's the problem:
<div class="row singlecard">
<a class="" href="{{ $single->id }}">
<div class="large-2 columns">
<img src="{{ $single->info->card_image }}">
</div>
<div class="large-10 columns">
<div class="row">
<div class="large-12 columns">
<p>{{ $single->info->name }}</p>
</div>
</div>
<div class="row">
<div class="large-12 columns">
#foreach ($single->attributes as $attribute)
<p>{{ $attribute->alias }}</p>
#endforeach
</div>
</div>
</div>
</a>
</div>
Here's the twist: The attributes code works correct. It grabbed the correct attributes from a one to many relationship I defined. But it's grabbing the wrong info from the Cards table. Even though I defined the keys to match on, it is matching based on the ID of the singlecard and the card_id in the Cards table.
I've tried removing the keys and that didn't do anything. I even removed the function all together just to verify that that was the function being called. I'm not sure what's wrong?
UPDATE:
I figured it out, I did two things. One, I used id from the Cards table as the record to match with Singlecards. I also changed my function in the Singlecards model like so:
public function info()
{
return $this->belongsTo('Card', 'card_id');
}
This allowed me to properly query the relationship.
I needed to update how my models were related and better form the relationship. I also needed to change the model so that Singlecards belonged to Cards. I assumed it should be the opposite.
Cards contains all the info about the various cards and Singlecards is what is in each individuals hands/decks. I assumed that would make Singlecards the parent but that was a mistake. Once I changed the function in the model to be like this:
public function info()
{
return $this->belongsTo('Card', 'card_id');
}
Then it worked.

How to reuse a blade partial in a template

I would like to be able to repeat a partial a number of times within a view, with different content in each repetition.
The partial is a simple panel, with a heading, and some content. The content within each panel can vary in complexity, so I would like to be able to use the #section('content') method of passing data.
The set up I have is as follows:
panel.blade.php - The partial to be repeated.
<div class="panel">
<header>
#yield('heading')
</header>
<div class="inner">
#yield('inner')
</div>
</div>
view.blade.php - The view in which the partial is repeated
#extends('default')
#section('content')
{{-- First Panel --}}
#section('heading')
Welcome, {{ $user->name }}
#stop
#section('inner')
<p>Welcome to the site.</p>
#stop
#include('panel')
{{-- Second Panel --}}
#section('heading')
Your Friends
#stop
#section('inner')
<ul>
#foreach($user->friends as $friend)
<li>{{ $friend->name }}</li>
#endforeach
</ul>
#stop
#include('panel')
#stop
I am running into the same issue as this: http://forums.laravel.io/viewtopic.php?id=3497
The first panel is displayed as intended, but the second is simply a repeat of the first.
How can I correct this? If this is a poor method of getting this done, what would be a better way?
For Laravel 5.4, Components & Slots may be useful for you. The following solution is for Laravel 4.x, and likely <= 5.3 as well.
In my opinion, this is a silly use case for the #include syntax. The amount of HTML retyping you're saving is negligible, especially since the only potentially-complicated part of it is the inner content. Keep in mind, the more parsing that needs to be done, the more overhead your application has, also.
Also, I don't know the inner workings of the #yield & #section features, so I can't say how "proper" it is to work your includes this way. Includes typically utilize a key => value pair passed as a parameter in the include call:
#include('panel', ['heading' => 'Welcome', 'inner' => '<p>Some stuff here.</p>'])
Not the most ideal place to pack a bunch of HTML, but that's the "designed" way (as far as I know, at least).
That said...
Use the #section ... #overwrite syntax mentioned in the "Other Control Structures" part of the template docs page.
#extends('default')
#section('content')
{{-- First Panel --}}
#section('heading')
Welcome, {{ $user->name }}
#overwrite
#section('inner')
<p>Welcome to the site.</p>
#overwrite
#include('panel')
{{-- Second Panel --}}
#section('heading')
Your Friends
#overwrite
#section('inner')
<ul>
#foreach($user->friends as $friend)
<li>{{ $friend->name }}</li>
#endforeach
</ul>
#overwrite
#include('panel')
#stop

Resources