CakePHP 3:Behavior如何处理多个数据?

时间:2015-10-07 14:56:39

标签: cakephp cakephp-3.0 behavior cakephp-3.1

我想创建一个CakePHP行为,它将在数据存储到db之前处理数据。

例如,我有帖子添加表单,如:

// Post title
echo $this->Form->input('title',['value'=>'aaa']);
// Post has many Photos (names)
echo $this->Form->input('photos.0.name',['value'=>'zzz']);
echo $this->Form->input('photos.1.name',['value'=>'hhh']);
echo $this->Form->input('photos.2.name',['value'=>'fff']);

PostsController:

public function add()
{
    $post = $this->Posts->newEntity();
    if ($this->request->is('post')) {
        $post = $this->Posts->patchEntity($post, $this->request->data);

        if ($this->Posts->save($post)) {
            $this->Flash->success(__('The post has been saved.'));
            return $this->redirect(['action' => 'index']);
        } else {
            $this->Flash->error(__('The post could not be saved. Please, try again.'));
        }
    }
    $this->set(compact('post'));
    $this->set('_serialize', ['post']);
}

表单中的数据正确存储在数据库中。

接下来,我烘焙一个新的行为(例如,MyBehavoir),并将其附加到PhotosTable。我想要检索所有三个" name"领域,例如处理它们。通过ucfirst方法转换,并将其发送回存储在数据库中。

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
    $data['name'] = ucfirst($data['name']);
    debug($data);
}
 // debug return three outputs for every field

object(ArrayObject) {
    name => 'Zzz' // Hhh, Fff
}

但只保存了第一个结果(Zzz)。

我该怎么办,在处理行为后保存所有字段?

此外,

public function beforeSave(Event $event, Entity $entity)
{   
    debug($entity);
    return true;
}

debug仅显示来自第一个字段的数据

object(App\Model\Entity\Photo) {

    'name' => 'Zzz',
    'post_id' => (int) 486,
    ...

1 个答案:

答案 0 :(得分:1)

这是对beforeMarshall功能的误用。你应该做的是使用Entity Mutator方法在持久化之前根据需要设置属性。

通过在protected function _setName()中创建PhotoEntity等方法,您可以在实体保留之前更改名称。

You can find out more about Entity Mutators in the book