File upload in AOBuilder

In questo tutorial sono riportati i passi da seguire per l’upload di file in applicazioni CakePHP che utilizzano AOBuilder. Nel caso specifico, si utilizza la libreria \Builder\Lib\Filesystem, che predeve che i file siano archiviati all’interno della directory /webroot/uploads/, dove gli stessi saranno organizzati in ulteriori due sotto directory anno/mese, es. /2017/01 per i file archiviati a gennaio 2017. E’ necessario procedere alla modifica del Controller e dei Templates, il codice illustrato di seguito si riferisce ad una tabella denominata BANDO_DOCUMENTO.

Modifica al Controller

Viene di seguito riportata la porzione di codice relativa alle funzioni di creazione e modifica, che prevedono l’integrazione della libreria \Builder\Lib\Filesystem.

<?php

namespace App\Controller;

use App\Controller\AppController;
use Cake\ORM\TableRegistry;

/**
 * BandoDocumento Controller
 *
 * @property \App\Model\Table\BandoDocumentoTable $BandoDocumento
 */
class BandoDocumentoController extends AppController {

     /*
     * Add method
     *
     * @return void Redirects on successful add, renders view otherwise.
     */
    public function add() {
        $bandoDocumento = $this->BandoDocumento->newEntity();
        if ($this->request->is('post')) {
            $bandoDocumento = $this->BandoDocumento->patchEntity($bandoDocumento, $this->request->data);

            /**
             * File upload in /webroot/uploads/
             */
            $Filesystem = new \Builder\Lib\Filesystem();
            if (isset($this->request->data['file']['name']))
                if (trim($this->request->data['file']['name']) != '')
                    $bandoDocumento->file = $Filesystem->upload($this->request->data['file']);

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

    /**
     * Edit method
     *
     * @param string|null $id Bando Documento id.
     * @return void Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Network\Exception\NotFoundException When record not found.
     */
    public function edit($id = null) {
        $bandoDocumento = $this->BandoDocumento->get($id, [
            'contain' => []
        ]);

        if ($this->request->is(['patch', 'post', 'put'])) {
            $bandoDocumento = $this->BandoDocumento->patchEntity($bandoDocumento, $this->request->data);

            /**
             * File upload in /webroot/uploads/
             */
            $Filesystem = new \Builder\Lib\Filesystem();
            if ($this->request->data['file']['name'])
                $bandoDocumento->file = $Filesystem->upload($this->request->data['file']);
            else
                $bandoDocumento->file = $this->BandoDocumento->get($id)->file;

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

}

Modifica dei Templates

Sono di seguito illustrate le modifiche ai templates, partendo dal codice generato attraverso il Bake.

Modifiche Template Add

Oltre alla modifica del campo FILE, è importante che la form sia di tipo file, per consentire il trasferimento dell’allegato attraverso l’http.

<?php $this->layout = null ?>
<h4><?= __('Add Bando Documento'); ?></h4>
<hr/>
<div>
    <?= $this->Form->create($bandoDocumento, ['type' => 'file']) ?>
    <?= $this->Form->input('titolo'); ?>
    <?= $this->Form->input('descrizione'); ?>
    <?= $this->Form->input('file', ['type' => 'file', 'label' => 'File da allegare']); ?>
    <hr/>
    <?= $this->Form->input('data_inserimento'); ?>
    <?= $this->Form->input('pubblicato_ck'); ?>
    <?= $this->Form->input('bando_id', ['options' => $bando]); ?>
    <hr/>
    <div class="text-center">
        <?= $this->Form->button(__('Save'), ['class' => 'btn btn-success']) ?>  
    </div>
    <?= $this->Form->end() ?>
</div>

Di seguito come si presenta il template di inserimento file.

form-inserimento-allegato-in-ajax

Modifiche Template Edit

Oltre alla modifica del campo FILE, è importante che la form sia di tipo file, per consentire il trasferimento dell’allegato attraverso l’http.

<?php $this->layout = null ?>
<h4><?= __('Edit Bando Documento'); ?></h4>
<hr/>
<div>
    <?= $this->Form->create($bandoDocumento, ['type' => 'file']) ?>
    <?= $this->Form->input('titolo'); ?>
    <?= $this->Form->input('descrizione'); ?>
    <?= $this->Form->input('file'); ?>
    <?= $this->Form->input('file', ['type' => 'file', 'label' => 'File da allegare']); ?>
    <a href="<?= $this->Url->build('/uploads') . h($bandoDocumento->file) ?>"><?= h($bandoDocumento->file) ?></a>
    <hr/>
    <?= $this->Form->input('data_inserimento'); ?>
    <?= $this->Form->input('pubblicato_ck'); ?>
    <?= $this->Form->input('bando_id', ['options' => $bando]); ?>
    <hr/>
    <div class="text-center">
        <?= $this->Form->button(__('Save'), ['class' => 'btn btn-success']) ?>  
    </div>
    <?= $this->Form->end() ?>
</div>

Il template della form di modifica si presenterà in identica a quella di inserimento.

Modifiche al Template Index

Viene riportata solo la porzione di codice relativa alle righe dei dati, in particolare, da notare come la colonna relativa all’allegato viene trasformata in un link con il link al file e riportante nel nome il path relativo del file.

<tbody>
    <?php foreach ($data as $bandoDocumento): ?>
        <tr>
            <td class="check"><input id="" class="" type="checkbox" name="" value="" /></td>
            <td><?= $this->Number->format($bandoDocumento->id) ?></td>
            <td><?= h($bandoDocumento->titolo) ?></td>
            <td><?= h($bandoDocumento->descrizione) ?></td>
            <td><a href="<?= $this->Url->build('/uploads') . h($bandoDocumento->file) ?>"><?= h($bandoDocumento->file) ?></a></td>
            <td><?= h($bandoDocumento->data_inserimento) ?></td>
            <td><?= h($bandoDocumento->pubblicato_ck) ?></td>
            <td><?= h($bandoDocumento->created) ?></td>
        </tr>
    <?php endforeach; ?>
</tbody>

Ecco come si presenta il template dopo la modifica.

form-inserimento-allegato

 

Conclusioni

Nel tutorial è illustrata una soluzione rapida e funzionale per l’upolad del file in AOBuilder, alla quale possono essere effettuate tante altre personalizzazioni. Per approfondimenti è possibile visionare la libreria su https://github.com/aoliverio/builder/blob/master/src/Lib/Filesystem.php

Lascia un commento