Laravel 5. Merge several Builders to paginate them with "paginate()" - laravel

I am trying to merge several builders to paginate search results of them, but this code returning me an error
My SearchController.php
public function index(Request $request)
{
$string = mb_strtolower($request->input('q'), "UTF-8");
if ($string != "") {
// $query = explode(" ", $string);
$query = $string;
} else {
$query = null;
}
if ($query != null) {
$news = $this->searchQuery(new News(), 'title', 'content', $query, false);
$last = $this->searchQuery(new Last(), 'title', 'description', $query, false);
$author = $this->searchQuery(new AuthorNews(), 'title', 'description', $query, false);
$tv = $this->searchQuery(new TvBroadcast(), 'name', 'description', $query, false);
$program = $this->searchQuery(new TvProgram(), 'name', 'description', $query, false);
$project = $this->searchQuery(new SpecProject(), 'title', 'description', $query, false);
$appointments = $this->searchQuery(new Appointment(), 'fio', 'position', $query, false);
//Новости по авторам
// $authors = $this->searchAuthor($query);
// dd($authors);
// 21520
$item = $news->merge($last);
$item = $item->merge($author);
$item = $item->merge($tv);
$item = $item->merge($program);
$item = $item->merge($project);
$item = $item->merge($appointments);
$items = $item->paginate(21);
$items_c = $items->total();
} else {
$items = null;
$items_c = 0;
$string = null;
}
$method = 'index';
return view('front.search.index', array('items' => $items, 'count' => $items_c, 'q' => $string, 'method' => $method));
}
public function searchQuery($model, $attr1, $attr2, $query, $stat, $author = false)
{
$items = $model->with('nodes')->whereHas('nodes', function ($q) use ($query, $attr1, $attr2) {
$q->where('language_id', '=', app()->getLocale())->where(function ($q) use ($query, $attr1, $attr2) {
$q->where(\DB::raw('lower(' . $attr1 . ')'), 'like', '%' . $query . '%')
->orWhere(\DB::raw('lower(' . $attr2 . ')'), 'like', '%' . $query . '%');
});
})->orderBy('created_at', 'desc');
if ($stat == true) {
$items = $items->where('stat', '=', 1);
}
if ($author) {
$items = $items->with(['author', 'author.nodes'])->orWhereHas('author.nodes', function ($q) use ($query) {
// foreach ($query as $elem) {
// $q->where(\DB::raw('lower(title)'), 'like', '%' . $elem . '%');
// }
$q->where(\DB::raw('lower(title)'), 'like', '%' . $query . '%');
});
}
return $items;
}
I have 7 Builders like this and I want to merge them
But when I am running my code I get an error like this
I also tried union() method and it doesn't work too

Related

Paginate for a collection, Laravel

I try to add some new values to each user from foreach, but because I use get, now I can't use paginate on response, but I also need to add that values to each user. Any ideas?
public function statistics()
{
$users = User::select(['id', 'name'])->get();
foreach ($users as $key => $user) {
$history = AnswerHistory::where('user_id', '=', $user->id)->get();
$user->total_votes = count($history);
$user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
}
return response()->json($users);
}
what you want is not possible in laravel by default, however there are a few things you can do.
Solution one you can return paginator first and then modify the collection.
$users = User::select(['id', 'name'])->paginate(4)->toArray();
$users['data'] = array_map(function ($user) {
$history = AnswerHistory::where('user_id', '=', $user->id)->get();
$user->total_votes = count($history);
$user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
return $user;
}, $users['data']);
return $users;
Solution two The macro way. If you prefer, add the Collection macro to a Service Provider. That way you can call paginate() on any collection:
See AppServiceProvider.php for a sample implementation.
public function boot()
{
Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
});
}
and then your code will be like this
$users = User::select(['id', 'name'])->get();
foreach ($users as $key => $user) {
$history = AnswerHistory::where('user_id', '=', $user->id)->get();
$user->total_votes = count($history);
$user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
}
return response()->json($users->paginate(4));
Solution three The subclass way. Where you want a "pageable" collection that is distinct from the standard Illuminate\Support\Collection, implement a copy of Collection.php in your application and simply replace your use Illuminate\Support\Collection statements at the top of your dependent files with use App\Support\Collection:
<?php
namespace App\Support;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection as BaseCollection;
class Collection extends BaseCollection
{
public function paginate($perPage, $total = null, $page = null, $pageName = 'page')
{
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
}
}
and your code will be like this
// use Illuminate\Support\Collection
use App\Support\Collection;
$users = User::select(['id', 'name'])->get();
foreach ($users as $key => $user) {
$history = AnswerHistory::where('user_id', '=', $user->id)->get();
$user->total_votes = count($history);
$user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
}
return response()->json((new Collection($users))->paginate(4);
According to your post, User has many AnswerHistory. You can build relationship between them.
So getting the total_votes and total_time by withCount:
$users = User::withCount('answerHistories AS total_votes')
->withCount(['answerHistories AS total_time' => function($query) {
$query->select(DB::raw("SUM(answer_time)"));
}])->paginate(10);
And you can get the pagination datas by getCollection, and change the datas inside:
$users->getCollection()->transform(function ($data) {
$data->total_time = gmdate('H:i:s', $data->total_time);
return $data;
});
You can create pagination by yourself look to this Laravel doc https://laravel.com/docs/7.x/pagination#manually-creating-a-paginator.
I will suggest to use LengthAwarePaginator
Here is some code example with array
// creating pagination
$offset = max(0, ($page - 1) * $perPage);
$resultArray = array_slice($result, $offset, $perPage);
$paginator = new LengthAwarePaginator($resultArray, count($result), $perPage, $page);
$paginator->setPath(url()->current());
$paginator->appends(['per_page' => $perPage]);
return response()->json([
'message' => 'Success',
'data' => $paginator
]);
But I think your case have better "good" solution, you can load AnswerHistory with hasMany Laravel relation and with function.

Laravel - alphabetical order

I would like to make an alphabetical sort in my function index().
I think I should use the Order By clause?
I am stuck in my code below:
public function index(Request $req)
{
if ($req->has('search') && !empty($req->search)) {
$validated = $req->validate([
'search' => 'alpha',
]);
$auteurs = Auteur::where('nom', 'LIKE', '%' . $validated['search'] . '%')->paginate(5);
$auteurs->appends($req->only('search'));
return view('admin.auteurs.index', compact('auteurs'));
}
$auteurs = Auteur::paginate(5);
return view('admin.auteurs.index', compact('auteurs'));
}
Yes use orderBy like this:
public function index(Request $req)
{
if ($req->has('search') && !empty($req->search)) {
$validated = $req->validate([
'search' => 'alpha',
]);
$auteurs = Auteur::where('nom', 'LIKE', '%' . $validated['search'] . '%')->orderBy('nom', 'ASC')->paginate(5);
$auteurs->appends($req->only('search'));
return view('admin.auteurs.index', compact('auteurs'));
}
$auteurs = Auteur::orderBy('nom', 'ASC')->paginate(5);
return view('admin.auteurs.index', compact('auteurs'));
}

Cannot Update On Laravel 5.5

I get problem.
This is my controller
public function finish(Request $request)
{
$result = $request->input('data');
//$data = json_decode($result, true);
return $this->InvoiceBayar($result);
}
public function InvoiceBayar($result)
{
$data = json_decode($result, true);
$transaction = $data['transaction_status'];
$type = $data['payment_type'];
$order_id = $data['order_id'];
$fraud = $data['fraud_status'];
Fee::where('invoice',$order_id)
->update([
'status' => 'Paid',
]);
echo "Transaction order_id: " . $order_id ." successfully transfered using " . $type;
}
This is my Route
Route::POST('/notification', 'SnapController#finish');
When Payment gateway, send a parameter to me, I cannot update DB.
But when I use POSTMAN. I success update DB
You need to use $request->all() as it will contain all payment gateway data.
public function finish(Request $request)
{
$result = $request->all();
return $this->InvoiceBayar($result);
}
Alternately you can do this
$update = Fee::where('invoice',$order_id)->first();
$update->status = 'Paid';
$update->save();
You should try this:
public function InvoiceBayar($result)
{
$data = json_decode($result, true);
$transaction = $data->transaction_status;
$type = $data->payment_type;
$order_id = $data->order_id;
$fraud = $data->fraud_status;
Fee::where('invoice',$order_id)
->update([
'status' => 'Paid',
]);
echo "Transaction order_id: " . $order_id ." successfully transfered using " . $type;
}

How to create api for search in lumen/laravel?

How to create api for search in lumen/laravel .. I tried using keyword but not working.
public function index(){
$Employees = Employees::all();
$page = Input::get('page', 1);
$keyword = Input::get('keyword', '');
if ($keyword!='') {
$keyword = Employees::
where("firstname", "LIKE","%$keyword%")
->orWhere("lastname", "LIKE", "%$keyword%");
}
$itemPerPage=5;
$count = Employees::count();
$offSet = ($page * $itemPerPage) - $itemPerPage;
$itemsForCurrentPage = array_slice($Employees->toArray(), $offSet, $itemPerPage);
return new LengthAwarePaginator($itemsForCurrentPage, count($Employees), $itemPerPage, $page,$keyword);
}
You should change this line :
if ($keyword!='') {
$Employees = Employees::
where("firstname", "LIKE","%$keyword%")
->orWhere("lastname", "LIKE", "%$keyword%")
->get();
}
Also i think You should the pagination within the model query, not on the returned result.
you can also do this
define your logic in a scope created in you model and consume it in your controller.here is what i mean
This should be in your model
public function scopeFilter($query, $params)
{
if ( isset($params['name']) && trim($params['name'] !== '') )
{
$query->where('name', 'LIKE', trim($params['name']) . '%');
}
if ( isset($params['state']) && trim($params['state'] !== '') )
{
$query->where('state', 'LIKE', trim($params['state']) . '%');
}
return $query;
}
and in your controller have something like
public function filter_property(Request $request)
{
$params = $request->except('_token');
$product = Product::filter($params)->get();
return response($product);
}
you can get more by reading scope on laravel doc and this blog post here

Two lots of pagination with codeigniter on one page

I have to lots of paginations one lot is for my user's results and the other is for my question results.
When I am on link 3 on my question results it also switches the results on users list pagination.
Question if I click on the questions pagination links how can I make sure it does not affect the results of the user's list.
I have tried this Best way to do multiple pagination on one page in codeigniter does not work
As you can see in image below because I am on questions list page 3 it has effected the users list
<?php
class Dashboard extends MY_Controller {
public $data = array();
public function __construct() {
parent::__construct();
$this->load->model('user/user_model');
$this->load->model('forum/question_model');
$this->load->library('pagination');
}
public function index() {
$this->data['title'] = 'Dashboard';
$this->data['is_logged'] = $this->session->userdata('is_logged');
$config1['base_url'] = base_url('dashboard/');
$config1['total_rows'] = $this->user_model->total_users();
$config1['per_page'] = 2;
$config1['uri_segment'] = 2;
$config1['num_links'] = 200;
$config1['use_page_numbers'] = FALSE;
$config1['prefix'] = 'u_';
$pagination1 = new CI_Pagination();
$pagination1->initialize($config1);
$this->data['pagination1'] = $pagination1->create_links();
$page_segment1 = explode('_', $this->uri->segment(2));
$page1 = ($this->uri->segment(2)) ? $page_segment1[1] : 0;
$this->data['users'] = array();
$users = $this->user_model->get_users($config1['per_page'], $page1);
foreach ($users as $user) {
$this->data['users'][] = array(
'user_id' => $user['user_id'],
'username' => $user['username'],
'status' => ($user['status']) ? 'Enabled' : 'Disabled',
'warning' => '0' . '%',
'date' => date('d-m-Y H:i:s A', $user['date_created_on']),
'href' => site_url('user/profile/') . $user['user_id']
);
}
// Questions Pagination & Results
$config2['base_url'] = base_url('dashboard/');
$config2['total_rows'] = $this->question_model->total_questions();
$config2['per_page'] = 2;
$config2['uri_segment'] = 2;
$config2['num_links'] = 200;
$config2['use_page_numbers'] = FALSE;
$config2['prefix'] = 'q_';
$pagination2 = new CI_Pagination();
$pagination2->initialize($config2);
$this->data['pagination2'] = $pagination2->create_links();
$page_segment2 = explode('_', $this->uri->segment(2));
$page2 = ($this->uri->segment(2)) ? $page_segment2[1] : 0;
$this->data['questions'] = array();
$questions = $this->question_model->get_questions($config2['per_page'], $page2);
foreach ($questions as $question) {
$this->data['questions'][] = array(
'user_id' => $question['user_id'],
'title' => $question['title']
);
}
$this->data['navbar'] = $this->load->view('common/navbar', $this->data, TRUE);
$this->data['header'] = $this->load->view('common/header', $this->data, TRUE);
$this->data['footer'] = $this->load->view('common/footer', '', TRUE);
$this->load->view('common/dashboard', $this->data);
}
}
Question Model
<?php
class Question_model extends CI_Model {
public function get_questions($limit, $start) {
$this->db->select('*');
$this->db->from('questions q');
$this->db->join('users u', 'u.user_id = q.user_id', 'left');
$this->db->limit($limit, $start);
$query = $this->db->get();
return $query->result_array();
}
public function total_questions() {
return $this->db->count_all("questions");
}
}
Users Model
<?php
class User_model extends CI_Model {
public function get_users($limit, $start) {
$this->db->select('u.status, u.date_created_on, ud.*');
$this->db->from('users u', 'left');
$this->db->join('users_userdata ud', 'ud.user_id = u.user_id', 'left');
$this->db->limit($limit, $start);
$query = $this->db->get();
return $query->result_array();
}
public function total_users() {
return $this->db->count_all("users");
}
}

Resources