How to use saveMany in cakephp 3.2.7 - cakephp-2.7

Having problems with saveMany() on a cake 3.2.7 install. It give an error Unknown method "saveMany".
$cartArrSave = Array
(
[0] => Array
(
[deal_id] => 4
[store_id] => 126
[user_id] => 124
[quantity] => 1
)
[1] => Array
(
[deal_id] => 9
[store_id] => 127
[user_id] => 124
[quantity] => 1
)
)
$this->Deals = TableRegistry::get('Deals');
if(!empty($cartArrSave)){
$this->Deals->newEntities($cartArrSave);
$this->Deals->saveMany($cartArrSave);
}
I have checked that saveMany is supported in even cakephp 2
And also its supported in cakephp 3.x
Then why its giving such error?
Please suggest any alternative to saveMany function in cakephp 2.7.8?

Related

cakephp linked model not showing in hasmany

I have three Models in cakephp
//Union
public $hasMany = 'Member';
and
//Member
public $hasOne = 'Post';
where as post contains post names
Now the problem is when I use:
$this->Union->findById(1);
in Union controller it shows linked Members but not name of posts
[Union] => Array
(
[id] => 1
[Name] => Dawa vyapar mandal
[created] => 2014-03-31 14:08:12
)
[Member] => Array
(
[0] => Array
(
[id] => 1
[Name] => Ashish
[post_id] => 1
[union_id] => 1
[created] => 2014-03-31 14:11:02
)
[1] => Array
(
[id] => 2
[Name] => Ashu
[post_id] => 1
[union_id] => 1
[created] => 2014-07-01 15:01:15
)
)
)
so how to achieve Post Model inside Member Model?
You have to make the model to be recursive to the level upto which you need data.
In your case, you need the data upto 2nd level, so make recursive as -
$this->Union->recursive = 2;
And after that find your data -
$this->Union->findById(1)

how to sort array date wise in cakephp

I have 2 table booking and message , now I want to show booking request and message in inbox at a time.
$this->paginate = array(
'conditions' => $conditions,'limit' =>10,
'order'=>array('Booking.created'=>'DESC'));
$bookings = $this->paginate('Booking');
$this->paginate = array(
'conditions' => $conditions,'limit' =>10,
'order'=>array('MessageDetail.created'=>'DESC'));
$messages = $this->paginate('MessageDetail');
i have merge both table data ( array_merge($bookings, $messages); )
now i want to it sort date wise (or any conditions)
Array
(
[0] => Array
(
[Booking] => Array
(
[id] => 4
[host_id] => 21
[place_id] => 10
[room_id] => 13
[user_id] => 12
[message_detail_id] => 16
[created] => 2013-04-23 14:44:03
[accept_date] =>
[cancel_date] =>
)
)
[1] => Array
(
[Booking] => Array
(
[id] => 3
[host_id] => 21
[place_id] => 10
[room_id] => 13
[user_id] => 12
[message_detail_id] => 13
[created] => 2013-04-15 14:10:59
[accept_date] => 2013-04-15 14:40:47
[cancel_date] =>
)
)
[2] => Array
(
[MessageDetail] => Array
(
[id] => 17
[message_id] => 2
[user_id] => 12
[sender_id] => 21
[unread] => 0
[created] => 2013-04-24 12:11:47
)
)
[3] => Array
(
[MessageDetail] => Array
(
[id] => 15
[message_id] => 2
[user_id] => 12
[sender_id] => 21
[booking_id] => 3
[unread] => 0
[created] => 2013-04-15 15:01:12
)
)
)
Thanks in advance.
Option #1:
Create a third Model named "BookingAndMessage". You could use the Model's afterSave method (on both Booking and Message) to create a duplicate record in your new model. You could then query the BookingAndMessage in the proper sort order.
Option #2: To solve the problem, as it stands, you will want to use PHP's usort function (also explained here PHP Sort a multidimensional array by element containing date).
<?php
$BookingsAndMessages = array_merge($bookings, $messages);
function date_compare($a, $b)
{
$modelKeyA = array_key_exists('Booking',$a) ? 'Booking' : 'MessageDetail';
$modelKeyB = array_key_exists('Booking',$b) ? 'Booking' : 'MessageDetail';
$t1 = strtotime($a[$modelKeyA]['created']);
$t2 = strtotime($b[$modelKeyB]['created']);
return $t1 - $t2;
}
usort($BookingsAndMessages, 'date_compare');
// Would sort the merged records by `created` date
?>
The downside to option 2 is, you are going to have to create rules for each field (and sort direction).
Perhaps you should Union your queries first, the Order.
$bookings = $this->Bookings->find('all', [
'conditions' => $conditions,'limit' =>10,
]);
$messages = $this->find('all', [
'conditions' => $conditions,'limit' =>10
]);
$data = $bookings->union($messages);
// This works if your first selected field is the one you want to sort.
$data->epilog('ORDER BY 1 ASC');
reference:
How do you modify a UNION query in CakePHP 3?

CakePHP same array from the direct and associated model

I have simple model relationship in CakePHP 1.3 with Categories -> Products
Category hasMany Products
There is slight difference between the data arrays which I get in the different controllers. The Product data is in the main product array when getting as associated model in the Categories controller and is separated when getting it in Products.
For Example to get 'Product1'
in Categories - $category['Product'][0]['title']
and in Products - $product[0]['Product']['title']
I would like to use same element for displaying the products. It does not matter which array scheme will be used just to be the same. And where is the right place to make the modification? I can modify those arrays after getting them, but don't think that it is the best option.
When I am in the Categories controller and get a category I get this:
// $this->Category->findById('12');
Array
(
[ProductCategory] => Array
(
[id] => 12
[title] => Category 1
[updated] => 2013-02-24 10:06:15
[created] => 2013-02-24 10:06:15
)
[Product] => Array
(
[0] => Array
(
[id] => 4
[parent_id] => 12
[title] => Product1
[updated] => 2013-02-24 10:17:01
[created] => 2013-02-24 09:12:59
)
[1] => Array
(
[id] => 6
[parent_id] => 12
[title] => Product2
[updated] => 2013-02-24 10:16:54
[created] => 2013-02-24 09:13:53
)
)
And when getting all the products inside the Products controller:
// $this->Product->find('all');
Array
(
[0] => Array
(
[Product] => Array
(
[id] => 10
[parent_id] => 12
[title] => Product1
[updated] => 2013-02-24 10:16:42
[created] => 2013-02-24 09:16:35
)
)
[1] => Array
(
[Product] => Array
(
[id] => 8
[parent_id] => 12
[title] => Product2
[updated] => 2013-02-24 10:16:47
[created] => 2013-02-24 09:15:39
)
)
)
)
One of your finds is a find('all') and the other is a findById() (which uses find('first')).
Both of these return data in a different format, since find('first') knows you only want one item, and find('all') is an unknown set of item(s).
Just use find('all') for both, but set your limit based on whether you need only one or more than one. Then, your data will be returned exactly the same.
Which Controller you retrieve your data from has no effect on the data returned. Which MODEL however, does - so just make sure you're doing your find from the same model.
Eg.
//in your ProductsController
$this->Product->find('all');
//in your CategoriesController
$this->Category->Product->find('all');
// in some other controller
$this->loadModel('Product);
$this->Product->find('all');
PS - BUT it's better if you don't do your "finds" in your Controller - make a method in your Model, and call it from your Controller(s) so instead of $this->Product->find(), it would be $this->Product->getProducts() (or whatever you want to call it). (read more about "fat models, skinny controllers" for reasons/examples...etc).
Dave is right, the difference is the method you're using... Even though you claim that associated data is always merged, your find on the 'Product' model is NOT associated data, so the format WILL always be different.
I've been here for a short while and I've already noticed that Dave knows his stuff. :)
I agree with the fat models/skinny controllers paradigm for clean, efficient code.
If you changed:
<?php
$this->Category->contain(array(
'Product'
));
$this->Category->find('all',
array(
'conditions' => array(
'Category.id' => $id // 12 for your OP.
),
'limit' => 1
)
);
?>
Should give you:
<?php
array
(
[0] => array
(
'Category' => array
(
[id] => 12
[title] => Category 1
[updated] => 2013-02-24 10:06:15
[created] => 2013-02-24 10:06:15
),
'Product' => array
(
[0] => array
(
...
),
[1] => array
(
...
)
)
)
)
?>
Please correct me if I am mistaken, thanks!
Or if you want "Products" to look like:
<?php
'Product' => array
(
[0] => array
(
'Product' => array
(
...
)
)
)
?>
when fetching data from the category model, you would need to fetch the associated data manually, e.g.:
<?php
$this->Category->contain();
$cats = $this->Category->find('all');
foreach ($cats as &$cat) {
$this->Category->Product->contain(); // You have to contain for each find.
$cat['Product'] = $this->Category->Product->find('all',
array(
'conditions' => array(
'Product.category_id' => $cat['Category']['id']
)
)
);
}
?>

cakephp find('all') not returning properly

So here is my latest issue:
I run this query in my Cakephp controller:
$acctRenewLast2Entries = $this->AccountRenew->find
(
'all',
array
(
'conditions' => array('Acc_Id' => $plan["Account"]["Acc_Id"]),
'order' => array('AccR_Id' => 'DESC')
)
);
I am expecting 4 records for this SQL statement. Instead, on running Debug in my controller, this is what I get for each row for above (see first record):
app/controllers/admins_controller.php (line 2584)
1
app/controllers/admins_controller.php (line 2584)
Array
(
[AccountRenew] => Array
(
[AccR_Id] => 470
[AccR_Date] => 2012-06-23 01:21:11
[AccR_Hstart_Date] => 2012-06-23 01:21:11
[AccR_Hend_Date] => 2012-08-23 01:21:11
[AccR_End_Date] => 2013-08-23 01:21:11
[AccR_Status] => PAID
[AccR_Reason] => RENEWAL
[Inv_Id] => 467
[Inac_Id] =>
[Acc_Id] => 196
[AccT_Id] => 44
[Amount] => 16
[AccP_Id] => 0
)
)
app/controllers/admins_controller.php (line 2584)
Array
(
[AccountRenew] => Array
(
[AccR_Id] => 465
[AccR_Date] => 2012-06-23 01:17:35
[AccR_Hstart_Date] => 2012-06-23 01:17:35
[AccR_Hend_Date] => 2012-07-23 01:17:35
[AccR_End_Date] => 2012-07-23 01:17:35
[AccR_Status] => PAID
[AccR_Reason] => RENEWAL
[Inv_Id] => 462
[Inac_Id] =>
[Acc_Id] => 196
[AccT_Id] => 41
[Amount] => 16
[AccP_Id] => 0
)
)
app/controllers/admins_controller.php (line 2584)
Array
(
[AccountRenew] => Array
(
[AccR_Id] => 269
[AccR_Date] => 2012-06-06 10:15:56
[AccR_Hstart_Date] => 2012-06-06 17:15:56
[AccR_Hend_Date] => 2012-06-20 17:15:56
[AccR_End_Date] => 2012-06-20 10:15:56
[AccR_Status] => TRIAL
[AccR_Reason] =>
[Inv_Id] => 0
[Inac_Id] =>
[Acc_Id] => 196
[AccT_Id] => 0
[Amount] => 0
[AccP_Id] => 0
)
)
Now, when I run sql_dump, I get the following query that was run :
SELECT `AccountRenew`.`AccR_Id`, `AccountRenew`.`AccR_Date`, `AccountRenew`.`AccR_Hstart_Date`, `AccountRenew`.`AccR_Hend_Date`, `AccountRenew`.`AccR_End_Date`, `AccountRenew`.`AccR_Status`, `AccountRenew`.`AccR_Reason`, `AccountRenew`.`Inv_Id`, `AccountRenew`.`Inac_Id`, `AccountRenew`.`Acc_Id`, `AccountRenew`.`AccT_Id`, `AccountRenew`.`Amount`, `AccountRenew`.`AccP_Id` FROM `account_renews` AS `AccountRenew` WHERE `Acc_Id` = 196 ORDER BY `AccR_Id` DESC 4 4
And when I run the above query in MySQL, I do get all my 4 records, including the first one which in the array appears as 1 (way up top of my write-up).
I sincerely hope someone out there can help, because I spent the last 1.5 days without any luck as to why MySQL pulls up the complete set, but Cake only seems to retrieve the last 3, and replace the first record with an array of "1".
Thanks in advance!
#user996302 this issue seems remotely connected to one of my Cake Lighthouse tickets you pointed out.
#GMOAdmin I suspect that there could be a problem with the name of your model as the word "renew" is a verb and since it has no plural form this could somehow be obstructing the CakePHP conventions as the Inflector class may not be able to translate this.
The correct noun is renewal and it's plural form: renewals. You can try renaming (according to the convetions) the DB table, Model - name and classname, Controller - name and classname and see if that works.
You can test if Inflector is handling this correctly via the following Inflector methods:
Inflector::pluralize($singular), Inflector::classify($tableName), Inflector::tableize($camelCase)
A quick fix would be to issue the working query with $this->ModelName->query($queryToRun); this way you can go around this since, as you say, the query runs correctly when ran over the DB. Overall this is truly and interesting issue and I suggest you have the CakeCore team look at it - if it is reproducable then this is a BUG and it need fixin.
Very strange problem.
I don't know what's happening, but I read recently a bug report which sounds a lot like your problem: ticket.
You may try as suggested by the author: put the param $showHTML (cake docs) as true:
debug($var, true, true);
Hope that helps.
Okay, I think I have found the answer. At least, this was causing the problems for me.
The CakePHP counterCache
What I had:
public $hasMany = array(
'Flight' => array(
'className' => 'Flight',
'foreignKey' => 'user_plane_id',
'counterCache' => true
)
);
Very stupid, but it did cause the problems. So perhaps you are having a counterCache as well? Or maybe you have set another key in the relationships wrong?
If you don't see the problem at my code snippet. I should have added the counterCache to the $belongsTo instead of the $hasMany. So it would be something like this:
public $belongsTo = array(
'UserPlane' => array(
'className' => 'UserPlane',
'foreignKey' => 'user_plane_id',
'counterCache' => true
)
);
note: I am running CakePHP 2.x and not 1.3!

cakephp: notice 8:undefined index: id error

i'm getting Undefined index: id [APP\controllers\merry_parents_controller.php, line 31]Code
debug($this->data['MerryParent']);
echo 'id: '.$this->data['MerryParent']['id'];
MerryParentsController::login() - APP\controllers\merry_parents_controller.php, line 31
Dispatcher::_invoke() - CORE\cake\dispatcher.php, line 204
Dispatcher::dispatch() - CORE\cake\dispatcher.php, line 171
[main] - APP\webroot\index.php, line 83
My code:
merry_parents_controller.php
if ($this->Auth->user()){
//debug($this->Auth->user());
$this->data['MerryParent']=$this->Auth->user();
debug($this->data['MerryParent']);
echo 'id: '.$this->data['MerryParent']['id'];
for debug($this->data['MerryParent']), the record is displaying fine:
Array
(
[MerryParent] => Array
(
[id] => 2
[initial] => Ms
[username] => hong
[email] => hong7#yahoo.com
[password2] => hong7
[landline] =>
[mobile] => 293472389472
[address] => dsaflkjasdlfk
[state_id] => 5
[city_id] => 62
[postal_code] => 825729
[created] => 2011-08-02 10:29:59
[modified] => 2011-09-26 06:42:27
)
)
but when i try
echo 'id: '.$this->data['MerryParent']['id'];
i'm getting notice 8: undefined index error. I have no idea on what is the problem. Can someone please help me?
Your array looks like this:
Array
(
[MerryParent] => Array
(
[MerryParent] => Array
(
[id] => 2
...
The id you're looking for is in $this->data['MerryParent']['MerryParent']['id']. You probably want
$this->data = $this->Auth->user();

Resources