Source code for brandon14/cloudinary-flysystem
- Requirements
- Purpose
- Installation
- Usage
- Standards
- Coverage
- Documentation
- Contributing
- Versioning
- Security Vulnerabilities
| Dependency | Version |
|---|---|
| PHP | ^7.2.5 || ^8.0 |
| cloudinary/cloudinary_php | ^2.0.0 |
| league/flysystem | ^2.0.0 || ^3.0.0 |
| psr/log | ^1.0.0 || ^2.0.0 || ^3.0.0 |
| ext-json | * |
This is a beta release package and should not be considered stable for production environments.
Cloudinary is a cloud-based image and video management service. They handle image optimization and transformations via their robust API. This package adapts the Cloudinary API to a Flysystem Adapter to allow for a seamless experience in fetching and uploading resources from your PHP application to Cloudinary's services.
If you are wanting to use this in your Laravel application I have provided a package to seamlessly integrate this package into your Laravel 9 and up application here.
composer require brandon14/cloudinary-flysystemThis Flysystem adapter provides robust configuration options and seamless integration with any PSR-3 compatible logging system. In order to get started, first you need to configure the adapter by creating a Cloudinary SDK instance.
<?php
use Cloudinary\Cloudinary;
$cloudinary = new Cloudinary();You can configure this SDK instance however you wish according to their documentation found here.
Next, you can optionally choose to configure the Flysystem adapter.
use Brandon14\CloudinaryFlysystem\Contracts\Configuration;
// Using default configuration options.
$config = new Configuration();This configuration object allows you to configure the behavior of the adapter including setting an adapter-wide folder prefix, an upload preset to use, whether to fetch raw resources (i.e. text files, etc.) alongside image and video resources, configuration of which extra metadata fields to fetch from Cloudinary's API for the resources, and configuring how to map Flysystem's visibility options to Cloudinary's resource visibility.
Once you have everything configured how like, you can then create the Flysystem adapter.
use Cloudinary\Cloudinary;
use League\Flysystem\Filesystem;use Brandon14\CloudinaryFlysystem\CloudinaryAdapter;
use Brandon14\CloudinaryFlysystem\Contracts\Configuration;
// Create Cloudinary SDK instance and configure to your liking.
$cloudinary = new Cloudinary();
$config = new Configuration();
// Set any configuration options.
// Create the Flysystem adapter.
$adapter = new CloudinaryAdapter($client, $config);
// Create Flysystem filesystem.
$filesystem = new Filesystem($adapter);
// Use Filesystem as needed.
$filesystem->listContents('/');I will eventually fully document this project but for now, the configuration class is
pretty well documented in the code for reference to the options available. Also, the
adapter is configured to be able to tune the mime-type detection, using Flysystem's
league/mime-type-detection library.
This adapter implements the PSR-3 LoggerAwareInterface so that if you want to
provide a compatible logger (i.e. monolog), you can do so. It logs out at debug
level most information occurring inside the adapter, and exceptions caught and thrown
will be logged out at either error (for exception caught in private methods that
might not necessarily lead to an exception being thrown from one of the public
methods) or critical (for exceptions that will make it out of the adapter through the
public methods).
use Monolog\Logger;use Cloudinary\Cloudinary;
use League\Flysystem\Filesystem;use Brandon14\CloudinaryFlysystem\CloudinaryAdapter;
use Brandon14\CloudinaryFlysystem\Contracts\Configuration;
// Create Cloudinary SDK instance and configure to your liking.
$cloudinary = new Cloudinary();
$config = new Configuration();
// Set any configuration options.
// Create PSR-3 logger.
$logger = new Logger('cloudinary');
// Create the Flysystem adapter.
$adapter = new CloudinaryAdapter($client, $config);
$adapter->setLogger($logger);
// Enable logging.
$adapter->enableLogging();NOTE: Cloudinary does not support writing empty files, so if you get an exception trying to write an empty file, this is the reason. If you see in the tests, I override the default Flysystem test case for writing an empty file to expect an exception.
NOTE: If you have issues uploading file types, please open an issue. Cloudinary may handle some files as image/media files instead of raw files. I ran into an issue with PDF files, where it treats them as an image, so I had to add a case in determining the upload resource type for PDF files to upload it as an image. It will still be accessible as a PDF file, just that Cloudinary treats it as an image resource. There may be other file types that are handled this way, so if you run into any please open an issue, so we can resolve them as I can't feasibly test every single file type.
I have gone through the supported media formats from Cloudinary found here and here and included as many as I could. The default mime type detector that Flysystem ships with doesn't include mappings for some of the supported audio and video formats. As long as the mime type contains image it will be handled, provided you supply a MimeTypeDetector that can handle those file types.
Image Types Not Supported By Mime Type Detector:
| Format | Extensions |
|---|---|
| BW (Browzwear file) | .bw |
| DNG (Digital Negative) | .dng |
| FBX (Filmbox) | .fbx |
| FLIF (Free Lossless Image Format) | .flif |
| InDesign | .indd |
| PLY | .ply |
| U3MA (Fabric file) | .u3ma |
| Raw image files | .arw, .cr2 |
Video Types Not Supported By Mime Type Detector:
| Format | Extensions |
|---|---|
| MPEG-2 Transport Stream | .m2ts (others are supported) |
Cloudinary also states to upload audio via the video resource type, and I haven't had a chance to test this very thoroughly, so it may be possible that issues will arise when uploading audio files.
If you know the official mime types of these files, you can either make an issue with
the mime type and I can add it so that it handles it correctly when using a
MimeTypeDetector that supports it, or you can open up a PR with the fixes. For
reference, the MimeTypeDetector is used in the method getResourceType() where it
gets the mime type from the detector, then uses the CloudinaryMimeTypeConverter
instance to transform it into a Cloudinary resource type of 'image', 'video' or
'raw'. The default converter can be modified with new mime types, or you can
provide a customized implementation of the converter to the adapter.
NOTE: Cloudinary's API will currently create a new file with the same name whenever you overwrite a file that already exists with a different visibility than it originally had. My solution to this is to check for a file existing before writing the file, and if it exists, delete it so the file can essentially be overwritten with the new file.
TODO: Add in notes about how to properly handle upload presets.
We strive to meet the PSR-12 coding style for PHP projects, and enforce our
coding standard via the php-cs-fixer linting tool. Our ruleset can be
found in the .php-cs-fixer.dist.php file.
The latest code coverage information can be found via Codecov. We strive to maintain 100% coverage across the entire Flysystem adapter, so if you are contributing, please make sure to include tests for new code added.
Documentation to this project can be found here.
Got something you want to add? Found a bug or otherwise bad code? Feel free to submit pull requests to add in new features, fix bugs, or clean things up. Just be sure to follow the Code of Conduct and Contributing Guide, and we encourage creating clean and well described pull requests if possible.
If you notice an issues with the library or want to suggest new features, feel free to create issues appropriately using the issue tracker.
In order to run the tests, it is recommended that you sign up for a Cloudinary account (it's a free service), and use that
account to run the full integration tests. In order to do that, you will need to copy .env.example to .env and fill
in the variables using the details in your account. The integration tests will use random prefixed directories and clean
everything up before and after the tests.
php-licenses-generator uses semantic versioning that looks like MAJOR.MINOR.PATCH.
Major version changes will include backwards-incompatible changes and may require refactoring of projects using it. Minor version changes will include backwards-compatible new features and changes and will not break existing usages. Patch version changes will include backwards-compatible bug and security fixes, and should be updated as soon as possible.
If you discover a vulnerability within this package, please email Brandon Clothier via [email protected]. All security vulnerabilities will be promptly addressed.
This code is released under the MIT license.
Copyright © 2024 Brandon Clothier