how to write following query in cakephp 2.x - cakephp

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');

Related

CakePHP - select from database with condition

I have this selector:
$this->Table->find('list',array('contain'=>false,'conditions'=>array('status'=>1,'unit_id'=>null,'country_id'=>$countryId,'eday'=>$eday),'fields'=>'id'));
And this works perfect. But now i need to have another one i cant find how to do this ;)
I need to select all records from Table but with condition:
'eday'>=$eday AND 'eday'<$eday+7
Its this posibble in easy way? Maybe this is stupid question but i dont have exp in PHP ;)
In cakephp the equivalent for and condition is
Example: column1 = 'value' AND column2 = 'value'
'AND' => array(
'column1' => 'value',
'column2' => 'value'
)
So your query builder would be like this
$this->Table->find('list',array(
'contain' => false,
'conditions' => array(
'status' => 1,
'unit_id' => null,
'country_id' => $country,
'AND' => array(
'eday >=' => $eday,
'eday <' => ($eday+7)
)
),
'fields'=>'id'
));
Just pass an AND array with in your current conditions array :
$this->Table->find('list',array('contain'=>false, 'conditions'=>array('status'=>1,'unit_id'=>null,'country_id'=>$countryId,'eday'=>$eday, AND => array( array('eday >=' => $eday) , array( 'eday <' => $eday+7) )), 'fields'=>'id' ));
Have you tried something like this :
$conditions['status'] = 1;
$conditions['unit_id'] = null;
$conditions['country_id'] = $countryId;
$conditions['eday >='] = $eday;
$conditions['eday <'] = $eday + 7;
$this->Table
->find('list') //either use this
->find('all') //or use this
->find() //or this
->where($conditions)
->select(['addFiledsToSelectHere'])
This looks more cleaner.

CakePHP HABTM queries

What's the CakePHP way to do such queries?
SELECT news.* FROM news, users
INNER JOIN news_users nu ON nu.user_id = users.id
WHERE users.id = $user_id
I have a link table news_users, so trying with something like $news = $this->News->findByUserId($this->User->id); does not work, because it looks for news.user_id
P.S. The above query works, I just desire to make the script shorter.
You can declare findByUserId function in your News model:
//put this code in your News model
public function findByUserId($user_id = null)
{
return $this->find('all', array(
'conditions' => array(
'NewsUser.user_id' => $user_id
),
'joins' => array(
array(
'table' => 'news_users',
'alias' => 'NewsUser',
'type' => 'INNER',
'conditions' => array(
'NewsUser.news_id = News.id'
)
)
)
));
}
Then you can use your findByUserId function enywhere in your NewsController
//this code in NewsController
$news = $this->News->findByUserId($this->User->id);

Join query using two table with where condition in cake php?

How we can write Join query using two table with where condition in cake php?
You can!!
check this if it would help you
$table = 'table_name';
$query['conditions'] = array($table.'.entity_id' => $entity_id, $table.'.is_active' => 1);
$query['fields'] = array('creator.first_name AS cf_name', 'creator.last_name AS cl_name', 'creator.email AS c_email', 'usr.first_name', 'usr.last_name',
$table.'.id AS id', $table.'.guid', $table.'.updated_date',
'usr.email AS email');
// To do joining to get attribute with value
$query['joins'] = array(
array(
'table' => $this->user,
'alias' => 'usr',
'type' => 'INNER',
'conditions' => array('usr.id = '.$table.'.user_id')
),
array(
'table' => $this->user,
'alias' => 'creator',
'type' => 'INNER',
'conditions' => array('creator.id = '.$table.'.creator_id')
),
);
$query['order'] = array($table.'.updated_date' => 'DESC');
// Cache implementation
$result = $this->find('all', $query);

Cakephp IN(x,x) with 'AND'

I am struggeling with a custom find in cakephp 2.1.
In my model I have this function:
public function findByGenres($data = array()) {
$this->Item2genre->Behaviors->attach('Containable', array('autoFields' => false));
$this->Item2genre->Behaviors->attach('Search.Searchable');
$query = $this->Item2genre->getQuery('all', array(
'conditions' => array('Genre.name' => $data['genre']),
'fields' => array('item_id'),
'contain' => array('Genre')
));
return $query;
}
This returns the following query:
SELECT `Item`.`id` FROM `items` AS `Item`
WHERE `Item`.`id`
IN(SELECT `Item2genre`.`item_id` FROM `item2genre` AS Item2genre
LEFT JOIN `genres` AS Genre ON(`genre_id` = `Genre`.`id`)
WHERE `Genre`.`name`
IN ('Comedy', 'Thriller')
)
The result of the query returns Items with either 'Comedy' or 'Thriller' genre associated to them.
How can I modify the query to only return Items with 'Comedy' AND 'Thriller' genre associated to them?
Any suggestions?
edit:
content of data is:
'genre' => array(
(int) 0 => 'Comedy',
(int) 1 => 'Thriller'
)
You would want your 'conditions' key to be this:
'conditions' => array(
array('Genre.name' => 'Comedy'),
array('Genre.name' => 'Thriller')
)
So specifically to your problem your $data['genre'] is array('Comedy', 'Thriller'). So you could create a variable that has contents similar to what you need by doing:
$conditions = array();
foreach ($data['genre'] as $genre) {
$conditions[] = array('Genre.name' => $genre);
}

Cakephp $this->paginate with custom JOIN and filtering options

I've been working with cakephp paginations options for 2 days. I need to make a INNER Joins to list a few fields, but I have to deal with search to filter results.
This is portion of code in which I deal with search options by $this->passedArgs
function crediti() {
if(isset($this->passedArgs['Search.cognome'])) {
debug($this->passedArgs);
$this->paginate['conditions'][]['Member.cognome LIKE'] = str_replace('*','%',$this->passedArgs['Search.cognome']);
}
if(isset($this->passedArgs['Search.nome'])) {
$this->paginate['conditions'][]['Member.nome LIKE'] = str_replace('*','%',$this->passedArgs['Search.nome']);
}
and after
$this->paginate = array(
'joins' => array(array('table'=> 'reservations',
'type' => 'INNER',
'alias' => 'Reservation',
'conditions' => array('Reservation.member_id = Member.id','Member.totcrediti > 0' ))),
'limit' => 10);
$this->Member->recursive = -1;
$this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
$this->paginate['fields'] = array('DISTINCT Member.id','Member.nome','Member.cognome','Member.totcrediti');
$members = $this->paginate('Member');
$this->set(compact('members'));
INNER JOIN works good, but $this->paginations ignore every $this->paginate['conditions'][] by $this->passedArgs and I cannot have idea how I can work it out.
No query in debug, just the original INNER JOIN.
Can someone helps me ?
Thank you very much
Update:
No luck about it.
I've been dealing with this part of code for many hours.
If I use
if(isset($this->passedArgs['Search.cognome'])) {
$this->paginate['conditions'][]['Member.cognome LIKE'] = str_replace('*','%',$this->passedArgs['Search.cognome']);
}
$this->paginate['conditions'][]['Member.sospeso'] = 'SI';
$this->Member->recursive = 0;
$this->paginate['fields'] = array(
'Member.id','Member.nome','Member.cognome','Member.codice_fiscale','Member.sesso','Member.region_id',
'Member.district_id','Member.city_id','Member.date','Member.sospeso','Region.name','District.name','City.name');
$sospesi = $this->paginate('Member');
everything goes well, and from debug I receive the first condition and the conditions from $this->paginate['conditions'][]['Member.cognome LIKE'], as you can see
array $this->passedArgs
Array
(
[Search.cognome] => aiello
)
Array $this->paginate['conditions'][]
(
[0] => Array
(
[Member.cognome LIKE] => aiello
)
[1] => Array
(
[Member.sospeso] => NO
)
But, if I write the joins with paginate , $this->paginate['conditions'][] will ignore all the stuff, and give me from debug, just $this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
Another bit of information.
If I put all the stuff dealing with $this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
before the $this->paginate JOIN, nothing will be in $this->paginate['conditions'][].
This is an old question, so I'll just review how to do a JOIN in a paginate for others who got here from Google like I did. Here's the sample code from the Widget's Controller, joining a Widget.user_id FK to a User.id column, only showing the current user (in conditions):
// Limit widgets shown to only those owned by the user.
$this->paginate = array(
'conditions' => array('User.id' => $this->Auth->user('id')),
'joins' => array(
array(
'alias' => 'User',
'table' => 'users',
'type' => 'INNER',
'conditions' => '`User`.`id` = `Widget`.`user_id`'
)
),
'limit' => 20,
'order' => array(
'created' => 'desc'
)
);
$this->set( 'widgets', $this->paginate( $this->Widget ) );
This makes a query similar to:
SELECT widgets.* FROM widgets
INNER JOIN users ON widgets.user_id = users.id
WHERE users.id = {current user id}
And still paginates.
I'm not sure if you need those [] - try just doing this:
$this->paginate['conditions']['Reservation.pagamento_verificato'] = 'SI';
I use the conditions when I call paginate method.
$this->paginate($conditions)
This works ok for me, I hope it works for you!
If you have setted previous params, you may use:
$this->paginate(null,$conditions)
This might be help full to someone....
This is how I did complicated joins with pagination in cakephp.
$parsedConditions['`Assessment`.`showme`'] = 1;
$parsedConditions['`Assessment`.`recruiter_id`'] = $user_id;
$this->paginate = array(
'conditions' => array($parsedConditions ),
'joins' => array(
array(
'alias' => 'UserTest',
'table' => 'user_tests',
'type' => 'LEFT',
'conditions' => '`UserTest`.`user_id` = `Assessment`.`testuser_id`'
),
array(
'alias' => 'RecruiterUser',
'table' => 'users',
'type' => 'LEFT',
'conditions' => '`Assessment`.`recruiter_id` = `RecruiterUser`.`id`'
)
,
array(
'alias' => 'OwnerUser',
'table' => 'users',
'type' => 'LEFT',
'conditions' => '`Assessment`.`owner_id` = `OwnerUser`.`id`'
)
),
'fields' => array('Assessment.id', 'Assessment.recruiter_id', 'Assessment.owner_id', 'Assessment.master_id', 'Assessment.title', 'Assessment.status', 'Assessment.setuptype','Assessment.linkkey', 'Assessment.review', 'Assessment.testuser_email', 'Assessment.counttype_2', 'Assessment.bookedtime', 'Assessment.textqstatus', 'Assessment.overallperc', 'UserTest.user_id', 'UserTest.fname', 'UserTest.lname', 'RecruiterUser.company_name', 'OwnerUser.company_name'),
'limit' => $limit,
'order'=> array('Assessment.endtime' => 'desc')
);

Resources