CakePHP 4 File Upload Using Proffer Plugin

CakePHP 4 File Upload Using Proffer Plugin

This tutorial shows how to upload image or file in CakePHP 4 using Proffer plugin. This plugin allows images and files to be uploaded and includes a bundled image library for generating thumbnails from source images. You can also rename the uploaded images. The reference table used in this tutorial is users table which contains id, username, avatar and avatar_dir. The avatar (profile image) will save the image filename and avatar_dir will save the path for the image (basically it based on the record ID).


Download the plugin
Navigate to your application root folder and execute the composer as shown below:

$ composer require 'davidyell/proffer:dev-cake-4'



Once download completed, load the plugin using the console:

bin/cake plugin load Proffer


or you also can load the plugin at ...\src\Application.php and add the following codes in public function bootstrap()

public function bootstrap(): void
{
	$this->addPlugin('Proffer');


Configure The Upload Behaviour
Next, add the upload behaviour to your model eg: UsersTable.php (if the files/image to be uploaded in users) in public function initialize.

File Location: ...\src\Model\Table\UsersTable.php

public function initialize(array $config): void
{
	parent::initialize($config);

	//other code
	
$this->addBehavior('Proffer.Proffer', [
	'avatar' => [	// The name of your upload field
		'root' => WWW_ROOT . 'files', // Customise the root upload folder here, or omit to use the default
		'dir' => 'avatar_dir',	// The name of the field to store the folder
		'thumbnailSizes' => [ // Declare your thumbnails
			'square' => [	// Define the prefix of your thumbnail
				'w' => 200,	// Width
				'h' => 200,	// Height
				'jpeg_quality'	=> 100
			],
			'portrait' => [		// Define a second thumbnail
				'w' => 100,
				'h' => 300
			],
		],
		'thumbnailMethod' => 'gd'	// Options are Imagick or Gd
	]
]);

}


Note*: Remove the thumbnail size configuration if it is unnecessary for your project.
Note: The avatar is referring to the field name in your table. If you name the field as an attachment, then the avatar should be changed as attachment and attachment_dir.

Configure Form
In your view, the for, create and form input should use 'type' => 'file'. If the form is not configured to type = file, no file/image will be upload.

File Location: ...\templates\Users\add.php

<?php echo $this->Form->create($user, ['type' => 'file']); ?>
... other code/input
<?php echo $this->Form->control('avatar', ['type' => 'file']); ?>


It will render your form as shown below for avatar input.


At this phase, you should be able to upload an image or file. Your file will be uploaded to the respective folder: .../files/users/avatar/...

View Uploaded File/Image
To call or view the uploaded image, add the following code in your view.

<?php echo $this->Html->image('../files/users/avatar/' . $user->avatar_dir . '/' . $user->avatar ); ?>


If it is not an image file, eg: PDF, use this code to download the attachment/file:

<?php echo $this->Html->link('Download Attachment', 
	'../files/users/avatar/' . $user->avatar_dir . '/' . $user->avatar,
    ['class'=>'button',  'download' => true, 'title'=>'Download', 'escape' => false]); ?>


To validate the input eg: .jpg file only can be upload, just validate using standard CakePHP validator as shown below:

$validator
	->scalar('avatar')
	->requirePresence('avatar', 'create')
	->allowEmpty('avatar')
	->add('avatar', [
		'validExtension' => [
			'rule' => ['extension',['pdf']], // default  ['gif', 'jpeg', 'png', 'jpg']
			'message' => 'These files extension are allowed: .pdf'
		]]);


That all. Happy coding :)