How to concatenate condition array in cakephp - cakephp

To get the DB result in basis of condition
if($keyword!='')
build condition;
/*
array('conditions' => array("AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%",
"esl.esl_songname LIKE"=>"%".$songname."%")),
'limit' => $arrFind['limit'],
'page'=>$arrFind['page']));
*/
if(!name!='')
/*
array('conditions' => array("esl.esl_artistname LIKE"=>"%".$artistname."%"),
'limit' => $arrFind['limit'],
'page'=>$arrFind['page'] ))
*/
$this->find('all',condition);
how to do this? how to concatenate both conditions?

Why not initialize the conditions array and just append to it?
$conditions = array();
if( keyword != '' ) {
array_push(
'conditions'
, array( "AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%", "esl.esl_songname LIKE"=>"%".$songname."%" ) )
}
if( !name != '' ) {
array_push( 'conditions', array("esl.esl_artistname LIKE"=>"%".$artistname."%")
}
$this->find( 'all', array( 'conditions' => $conditions, 'limit' => $arrFind['limit'], 'page' => $arrFind['page'];

I would do something like Rob Wilkerson suggested but like this:
$conditions = array();
if(keyword != '') {
$conditions[] = array( "AND" => array ("esl.esl_artistname LIKE"=>"%".$artistname."%", "esl.esl_songname LIKE"=>"%".$songname."%" ) );
}
if(!name != '') {
$conditions[] = array("esl.esl_artistname LIKE"=>"%".$artistname."%");
}
$this->find( 'all', array( 'conditions' => $conditions, 'limit' => $arrFind['limit'], 'page' => $arrFind['page'];

Concatenating condition could be done in following way:
$condition1 = array('Model1.field1 LIKE'=>'%'.$value.'%', 'Model1.field2'=>2);
$condition2 = array('Model2.field2 LIKE'=>'%'.$value.'%', 'Model2.field2'=>1);
$this->MyModel->find('all', array('conditions'=>am($condition1, $condition2)));
am is the cake's shortcut to array_merge.

Related

how to write following query in cakephp 2.x

SELECT categories.category_name, categories.status, experts.name, experts.email, expert_categories.category_id, expert_categories.expert_id
FROM categories, experts, expert_categories
WHERE expert_categories.category_id = categories.id AND expert_categories.expert_id = experts.id AND categories.status = 'A'
If you know what you want then go with prepared statement:
$db = $this->Category->getDataSource(); // if you make function in categories controller
// $db = $this->getDataSource(); // if you make function in any model
$result = $db->fetchAll("SELECT categories.category_name,categories.status,
experts.name, experts.email, expert_categories.category_id,
expert_categories.expert_id FROM categories, experts, expert_categories
WHERE expert_categories.category_id = categories.id AND
expert_categories.expert_id = experts.id AND categories.status = 'A'");
// debug($result);
That is why cakephp prepared statement are made.
See here: Cakephp2 prepared statement.
$this->Category->ExpertCategory->bindModel(array('belongsTo' => array(
'Category' => array(
'foreignKey' => false,
'type'=>'INNER',
'conditions' => array(
'Category.id = ExpertCategory.category_id
ExpertCategory.category_id = ' . $cat_id . ' and
Category.status = "A"'
)
),
'Expert' => array(
'foreignKey' => false,
'type'=>'INNER',
'conditions' => array(
'Expert.id = ExpertCategory.expert_id'
)
)
)), false);
$allExpertArr = $this->Category->ExpertCategory->find('all');

CakeDC search plugin not working, no errors

I am working on view which displays all reservations(I am making reservations app) and has form to search. I am using CakeDC Plugin, but it doesn't work.
Here is my action:
public function index() {
if (!App::import('Component', 'Search.Prg')) {
throw new MissingPluginException(array('plugin' => 'Search'));
}
$this->Prg->commonProcess();
//$this->Paginator->settings['conditions'] = $this->Reservation->parseCriteria(/*$this->Prg->parsedParams()*/);
//$this->set('users', $this->Paginator->paginate());
$searchTerm = '';
//$this->Prg->commonProcess($this->modelClass, $this->modelClass, 'search', false);
$by = null;
if (!empty($this->request->params['named']['searchTerm'])) {
$searchTerm = $this->request->params['named']['searchTerm'];
$by = 'any';
}
$this->request->data[$this->modelClass]['searchTerm'] = $searchTerm;
$this->set('reservation_mode', Configure::read('webakis.reservation_type'));
$this->Reservation->recursive = 0;
$this->paginate = array(
'fields' => array('Reservation.id', 'Reservation.start', 'Reservation.ucode', 'Reservation.ticket_nr', 'Location.name', 'User.username', 'User.id', 'Opmenu.name', 'Queue.name'),
'conditions' => array(
// 'ucode <>' => 0,
'user_id <>' => 0,
'deleted' => 0,
// 'start >=NOW() '
),
'order' => array(
'Reservation.start' => 'asc'
),
//'search',
'limit' => 12,
'by' => $by,
'search' => $searchTerm,
);
$this->set('reservations', $this->paginate($this->modelClass));
$this->set('searchTerm', $searchTerm);
$this->set('model', $this->modelClass);
}
My form in view:
<?php
echo $this->Form->create($model, array(
'action' => 'index'));
echo $this->Form->input('searchTerm', array(
'label' => false, 'style' => 'float:left;', 'class' => 'offset1'));
echo $this->Form->submit(__('Search'), array('class' => 'btn', 'style' => ''));
echo $this->Form->end();
?>
My code in Model:
public $actsAs = array('Search.Searchable');
public $filterArgs = array(
array('name' => 'searchTerm', 'type' => 'like', 'fields'=>array(/*'Reservation.start', 'Reservation.ucode', 'Reservation.ticket_nr', 'Location.name',*/ 'User.username'/*, 'Opmenu.name', 'Queue.name'*/)));
UPDATE:
I included this to make it work, but it's probably not best way:
$conditions = array();
$conditions[] = array("Reservation.start LIKE '%{$searchTerm}%'");
$conditions[] = array("Reservation.ucode LIKE '%{$searchTerm}%'");
$conditions[] = array("Reservation.ticket_nr LIKE '%{$searchTerm}%'");
$conditions[] = array("Location.name LIKE '%{$searchTerm}%'");
$conditions[] = array("User.username LIKE '%{$searchTerm}%'");
$conditions[] = array("Opmenu.name LIKE '%{$searchTerm}%'");
$conditions[] = array("Queue.name LIKE '%{$searchTerm}%'");
Ok, so after reading readme of my Plugin, I got it working.
Here is my Model code:
public $actsAs = array('Search.Searchable');
public $filterArgs = array(
'searchTerm' => array(
'type' => 'like',
'field'=>array('Reservation.start', 'Reservation.ucode', 'Reservation.ticket_nr', 'Location.name', 'User.username', 'Opmenu.name', 'Queue.name')),
'filter' => array('type' => 'query', 'method' => 'orConditions'));
public function orConditions($data = array()) {
$filter = $data['filter'];
$cond = array(
'OR' => array(
'Reservation.start LIKE' => '%' . $filter . '%',
'Reservation.ucode LIKE' => '%' . $filter . '%',
'Reservation.ticket_nr LIKE' => '%' . $filter . '%',
'Location.name LIKE' => '%' . $filter . '%',
'User.username LIKE' => '%' . $filter . '%',
'Opmenu.name LIKE' => '%' . $filter . '%',
'Queue.name LIKE' => '%' . $filter . '%'
));
return $cond;
}
Controller:
public $components = array('Search.Prg');
public $presetVars = true;
public function index() {
$this->Prg->commonProcess();
$this->paginate = array();
$conditions = $this->Reservation->parseCriteria($this->passedArgs);
$searchTerm = '';
$this->set('reservation_mode', Configure::read('webakis.reservation_type'));
$this->Reservation->recursive = 0;
$this->paginate = array(
'fields' => array('Reservation.id', 'Reservation.start', 'Reservation.ucode', 'Reservation.ticket_nr', 'Location.name', 'User.username', 'User.id', 'Opmenu.name', 'Queue.name'),
'conditions' => array(
// 'ucode <>' => 0,
'user_id <>' => 0,
'deleted' => 0,
// 'start >=NOW() '
),
'order' => array(
'Reservation.start' => 'asc'
),
'limit' => 12,
);
$this->set('reservations', $this->paginate($this->modelClass, $conditions));
$this->set('searchTerm', $searchTerm);
$this->set('model', $this->modelClass);
}

CakePHP find conditions with multiple 'OR'

I'm having a real headache getting this to work correctly. This is my desired outcome in raw MySQL:
WHERE `EmailTemplate`.`is_archived` = '0'
AND
((`EmailTemplate`.`project_id` IS NULL) OR (`EmailTemplate`.`project_id` = 101))
AND
((`EmailTemplate`.`user_id` IS NULL) OR (`EmailTemplate`.`user_id` = 44))
How does this translate into a CakePHP conditions array?
Solved this, eventually.
$templateConditions = array(
'EmailTemplate.is_archived' => 0,
'AND' => array(
'OR' => array(
array('EmailTemplate.project_id IS NULL'),
array('EmailTemplate.project_id' => $this->request->data['Project']['project_id'])
)
),
array(
'OR' => array(
array('EmailTemplate.user_id IS NULL'),
array('EmailTemplate.user_id' => $this->Auth->user('id'))
)
)
);

CakePHP find condition for a query between two dates

I have a start and an end date in my database and a $date variable from a form field. I am now trying to query all the rows where $date is either = start/end date in the db, or ANY date between those two.
It's kind of the opposite of what is described in the docs of how daysAsSql works. I can't figure out how to get it to work. The following line does not work as a find condition in the controller:
'? BETWEEN ? AND ?' => array($date, 'Item.date_start', 'Item.date_end'),
Any help is greatly appreciated. This is driving me crazy.
Here is the complete Query and corresponding SQL:
$conditions = array(
'conditions' => array(
'and' => array(
'? BETWEEN ? AND ?' => array($date, 'Item.date_start', 'Item.date_end'),
'Item.title LIKE' => "%$title%",
'Item.status_id =' => '1'
)));
$this->set('items', $this->Item->find('all', $conditions));
WHERE (('2012-10-06' BETWEEN 'Item.date_start' AND 'Item.date_end') AND (`Item`.`title` LIKE '%%') AND (`Item`.`status_id` = 1))
$conditions = array(
'conditions' => array(
'and' => array(
array('Item.date_start <= ' => $date,
'Item.date_end >= ' => $date
),
'Item.title LIKE' => "%$title%",
'Item.status_id =' => '1'
)));
Try the above code and ask if it not worked for you.
Edit:
As per #Aryan request, if we have to find users registered between 1 month:
$start_date = '2013-05-26'; //should be in YYYY-MM-DD format
$this->User->find('all', array('conditions' => array('User.reg_date BETWEEN '.$start_date.' AND DATE_ADD('.$start_date.', INTERVAL 30 DAY)')));
Here is CakePHP BETWEEN query example.
I'm defining my arrays as variables, and then using those variables in my CakePHP find function call:
// just return these two fields
$fields = array('uri', 'page_views');
// use this "between" range
$conditions = array('Event.date BETWEEN ? and ?' => array($start_date, $end_date));
// run the "select between" query
$results = $this->Event->find('all',
array('fields'=>$fields,
'conditions'=>$conditions));
Ref from
General Example For CakePHP 2.x Query
$_condition = array("TABLENAME.id" => $id, "TABLENAME.user_id" => array_unique($_array), 'date(TABLENAME.created_at) BETWEEN ? AND ?' => array($start_date, $end_date));
$result_array = $this->TABLENAME->find("all", array(
'fields' => array("TABLENAME.id", "TABLENAME.user_id", 'TABLENAME.created_at'),
"conditions" => $_condition,
"group" => array("TABLENAME.id"), //fields to GROUP BY
'joins' => array(
array(
'alias' => 'T2',
'table' => 'TABLENAME2',
'type' => 'LEFT',
'conditions' => array('TABLENAME.t_id = TABLENAME2.t_id')
),
array(
'alias' => 'T3',
'table' => 'TABLENAME3',
'type' => 'LEFT',
'conditions' => array(
'IF(
TABLENAME.t3_id > 0,
T2.f_id = T3.f_id,
TABLENAME.ff_id = T2.ff_id
)'
)
),
),
'recursive' => 0
)
);
This is more efficient and understandable IN BETWEEN query in cakephp 2.x
$testing_log_device_site_name = $testingLogData['TestingLogDevice']['Siteid'];
$conditions = array('TestingLogDevice.dateee BETWEEN ? and ?' => array($start_date, $end_date));
$results = $this->TestingLogDevice->find('all',
array(
'fields'=>array('dateee','timeee','Siteid'),
'conditions'=>array($conditions, 'TestingLogDevice.Siteid'=>$testing_log_device_site_name)
)
);
pr($results);
$data=$this->post->find('all')->where([ 'id'=>$id,
'price between'=>$price1,'and'=>$price2])->toArray();
This query works as following:
select * from post where id=$id and price between $price1 and $price2;
" -- 'price between'=>$price1 --" become "price between $price1"
Use this
$today = new DateTime( date('Y-m-d'));
$fiveYearsBack = $today->sub(new DateInterval('P5Y'));

How to Limit the paginate in cakephp

How to Limit the paginate in cakephp ?
Assume that i have 400 records.
I need to get only 25 records from 50th record to 75th record
and need to display 5 records per page.
How i can do this in paginate ?
Sample Code:
$this->paginate = array(
'contain'=>array('User'),
'recursive' => 2,
'order' => array('Profile.winning' => 'DESC'),
'limit' =>5
);
You can set conditions for the pagination.
function listRecords()
{
$this->paginate = array(
'conditions' => array('Model.id >=' => 50, 'Model.id <=' => 75),
'limit' => 5
);
$this->paginate('Model');
);
EDIT:
A solution from here:
$this->paginate = array(
'limit' => 20,
'totallimit' => 1000
);
And then in the Model:
public function paginateCount($conditions = null, $recursive = 0, $extra = array())
{
if( isset($extra['totallimit']) ) return $extra['totallimit'];
}
Improved version with reference of: http://www.mainelydesign.com/blog/view/best-paginatecount-cakephp-with-group-by-support
This return the correct total count base on whichever is less.
public function paginateCount($conditions = null, $recursive = 0, $extra = array())
{
$conditions = compact('conditions');
if ($recursive != $this->recursive) {
$conditions['recursive'] = $recursive;
}
unset( $extra['contain'] );
$count = $this->find('count', array_merge($conditions, $extra));
if (isset($extra['group'])) {
$count = $this->getAffectedRows();
}
if (isset($extra['totallimit']) && $extra['totallimit'] < $count) {
return $extra['totallimit'];
}
return $count;
}
Use maxLimit in CakePHP v2.x .
public $paginate = array(
// other keys here.
'maxLimit' => 10
);
read more about it here.
$query = $this->User->find('all', [
'recursive' => 2,
'order' => array('Profile.winning' => 'DESC'),
'limit' => 25,
'offset' => 50
]);
$this->paginate = array(
$query,
'limit' => 5
);
In cakephp 4.x version we have to call like below
public function index()
{
$this->loadComponent('Paginator');
$settings = array(
'limit' => 50
);
$prices = $this->Paginator->paginate($this->Prices->find(), $settings);
$this->set(compact('prices'));
}

Resources