Sympfony Request (AndWhere, OrWhere) with conditions - php

I have 2 DQL queries
I want the user (with a select form) to be able to select:
1 filter at a time. Either party or city
or
several filters at the same time: party + city ... then others afterwards.
In summary :
In my database there are Party and City. With a form of select. The user must be able to choose the filters he wants. If he chose a particular Party without specifying the city, this will display all the Party in all the City. He can also choose a city, in which case he will have all the party of the chosen city. or 3rd case, he chose an Party + a City.
When one works the other is not.
I think I have a problem with my conditions and operators.
I read that using the orWhere () was bad practice.
Thanking you in advance.
public function searchByParty($party, $city)
{
$query = $this->createQueryBuilder('s');
$query = $query
->select( 'party', 'city', 's')
->join ('s.party', 'party ')
->join ('s.city', 'city');
if (!empty($party) === !empty($city)) {
$query = $query
->andWhere('party .id = :sport')
->andWhere('city.id = :city')
->setParameter('party ', $party )
->setParameter('city', $city);
}
if (!empty($party) && !empty($city)) {
$query = $query
->orWhere('party.id = :party')
->orWhere('city.id = :city')
->setParameter('party', $party )
->setParameter('city', $city);
}
return $query->getQuery()->getResult();

You have a logical issue. Your first if checks whether the existence of $party and $city is equivalent, which is true if and only if both exists or both does not exist. It does not make sense to check for their value if they both do not exist. The second if checks whether neither is defined. In that case it does not make sense to check the value against them. Fix:
public function searchByParty($party, $city) {
$query = $this->createQueryBuilder('s');
$query = $query
->select( 'party', 'city', 's')
->join ('s.party', 'party ')
->join ('s.city', 'city');
if (!empty($party)) {
$query = $query
->andWhere('party .id = :sport')
->setParameter('party ', $party )
}
if (!empty($city)) {
$query = $query
->andWhere('city.id = :city')
->setParameter('city', $city);
}
return $query->getQuery()->getResult();
}
EDIT: if you want to check whether any of them matches, then use orWhere:
public function searchByParty($party, $city) {
$query = $this->createQueryBuilder('s');
$query = $query
->select( 'party', 'city', 's')
->join ('s.party', 'party ')
->join ('s.city', 'city');
if (!empty($party)) {
$query = $query
->orWhere('party .id = :sport')
->setParameter('party ', $party )
}
if (!empty($city)) {
$query = $query
->orWhere('city.id = :city')
->setParameter('city', $city);
}
return $query->getQuery()->getResult();
}

Solution :
public function searchBySession($party, $city)
{
$query = $this->createQueryBuilder('s');
$query = $query
->select( 's');
if($party){
$query = $query
->join ('s.party', 'party')
->addSelect('party')
->andWhere('party.id = :party')
->setParameter('party', $party)
;
}
if($city){
$query = $query
->join ('s.city', 'city')
->addSelect('city')
->andWhere('city.id = :city')
->setParameter('city', $city)
;
}
return $query->getQuery()->getResult();
}
Thanks you

Related

I need help to turn some raw SQL into Eloquent code

As the title says, I'm having trouble turning my SQL code into Eloquent.
Here's the raw SQL:
select * from `students`
where (
select status_student.id from `status_student`
WHERE
status_student.id = (SELECT MAX(status_student.id) from `status_student`
WHERE
status_student.student_id = students.id)
AND
status_student.status_id = 6
)
IS NOT NULL;
and here's the code so far:
$status = $this->request->get('status');
if ($status !== "0") {
dd($query = Student::where(function($q) use($status){
$q->where('status_student.id', function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
});
})->toSql());
}
which translates into SQL:
"select * from `students` where (`status_student`.`id` = (select MAX(status_student.id) where `status_student`.`student_id` = ? and `status_student`.`status_id` = ?))
so it's not working properly yet.
I'm having trouble introducing that IS NOT NULL clause and doing
select status_student.id from 'status_student'
instead of just
status_student.id =
How should I modify my code to get the desired SQL?
Thanks.
$status = request()->get('status');
if ($status !== "0") {
dd($query = Student::where(function($q) use($status){
$q->where([['status_student.id' => function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
}],
['status_student.id', '<>', null]
]);
})->toSql());
}
Generated SQL query:
SELECT *
FROM `students`
WHERE (((`status_student`.`student_id` = ?
AND `status_student`.`status_id` IS NULL)
AND `status_student`.`id` IS NOT NULL))
Not sure if I understanded you correctly but I assume you just didn't get the syntax right
try this one:
$status = $this->request->get('status');
if ($status !== "0") {
// log the queries:
\DB::enableQueryLog();
$query = Student::with([
'statusStudent' => function($q1) use($status) {
$q1->where('status_student.id', function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
});
}
])
->get();
$pureQuery = \DB::getQueryLog();
dd($pureQuery);
}
If you would like to join in eloquent, you must use with() or load() to do that.

Codeigniter display TYPE_LABLE from TYPE table if result equal to specific CATEGORY

I'm working on Codeigniter rest API project and came across a problem. I would like my model to select additional data by condition.
if CATEGORY equals $CATEGORY show TYPE.TYPE_LABLE
otherwise just don't show "TYPE.TYPE_LABLE"
so how can i get this result?
thank you for your help.
function get_data() {
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
$CATEGORY = array('CATEGORY1', 'CATEGORY2', 'CATEGORY3', 'CATEGORY4');
$types = array('type_1', 'type_2');
if ($id != null) {
$this->db->where('ID',$id);
//selct TYPE.TYPE_LABLE if CATEGORY equals $CATEGORY
$this->db->select('POST.ID, POST.DATE, TYPE.Post_Type as P_TYPE, TYPE.TYPE_LABLE$CATEGORY', FALSE);
$this->db->join('TYPE', 'POST.TYPE_ID = TYPE.ID', 'left');
$this->db->join('CATEGORY', 'POST.CATEGORY_ID = CATEGORY.ID', 'left');
$this->db->order_by('POST.ID', 'DESC');
$this->db->where_in('POST.Post_Type', $types);
$this->db->where('POST.DATE >', date('Y-m-d', strtotime('01-01-2019')) );
$this->db->from('POST');
$result = $this->db->get();
}
return $result;
}

Doctrine - conditional andWhere in query

I want to bind a condition in my function. I have a function MarketersGet which give me marketers name . Here is my code :
public function MarketersGet(string $marketerId = ''):array
{
$marketerId = (int)$marketerId;
$userRoles = config('constantTypes.blah');
$marketerRole = $userRoles['MARKETER'];
$userRepository = App::make( DoctrineUserRepo::class );
$result = $userRepository
->selectFrom(' model ')
->where(' model.rolesRole = '.$marketerRole)
->getQuery()
->getResult();
$marketers = [];
foreach ($result as $user) {
$marketers[] = [
'name' => $user->getUserName(),
'id' => $user->getId()
];
}
return $marketers;
}
I want to conditional on $marketerId, if it has value I added
->andWhere(' model.id = '.$marketerId)
I tried like this :
$result = $userRepository
->selectFrom(' model ')
->where(' model.rolesRole = '.$marketerRole);
if ($marketerId != '')
$result->andWhere(' model.id = '.$marketerId);
$result->getQuery()
->getResult();
Above result is :
[]
No Properties
Actually if I put andWhere in default query like this :
$result = $userRepository
->selectFrom(' model ')
->where(' model.rolesRole = '.$marketerRole)
->andWhere(' model.id = '.$marketerId)
->getQuery()
->getResult();
Real result would be like this :
{name: "blah blah", id: 28}
Surely my conditional query is false , Any suggestion to resolve it?
No way to tell if this might make any difference but you might try it:
$result = $userRepository
->selectFrom(' model ')
->where(' model.rolesRole = '. $marketerRole);
if( isset($marketerId) && $marketerId){
$result->where(' model.id = '.$marketerId);
}
$result->getQuery()
->getResult();
You can use this approach. If marketedId is empty string - andWhere has no effect. It always passing. But if it has value then model.id condition is checked.
$result = $userRepository
->selectFrom(' model ')
->where(' model.rolesRole = '.$marketerRole)
->andWhere(':marketerId = "''" OR model.id = :marketerId')
->setParameter('marketerId', $marketerId)
->getQuery()
->getResult();

Is it possible to split query builder in Laravel?

Is it possible to split queries somehow like this?
public function getStatuses($dates)
{
$query = DB::table('tickets');
if ($dates['from'])
$query = $query->where('from', $dates['from']);
if ($dates['to'])
$query = $query->where('to', $dates['to']);
$query = $query->select('Active');
return $query->get()->toArray();
}
Yes, it's possibile. But don't reassign to the same variable or you risk messing it up:
public function getStatuses($dates)
{
$query = DB::table('tickets');
if ($dates['from'])
$query->where('from', $dates['from']);
if ($dates['to'])
$query->where('to', $dates['to']);
$query->select('Active');
return $query->get()->toArray();
}
In Laravel 4, its necessary to assign the get method to a variable
public function scopeGetPosts($query, $this_user = NULL){
$results = DB::table('post')
->select('*')
->where('post_status','=','publish');
if( $this_user != NULL ){
$results->where('post_author','=',$this_user->user_id);
}
$data = $results->orderBy('created_at', 'desc')
->get();
if( empty( $results ) )
$data = 'no results';
return $data;
}
In Laravel Eloquent :
$query = ModelName::where('status',1);
if($userId){
$query->where('user_id',$userId);
}
if($limit){
$query->limit($limit);
}
$result = $query->get();

How to JOIN three tables in Codeigniter

I'm using codeigniter framework to develop one music cms. i have 3 tables in mysql database, Currently im working in "Album" Table and "Model, Controller". i want to SELECT "Album" Table 1 and JOIN "Album" -> "cat_id" with "Category" -> "cat_id", and fetch all categories records.
Then i want to JOIN "Album" -> "album_id" on "Soundtrack" -> "album_id" then fetch all soundtrack records A to Z.
Please somebody help me to show proper codeigniter query, how i can SELECT and JOIN Tables then fetch records from 3 tables, ?
Table 1 -> Category
cat_id
cat_name
cat_title
date
Table 2 -> Album
cat_id
album_id
album_title
album_details
Table 3 -> Soundtrack
album_id
track_title
track_url
date
Use this code in model
public function funcname($id)
{
$this->db->select('*');
$this->db->from('Album a');
$this->db->join('Category b', 'b.cat_id=a.cat_id', 'left');
$this->db->join('Soundtrack c', 'c.album_id=a.album_id', 'left');
$this->db->where('c.album_id',$id);
$this->db->order_by('c.track_title','asc');
$query = $this->db->get();
if($query->num_rows() != 0)
{
return $query->result_array();
}
else
{
return false;
}
}
try this
In your model
If u want get all album data use
function get_all_album_data() {
$this->db->select ( '*' );
$this->db->from ( 'Album' );
$this->db->join ( 'Category', 'Category.cat_id = Album.cat_id' , 'left' );
$this->db->join ( 'Soundtrack', 'Soundtrack.album_id = Album.album_id' , 'left' );
$query = $this->db->get ();
return $query->result ();
}
if u want to get specific album data use
function get_album_data($album_id) {
$this->db->select ( '*' );
$this->db->from ( 'Album' );
$this->db->join ( 'Category', 'Category.cat_id = Album.cat_id' , 'left' );
$this->db->join ( 'Soundtrack', 'Soundtrack.album_id = Album.album_id' , 'left' );
$this->db->where ( 'Album.album_id', $album_id);
$query = $this->db->get ();
return $query->result ();
}
Try this one for data...
function get_album_data() {
$this->db->select ( 'album.*,cat.*,s_track.*' )
->from ( 'albums as album' )
->join ( 'categories cat', 'cat.cat_id = album.cat_id')
->join ( 'soundtracks s_tracks ', 's_tracks.album_id = album.album_id');
$query = $this->db->get ();
return $query->result ();
}
while for datum try this...
function get_album_datum($album_id) {
$this->db->select ( 'album.*,cat.*,s_track.*' )
->from ( 'albums as album' )
->join ( 'categories cat', 'cat.cat_id = album.cat_id')
->join ( 'soundtracks s_tracks ', 's_tracks.album_id = album.album_id');
$this->db->where ( 'album.album_id', $album_id);
$query = $this->db->get ();
return $query->row();
}7
855788
Check bellow code it`s working fine and common model function also
supported more then one join and also supported multiple where condition
order by ,limit.it`s EASY TO USE and REMOVE CODE REDUNDANCY.
================================================================
*Album.php
//put bellow code in your controller
=================================================================
$album_id='';//album id
//pass join table value in bellow format
$join_str[0]['table'] = 'Category';
$join_str[0]['join_table_id'] = 'Category.cat_id';
$join_str[0]['from_table_id'] = 'Album.cat_id';
$join_str[0]['join_type'] = 'left';
$join_str[1]['table'] = 'Soundtrack';
$join_str[1]['join_table_id'] = 'Soundtrack.album_id';
$join_str[1]['from_table_id'] = 'Album.album_id';
$join_str[1]['join_type'] = 'left';
$selected = "Album.*,Category.cat_name,Category.cat_title,Soundtrack.track_title,Soundtrack.track_url";
$albumData= $this->common->select_data_by_condition('Album', array('Soundtrack.album_id' => $album_id), $selected, '', '', '', '', $join_str);
//call common model function
if (!empty($albumData)) {
print_r($albumData); // print album data
}
=========================================================================
Common.php
//put bellow code in your common model file
========================================================================
function select_data_by_condition($tablename, $condition_array = array(), $data = '*', $sortby = '', $orderby = '', $limit = '', $offset = '', $join_str = array()) {
$this->db->select($data);
//if join_str array is not empty then implement the join query
if (!empty($join_str)) {
foreach ($join_str as $join) {
if ($join['join_type'] == '') {
$this->db->join($join['table'], $join['join_table_id'] . '=' . $join['from_table_id']);
} else {
$this->db->join($join['table'], $join['join_table_id'] . '=' . $join['from_table_id'], $join['join_type']);
}
}
}
//condition array pass to where condition
$this->db->where($condition_array);
//Setting Limit for Paging
if ($limit != '' && $offset == 0) {
$this->db->limit($limit);
} else if ($limit != '' && $offset != 0) {
$this->db->limit($limit, $offset);
}
//order by query
if ($sortby != '' && $orderby != '') {
$this->db->order_by($sortby, $orderby);
}
$query = $this->db->get($tablename);
//if limit is empty then returns total count
if ($limit == '') {
$query->num_rows();
}
//if limit is not empty then return result array
return $query->result_array();
}
Try as follows:
public function funcname($id)
{
$this->db->select('*');
$this->db->from('Album a');
$this->db->join('Category b', 'b.cat_id=a.cat_id', 'left');
$this->db->join('Soundtrack c', 'c.album_id=a.album_id', 'left');
$this->db->where('c.album_id',$id);
$this->db->order_by('c.track_title','asc');
$query = $this->db->get();
return $query->result_array();
}
If no result found CI returns false otherwise true
public function getdata(){
$this->db->select('c.country_name as country, s.state_name as state, ct.city_name as city, t.id as id');
$this->db->from('tblmaster t');
$this->db->join('country c', 't.country=c.country_id');
$this->db->join('state s', 't.state=s.state_id');
$this->db->join('city ct', 't.city=ct.city_id');
$this->db->order_by('t.id','desc');
$query = $this->db->get();
return $query->result();
}

Categories