chialab / cakephp-object-storage
Object storage plugin for CakePHP applications
Installs: 87
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 1
Type:cakephp-plugin
pkg:composer/chialab/cakephp-object-storage
Requires
- php: >=8.1
- cakephp/cakephp: ^4.3
- cakephp/migrations: ^3.0
- chialab/object-storage: v0.1.0
- webmozart/assert: ^1.11
Requires (Dev)
- cakedc/cakephp-phpstan: ^2.0
- cakephp/cakephp-codesniffer: ^5.1
- guzzlehttp/psr7: ^2.5
- phpstan/extension-installer: ^1.2
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpunit/phpunit: ^9.3
This package is auto-updated.
Last update: 2025-10-04 11:10:04 UTC
README
This plugin offers an implementation of an object storage for CakePHP applications.
Features
This plugin provides:
- migration for creating the
filestable - entity and table classes for
Filesmodel - REST controller
- default routing
- service provider for the storage service using CakePHP's service container
- event listener to inject the service container in table instance on initialization
- modeless forms to handle file operations
- shell command to cleanup incomplete multipart uploads
Installation
You can install this plugin using composer:
composer install chialab/cakephp-object-storage
To use AWS S3 as a backend storage, the SDK is also needed:
composer install aws/aws-sdk-php
Usage
Add the plugin in your Application.php bootstrap:
public function bootstrap(): void { // ... $this->addPlugin('Chialab/CakeObjectStorage'); // ... }
Run the migration to create the files table:
bin/cake migrations migrate --plugin Chialab/CakeObjectStorage
Add the configuration for the backend storage in your app.php:
// ... 'Storage' => [ 'className' => FilesystemAdapter::class, 'args' => [ WWW_ROOT . 'files' . DS, TMP . 'incomplete-uploads' . DS, '/files/', 0007, ], ], // ...
See chialab/php-object-storage library's README for more information on the adapters.
Disable routing
Use ['routes' => false] when adding the plugin to implement your own routes. You can still use Chialab/CakeObjectStorage.Files as controller
if you only want to change the paths, or implement your own controller.
Disable event listener
Use ['bootstrap' => false] when adding the plugin to disable automatically adding the event listener.
If you're using the plugin's FilesTable, you are required to set the DI container to its instances, or implement your own service handling.
Disable service provider
Use ['services' => false] when adding the plugin to disable automatically adding the storage service provider.
You are required to provide a MultipartUploadInterface implementation to FilesTable instances, or implement your own service handling.
Upload
See File::getMultipartChunkSize() for the threshold between small file and multipart upload.
Create file entity
The default controller accepts a request like the following:
POST /files
{
"filename": "example.jpg",
"mime_type": "image/jpg",
"size": 20480 // 20 MiB
}
The response is like the following:
{
"file": {
"filename": "example.jpg",
"mime_type": "image/jpg",
"size": 20480, // 20 MiB
"created": "2023-05-08T15:58:27+00:00",
"id": "076e11d0-4ba6-4680-8796-ee232eeca090",
"is_multipart": true,
"is_finalized": false,
"url": null
},
"chunk_size": 10485760, // 10 MiB, present only if `is_multipart === true`
"upload": "http://ossma.localhost/api/v1/files/076e11d0-4ba6-4680-8796-ee232eeca090/upload",
"finalize": "http://ossma.localhost/api/v1/files/076e11d0-4ba6-4680-8796-ee232eeca090/finalize" // present only if `is_multipart === true`
}
The file entity in the response has a property is_multipart to let the client know if a multipart upload is required.
In this case, the response will also contain a chunk_size property with the maximum file part size, and a finalize URL
to call after all parts have been uploaded.
Upload file
To upload the file, make a request like the following with the file as body:
POST /files/{file_id}/upload
Multipart upload
To upload a part of a multipart upload, add the part query parameter to the request:
POST /files/{file_id}/upload?part=1
The parameter is an incremental number starting from 1, which represent the "index" of the part currently uploading.
The endpoint will respond with a hash of the uploaded part that needs to be stored to finalize the upload later:
{
"part": "1",
"hash": "86507bea6d332c2814df1d244abdd3696169607f5f42ac3f6782dd69883f6b0d"
}
To finalize the upload:
POST /files/{file_id}/finalize
{
"hashes": [
{ "part": 1, hash: "86507bea6d332c2814df1d244abdd3696169607f5f42ac3f6782dd69883f6b0d" },
{ "part": 2, hash: "df7c1db235bac334dab81d0a25824055bdb738bf54fd2857698d4a9fd88af2c6" },
]
}
To abort a multipart upload:
DELETE /files/{file_id}/abort