get records with 2 not like conditions in cakephp3 - cakephp

This query doesnt work as expected. What happens it will select records with the word assessment in it. I have tried a few variations but as you can see the query should only get records with the word 'maths' and exclude records with 'scholarship' and 'assessment'.
I cant get this to work in cakephp3. What happens is that i get records with the words assessment or scholarship.
$subjectMaths = $this->Students->Subjects->find('list')
->select(['id', 'name'])
->where([
'Subjects.name not LIKE' => '%assessment%' ,
'Subjects.name LIKE' => '%maths%',
'Subjects.name not LIKE' => '%scholarship%'
])
->order(['Subjects.name' => 'asc']);
$subjectMaths = $this->Students->Subjects->find('list')
->select(['id', 'name'])
->where([
'Subjects.name LIKE' => '%maths%',
'OR'=> [
['Subjects.name not LIKE' => '%assessment%' ],
[ 'Subjects.name not LIKE' => '%scholarship%',]
]
])
->order(['Subjects.name' => 'asc']);

the proble here is that you have two identical array keys Subjects.name not LIKE. The second overwrites the first
So you havw to use AndWhere()
$subjectMaths = $this->Students->Subjects->find('list')
->select(['id', 'name'])
->where(['Subjects.name not LIKE' => '%assessment%'])
->andWhere(['Subjects.name LIKE' => '%maths%'])
->andWhere(['Subjects.name not LIKE' => '%scholarship%'])
->order(['Subjects.name' => 'asc']);

Related

How to add multiple conditions for a single column?

I have many sentences that I need filter for a same column:
'conditions' => array('Zona.nombre LIKE' => $buscar,
'Zona.nombre LIKE' => 'CUPONATIC%',
'Zona.nombre LIKE' => 'GROUPON%'
),
your question is not very clear but I suppose the problem is that you use multiple time the same array key
You don't even mention the cakephp version but it seems cake2
If I remember well the workaround for cake2 is putting every condition in a different array
'conditions' => array(
array('Zona.nombre LIKE' => $buscar),
array('Zona.nombre LIKE' => 'CUPONATIC%'),
array('Zona.nombre LIKE' => 'GROUPON%')
),
edit: of course this way you'll have the 3 conditions joined in AND.
It seems more logical to put them in OR so
'conditions' => array(
'OR' => array(
array('Zona.nombre LIKE' => $buscar),
array('Zona.nombre LIKE' => 'CUPONATIC%'),
array('Zona.nombre LIKE' => 'GROUPON%')
)
),

retreiving fields from asscoaied models cakephp3

I dont understand from the docs why I cant retrieve selected fields from associated data.
I have 2 many to many relationships in the contain which displays everything fine.
$query3 = $this->find()
->contain(['Subjects','AvailabilityForStudents'])
->select([
'Students.id','Students.first_name','Students.last_name','Students.address_billing','Students.address_lat','Students.address_long',
'Students.class_year','Students.address_street','Students.address_suburb','Students.address_postcode','Students.address_state'])
->where(['Students.id IN' => $stids])
->order(['Students.first_name' => 'ASC'])
->hydrate(true);
My Question is that instead of getting every field from the contained models why cant I select fields from the contained model as below? I am not selecting based on a criteria like in matching clause?
$query3 = $this->find()
->contain(['Subjects','AvailabilityForStudents'])
->select(['Subjects.name','Subjects.id','AvailabilityForStudents.id',
'Students.id','Students.first_name','Students.last_name','Students.address_billing','Students.address_lat','Students.address_long',
'Students.class_year','Students.address_street','Students.address_suburb','Students.address_postcode','Students.address_state'])
->where(['Students.id IN' => $stids])
->order(['Students.first_name' => 'ASC'])
->hydrate(true);
//student model
$this->hasMany('AvailabilityForStudents', [
'className' => 'AvailabilityForStudents',
'foreignKey' => 'student_id',
'dependent' => false,
]);
$this->belongsToMany('Subjects', [
'foreignKey' => 'student_id',
'targetForeignKey' => 'subject_id',
'joinTable' => 'subjects_students'
]);
//update contain
$query3 = $this->find()
->contain([
'Subjects'=>['fields'=>['name','id','SubjectsStudents.student_id']],
'AvailabilityForStudents' ])
// ->contain(['Subjects','AvailabilityForStudents'])
->where(['Students.student_unallocated' => 1,'Students.student_inactive' => 0])
->order(['Students.first_name' => 'ASC'])
->hydrate(true);
https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html
You are doing right.
You can try this also,
$query3 = $this->find()
->contain([
'Subjects'=>['fields'=>['name','id','SubjectsStudents.student_id']],
'AvailabilityForStudents'=>['fields'=>'id']
])
->select(['Students.id','Students.first_name','Students.last_name','Students.address_billing','Students.address_lat','Students.address_long',
'Students.class_year','Students.address_street','Students.address_suburb','Students.address_postcode','Students.address_state'])
->where(['Students.id IN' => $stids])
->order(['Students.first_name' => 'ASC'])
->hydrate(false)->toArray();

Search with concat fields in cakephp 3

I need to make a search query using $this->Paginate in CakePHP 3. Following is the code I am using
$searchCondition = array(
'OR' => array(
'Quotes.quotenum LIKE' => "%" . $this->request->data['Quote']['keyword'] . "%",
'Branches.name LIKE' => '%' . $this->request->data['Quote']['keyword'] . '%',
'Contacts.fname LIKE' => '%' . $this->request->data['Quote']['keyword'] . '%',
'Contacts.lname LIKE' => '%' . $this->request->data['Quote']['keyword'] . '%',
'CONCAT(Contacts.fname, Contacts.lname) LIKE' => '%' . $this->request->data['Quote']['keyword'] . '%',
'Quotes.description LIKE' => '%' . $this->request->data['Quote']['keyword'] . '%'
)
);
$cond = array(
'conditions' => array_merge($searchConditions, $searchCondition, $limo),
'order'= > array('Quotes.quotenum desc'),
'contain' => array('Branches','Contacts')
);
$this->set('articleList', $this->paginate($this->Quotes));
As you can see I merge the condition arrays with each other and then send them to paginate. This worked fine in CakePHP 2.7. However now I get the error
Column not found: 1054 Unknown column 'contacts.lname' in 'where clause'.
The lname column definitely exits in the database table. Is there something I am doing wrong. If so, could someone tell me the right way to do concat search as I have been trying to do this for quite some time.
Yu have to use query expression but this can't be done in a pagination array.
So Following ndn suggestion here's how I would do
create a custom finder. In your QuotesTable file
public function findByKeyword(Query $query, array $options)
{
$keyword = $options['keyword'];
$query->where(
function ($exp, $q) use($keyword){
$conc = $q->func()->concat([
'Contacts.fname' => 'literal', รน
'Contacts.lname' => 'literal']);
return $exp
->or_([
'Quotes.quotenum LIKE' => "%$keyword%",
'Branches.name LIKE' => "%$keyword%",
'Contacts.fname LIKE' => "%$keyword%",
'Contacts.lname LIKE' => "%$keyword%",
'Quotes.description LIKE' => "%$keyword%"
])
->like($conc, "%$keyword%");
}
);
return $query;
}
Then in your controller
$this->paginate = [
'finder' => [
'byKeyword' => [
'keyword' => $this->request->data['Quote']['keyword']
]],
'conditions' => $limo, // this will merge your $limo conditions
// with the ones you set in the custom finder
'order'= > ['Quotes.quotenum desc'],
'contain' => ['Branches','Contacts']
];
$this->set('articleList', $this->paginate($this->Quotes));

How to apply && between 3 $conditions[] ? in cakephp

In Cakephp how can i add apply 'AND' between these lines , $conditions[]= codition1 && codition2 && condition3;
$conditions[]= array('Flight.from LIKE' => "%".$this->request->data['Flight']['from']."%");
$conditions[]= array('Flight.to LIKE' => "%".$this->request->data['Flight']['to']."%");
$conditions[]= array('Flight.date LIKE' => "%".$this->request->data['Flight']['date']."%");
You can simplify your query by using:
$conditions = array(
'Flight.from LIKE' => "%".$this->request->data['Flight']['from']."%",
'Flight.to LIKE' => "%".$this->request->data['Flight']['to']."%",
'Flight.date LIKE' => "%".$this->request->data['Flight']['date']."%"
);
You don't actually need the arrays around each field when the conditions are on different fields. Plus CakePHP will automatically use AND between your conditions.
$conditions = array(
'AND' => array(
'Flight.from LIKE' => "%".$this->request->data['Flight']['from']."%",
'Flight.to LIKE' => "%".$this->request->data['Flight']['to']."%",
'Flight.date LIKE' => "%".$this->request->data['Flight']['date']."%"
)
);
Official docs and examples here.

CakePHP adding array elements to an array

I think I have my dumber-than-usual head on today.
I am trying to parse text from a textbox in a form to generate an array that I can pass to the find method in cakePHP.
I have used php regular expressions to generate an array of the terms entered (including "phrases included in speech marks" as single item)
This may look like this:
array(
(int) 0 => 'test',
(int) 1 => 'this out',
(int) 2 => 'now')
In the cakePHP cookbook it says that I have to get an array that looks like this (using above example):
array(
array('ProjectDocumentSectionVariable.variable_description LIKE' => '%test%'),
array('ProjectDocumentSectionVariable.variable_description LIKE' => '%this out%'),
array('ProjectDocumentSectionVariable.variable_description LIKE' => '%now%'))
Try as I might, I end up with arrays that do NOT look like an array of arrays.
Typically I am ending up with this horrible looking thing:
array(
(int) 0 => array(
'ProjectDocumentSectionVariable.variable_description LIKE' => '%test%'
),
(int) 1 => array(
'ProjectDocumentSectionVariable.variable_description LIKE' => '%this out%'
),
(int) 2 => array(
'ProjectDocumentSectionVariable.variable_description LIKE' => '%now%'
))
The code for the above is:
$i = 0;
foreach($matches[1] as $match) :
$searcharray['ProjectDocumentSectionVariable.variable_description LIKE'] = "%" . $match . "%";
array_push($array_full,$searcharray);
$i++;
endforeach;
THis must be a common requirement, so I am hoping one of you guys could put me on the straight an narrow...
Thanks
If you're trying to build a search query (not clear what your goal is), your conditions should all be in the same array within an OR or AND - something like this:
$searchResults = $this->find('all', array(
'conditions' => array(
'OR' => array(
'ProjectDocumentSectionVariable.variable_description LIKE' => '%test%',
'ProjectDocumentSectionVariable.variable_description LIKE' => '%this out%',
'ProjectDocumentSectionVariable.variable_description LIKE' => '%now%'
)
)
));
If you want to build it out in a foreach() loop, you can do it something like this:
$conditions = array('OR' => array());
$matches = array('test', 'this out', 'now');
foreach($matches as $match) {
array_push($conditions['OR'], array('variable_description LIKE' => '%' . %match . '%'));
}
$searchResults = $this->find('all', array(
'conditions' => $conditions
));
its as simple as this:
$array= array();
foreach ( $colors as $c):
$uniques[] = $c;
endforeach;
not having the [] will treat it as a regular variable. This will append it to the array

Resources