php - cakephp - Specify hasMany columns / fields in pagination with recursive - php

I have looked through containable component and other questions here, but doesn't look like that can help me.
Basically, I have paginate set to 1, which returns me something just like
Array
(
[0] => Array
(
[ModelName1] => Array
(
[id] => 83
[parent_id] => null
[field1] => value1
)
[AssociatedModelName1] => Array
(
[id] => 1
[field1] => value1
)
[children] => Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 42
[parent_id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
[field3] => value3
)
I am able to limit the output of ModelName1 and AssociatedModelName1 's field by adding
$fields => array("ModelName1.field1")
to the setting array. In fact I pass this to the "column" of the DataTable Plugin's component initialization, but it should be the same.
However, since there are SO MANY CHILDREN, and each children contains a lot of fields, I would like to get only the "field2" of each children.
How can I achieve that? If I specify "Children.ModelName1", I get a SQL1054 error, which is column not found.
Any clue?

You must use a conditional array in one way or another:
$this->paginate['Model'] = array(
'contain' => array(
'ChildModel' => array(
'fields' => array('ChildModel.field1', 'Childmodel.field2'),
'ChildChildModel' => array(
'fields' => array('ChildChildModel.field1', 'ChildChildModel.field2'),
)
)
)
);

Related

Retrieving data in unidimensional array in Cakephp 1.3

I am using cakephp 1.3 to extract data from a table with Cities and Postal Codes and I would like to extract these two columns to populate drop down menu with postal codes as menu 'id' and town names as menu 'values'.
The “find( 'list')” method is out of option because some of the towns have the same postcodes and the class is picking only unique value so instead of getting :
Array
(
[800] => Darwin
[801] => Darwin
[810] => Allawa
)
I am getting
Array
(
[800] => Darwin
[810] => Allawa
)
The method find('all') is returning a multidimensional array
Array
(
[0] => Array
(
[GeoPostcode] => Array
(
[state_id] => 26
[region] => Acton
)
)
[1] => Array
(
[GeoPostcode] => Array
(
[state_id] => 26
[region] => Ainslie
)
)
)
What is the best work around to get the desired data in unidimensional array without reducing the output to unique array keys? Something like :
Array ( [800] => Darwin [801] => Darwin [810] => Allawa )
You should still be able to do this with $Model->find('list').
$this->Model->find(
'list',
array(
'fields' => array(
'postal_code',
'city_name'
),
'contain' => false
)
);
This should return a list resultset using the two fields that you selected (postal code and city name).
Your alternate option, is to do a find('all'):
$results = $this->Model->find(
'all',
array(
'conditions' => array( ... )
)
);
Now, you have this format in your data results:
$results = Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 1
[postal_code] => 800,
[city_name] => 'Darwin'
)
)
[1] => Array
(
[ModelName] => Array
(
[id] => 2
[postal_code] => 801,
[city_name] => 'Darwin'
)
)
[2] => Array
(
[ModelName] => Array
(
[id] => 3
[postal_code] => 810,
[city_name] => 'Allawa'
)
)
)
Then use the Set class within Cake to extract some data:
$keys = Set::extract('/ModelName/postal_code', $results);
$values = Set::extract('/ModelName/city_name', $results);
/* Then some array_combine magic */
$list = array_combine($keys, $values);
Now you have an array that is what you want. Albeit a longer way, but it works. You can then pass this variable to your Form::select() helper to create your dropdown.
Hope this helps!

Cakephp retrieving data from database

I'm having trouble modeling my database. Currently it looks like this (I'm hiding the irrelevant fields): http://i.imgur.com/SF9FzaD.png
It is working fine, for example, when I want it to return a list of all the servers:
$this->Server->find('all');
It returns an array with the right information:
Array
(
[0] => Array
(
[Server] => Array (...)
[User] => Array (...)
[Highlight] => Array
(
[0] => Array
(
[id] => 39
[id_server] => 8
[id_highlight] => 1
)
[1] => Array
(
[id] => 40
[id_server] => 8
[id_highlight] => 5
)
)
[SubServer] => Array(...)
)
[1] => Array
(
[Server] => Array (...)
[User] => Array (...)
[Highlight] => Array
(
[0] => Array
(
[id] => 41
[id_server] => 10
[id_highlight] => 4
)
[1] => Array
(
[id] => 42
[id_server] => 10
[id_highlight] => 5
)
)
[SubServer] => Array(...)
)
)
In short, each game "server" has some kind of higlights pointed by the user. Like "Anti-cheat system", "Active staff", "Custom events", etc. Each of these highlights have an id and a name.
Is there a way to grab the name from the table highlight_names corresponding to each of the highlights.id_hightlight (and the rest of the data, like the array above) using Model::find()?

mongodb $inc a field inside an array

hi i have the follwing array structure
Array
(
[_id] => MongoId Object
(
[$id] => 538978ce8ead0ec1048b456c
)
[cartId] => 98374319ff71dbc3a84b842b7a443cf7
[products] => Array
(
[0] => Array
(
[productId] => 100343
[quantity] => 17
[name] => a
)
[1] => Array
(
[productId] => 100344
[quantity] => 3
[name] => ab
)
[2] => Array
(
[productId] => 100345
[quantity] => 1
[name] => abc
)
)
And i'm having problems to increment the quantity of the products based on the productId
I now use the position but i have no reference on id
$oCartsCollection->update(array('cartId'=>'98374319ff71dbc3a84b842b7a443cf7'), array('$inc' => array('products.0.quantity'=>1)));
What you need to do is add to your query to select and element from your array and then use the positional $ operator in order to match that position:
$oCartsCollection->update(
array(
'cartId'=>'98374319ff71dbc3a84b842b7a443cf7',
'products.productId' => 100343
),
array('$inc' => array('products.$.quantity'=>1)));
The "dot" notation method is fine for accessing the productId element in this case. For multiple fields to match use $elemMatch instead
$oCartsCollection->update(
array(
'cartId'=>'98374319ff71dbc3a84b842b7a443cf7',
'products' => array(
'$elemMatch' => array(
'productId' => 100343,
'name' => 'a'
)
)
),
array('$inc' => array('products.$.quantity'=>1)));

cakephp find order sorting with associated fields

Array
(
[Site] => Array
(
[id] => 1
[parent_id] => 0
[title] => test
[url] => http://www.test.com
[slug] => www_test_com
[keywords] => cpc,seo
[language_id] => 1
)
[SiteMeta] => Array
(
[0] => Array
(
[id] => 1
[site_id] => 1
[key] => pagerank
[value] => 5
[created] => 2010-08-03 00:00:00
)
)
)
By using cakephp, I debug my find('all') and returned me above array. I can sort Site field values by order value inside find function how I am able to order also with SiteMeta values
Any ideas?
Thanks
I'd do this in the Model as part of the association.
$hasMany = array('SiteMeta'=>array('order'=>array('SiteMeta.value'=>'asc')))
You won't have to repeat yourself anywhere then.
you can use a default query with a order condition like this:
$result = $this->Site->find('all', array(
'order'=>array('SiteMeta.value DESC' , 'Site.value DESC'),
'recursive'=>1));
Obviously you can put a condition inside the array to retrieve your right result
I would do it this way (as shown in the Docs)
$result = $this->Site
->find()
->contain([
'SiteMeta' => [
'sort' => ['SiteMeta.pagerank' => 'ASC']
]
]);

Fetching mysql records from CakePHP with specific index

I am using the following cakephp query to retrieve data from mysql:
$tops = $this->PageBanner->find('all', array(
'conditions' => array(
'PageBanner.status' => 1
),
'fields' => array(
'PageBanner.page_url',
'PageBanner.image',
'PageBanner.logo',
'PageBanner.logo_text',
'PageBanner.content'
)
));
This query returns me the following results:
[0] => Array
(
[PageBanner] => Array
(
[page_url] => index
[image] => home_banner.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
)
[1] => Array
(
[PageBanner] => Array
(
[page_url] => write_review
[image] => kids2.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
)
But I want the data to be returned in the following format:
[index] => Array
(
[page_url] => index
[image] => home_banner.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
[write_review] => Array
(
[page_url] => write_review
[image] => kids2.png
[logo] => home_logo.png
[logo_text] => abc
[content] => abc.
)
I need page_url field content in place of Array index (e.i. 0, 1). Is that possible to get data in this format or I need to manually configure the arrays?
$result = Set::combine($tops, '{n}.PageBanner.page_url', '{n}.PageBanner');
pr($result);

Categories