Skip to main content
📦 Uploading Files With Cake Php and Fileupload Plugin
  1. Posts/

📦 Uploading Files With Cake Php and Fileupload Plugin

·1098 words·6 mins·
PHP Php Cakephp Fileupload
May Meow
Author
May Meow
MayMeow is a developer and cybersecurity enthusiast with a passion for cryptography, DevSecOps, and open-source contributions. They enjoy creating tools that strengthen digital security, blending creativity and technology to innovate in fields like PHP and .NET. Always exploring new frontiers in tech, MayMeow is dedicated to safeguarding the digital landscape through their work.
Table of Contents

I just release new version of my FileUpload plugin for CakePHP.

It will make uploading and downloading files really easi. Want to see? Continue reading.

Prerequisites
#

If you have existing application you can skip right to Create fileupload app.

  • CakePHP 4
  • Https server
  • PHP 7.x or 8
  • php extensions mgstring, intl, SimpleXML, PDO

For more informations check CakePHP Installation

OR

  • Docker
  • Docker-compose

Right, only those two. I will show you ho to do it in this tutorial.

Prepare Environment
#

I will use for this tutorial my CakePHP starter kit, but you are ok to use your existing installation. This starter kit contains all you will need to create your app in no time. It contains:

  • CakePHP 4
  • PHP 7.4.16, witth all required extensions
  • Postgres
  • Minio (s3 storage)
  • Redis
  • Adminer

Ok so start it up, and run comands in shell as follows

mkdir fileupload-tutorial
cd fileupload-tutorial
docker run --rm --volume $(pwd):/app ghcr.io/maymeow/php-ci-cd/php-ci-cd:7.4.16-cs-1 sh -c "composer create-project --prefer-dist maymeow/cakephp-starter-kit:dev-main /app"
sudo chown -R $USER:$GID .

You can run ls -la to check if all folders are owned by you. Ok now we create our application

Create fileupload app
#

Installing plugin
#

First of all we need to install fileupload plugin and load it, run following command

docker-compose -f docker-compose.dev.yml run --rm cake-app composer require maymeow/file-upload

and load it

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php plugin load FileUpload

Creating MVC for Files
#

Next step is to create MVC for our files controller. For our need is enough to have table with file name and time for creating and modifiing. Create migration as follow

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake migration CreateFiles name:string created modified

push changes to database

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php migrations migrate

and create MVC for our files

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake all Files

Now is time to start our application with following command

docker-compose -f docker-compose.dev.yml up -d

Navigate to the http://127.0.0.1:8765/ on your favorite browser an you will see Welcome to CakePHP 4.2.10 Strawberry message. This is OK and or applications is now running. To open or files contriller go to http://127.0.0.1:8765/files.

Creating upload view and controller
#

Standardly CakePHP create controller for viewing, list, editing and adding. But it is not what we need. We want upload file to the server and this one is missing. So create it. First of all create new Modelless form

docker-compose -f docker-compose.dev.yml run --rm cake-app php bin/cake.php bake form Upload 

Navigate to src/Form/UploadForm.php and edit _buildSchema as follows

protected function _buildSchema(Schema $schema): Schema
{
    return $schema->addField('file', 'string');
}

Creating view and controller for Upload form
#

Go to src/Controller/FilesController and add following function

public function upload()
{
    $uploadForm = new UploadForm();

    $this->set(compact('uploadForm'));
}

and create upload.php view in templates/Files with following content

/**
 * @var \App\View\AppView $this
 * @var \App\Form\UploadForm $uploadForm
 */
?>
<div class="row">
    <aside class="column">
        <div class="side-nav">
            <h4 class="heading"><?= __('Actions') ?></h4>
            <?= $this->Html->link(__('List Files'), ['action' => 'index'], ['class' => 'side-nav-item']) ?>
        </div>
    </aside>
    <div class="column-responsive column-80">
        <div class="files form content">
            <?= $this->Form->create($uploadForm, ['type' => 'file']) ?>
            <fieldset>
                <legend><?= __('Upload file') ?></legend>
                <?php
                echo $this->Form->control('file',  ['type' => 'file']);
                ?>
            </fieldset>
            <?= $this->Form->button(__('Submit')) ?>
            <?= $this->Form->end() ?>
        </div>
    </div>
</div>

Now you can navigate to http://127.0.0.1:8765/files/upload and if you see no error but Upload file form you are good to go.

Configuring upload plugin and uploading files
#

Next stem is load our components to the controller

public function initialize(): void
{
    parent::initialize(); // TODO: Change the autogenerated stub

    $this->loadComponent('FileUpload.Upload', [
        'fieldName' => 'file',
    ]);

    $this->loadComponent('FileUpload.Download');
}

Uploading files
#

Now you have loaded Uploadfile plugin’s components so there is left some more thing to do. Update upload function as follows

public function upload()
{
    $uploadForm = new UploadForm();

    if ($this->request->is('post')) {
        $uploadedFile = $this->Upload->getFile($this->request);

        $file = $this->Files->newEmptyEntity();
        $file->name = $uploadedFile->getFileName();
        $this->Files->save($file);

        return $this->redirect(['action' => 'index']);
    }

    $this->set(compact('uploadForm'));
}

If everything goes right you will see your uploading file name in list of all files.

Downloading files
#

Create new function for downloading files in FilesController

public function download($fileName)
{
    $downloadedFile = $this->Download->getFile($fileName);

    $response = $this->response;
    $response = $response->withStringBody($downloadedFile->getFileContent());
    $response = $response->withType($downloadedFile->getFileType());

    if ($this->request->getParam('?.download') == true) {
        $response = $response->withDownload($fileName);
    }

    return $response;
}

And edit templates/Files/index.ctp

# edit line 
<td><?= h($file->name) ?></td>
# to this
<td><?= $this->Html->link($file->name, ['action' => 'download', $file->name, '?' => ['download' => false]]) ?></td>

Refresh page. This will display picture you have uploaded befor by clinking on file name. If you want to show download form instead, cahnge download to true.

S3 Support
#

If you want to use S3 instead of local storage, you need make some small changes for it… First of all open your app_local.php and add at the end of file following config

'S3' => [
    'version' => 'latest',
    'region'  => 'us-east-1',
    'endpoint' => 'http://cake_minio:9000',
    'use_path_style_endpoint' => true,
    'credentials' => [
        'key'    => 'minioadmin',
        'secret' => 'minioadmin',
    ],
]

Now navigate to the http://127.0.0.1:9001 and login with default creadentials, both password and username are minioadmin. In right menu go to buckets and create bucket for your needs. For this purposes i create bucket with name fileupload.tutorial.

You can check it in Object browser on sidebar.

Now let’s configure our application. Update FilesController as follows:

public function initialize(): void
{
    parent::initialize(); // TODO: Change the autogenerated stub

    $this->loadComponent('FileUpload.Upload', [
        'fieldName' => 'file',
        'storagePath' => 'fileupload.tutorial', // bucket name
        'storage_type' => 's3'
    ]);

    $this->loadComponent('FileUpload.Download', [
        'storagePath' => 'fileupload.tutorial', // bucket name
        'storage_type' => 's3'
    ]);
}

Ok, That all now you have application which can upload / download files to local or S3 storage. Easy no?

Conclusion
#

I’m lazy person so I wanted to make it more easier (dont telling that CakePHP on itself is not easy to start) to start my applications. And with Starter kit you are good to go in few seconds and you can focus on your application.

With Fileupload plugin you can upload/download files on bot local and s3 storage literally with one line of code (dont counting configuration). I hope it will make easier for you to manage files uploading in your application to. If you find bugs please report them on FileUpload’s Issue tracker, also if you have some ideas i have opened Discussions for project where you can share your ideas.

Anyway if you like this project you can contibute to it on GitHub repository which is also participating in Hacktoberfest.

Same is for CakePHP starter kit which is on Github too.

Bonus
#

All source codes from this tutorial are awailable here on FileUpload Tutorial Github.

Thank you for reading and have a nice day!

Reply by Email

Related

Sending Strings as Files with CakePHP server response
·83 words·1 min
PHP Back End Cakephp Php
🌈 Php Color Conversion From Hex to Rgb and Back
·277 words·2 mins
PHP Colors Php Daily Rgb Hex
Create API With CakePHP
·490 words·3 mins
PHP Cakephp