Trying to contain a field that uses UNIX_TIMESTAMP - cakephp

I'm trying to convert the updated datetime column to a number. So I did this in my Containable behavior.
$this->paginate = array(
'limit'=>1,
'fields'=>array(
'id',
),
'contain'=>array(
'Image'=>array('fields'=>array(
'id',
'UNIX_TIMESTAMP(Image.updated) AS `rev`',
))
)
);
I get this data from Paginator
Array
(
[0] => Array
(
[Receipt] => Array
(
[id] => 19938
)
[Image] => Array
(
[0] => Array
(
[id] => 18143
[receipt_id] => 19938
[Image] => Array
(
[0] => Array
(
[rev] => 1357872726
)
)
)
[1] => Array
(
[id] => 18144
[receipt_id] => 19938
[Image] => Array
(
[0] => Array
(
[rev] => 1357872728
)
)
)
)
)
)
For some reason Image is nested twice for each record. If I remove the UNIT_TIMESTAMP it gets the data correctly.
$this->paginate = array(
'limit'=>1,
'fields'=>array(
'id',
),
'contain'=>array(
'Image'=>array('fields'=>array(
'id',
'updated',
))
)
);
Output
Array
(
[0] => Array
(
[Receipt] => Array
(
[id] => 19938
)
[Image] => Array
(
[0] => Array
(
[id] => 18143
[updated] => 2013-01-10 21:52:06
[receipt_id] => 19938
)
[1] => Array
(
[id] => 18144
[updated] => 2013-01-10 21:52:08
[receipt_id] => 19938
)
)
)
)
Any idea why Cake is going this when I add an expression to a field?

You can try using virtual fields:
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->virtualFields['name'] = sprintf(
'UNIX_TIMESTAMP(%s.updated) AS %s.rev', $this->alias, $this->alias
);
}
Not sure if my notation is right, give it a try, I haven't tested it.

Related

Reindex PHP Nested Array

After printing my $my_values['outer_group']['fieldset'] I'm getting the following output as per the data:
Array
(
[fieldset] => Array
(
[1] => Array
(
[title] => Dummy_Value1
[inner_group] => Array
(
[fieldset] => Array
(
[1] => Array
(
[id] => 11
[title] => Dummy_Value11
)
[2] => Array
(
[id] => 12
[title] => Dummy_Value12
)
[3] => Array
(
[id] => 13
[title] => Dummy_Value13
)
[actions] => Array
(
[add] => Add InnerGroup
[remove] => Remove InnerGroup
)
)
)
)
[2] => Array
(
[title] => Dummy_Value2
[inner_group] => Array
(
[fieldset] => Array
(
[1] => Array
(
[id] => 21
[title] => Dummy_Value21
)
[actions] => Array
(
[add] => Add InnerGroup
)
)
)
)
[actions] => Array
(
[add] => Add OuterGroup
[remove] => Remove OuterGroup
)
)
)
My requirement is to re-index the output data, hence I've performed the following code to re-index the same:
<?php
if (isset($my_values['outer_group']) && !empty($my_values['outer_group'])) {
$outer_types = $my_values['outer_group']['fieldset'];
$inner = [];
foreach ($outer_types as $outer_key => $outer_value) {
if (is_numeric($outer_key)) {
if (isset($outer_value['inner_group']['fieldset'])) {
foreach ($outer_value['inner_group']['fieldset'] as $k => $v) {
if (is_numeric($k)) {
$inner[] = [
'id' => $v['id'],
'title' => !empty($v['title']) ? $token->replace($v['title']) : NULL,
];
}
}
}
$my_values['outer'][$outer_key] = [
'title' => !empty($outer_value['title']) ? $token->replace($outer_value['title']) : NULL,
'inner' => $inner,
];
}
}
}
As per the output its getting re-indexed but with some errors in data. I'm getting trouble while populating the [inner] data, following is the output for the same:
Array
(
[0] => Array
(
[title] => Dummy_Value1
[inner] => Array
(
[0] => Array
(
[id] => 11
[title] => Dummy_Value11
)
[1] => Array
(
[id] => 12
[title] => Dummy_Value12
)
[2] => Array
(
[id] => 13
[title] => Dummy_Value13
)
)
)
[1] => Array
(
[title] => Dummy_Value2
[inner] => Array
(
[0] => Array
(
[id] => 11
[title] => Dummy_Value11
)
[1] => Array
(
[id] => 12
[title] => Dummy_Value12
)
[2] => Array
(
[id] => 13
[title] => Dummy_Value13
)
[3] => Array
(
[id] => 21
[title] => Dummy_Value21
)
)
)
)
Whereas, it should be:
Array
(
[0] => Array
(
[title] => Dummy_Value1
[inner] => Array
(
[0] => Array
(
[id] => 11
[title] => Dummy_Value11
)
[1] => Array
(
[id] => 12
[title] => Dummy_Value12
)
[2] => Array
(
[id] => 13
[title] => Dummy_Value13
)
)
)
[1] => Array
(
[title] => Dummy_Value2
[inner] => Array
(
[0] => Array
(
[id] => 21
[title] => Dummy_Value21
)
)
)
)
$inner = []; needs to be within the foreach loop so that it is empty before building each internal element.
Untested - but as follows:
<?php
if (isset($my_values['outer_group']) && !empty($my_values['outer_group'])) {
$outer_types = $my_values['outer_group']['fieldset'];
foreach ($outer_types as $outer_key => $outer_value) {
$inner = [];
if (is_numeric($outer_key)) {
if (isset($outer_value['inner_group']['fieldset'])) {
foreach ($outer_value['inner_group']['fieldset'] as $k => $v) {
if (is_numeric($k)) {
$inner[] = [
'id' => $v['id'],
'title' => !empty($v['title']) ? $token->replace($v['title']) : NULL,
];
}
}
}
$my_values['outer'][$outer_key] = [
'title' => !empty($outer_value['title']) ? $token->replace($outer_value['title']) : NULL,
'inner' => $inner,
];
}
}
}

group after order

In cakephp 2 I want to group table after descending order
always returned the first record of table
but I want returned last record by ordering
my data, code and result in here:
My data in table:
Code in controller:
$books = $this->Book->find('all', array(
'order' => array('age' => 'DESC'),
'group' => 'name'
));
print_r($books);
Result after the code above:
Array
(
[0] => Array
(
[Book] => Array
(
[id] => 1
[name] => ramin
[family] => zardoshti
[age] => 32
[city] => semnan
)
)
[1] => Array
(
[Book] => Array
(
[id] => 2
[name] => esmaeil
[family] => seydi
[age] => 30
[city] => semnan
)
)
)
But I want this result:
Array
(
[0] => Array
(
[Book] => Array
(
[id] => 1
[name] => ramin
[family] => zardoshti
[age] => 42
[city] => tehran
)
)
[1] => Array
(
[Book] => Array
(
[id] => 2
[name] => esmaeil
[family] => seydi
[age] => 30
[city] => semnan
)
)
)
Add a virtual field on the fly to your Book model
$this->Book->virtualFields = array(
'max_age' => sprintf('max(%s.age)', $this->Book->alias)
);
$books = $this->Book->find('all', array(
'order' => array('age' => 'DESC'),
'group' => 'name'
));
print_r($books);
The virtual field will help to get the rows with the maximum age value.
Your SQL query will look like :
SELECT
`Book`.`id`, `Book`.`name`, `Book`.`family`, `Book`.`age`,
`Book`.`city`, (max(`Book`.`age`)) AS `Book__max_age`
FROM
`test`.`books` AS `Book`
WHERE
1 = 1
GROUP BY
name
ORDER BY
`age` DESC

Cakephp: Contain Behavior, conditions on array of array

I have a problem with contain behavior conditions and empty array.
There is part of code:
$menusTopUser = $this->Menu->find('all', array(
'contain' => array('TemplateRegion', 'Language', 'Item', 'MenusUserGroup' => array('conditions' => array('MenusUserGroup.user_group_id ' => $this->Auth->user('UserGroup.id')))
),
'conditions' => array(
'TemplateRegion.alias' => 'menu_top_user',
'Menu.active' => 1,
'Language.ISO-639-2' => $this->Session->read('Config.frontendLanguage'),
),
'fields' => array('Menu.title', 'Item.slug', 'Menu.url', 'Menu.target', 'Language.ISO-639-2'),
'order' => array('Menu.lft'),
'recursive' => 0));
$this->set(compact('menusTopUser'));
My associations look like:
Menu
hasMany: MenusUserGroup
MenusUserGroup
belongsTo: Menu, UserGroup
After executing the find, I have the next array where there are many MenusUserGroup empty. How make to filter only the record with 'MenusUserGroup.user_group_id ' => $this->Auth->user('UserGroup.id')?
Array(
[0] => Array
(
[Menu] => Array
(
[title] => Offerte e modulistica promoter
[url] =>
[target] => _self
[id] => 11
)
[Item] => Array
(
[slug] => offerte-e-modulistica-promoter
[id] => 36
)
[Language] => Array
(
[ISO-639-2] => ita
[id] => 1
)
[TemplateRegion] => Array
(
[id] => 10
)
[MenusUserGroup] => Array
(
)
)
[1] => Array
(
[Menu] => Array
(
[title] => Offerte e modulistica agenti
[url] =>
[target] => _self
[id] => 10
)
[Item] => Array
(
[slug] => offerte-modulistica
[id] => 29
)
[Language] => Array
(
[ISO-639-2] => ita
[id] => 1
)
[TemplateRegion] => Array
(
[id] => 10
)
[MenusUserGroup] => Array
(
[0] => Array
(
[id] => 7
[menu_id] => 10
[user_group_id] => 5
)
)
)
[2] => Array
(
[Menu] => Array
(
[title] => Gestione contratti
[url] =>
[target] => _self
[id] => 13
)
[Item] => Array
(
[slug] =>
[id] =>
)
[Language] => Array
(
[ISO-639-2] => ita
[id] => 1
)
[TemplateRegion] => Array
(
[id] => 10
)
[MenusUserGroup] => Array
(
[0] => Array
(
[id] => 10
[menu_id] => 13
[user_group_id] => 5
)
)
)
Use a join.
$menusTopUser = $this->Menu->find('all', array(
// join statement
'joins' => array(
array(
'table' => 'menus_user_groups',
'alias' => 'MenuUserGroupJoin',
'type' => 'INNER',
'conditions' => array(
'MenuUserGroupJoin.menu_id = Menu.id',
// condition
'MenuUserGroupJoin.user_group_id = ' . $this->Auth->user('UserGroup.id'),
),
),
),
'contain' => array('TemplateRegion', 'Language', 'Item', 'MenusUserGroup'),
'conditions' => array(
'TemplateRegion.alias' => 'menu_top_user',
'Menu.active' => 1,
'Language.ISO-639-2' => $this->Session->read('Config.frontendLanguage'),
),
'fields' => array('Menu.title', 'Item.slug', 'Menu.url', 'Menu.target', 'Language.ISO-639-2'),
'order' => array('Menu.lft'),
'recursive' => 0));

group is not working in CakePHP

I am running following query in CakePHP:
$options = array('conditions' => array('Patient.' . $this->Patient->primaryKey => $id),array('recursive'=>2,'group'=>array('group_id')));
$this->set('patient', $this->Patient->PatientTest->find('all', $options));
But my group is not working as needed. It gives me output as follows:
Array
(
[0] => Array
(
[PatientTest] => Array
(
[patient_id] => 2
[test_id] => 1
[date] => 2014-03-27 17:44:17
[result] => 55
[group_id] => 1
)
[Patient] => Array
(
[id] => 2
[name] => Test Patient
[age] => 44
[gender] => 0
[email] => emailid#gmail.com
[contact] => 789654123
[date] => 0000-00-00 00:00:00
)
[Test] => Array
(
[id] => 1
[name] => Hb
[group_id] => 1
[normal] => 12 - 16 gma%
)
[Group] => Array
(
[id] => 1
[name] => Haematology
)
)
[1] => Array
(
[PatientTest] => Array
(
[patient_id] => 2
[test_id] => 2
[date] => 2014-03-27 17:44:17
[result] => 55
[group_id] => 1
)
[Patient] => Array
(
[id] => 2
[name] => Test Patient
[age] => 44
[gender] => 0
[email] => emailid#gmail.com
[contact] => 789654123
[date] => 0000-00-00 00:00:00
)
[Test] => Array
(
[id] => 2
[name] => PCV
[group_id] => 1
[normal] => 35-50%
)
[Group] => Array
(
[id] => 1
[name] => Haematology
)
)
)
I need them group by either group_id or by Group.id.
I am unable to find why it is not grouping.
not
$options = array
(
'conditions' => array
(
'Patient.' . $this->Patient->primaryKey => $id
),
array(
'recursive'=>2,
'group'=>array('group_id')
)
);
but
$options = array
(
'conditions' => array
(
'Patient.' . $this->Patient->primaryKey => $id
),
'recursive'=>2,
'group'=>array('group_id')
);
recursive, conditions and group are at the same level
Simple and sweet code :
$groupBy = 'Patient.group_id';
$options = array (
'conditions' => array
(
'Patient.' . $this->Patient->primaryKey => $id
),
'group'=>array($groupBy)
);

How do I format the output array in CakePHP

Let's say I have an index action where I want to get a list of projects:
$this->Project->find('all', array('order' => 'Project.modified DESC', 'conditions' => array('Project.user_id' => 1)));
It works well and returns the following array:
Array ( [0] => Array ( [Project] => Array ( [id] => 2 [title] => test project ) ) [1] => Array ( [Project] => Array ( [id] => 1 [title] => first project ) ) )
How do I modify the find function, so it returns the array in the following format:
Array ( [projects] => Array ( [0] => Array ( [id] => 2 [title] => test project ) [1] => Array ( [id] => 1 [title] => first project ) ) )
Thank you!
You could use the Set::combine() utility method to do this. I've used it for similar means as so:
public function groupByMenu() {
return Set::combine (
$this->find (
'all',
array (
'conditions' => array ( 'NavItem.active' => 1 ),
'order' => 'NavMenuItem.display_order'
)
),
'{n}.NavItem.title',
'{n}',
'{n}.NavMenu.id'
);
}
The code above takes a set of navigation items and reorganizes them so that they're grouped by the menu(s) they are displayed within.
It's not really clear if it's the fact that the result is under 'Project' rather than 'projects', but if you don't like that it's under [0] I believe you could use PHPs array_shift:
$result = $this->Project->find('all', array('order' => 'Project.modified DESC', 'conditions' => array('Project.user_id' => 1)));
$result = array_shift($result);
The result will be:
Array ( [Project] => Array ( [id] => 2 [title] => test project ) ) [1] => Array ( [Project] => Array ( [id] => 1 [title] => first project ) )

Resources