samedi 30 décembre 2017

Comment créer uploader dans CakePHP3

1.  Comment créer uploader dans CakePHP3
2.  Comment créer downloader dans CakePHP3
3.  Comment créer downloader pour des fichiers de PDF dans CakePHP3

D'abord, nous créons une table avec un fichier de migration:
<?php
use Migrations\AbstractMigration;

class CreateCustomers extends AbstractMigration
{
    /**
     * Change Method.
     *
     * More information on this method is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-change-method
     * @return void
     */
    public function change()
    {
        $table = $this->table('customers');
        $table->addColumn('name', 'string', [
            'default' => null,
            'limit' => 255,
            'null' => false,
        ]);
        $table->addColumn('description', 'text', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('file_location', 'string', [
            'default' => null,
            'null' => true,
            'limit' => 255,
        ]);
        $table->addColumn('created', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->addColumn('modified', 'datetime', [
            'default' => null,
            'null' => false,
        ]);
        $table->create();
    }
}

Et faites les commandes de la migration pour la table de "customers":
$ bin/cake migrations migrate
$ bin/cake bake all customers

Maintenant, créez un uploader avec html5 comme ça:
<input type = "file" name="file"/>

Si nous utilisons $this->Form->input() dans "index.ctp" de CakePHP3:
$this->Form->input('file', ['type'=>'file']);

Et vous allez avoir un uploader comme ça:


Dans l'ensemble, la page de template (index.ctp) sera:
Le code:
<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\Customer $customer
 */
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('List Customers'), ['action' => 'index']) ?></li>
    </ul>
</nav>
<div class="customers form large-9 medium-8 columns content">
    <?= $this->Form->create($customer, ['enctype' => 'multipart/form-data']) ?>
    <fieldset>
        <legend><?= __('Add Customer') ?></legend>
        <?php
            echo $this->Form->control('name');
            echo $this->Form->control('description');
            echo $this->Form->control('file_location', ['type'=>'file']);
        ?>
    </fieldset>
    <?= $this->Form->button(__('Submit')) ?>
    <?= $this->Form->end() ?>
</div>


Maintenant, nous avons un "controller" de la table de "customers". Ouvrez le controller de customers et éditez le pour ajouter la fonction suivante: (Ajoutez "use Cake\Network\Exception\BadRequestException;" et "use Cake\I18n\Date;" dans le fichier)
    private function upload($file, $directory) {
        $today = new Date();
        $yearmonth = $today->i18nFormat('yyyyMM');
        $directory = $directory . "/" . $yearmonth;
        if (!file_exists($directory)) {
            if (!mkdir($directory, 0755, true)) {
                throw new BadRequestException('Impossible de créer le répertoire.');
            }
            chmod($directory, 0755);
        }
        switch ($file['error']) {
            case 0:
                break;
            case UPLOAD_ERR_OK:
                break;
            case UPLOAD_ERR_NO_FILE:
                throw new BadRequestException('Fichier introuvable.');
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                throw new BadRequestException('Fichier trop grand.');
            default:
                throw new BadRequestException('Erreur inconnu');
        }
        $temp = explode('.', $file["name"]);
        $extension = strtolower(end($temp));
        $randString = sha1(time() . rand());
        $uploadFile = $randString . "." . $extension;
        if (!rename($file["tmp_name"], $directory . "/" . $uploadFile)) {
            throw new BadRequestException('Impossible de déplacer le fichier.');
        }
        return $yearmonth.'/'.$uploadFile;
    }

Et changez la fonction de "add":
    public function add()
    {
        $customer = $this->Customers->newEntity();
        if ($this->request->is('post')) {
            $data = $this->request->getData();
            $data['file_location'] = $this->upload($data['file_location'], WWW_ROOT.'uploads/customers');
            $customer = $this->Customers->patchEntity($customer, $data);
            if ($this->Customers->save($customer)) {
                $this->Flash->success(__('The customer has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The customer could not be saved. Please, try again.'));
        }
        $this->set(compact('customer'));
        $this->set('_serialize', ['customer']);
    }

Et vous pouvez uploader un fichier depuis la page de "add".

Le fichier est dans le dossier suivant: \cake\webroot\uploads\customers\201712

Nous pouvons utiliser les fichiers comme ça (dans le fichier de "index.ctp"):

<?php foreach ($customers as $customer): ?>
            <tr>
                <td><?= $this->Number->format($customer->id) ?></td>
                <td><?= h($customer->name) ?></td>
                <td><img src="/cake/uploads/customers/<?= $customer->file_location ?>" width="100" /></td>
                <td><?= h($customer->created) ?></td>
                <td><?= h($customer->modified) ?></td>
                <td class="actions">
                    <?= $this->Html->link(__('View'), ['action' => 'view', $customer->id]) ?>
                    <?= $this->Html->link(__('Edit'), ['action' => 'edit', $customer->id]) ?>
                    <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $customer->id], ['confirm' => __('Are you sure you want to delete # {0}?', $customer->id)]) ?>
                </td>
            </tr>
            <?php endforeach; ?>

Le code complet de "index.ctp"
<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\Customer[]|\Cake\Collection\CollectionInterface $customers
 */
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
    <ul class="side-nav">
        <li class="heading"><?= __('Actions') ?></li>
        <li><?= $this->Html->link(__('New Customer'), ['action' => 'add']) ?></li>
    </ul>
</nav>
<div class="customers index large-9 medium-8 columns content">
    <h3><?= __('Customers') ?></h3>
    <table cellpadding="0" cellspacing="0">
        <thead>
            <tr>
                <th scope="col"><?= $this->Paginator->sort('id') ?></th>
                <th scope="col"><?= $this->Paginator->sort('name') ?></th>
                <th scope="col"><?= $this->Paginator->sort('file_location', 'File') ?></th>
                <th scope="col"><?= $this->Paginator->sort('created') ?></th>
                <th scope="col"><?= $this->Paginator->sort('modified') ?></th>
                <th scope="col" class="actions"><?= __('Actions') ?></th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($customers as $customer): ?>
            <tr>
                <td><?= $this->Number->format($customer->id) ?></td>
                <td><?= h($customer->name) ?></td>
                <td><img src="/cake/uploads/customers/<?= $customer->file_location ?>" width="100" /></td>
                <td><?= h($customer->created) ?></td>
                <td><?= h($customer->modified) ?></td>
                <td class="actions">
                    <?= $this->Html->link(__('View'), ['action' => 'view', $customer->id]) ?>
                    <?= $this->Html->link(__('Edit'), ['action' => 'edit', $customer->id]) ?>
                    <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $customer->id], ['confirm' => __('Are you sure you want to delete # {0}?', $customer->id)]) ?>
                </td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
    <div class="paginator">
        <ul class="pagination">
            <?= $this->Paginator->first('<< ' . __('first')) ?>
            <?= $this->Paginator->prev('< ' . __('previous')) ?>
            <?= $this->Paginator->numbers() ?>
            <?= $this->Paginator->next(__('next') . ' >') ?>
            <?= $this->Paginator->last(__('last') . ' >>') ?>
        </ul>
        <p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
    </div>
</div>




Aucun commentaire:

Enregistrer un commentaire