Find CakePHP - different query criteria - cakephp

I have a simple search form with 3 data and now not all data needs to be filled, some may stay empty ...
as they filled :
$this->Praca->find('all',array(
'conditions'=>array(
'kategoria'=>$wyniki['kategoria'][0],
'wojewodztwo'=>$wyniki['wojewodztwo'],
'poziom'=>$wyniki['poziom']
)));
Now, fe. when $wyniki['kategoria'] is empty I must :
$this->Praca->find('all',array(
'conditions'=>array(
'wojewodztwo'=>$wyniki['wojewodztwo'],
'poziom'=>$wyniki['poziom']
)));
To many possibilities, I need to find a SMART way, any idea? :)

try this
$conditions = array();
if(!empty($wyniki['kategoria'][0])){
$conditions = array('kategoria'=>$wyniki['kategoria'][0]);
}
and so on...
........
$this->Praca->find('all', compact('conditions'));

In Fazel way you need to add conditions per each node. But case below you can add conditions as many as you want
$conditions = array();
$i=1;
foreach ($wyniki as $key=>$wyn){
if(!empty($wyniki[$key])){
$conditions[$i++] = array($key=>$wyn); //or array($key=>end($wyn))
}
}
$this->Praca->find('all',array('conditions'=>$conditions));

Related

How to put where conditions with group by in cakephp find all query

I have created sql query which is working fine.
But i want to convert this sql query in cakephp format.
I try to convert this query in cakephp but
i am not understanding how to apply where conditions with group by clause.
And i only need to select this column u_data.lane_id AS LaneId, origin_city.pcode AS origin_pcode, dest_city.pcode AS dest_pcode....
not all columns from table.
plz help me to do this.
$options['conditions'] = array(
'CustomerRoute.portfolio_id' => '".$_SESSION["portfolioid"]."'
);
$content = $this->Customer->find('all', $options);
You simply need to define "group" and "fields" within $options-
Instead of $_SESSION, you should stick to the convention and use $this->Session->read instead.
//Eg: $_SESSION["portfolioid"] can be replaced with $this->Session->read("portfolioid")
$options['conditions'] = array(
"CustomerRoute.portfolio_id" => $this->Session->read("portfolioid"),
"u_data.supplier_id" => $this->Session->read("supplierid")
);
$options['fields'] = array(
"u_data.lane_id AS LaneId",
"origin_city.pcode AS origin_pcode",
"dest_city.pcode AS dest_pcode"
); // Add this
$options['group'] = array('CustomerRoute.id'); // Add this
$content = $this->Customer->find('all', $options);
This should give you what you're looking for.
Peace! xD

CakePhp foreach saving only last value in array

I have a problem, right now Im using this foreach loop on CakePhp on which I want to add all the values which are still not on the table for the respecting user. To give a little more context, the user has a menu. And the admin can select which one to add for the user to use. On the next code I receive a array with the menus which will be added as so:
//This is what comes on the ['UserMenuAccessibility'] array:
Array ( [menu_accessibility_id2] => 2 [menu_accessibility_id3] => 3 [menu_accessibility_id4] => 4 [menu_accessibility_id5] => 5 [menu_accessibility_id8] => 8 )
I get the ids of the menus which want to be added to the table for the user to use. And I use the next code to add the menus to the table if they are not there still:
//I check if the array has something cause it can come with no ids.
if (!(isset($this->request->data['UserMenuAccessibility']))) {
$this->request->data['UserMenuAccessibility'] = array();
}
$UserMenuAccessibility = $this->request->data['UserMenuAccessibility'];
foreach ($UserMenuAccessibility as $key => $value) {
$conditions = array(
'UserMenuAccessibility.menu_accessibility_id' => $value,
'UserMenuAccessibility.users_id' => $id
);
if ($this->User->UserMenuAccessibility->hasAny($conditions)) {
} else {
$valuemenu['UserMenuAccessibility']['users_id'] = $id;
$valuemenu['UserMenuAccessibility']['menu_accessibility_id'] = $value;
if ($this->User->UserMenuAccessibility->save($valuemenu)) {
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
}
}
For some reason the array is only saving the last new id which is not on the table and not the rest. For example if I have menu 1 and 2 and add 3 and 4 only 4 gets added to the table. For some reason I cant add all the missing menu ids to the table. Any ideas why this is happening?
Thanks for the help on advance.
It looks like your code will save each item, but each call to save() is overwriting the last entry added as $this->User->UserMenuAccessibility->id is set after the first save and will be used for subsequent saves. Try calling $this->User->UserMenuAccessibility->create() before each save to ensure that the model data is reset and ready to accept new data:-
$valuemenu['UserMenuAccessibility']['users_id'] = $id;
$valuemenu['UserMenuAccessibility']['menu_accessibility_id'] = $value;
$this->User->UserMenuAccessibility->create();
if ($this->User->UserMenuAccessibility->save($valuemenu)) {
}
In cakephp 2.0 $this->Model->create() create work fine. But if you are using cakephp version 3 or greater then 3. Then follow the below code
$saveData['itemId'] = 1;
$saveData['qty'] = 2;
$saveData['type'] = '0';
$saveData['status'] = 'active';
$saveData = $this->Model->newEntity($saveData);
$this->Model->save($materialmismatch);
In normal case we use patchEntity
$this->Model->patchEntity($saveData, $this->request->data);
It will only save last values of array so you have to use newEntity() with data
In cakephp3, patchEntity() is normally used. However, when using it for inserting-new/updating entries in a foreach loop, I too saw that it only saves the last element of the array.
What worked for me was using patchEntities(), which as explained in the patchEntity() doc, is used for patching multiple entities at once.
So simplifying and going by the original code sample to handle multiple entities, it could be:
$userMenuAccessibilityObject = TableRegistry::get('UserMenuAccessibility');
foreach ($UserMenuAccessibility as $key => $value) {
$userMenuAccessibility = $userMenuAccessibilityObject->get($value);//get original individual entity if exists
$userMenuAccessibilities[] = $userMenuAccessibility;
$dataToPatch = [
'menu_accessibility_id' => $value,
'users_id' => $id
]//store corresponding entity data in array for patching after foreach
$userMenuAccessibilitiesData[] = $dataToPatch;
}
$userMenuAccessibilities = $userMenuAccessibilityObject->patchEntities($userMenuAccessibilities, $userMenuAccessibilities);
if ($userMenuAccessibilityObject->saveMany($requisitions)) {
} else {
$this->Session->setFlash(__('The users could not be saved. Please, try again.'));
}
Note: I haven't made it handle if entity doesn't exist, create a new one and resume. That can be done with a simple if condition.

cakephp pagination set condistion from array

I am using a form with several check boxes i need to display only those data which is in check box category.
How to write conditions for that.
for($i=0;$i<count($this->request->data['filter']['delivering']);$i++)
{
$opt1=".'Gig.bangsalsodeliverings' => ".$this->request->data['filter']['delivering'][$i];
$opt2=$opt2.$opt1.',';
}
$options=array('conditions' => array($opt2));
$this->Paginator->settings = $options;
$agetGigsItem = $this->Paginator->paginate('Gig');
But getting error.
Thanks in advance
It seems you're using a string contatenation instead of array to build the conditions array.
Also it's not clear to me if the filter delivering is a set of strings or integers.
I guess you can try:
// Merge the filters into a csv string
$filters = array();
foreach($this->request->data['filter']['delivering'] as $v){
$filters[] = "'{$v}'";
}
$csv_filters = implode(",", $filters);
// Use the csv to make a IN condition
$this->Paginator->settings = array('conditions' => array(
"Gig.bangsasodeliverings IN ({$csv_filters})",
));
Please note that sql injection can be made here, so prepare your data before creating $csv_filters.

Cakephp value from array

I've read many similar topics here but not one helps me with problem.
i'm trying to get sections_id value from query in controller.
$query_id = "SELECT sections_id FROM sections WHERE name='".$table_name."'";
debug($id = $this->Info->query($query_id)); die();
there is debug result
array(
(int) 0 => array(
'sections' => array(
'sections_id' => '14'
)
)
)
and i tried in controller get value of id typing $id['sections']['sections_id'], or
$id['sections_id'] and many other types, nothing works. Do you have any idea ?
use $id[0]['sections']['sections_id'] to access it
For one result use
$data[0]['sections']['sections_id']
If query returns more than one result the use below code:
foreach($id as $data){
echo $data['sections']['sections_id']
}
Look for array index's carefully! Iinjoy

Foreach logic issue with CakePHP

I have I problem that I hope someone can help me with. I thought this code was right, but it will not work. Below is my code, it is a function for my CakePHP 2.2.2 site, the main aim of the code is to produce a menu system from database results. The problem is with my foreach loop, it will not loop. All $Key does is return the value of 2 (three records within the table at this time). So When I display / echo / debug $Menu, the only result I get is the last result stored within the database.
I know the SQL command is right, if that is debuged / echoed then all three results are displayed. The idea of this loop was to get it to count the results, so that I could run a check on a selected field. Where I am going wrong?
function MenuSystem() {
$this->loadModel('Menu');
$MenuSQL = $this->Menu->find('all', array('conditions' => array('active' => true)));
foreach ($MenuSQL as $Key=>$Value) {
$MenuSystem = $MenuSQL[$Key];
$this->Menu = $MenuSystem;
}
}
Many Thanks,
Glenn.
UPDATE :::
Below is my function, now my foreach loop now works, don't know what I was doing wrong, but I know think its working. You can see the print_r command that I am using for testing, if I use that, then all links from my database are printed / echoed on the screen and all works. But if I try and call the $this->Menu from another controller, then only the last record is echoed on the screen. I have moved the $this->Menu outside of the foreach loop, but it made no difference, with it inside the loop or outside, it still only echoes the last record and not all three. So what I am doing wrong?
function MenuSystem() {
$this->loadModel('Menu');
$SiteBase = '/projects/cake/';
$MenuSQL = $this->Menu->find('all', array('conditions' => array('active' => true)));
foreach ($MenuSQL as $key => $Value) {
$MenuAccessLevel = $MenuSQL[$key]['Menu']['roles_id'];
if ($MenuAccessLevel == 1) {
$Path = $MenuSQL[$key]['Menu']['path'];
$Title = $MenuSQL[$key]['Menu']['title'];
$MenuSys = "<a href=\" " . $SiteBase . $Path . " \">" . $Title ."";
} else {
print ("Admin");
}
//print_r($MenuSys);
} //End of Foreach Loop
$this->Menu = $MenuSys;
} //End of function MenuSystem
So When I display / echo / debug $Menu, the only result I get is the last result stored within the database.
You're setting the value of $this->Menu within the foreach, so when the foreach is complete it will take the last value iterated over.
If you want to find the number of records matching a condition, try:
$menuCount = $this->Menu->find('count', array(
'conditions'=>array('active'=>true)
));
$this->set(compact('menuCount'));
Edit: also, by setting the value of $this->Menu within the foreach, you're overwriting the Menu model variable. This is not a good idea.
Edit2: to get the counts of rows as grouped by some value, try:
$this->Menu->virtualFields = array('count' => 'count(*)');
$counts = $this->Menu->find('all', array(
'group'=>'Role',
'fields'=>array('Role', 'count'),
));
This generates SQL to have the results grouped by the Role column. Returned fields are the name of the role, and the number of rows having that value.
If you wanted to do it with a foreach loop instead, it might look like:
$menus = $this->Menu->find('all', array('fields'=>array('id', 'Role')));
$counts = array('user'=>0, 'admin'=>0);
foreach ($menus as $menu) {
$role = $menu['Menu']['Role'];
$counts[$role] += 1;
}

Resources