php - Cakephp - Cannot set Model->id in KeyValue Behavior::beforeSave -
i'm trying implement key/value behavior based on https://github.com/josegonzalez/cakephp-keyvalue
my behavior insert new rows database each new key form submission, regardless number of keys, , update existing records if user_id , key found in keyvalue table. have linked user model keyvalue model, behavior.
when database has no record of user_id/key, insert new records correctly. found if trying update existing key-value pairs of same user, first 2 values updated correctly last value submitted produce new record.
after investigation found in saving loop in beforesave()
, if assign id model in beforesave()
$model->id
before returning true, not passed model->save()
class.
i'm using cake 2.5.4
model->id
in beforesave not pass model->save()
in lib/model/model.php:# 1841
if ($count > 0) { $cache = $this->_prepareupdatefields(array_combine($fields, $values)); **pr($this->id); //this value empty** if (!empty($this->id)) { $this->__safeupdatemode = true; try { $success = (bool)$db->update($this, $fields, $values); } catch (exception $e) { $this->__safeupdatemode = false; throw $e; } $this->__safeupdatemode = false; }
keyvaluebehavior:
public function beforesave(model $model, $options = array()) { extract($this->options[$model->alias]); $keys = array_keys($model->data[$model->alias]); $data = $model->data; if (in_array($fields['key'], $keys) && in_array($fields['value'], $keys)) { return true; } if (isset($data[$model->alias]) && ! empty($data[$model->alias])) { $datatemplate = array($model->alias => array()); foreach ($data[$model->alias] $field => $value) { if ($model->hasfield($field)) { $datatemplate[$model->alias][$field] = $value; unset($data[$model->alias][$field]); } } $index = 0; foreach ($data[$model->alias] $key => $value) { $index ++; $insert = $datatemplate; $insert[$model->alias][$fields['key']] = $key; if ($uniquekeys) { $model->deleteall(reset($insert)); } $insert[$model->alias][$fields['value']] = $value; //check existing key value $belongsto = reset($model->belongsto); $existing = $model->find('first', array( 'conditions' => array( $belongsto['foreignkey'] => $insert[$model->alias][$belongsto['foreignkey']], $fields['key'] => $insert[$model->alias][$fields['key']] ) )); $model->create(); if(sizeof($existing) > 0){ $existingkv = reset($existing); //pr($existingkv); $model->read(null, $existingkv['id']); } if ($index == count($data[$model->alias])) { // if model->id set here, not passed model->save() $model->id = $existingkv['id']; $model->data = $insert; pr($model); // model->id set here not in model->save() return true; } else { pr($insert); //updates correctly if (false === $model->save($insert)) { return false; } } } }
userscontroller:
public function test() { if ($this->request->is('post')) { $this->userdetail->create(); $this->request->data['userdetail']['user_id'] = $this->auth->user('id'); if ($this->userdetail->save($this->request->data)) { $this->session->setflash(__('the userdetail has been saved')); // $this->redirect(array('action' => 'index')); } else { $this->session->setflash(__('the userdetail not saved. please, try again.')); } } $users = $this->userdetail->user->find('list'); $this->set(compact('users')); }
then have 3 sample fields in view view/users/test.ctp:
<?php echo $this->form->create('userdetail'); echo $this->form->input('field1'); echo $this->form->input('field2'); echo $this->form->input('field3'); echo $this->form->end('submit');
to workaround added key named "id_holder" model in beforesave()
, , edited model/model.php
. don't want edit cakephp core.
edit: on new savekeyvalues()
method:
public function savekeyvalues(model $model, $data){ if($model == null || $data == null){ return false; } if (isset($data[$model->alias]) && ! empty($data[$model->alias])) { $datatemplate = array($model->alias => array()); foreach ($data[$model->alias] $field => $value) { if ($model->hasfield($field)) { $datatemplate[$model->alias][$field] = $value; unset($data[$model->alias][$field]); } } } $belongsto = reset($model->belongsto); $index = 0; foreach ($data[$model->alias] $key => $value) { $index++; $insert = $datatemplate; $insert[$model->alias][$this->options[$model->alias]['fields']['key']] = $key; $insert[$model->alias][$this->options[$model->alias]['fields']['value']] = $value; $insert[$model->alias][$belongsto['foreignkey']] = $data[$belongsto['foreignkey']]; //check existing key value $existing = $model->find('first', array( 'conditions' => array( $belongsto['foreignkey'] => $data[$belongsto['foreignkey']], $this->options[$model->alias]['fields']['key'] => $key ) )); //reset create/update $model->create(); if(sizeof($existing) > 0){ $existingkv = reset($existing); $model->read(null, $existingkv['id']); } if (false === $model->save($insert)) { return false; } if($index == count($data[$model->alias])){ return true; } } }
Comments
Post a Comment