- Rename Files
- Protect Files
- Fetch Files
- Filter Files
- Send Data to Server
- Insert Watermark
- Save to Database
To rename an uploaded file use the upload.before event:
$handler->on('upload.before', function ($file) {
$file->save = 'myfile';
// OR
$file->saveWithExtension = 'myfile.txt';
});
If you use Filepicker in a application with users you may want to protect the files directory from users that are not logged in.
First create a .htaccess
file inside the files directory containing:
Deny from all
Next edit uploader/index.php
and enable the php_download option:
$config['php_download'] = true;
Now in before any other event listeners register one with these events: upload.before, files.fetch, file.download, file.delete, crop.before:
$handler->on(array('upload.before', 'files.fetch', 'file.download', 'file.delete', 'crop.before'),
function () {
// If the user is Unauthorized, then:
throw new \Hazzard\Filepicker\Exception\AbortException('Unauthorized');
});
To check if the user is authorized you may include a library from your app, call a function, check if a specific session is set, etc.
By default all files will be returned, but you may want to return just some files, for example the ones that belong to a specific user. To do that use the files.fetch event.
$handler->on('files.fetch', function (&$files) {
// Here you may fetch just some files from the database based on the current user, etc.
// $files = array('file1.txt', 'file2.jpg', 'file3.zip');
});
Instead of returning the files you want to show, you can use the files.filter event to filter the files.
The $files
is an array of file instances and $total
is the number of files. You may iterate through the files and unset some.
$handler->on('files.filter', function (&$files, &$total) {
foreach ($files as $index => $file) {
if ($index % 2 == 0) {
unset($files[$index]);
$total--;
}
}
});
To send data to the server use the data option. You can either pass an object or a function that returns an object.
// Example 1
$('#filepicker').filePicker({
// ...
data: {
paramA: 'value1',
paramB: 'value2',
},
});
// Example 2
$('#filepicker').filePicker({
// ...
data: function() {
// Grab the value from an input.
var val = $('#myinput').val();
// Return the object.
return {
paramA: 'value 1',
paramB: val,
}
},
});
On the server side in any of the handler events you can access the data with from the request:
$handler->on('upload.before', function ($file) use ($handler) {
$valueA = $handler->request()->get('paramA'); // <=> $_POST['paramA']
$valueB = $handler->request()->get('paramB'); // <=> $_POST['paramB']
});
$handler->on('files.fetch', function (&$files) use ($handler) {
$valueA = $handler->request()->get('paramA'); // <=> $_GET['paramA']
$valueB = $handler->request()->get('paramB'); // <=> $_GET['paramB']
});
Make sure you add use ($handler)
to use the $handler
variable inside the scope of the function.
To insert a watermark, in the after option callback use the insert method on the $image
object (and don't forget to save it):
/**
* Insert watermark.
*
* @param \Intervention\Image\Image $image
* @param string $filename
* @param string $version
*/
$watermark = function ($image, $filename, $version) {
$image->insert(__DIR__.'/watermark.jpg', 'bottom-left')->save();
};
// Add watermark to the default image version.
$config['image_versions..after'] = $watermark;
// Add watermark to the "thumb" image version.
$config['image_versions.thumb.after'] = $watermark;
If you want to position the watermark somewhere else make sure to read the docs for the insert method.
This example will show how to save files for a specified user. This could also be a page id or some other identifier for which you want to attach files to.
You will need a table for the files, a library to interact with the database and the id of the current user (for this example).
For the database table let's let's use MySQL:
CREATE TABLE `files` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`file_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`mime_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`size` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
The user_id
you could use something else, like a post_id
, customer_id
etc.
Next we'll create a simple PDO connection, but you could use your own database library:
// uploader/index.php
$host = 'localhost';
$username = 'root';
$password = 'secret';
$dbname = 'filepicker';
$db = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
To save the files to database, use the upload.success event. Here you'll need the user id that you can either send it via data option or the session.
$handler->on('upload.success', function ($file) use ($db) {
// Here you may use $_POST['user_id'], $_SESSION['user_id'] etc. to ge the id of the user.
$userId = 1;
$db->prepare('INSERT INTO `files` (`user_id`, `file_name`, `mime_type`, `size`) VALUES (?, ?, ?, ?)')
->execute([$userId, $file->getFilename(), $file->getMimeType(), $file->getSize()]);
// Set the id to be available on the client side via file.data.id
$file->data = ['id' => $db->lastInsertId()];
});
To only fetch files for a specified user use the files.fetch event:
$handler->on('files.fetch', function (&$files, &$total) use ($db) {
$userId = 1;
$limit = (int) $_GET['limit'];
$offset = (int) $_GET['offset'];
// Fetch files
$stmt = $db->prepare("SELECT * FROM `files` WHERE `user_id` = ? LIMIT $limit OFFSET $offset");
$stmt->execute([$userId]);
$data = $stmt->fetchAll(PDO::FETCH_CLASS);
$files = array_map(function ($file) { return $file->file_name; }, $data);
// Fetch the total number of files
$stmt = $db->prepare('SELECT count(id) as aggregate FROM `files` WHERE `user_id` = ?');
$stmt->execute([$userId]);
$data = $stmt->fetchAll(PDO::FETCH_CLASS);
$total = isset($data[0]->aggregate) ? $data[0]->aggregate : 0;
});
To delete a file from database use the file.delete event:
$handler->on('file.delete', function ($file) use ($db) {
$userId = 1;
$stmt = $db->prepare('DELETE FROM `files` WHERE `user_id` = ? AND `file_name` = ?');
$stmt->execute([$userId, $file->getFilename()]);
});