仅保存CakePHP 2.0表单中已更改的字段

时间:2013-02-20 03:57:18

标签: forms cakephp save field

我正在创建一个CakePHP应用程序,可以让多个用户同时编辑相同的信息。为了防止用户覆盖彼此的更改,我希望将其设置为用户保存表单的位置,它只保存用户更改的一个或两个字段。

我不能只是将字段与数据库值进行比较,因为这些数据库值实际上可能是其他用户的新值。

CakePHP是否提供任何方式只通过POST发送更新的字段?

1 个答案:

答案 0 :(得分:2)

我不相信有内置的解决方案。我想出了一些可行的代码,但你肯定想把它放到它自己的函数中,以便它可以被多个控制器动作使用。而且,它并不完美。例如,它会在日期字段上失败,因为CakePHP的日期字段在表单中呈现为select

这是针对编辑操作。原始代码:

public function edit($id = null) {
    $this->User->id = $id;
    if (!$this->User->exists()) {
        throw new NotFoundException(__('Invalid user'));
    }
    if ($this->request->is('post') || $this->request->is('put')) {
        if ($this->User->save($this->request->data)) {
            $this->Session->setFlash(__('The user has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $this->request->data = $this->User->read(null, $id);
    }
}

修改后的代码:

public function edit($id = null) {
    $this->User->id = $id;
    if (!$this->User->exists()) {
        throw new NotFoundException(__('Invalid user'));
    }
    if ($this->request->is('post') || $this->request->is('put')) {
        $originalData = unserialize(base64_decode($this->request->data['Extra']['original_data']));
        $save = $this->request->data;
        unset($save['Extra']);

        foreach ($save as $model => $modelFields) {
            if (!array_key_exists($model, $originalData)) {
                continue;
            }

            foreach ($modelFields as $field => $value) {
                if (!array_key_exists($field, $originalData[$model])) {
                    continue;
                }

                if ($save[$model][$field] === $originalData[$model][$field]) {
                    unset($save[$model][$field]);
                }
            }
        }

        $this->User->set($save);

        if ($this->User->validates() && $this->User->save($save, false)) {
            $this->Session->setFlash(__('The user has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $this->request->data = $this->User->read(null, $id);
        $this->request->data['Extra']['original_data'] = base64_encode(serialize($this->request->data));
    }
}

另外,在edit.ctp

中的表单中添加此内容
echo $this->Form->hidden('Extra.original_data');