Laravel 4 - How to access outside variables from an advance where - php

I have a scope method in my model named Book.
public function scopeBookAuthor($query, $input = array()){
if($input['book_author'] != ''){
return $query->where(function ($query) {
$query->where('book_author_last_name', 'LIKE', "%".$input['book_author']."%")
->orWhere('book_author_middle_name', 'LIKE', "%".$input['book_author']."%")
->orWhere('book_author_first_name', 'LIKE', "%".$input['book_author']."%");
});
}
}
An error occurred inside the function in the 3rd line. it says Undefined variable: input.
I tried to include the input variable as another parameter but it didn't work
return $query->where(function ($query, $input) {...
Is there a way to make this possible? thanks in advance.

There is a dirty hack:
return $query->where(function ($query) use ($input){

Related

dynamic query laravel eloquent with whereHas

I want to create dynamic filters.
for example I want to create this code
$Contact = Contact::whereHas('User', function ($query) use ($searchString) {
$query->where('name', 'like', '%Jhone%')->orwhere('family', '<>' . 'Doe');
})->whereHas('Account', function ($query) use ($searchString) {
$query->where('account_name', '=' , 'test_account' )->orwhere('account_city', 'like', '%test_city%');
})->get();
and all of parameters is variable
name,like,%Jhone%,family,<>,Doe,.....
and I want to pass variables to function and function create above query.
I assume that the relationship functions within your Contact, User and Account models are written in camelCase and not PascalCase like your example shows.
public function getContacts(Request $request)
{
return Contact::when($request->get('username'), function ($query, $val) use ($request) {
$query->whereHas('user', function ($q) use ($val, $request) {
$q->where('name', 'like', '%'.$val.'%');
if ($request->has('familyname')) {
$q->orWhere('family', '<>', $request->get('familyname'));
}
});
})
->when($request->get('accountname'), function ($query, $val) use ($request) {
$query->whereHas('account', function ($q) use ($val, $request) {
$q->where('account_name', $val);
if ($request->has('city')) {
$q->orWhere('account_city', 'like', '%'.$request->get('city').'%');
}
});
})
->get();
}
This function will return all contacts when no GET parameters are given on the request. If a parameter for username is present, it will only return contacts where a user with the given name exists for. If furthermore a familyname parameter is present, it will give contacts with a user that has a matching username or a familyname different from the one given. The very same applies to the account, accountname and city.
In particular, there are two things interesting about this example:
The when($value, $callback) function can be used to build very dynamic queries which only execute the $callback when $value is true. If you use $request->get('something') and something is not available as parameter, the function will return null and the callback is not executed. The callback itself has the form function ($query, $value) { ... }, where $value is the variable you passed to when() as first parameter.
Using $request->has('something') inside the query builder functions to dynamically build constraints on the query is an alternative to when(). I only added it for the purpose of demonstration - in general I'd recomment sticking to one style.
If you would extend on the example, you could also build highly dynamic queries where not only the variable content like Doe for the family name is given as parameters, but also the comparator like =, <> or like. But extending further on this topic is too much for this answer and there are already tutorials about this topic available anyway.
Edit: here an example for a dynamic query with more detailed input
Expected input (slightly different than your request because yours cannot work):
$filters = [
'user' => [
['name','like','%Jhone%'],
['family','<>','Doe'],
],
'account' => [
['account_name','=','test_account'],
['account_city','like','%test_city%'],
]
];
And the function:
public function getContacts(Request $request, array $filters)
{
$query = Contact::query();
foreach ($filters as $key => $constraints) {
$query->whereHas($key, function ($q) use ($constraints) {
if (count($constraints) > 0) {
$q->where($constraints[0][0], $constraints[0][1], $constraints[0][2]);
}
for ($i = 1; $i < count($constraints); $i++) {
$q->orWhere($constraints[$i][0], $constraints[$i][1], $constraints[$i][2]);
}
});
}
return $query->get();
}
This will always use OR for multiple constraints and not AND. Using AND and OR mixed would require a lot more sophisticated system.

Why does my whereHas query error out with undefined method "getHasCompareKey()"?

I have a model Job which is attached to one model Project.
Here are the class definitions:
class Job extends Model
{
public function project() {
return $this->belongsTo('App\Project');
}
}
class Project extends Model
{
public function jobs() {
return $this->hasMany('App\Job');
}
}
I'm trying to query the Jobs collection and filter on either jobs.title or project.title.
Here is my current search query:
$jobs = Job::where(function($query) use ($searchTerm) {
$query->where('title', 'LIKE', $searchTerm)
->orWhereHas('project', function ($subQuery) use ($searchTerm) {
return $subQuery->where('title', 'LIKE', $searchTerm);
});
})->get();
However, this is returning an error:
Call to undefined method Jenssegers\Mongodb\Query\Builder::getHasCompareKey()
I think you need to clean up your code a bit:
$jobs = Job::where('title', 'LIKE', $searchTerm)
->orWhereHas('project', function ($query) use ($searchTerm) {
$query->where('title', 'LIKE', $searchTerm);
})->get();

Why can I not acces my variable in this eloquent database call method?

I'm trying to build a search functionality in my laravel app. I want to search on the name of a tag that is related with a pivot table to my loops. But I get the error 'undefined variable : query'
This is my controller method :
public function search($query) {
$searchResult = Loop::whereHas('tags', function ($q) {
$q->where('name', 'LIKE', '%'. $query .'%');
})->get();
return Response::json($searchResult);
}
You should pass $query variable into a closure with use(), like this:
$searchResult = Loop::whereHas('tags', function ($q) use ($query) {
$q->where('name', 'LIKE', '%'. $query .'%');
})->get();
http://php.net/manual/en/functions.anonymous.php (check example #3)

undefined variable in model method (laravel)

this is my JadwalKlinik method:
public function scopeByParams($query, $params)
{
if( isset($params) ){
$query->whereHas('user', function($q){
$q->where('name', 'LIKE', '%'.$params.'%');
});
}
return $query;
}
$params in query function (line 5) is undefined, why ???
You need the keyword use with your closure
$query->whereHas('user', function($q) use ($params){
$q->where('name', 'LIKE', '%'.$params.'%');
});

Laravel paginate order by

What should I do to pass the values ​​that you order by in patinate?
routes.php
$ondata = DB::table('official_news') -> orderBy('created_date', 'desc') -> get() -> paginate(7);
return View::make('main',array('ondata' => $ondata));
error
Call to a member function paginate() on a non-object
I need your help
This should do the trick:
$ondata = DB::table('official_news')->orderBy('created_date', 'desc')->paginate(7);
It will be better if you order it by the id because it is going to be faster from the database.
$posts = Post::orderBy('id', 'desc')->paginate(6);
https://laracasts.com/discuss/channels/laravel/combining-paginate-with-orderby
It works fine for Laravel 5.1.
You can use something like this in your controller file.
$transactions = Transaction::orderBy('name')->paginate(10);
return view('index', compact('transactions'));
If you are using scope
public function scopeSearch($query, $term)
{
$term = "%$term%";
$query->where(function ($query) use ($term) {
$query->where('name', 'like', $term)
.............
..............
->orWhere('pan_number', 'like', $term);
})->orderBy('created_at', 'DESC');
}

Categories