davidyell / CakePHP-Proffer

An upload plugin for CakePHP 3
MIT License
117 stars 63 forks source link

Proffer doesn't create a value for scource_dir in the entity #270

Open Fluit opened 5 years ago

Fluit commented 5 years ago

I'm using the Proffer plugin to upload several documents or pictures, linked to a machine.

In DocsTable I added:

        $this->addBehavior('Proffer.Proffer', [
            'photo' => [
                'root'=>WWW_ROOT.'files',
                'dir' => 'scource_dir',
                'thumbnailSizes' => [
                    'square' => ['w' => 100, 'h' => 100, 'crop'=>true],
                ],
                'thumbnailMethod' => 'Gd'
            ],
            // -> files/<table naam>/<key -> scource>/<value of scource_dir>/
            'scource' => [
                'root'=>WWW_ROOT.'files',
                'dir'=>'scource_dir'
            ]
        ]);

Since Machines has a hasMany association, I added in MachinesTable:

        $this->hasMany('MachineDocs',[
            'className'=>'Docs',
            'foreignKey'=>'machine_id'
        ]);

In the form is I use this code:

        $i = 0;
        <?= $this->Form->create($result,['type' => 'file']);?>
        <?= $this->Form->control('machine_docs.'.$i.'.id', ['type' => 'text','label' => __('id')])?>
        <?= $this->Form->control('machine_docs.'.$i.'.machine_id', ['type' => 'text','label' => __('machine_id')])?>
        <?= $this->Form->control('machine_docs.'.$i.'.idv_id', [
                'type' => 'text',
                'label' => __('idv_id'),
                'default' => 0
        ])?>
        <?= $this->Form->control('machine_docs.'.$i.'.omschrijving', [
                'type' => 'text',
                'default' => 'omschrijving'
        ])?>
        <?= $this->Form->control('machine_docs.'.$i.'.scource', ['type' => 'file','label' => __('Document')])?>
        <?= $this->Form->control('machine_docs.'.$i.'.scource_dir', ['type' => 'hidden',])?>
        <?= $this->Form->button(__('Upload file'),['type'=>'submit','confirm'=>'Confirm', 'class'=>'upload_button']);?>
      <?= $this->Form->end();?>

In the controller there is

            $result = $this->Machines->patchEntity($result, $data, ['associated' => ['MachineDocs']]);

            if ($this->Machines->save($result)) {
                $this->Flash->success(__('The {0} has been saved.',  strtolower($this->name)));
                if ($this->request->is('put')) $this->render; //de edit-view wordt opnieuw gerenderd
                /*
                 * @todo
                 * de index-view renderen als deze pagina beschikbaar is.
                 */
            }

Problem

Al seems to work fine. The result with al the data is send to my database correctly, except for "source_dir", which stays empty.

debug

After patching the $data in the controller I get as $result:

object(App\Model\Entity\Machine) {

    'id' => (int) 373,
    'reg_datum' => object(Cake\I18n\Time) {

        'time' => '2019-02-05T14:54:49+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'naam' => 'MAKITA DTW450RTJ SLAGMOERSLEUTEL',
    'naamlijstnummer' => '',
    'asset_im_nr' => 'IM31561',
    'fabrikant' => 'MAKITA',
    'model_type' => 'DTW450RTJ',
    'leverancier' => 'ERIKS',
    'bouwjaar' => object(Cake\I18n\Date) {

        'time' => '2018-05-18T00:00:00+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false

    },
    'gebruik' => '',
    'instructiebundel' => 'MAKITA DTW450_Accuslagmoersleutel_manual.pdf',
    'foto_id' => (int) 376,
    'vik_id' => (int) 0,
    'idvs_id' => (int) 0,
    'machine_parent_id' => (int) 0,
    'url_vifis' => '',
    'url_instructiebundel' => '',
    'vifis_id' => (int) 0,
    'manual_dir' => 'a9ecf18c-3284-495b-9bee-d2d206f734cc',
    'vifis_dir' => null,
    'vifis_file' => null,
    'asset_id' => null,
    'machine_docs' => [
        (int) 0 => object(App\Model\Entity\Doc) {

            'idv_id' => (int) 0,
            'omschrijving' => 'omschrijving test dsfq',
            'typedoc_id' => (int) 3,
            'scource' => '1GL_Algemeen.docx',
            'scource_dir' => null,
            '[new]' => true,
            '[accessible]' => [
                '*' => true,
                'id' => false,
                'photo' => true,
                'scource' => true,
                'scource_dir' => true
            ],
            '[dirty]' => [
                'idv_id' => true,
                'omschrijving' => true,
                'typedoc_id' => true,
                'scource' => true,
                'scource_dir' => true
            ],
            '[original]' => [],
            '[virtual]' => [],
            '[errors]' => [],
            '[invalid]' => [],
            '[repository]' => 'MachineDocs'

        }
    ],
...
...
    '[new]' => false,
    '[accessible]' => [
        '*' => true,
        'docs' => true,
        'id' => false
    ],
    '[dirty]' => [
        'machine_docs' => true
    ],
    '[original]' => [
        'machine_docs' => [
            (int) 0 => object(App\Model\Entity\Doc) {

                'id' => (int) 1,
                'reg_datum' => object(Cake\I18n\Time) {

                    'time' => '2019-02-08T11:05:02+00:00',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'omschrijving' => 'omschrijving',
                'url' => '',
                'scource' => null,
                'scource_dir' => null,
                'typedoc_id' => (int) 2,
                'machine_id' => (int) 373,
                'idv_id' => (int) 0,
                'photo' => null,
                'typedoc' => object(Cake\ORM\Entity) {

                    'id' => (int) 2,
                    'naam' => 'handlediing',
                    'nom' => '',
                    'img' => 'tag_gray.png',
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[invalid]' => [],
                    '[repository]' => 'Typedoc'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true,
                    'id' => false,
                    'photo' => true,
                    'scource' => true,
                    'scource_dir' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[invalid]' => [],
                '[repository]' => 'MachineDocs'

            },
            (int) 1 => object(App\Model\Entity\Doc) {

                'id' => (int) 2,
                'reg_datum' => object(Cake\I18n\Time) {

                    'time' => '2019-02-08T11:16:59+00:00',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'omschrijving' => 'omschrijving',
                'url' => '',
                'scource' => null,
                'scource_dir' => null,
                'typedoc_id' => (int) 2,
                'machine_id' => (int) 373,
                'idv_id' => (int) 0,
                'photo' => null,
                'typedoc' => object(Cake\ORM\Entity) {

                    'id' => (int) 2,
                    'naam' => 'handlediing',
                    'nom' => '',
                    'img' => 'tag_gray.png',
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[invalid]' => [],
                    '[repository]' => 'Typedoc'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true,
                    'id' => false,
                    'photo' => true,
                    'scource' => true,
                    'scource_dir' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[invalid]' => [],
                '[repository]' => 'MachineDocs'

            },
...
...
            (int) 9 => object(App\Model\Entity\Doc) {

                'id' => (int) 10,
                'reg_datum' => object(Cake\I18n\Time) {

                    'time' => '2019-02-08T15:58:24+00:00',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'omschrijving' => 'omschrijving 16u59',
                'url' => '',
                'scource' => '1GL_Algemeen.docx',
                'scource_dir' => null,
                'typedoc_id' => (int) 5,
                'machine_id' => (int) 373,
                'idv_id' => (int) 0,
                'photo' => null,
                'typedoc' => object(Cake\ORM\Entity) {

                    'id' => (int) 5,
                    'naam' => '3de GL',
                    'nom' => '',
                    'img' => 'tag_orange.png',
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[invalid]' => [],
                    '[repository]' => 'Typedoc'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true,
                    'id' => false,
                    'photo' => true,
                    'scource' => true,
                    'scource_dir' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[invalid]' => [],
                '[repository]' => 'MachineDocs'

            },
            (int) 10 => object(App\Model\Entity\Doc) {

                'id' => (int) 11,
                'reg_datum' => object(Cake\I18n\Time) {

                    'time' => '2019-02-08T16:08:02+00:00',
                    'timezone' => 'UTC',
                    'fixedNowTime' => false

                },
                'omschrijving' => 'omschrijving test',
                'url' => '',
                'scource' => '1GL_Algemeen.docx',
                'scource_dir' => null,
                'typedoc_id' => (int) 4,
                'machine_id' => (int) 373,
                'idv_id' => (int) 0,
                'photo' => null,
                'typedoc' => object(Cake\ORM\Entity) {

                    'id' => (int) 4,
                    'naam' => '1ste GL',
                    'nom' => '',
                    'img' => 'tag_green.png',
                    '[new]' => false,
                    '[accessible]' => [
                        '*' => true
                    ],
                    '[dirty]' => [],
                    '[original]' => [],
                    '[virtual]' => [],
                    '[errors]' => [],
                    '[invalid]' => [],
                    '[repository]' => 'Typedoc'

                },
                '[new]' => false,
                '[accessible]' => [
                    '*' => true,
                    'id' => false,
                    'photo' => true,
                    'scource' => true,
                    'scource_dir' => true
                ],
                '[dirty]' => [],
                '[original]' => [],
                '[virtual]' => [],
                '[errors]' => [],
                '[invalid]' => [],
                '[repository]' => 'MachineDocs'

            }
        ]
    ],
    '[virtual]' => [
        (int) 0 => 'url_instructiebundel_cake',
        (int) 1 => 'url_keuring_cake'
    ],
    '[errors]' => [],
    '[invalid]' => [],
    '[repository]' => 'Machines'

When I look deeper into your code, I notice that there might be an issue with the method "beforeSave" in "ProfferBehavior.php". Although $entity does have 'scource' as a field it never creates an seed for 'scource_dir' and won't save the file to the server, I think caused by the fact that $entity->get('scource') isn't an array.

How can I solve this?

Thanks in advance.

davidyell commented 5 years ago

There is code to set the path back to the entity,

https://github.com/davidyell/CakePHP3-Proffer/blob/master/src/Model/Behavior/ProfferBehavior.php#L137

I think you are setting a value in your post data because you've got a hidden input. This empty value might be overwriting the entity property when you patchEntity with the request data.

Fluit commented 5 years ago

I've removed these lines. Even when de posted data doesn't contain the 'scource_dir' field, there is still no value in de saved record. The problem, I think (when looking a bit deeper) is that in line 87 $entity->get($field)['error'] === UPLOAD_ERR_OK returns 'false' and even '$entity->get('error') === UPLOAD_ERR_OK' in elseif, so it's why '$this->process()' is skipped. After passing line 87, directly true is returned (line 102)

davidyell commented 5 years ago

So you're having a problem uploading a file to the server. Perhaps this could be a file system permissions issue? move_uploaded_file() would be a good test to ensure that PHP can write to your file system.