Which design pattern helps me in this case using - Laravel - laravel

so I have a controller which returns a view with a DB Collection which I have a repository,
now, in case I have a request I want to return an array - json and not a view
any ideas if this is the correct approach?
public function index(
Request $request,
CampaignPerformanceRepository $campaignPerformanceRepository
) {
$data = $campaignPerformanceRepository->getDataByPeriod($request);
if ($request->all()) {
return $campaignPerformanceRepository->getDataByPeriod($request);
}
return view('reports.campaign-performances', compact('data'));
}

I do something similar in cases where I may want to return a view or just json based on the request. There's an easy helper function request()->wantsJson() which you can use.
$data = $campaignPerformanceRepository->getDataByPeriod($request);
if ($request->wantsJson()) {
return $campaignPerformanceRepository->getDataByPeriod($request);
}
return view('reports.campaign-performances', compact('data'));

Related

recover the slug of a category linked to another category Laravel

I would like to recover the slug of 2 categories from my routes but can’t write the Controller.
My Route
Route::get('technicians/o/{occupation}/c/{city}', 'User\TechnicianController#viewoccupationcity');
My Controller
public function viewoccupationcity($slug)
{
$technicians = TechnicianResource::collection(occupation::where('slug',$slug)->firstOrFail()->technicians()
->with('city','occupation')
->latest()->get());
return $technicians;
}
Route::get('technicians/o/{occupation}/c/{city}', 'User\TechnicianController#viewoccupationcity');
Your controller will accept the parameters from your route as variables by order
public function viewoccupationcity($ocupation, $city)
{
...
}
Example:
URL: technicians/o/foo/c/bar
public function viewoccupationcity($ocupation, $city)
{
// $ocupation will be 'foo'
// $city will be 'bar
}
Ok, you would need to retrieve 2 variables as that is what you are passing
public function viewoccupationcity($occupation, $city)
If you want the whole slug to do another search then you would use the $request object. So like so
public function viewoccupationcity(Request $request, $occupation, $city){ // You also need to include the Request decleration
$slug = $request->path();
$technicians = TechnicianResource::collection(occupation::where('slug',$slug)->firstOrFail()->technicians()
->with('city','occupation')
->latest()->get());
return $technicians;
}
EDIT: We are having to do a lot of guesswork as your question isn't very clear. I think what you are trying to achieve is probably this
public function viewoccupationcity($occupation, $city){
$technicians = TechnicianResource::collection(occupation::where('city',$city)->where('occupation',$occupation)->firstOrFail()->technicians()
->with('city','occupation')
->latest()->get());
return $technicians;
}
If you need something more then you need to give more details

Filtering one-to-many connections in entity

I have an entity User which has a one-to-many connection to questions. Questions has a one to many connection to answers. The question and answer entity each has a property called state.
In generally after execute a GET request API Platform returns all users, with all questions including all answers. That works fine!
Now I would like to implement a get request that returns the user with all questions that has a specific state (e.g. "X"). The questions should only include the answers with the same state ("X").
I used the filter function (to filter the whole not necessary data)
Therefore I generated a controller called GetUserObjectAction which the following function
public function __invoke(PaginatorInterface $data, Request $request): PaginatorInterface
{
$repo = $this->managerRegistry->getRepository(Question::class);
foreach ($data as $value) {
$q = $value->getQuestions()->filter(function($q1) {
if($q1->getState() === 'a') {
$q1->values = $q1->values->filter(function($a) {
return $a->getState() === 'a';
});
return true;
} else {
return false;
}
return ;
});
$value->setQuestions($int);
}
return $data;
}
Is there a better way to implement it?
Thanks
You chose the right way because you did not tell us how are your data managed (Doctrine ORM/ODM, custom data providers) we cannot tell you more. But I suggest you are using API Platform defaults, so you can filter your data before fetching them in your QuestionRepository and omit to iterate over data.
Here is example:
QuestionRepository
...
public function findWithAnswersByState(string $state): array
{
$qb = $this->createQueryBuilder('q')
->join('q.answers', 'a')
->andWhere('q.state = :state')
->andWhere('a.state = :state')
->setParameter('state', $state);
return $qb->getQuery()->getResult();
}
...
Controller:
...
public function __invoke(PaginatorInterface $data, Request $request): PaginatorInterface
{
$repo = $this->managerRegistry->getRepository(Question::class);
return $repo->findWithAnswersByState('a');
}
...

Handling non objects

I might have a controller function like so
public function index()
{
$poll = DB::table('poll')->whereNull('deleted_at')->orderBy('id', 'desc')->first();
$question = DB::table('poll_question')->whereNull('deleted_at')->where('poll_id', $poll->id)->first();
$answers = DB::table('poll_answer')->whereNull('deleted_at')->where('question_id', $question->id)->orderBy('id')->get();
return view('index', compact('poll', 'question', 'answers'));
}
This is fine if the three collections I am obtaining contain data. If they dont and I try to visit the index page, I get
ErrorException in PollResponseController.php line 20: Trying to get property of non-object
So what is the best way to handle non-object's? To bypass this, I could do
public function index()
{
$poll = DB::table('poll')->whereNull('deleted_at')->orderBy('id', 'desc')->first();
if($poll) {
$question = DB::table('poll_question')->whereNull('deleted_at')->where('poll_id', $poll->id)->first();
if($question) {
$answers = DB::table('poll_answer')->whereNull('deleted_at')->where('question_id', $question->id)->orderBy('id')->get();
return view('index', compact('poll', 'question', 'answers'));
}
}
return view('error');
}
But is that not a bit exessive? I was just wondering if there was a better approach to handling this?
Thanks
You can use simple if($question) clause or if(is_null($question)).
$question = DB::table('poll_question')->whereNull('deleted_at')->where('poll_id', $poll->id)->first();
if($question){
// The object is not empty, so I'll use it
}else{
// The object is empty
}
In a blade template it will look like #if($question) and #if(is_null($question)) respectively.
#if($question)
{{ $question->property }}
#endif
In most cases you should just bypass all variables in a template and then check each of them with #if clauses.

Authorization Using Form Requests in Laravel

Not sure what I am doing wrong here but I am having trouble getting the $id of the post to pass to the form request when checking to see if the person editing owns the post. "Job" would be a job posting. Below is the logic in the JobsRequest.
public function authorize()
{
$job=Job::find($this->id);
if($job->user_id == Auth::user()->id){
return true;
}else{
return false;
}
The above keeps returning as false. The update method in the controller is below
public function update(JobsRequest $request, $id)
{
$job=Job::find($id);
$job_data=$request->all();
$job->update($job_data);
return redirect('/jobs/'.$job->id.'/edit');
}
To grab the id within the FormRequest object, you'd need to use the following...
$id = $this->route('id');
Go to the AuthServiceProvider.php and write
$gate->define('show-product',function($user,$product){
return $user->id==$product->customer_id;
});
Then write your controller
$product= Product::find($id);
Auth::loginUsingId(3);
//Auth::logout();
if(Gate::denies('update',$product)){
App::abort('404','Product Not Found');
}
// $this->authorize('update',$product);
return $product->name;
I think It's working perfectly
Try this, which gets the id from the route parameter.
public function authorize(){
$job_id = $this->route('id');
$job=Job::find($job_id);
$user = $this->user();
if($job->user_id == $user->id) return true;
return false;
}
Thanks for pointing me in the right direction. I got this straight from the docs.. This worked for me.
$jobId = $this->route('jobs');
return Job::where('id', $jobId)
->where('user_id', Auth::id())->exists();

codeigniter passing count_all_results to view

I'm using the count_all_results() function to return a user's number of languages spoken. But when I try to pass the number to the view, I keep getting a php undefined variable (for $lang_cnt). Below is my code:
Model
function countLanguages($id) {
$this->db->where('user_id', $id)->from('languages');
return $this->db->count_all_results();
}
Controller
function showLangCount() {
$data['lang_cnt'] = $this->language_model->countLanguages($id);
$this->load->view('lang_view', $data);
}
View
<p>This user speaks <?php echo $lang_cnt; ?> languages.</p>
One problem is that your model function takes two arguments:
function countLanguages($id, $cnt_languages)
But when you call it you are only passing one argument:
$this->language_model->countLanguages($cnt_languages);
And an even bigger problem, as Rocket points out, is that countLanguages doesn't return anything. Try this:
function countLanguages($id) {
$this->db->where('user_id', $id)->from('languages');
return $this->db->count_all_results();
}
Always check your model functions if they return value or not. Try this:
function showLangCount() {
if($this->language_model->countLanguages($id))
{
$data['lang_cnt'] = $this->language_model->countLanguages($id);
}
else
{
$data['lang_cnt'] = NULL;
}
$this->load->view('lang_view', $data);
}
Its better to use:
return $query->num_rows();
to return the number of rows effected...

Resources