1. Go to this page and download the library: Download tobento/app-media library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
tobento / app-media example snippets
use Tobento\App\AppFactory;
use Tobento\App\Media\FeaturesInterface;
// Create the app
$app = (new AppFactory())->createApp();
// Add directories:
$app->dirs()
->dir(realpath(__DIR__.'/../'), 'root')
->dir(realpath(__DIR__.'/../app/'), 'app')
->dir($app->dir('app').'config', 'config', group: 'config')
->dir($app->dir('root').'public', 'public')
->dir($app->dir('root').'vendor', 'vendor');
// Adding boots
$app->boot(\Tobento\App\Media\Boot\Media::class);
// Implemented interfaces:
$features = $app->get(FeaturesInterface::class);
// Run the app
$app->run();
'features' => [
new Feature\File(
// define the supported storages which have public urls:
supportedStorages: ['images'],
// you may throw exeptions if storage or file does not exist for debugging e.g.:
throw: true, // false default
),
],
use Tobento\Media\Feature\File;
use Tobento\Service\FileStorage\FileInterface;
use Tobento\Service\FileStorage\StorageInterface;
$fileUrl = $app->get(File::class)
->storage(storage: 'images')
->file(path: 'path/to/file.jpg')
->url();
$storage = $app->get(File::class)->storage(storage: 'images');
// StorageInterface
$file = $storage->file(path: 'path/to/file.jpg');
// FileInterface
'storages' => [
'files' => [
'factory' => \Tobento\App\FileStorage\FilesystemStorageFactory::class,
'config' => [
// The location storing the files:
'location' => directory('app').'storage/files/',
// Point to the file display feature route uri:
'public_url' => 'https://example.com/media/file/',
],
],
],
'features' => [
new Feature\FileDisplay(
// define the supported storages:
supportedStorages: ['images'],
// you may change the route uri:
routeUri: 'media/file/{storage}/{path*}', // default
// you may define a route domain:
routeDomain: 'media.example.com', // null is default
),
],
'features' => [
new Feature\FileDownload(
// define the supported storages:
supportedStorages: ['images'],
// you may change the route uri:
routeUri: 'media/download/{storage}/{path*}', // default
// you may define a route domain:
routeDomain: 'media.example.com', // null is default
),
],
'features' => [
new Feature\Icons(
// Define the directory where to store cached icons:
cacheDir: directory('app').'storage/icons/',
// You may enable to throw an exception if an icon is not found.
// This is useful during development, but in production, you may want to log a message instead (see below).
throwIconNotFoundException: true, // default is false
),
],
use Tobento\Service\Icon\IconInterface;
use Tobento\Service\Icon\IconsInterface;
final class SomeService
{
public function __construct(
private IconsInterface $icons,
) {
$icon = $icons->get('edit');
// IconInterface
}
}
'aliases' => [
\Tobento\App\Media\Icon\FallbackIcons::class => 'daily',
// or do not log at all:
\Tobento\App\Media\Icon\FallbackIcons::class => 'null',
],
'features' => [
new Feature\ImageEditor(
// define different image editors templates:
templates: [
'default' => [
'crop', 'resize', 'fit', // Used for cropping. You may uncomment all if you want to disable cropping.
'background', 'blur', 'brightness', 'contrast', 'colorize', 'flip', 'gamma', 'pixelate', 'rotate', 'sharpen',
'greyscale', 'sepia', // Filters
'quality', 'format',
],
],
// define the supported storages:
supportedStorages: ['uploads'],
// define the supported mime types:
supportedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
// you may define a custom image actions class:
imageActions: \Tobento\App\Media\Image\ImageActions::class, // default
// define the user permission or null if no permission is needed (not recommended):
userPermission: 'media.image.editor', // default
// you may localize routes:
localizeRoute: true, // false (default)
),
],
'features' => [
new Feature\Picture(
// Define the storage name where to store the generated picture data.
pictureStorageName: 'picture-data',
// Define the storage name where to store each created image. The storage must support urls.
imageStorageName: 'images',
// Define the queue to be used for generating the images:
queueName: 'file',
),
],
'aliases' => [
// Logs if picture generation fails:
\Tobento\App\Media\Picture\PictureGenerator::class => 'daily',
// or do not log at all:
\Tobento\App\Media\Picture\PictureGenerator::class => 'null',
// Logs if image action fails:
\Tobento\App\Media\Image\ImageActions::class => 'daily',
// or do not log at all:
\Tobento\App\Media\Image\ImageActions::class => 'null',
],
'features' => [
new Feature\PictureEditor(
// define different image editors templates:
templates: [
'default' => [
'crop', 'resize', 'fit', // Used for cropping. You may uncomment all if you want to disable cropping.
'background', 'blur', 'brightness', 'contrast', 'colorize', 'flip', 'gamma', 'pixelate', 'rotate', 'sharpen',
'greyscale', 'sepia', // Filters
'quality',
],
],
// define the supported storages:
supportedStorages: ['uploads'],
// define the supported mime types:
supportedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
// you may define a custom image actions class:
imageActions: \Tobento\App\Media\Image\ImageActions::class, // default
// define the user permission or null if no permission is needed (not recommended):
userPermission: 'media.picture.editor', // default
// you may localize routes:
localizeRoute: true, // false (default)
// Images will be generated in the background by the queue by default:
queuePictureGeneration: true, // true (default)
),
],
use Tobento\App\Media\FileStorage\FileWriter;
use Tobento\App\Media\FileStorage\FileWriterInterface;
use Tobento\App\Media\Image\ImageProcessor;
use Tobento\App\Media\Image\Writer;
use Tobento\Service\FileStorage\StorageInterface;
$fileWriter = new FileWriter(
// Define the file storage where to write the files to:
storage: $storage, // StorageInterface
// Define how filenames should be handled:
filenames: FileWriter::ALNUM, // RENAME, ALNUM, KEEP
// Or using a closure for customized filenames:
filenames: function (string $filename): string {
// customize
return $filename;
},
// Define how dublicates should be handled:
duplicates: FileWriter::RENAME, // RENAME, OVERWRITE, DENY
// Define how folders should be handled:
folders: FileWriter::ALNUM, // or KEEP
// Or using a closure for customized folders:
folders: function (string $path): string {
// customize
return $path;
},
// Define the max folder depth limit:
folderDepthLimit: 5,
// You may add writers handling specific files:
writers: [
new Writer\ImageWriter(
imageProcessor: new ImageProcessor(
actions: [
'orientate' => [],
'resize' => ['width' => 2000],
],
),
),
new Writer\SvgSanitizerWriter(),
],
);
use Psr\Http\Message\StreamInterface;
use Tobento\App\Media\Exception\WriteException;
use Tobento\App\Media\FileStorage\WriteResponseInterface;
$writeResponse = $fileWriter->writeFromStream(
stream: $stream, // StreamInterface
filename: 'file.txt',
folderPath: 'path/to', // or an empty string if no path at all
);
var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)
// throws WriteException if writing failed!
use Psr\Http\Message\UploadedFileInterface;
use Tobento\App\Media\Exception\WriteException;
use Tobento\App\Media\FileStorage\WriteResponseInterface;
$writeResponse = $fileWriter->writeUploadedFile(
file: $uploadedFile, // UploadedFileInterface
folderPath: 'path/to', // or an empty string if no path at all
);
var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)
// throws WriteException if writing failed!
use Psr\Http\Message\UploadedFileInterface;
use Tobento\App\Media\FileStorage\WriteResponseInterface;
use Tobento\Service\Message\MessagesInterface;
$writeResponse = $fileWriter->writeUploadedFile(file: $uploadedFile, folderPath: '');
var_dump($writeResponse instanceof WriteResponseInterface);
// bool(true)
// Get the path (string) e.g. path/to/file.txt
$path = $writeResponse->path();
// Get the content (string|\Stringable):
$content = $writeResponse->content();
// Get the original filename (unmodified). Might come from client.
$originalFilename = $writeResponse->originalFilename();
// Get the messages:
$messages = $writeResponse->messages();
// MessagesInterface
use Tobento\App\Media\Upload\Validator;
use Tobento\App\Media\Upload\ValidatorInterface;
$validator = new Validator(
// Define the allowed file extensions:
allowedExtensions: ['jpg', 'png', 'gif', 'webp'],
// Define if you want to allow only strict filename characters
// which are alphanumeric characters, hyphen, spaces, and periods:
strictFilenameCharacters: true, // default
// Define the max. filename length:
maxFilenameLength: 255, // default
// You may define the max. file size in bytes or null (unlimited).
maxFileSizeInKb: 2000,
);
var_dump($validator instanceof ValidatorInterface);
// bool(true)
$filename = $uploadedFile->getClientFilename();
$extension = pathinfo($filename, PATHINFO_EXTENSION);
// is valid as verified
use Tobento\App\Media\FileStorage\FileWriter;
$fileWriter = new FileWriter(
filenames: FileWriter::ALNUM,
// or
filenames: FileWriter::RENAME,
// or
filenames: function (string $filename): string {
// verify filename!
return $verifiedFilename;
},
);
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface as Psr17UploadedFileFactoryInterface;
use Tobento\App\Media\Upload\UploadedFileFactory;
use Tobento\App\Media\Upload\UploadedFileFactoryInterface;
$factory = new UploadedFileFactory(
uploadedFileFactory: $uploadedFileFactory, // Psr17UploadedFileFactoryInterface
streamFactory: $streamFactory, // StreamFactoryInterface
);
var_dump($factory instanceof UploadedFileFactoryInterface);
// bool(true)
use Tobento\App\Media\Image\ImageProcessor;
use Tobento\App\Media\Image\ImageProcessorInterface;
use Tobento\Service\Imager\Action;
use Tobento\Service\Imager\ActionFactoryInterface;
$imageProcessor = new ImageProcessor(
// Define the imager actions to be processed:
actions: [
'orientate' => [],
'resize' => ['width' => 300],
new Action\Contrast(20),
],
// You may define imager actions which are allowed only.
// If empty array all are allowed if not in disallowedActions.
allowedActions: [
Action\Greyscale::class,
],
// You may define imager actions which are not allowed and will be skipped:
disallowedActions: [
Action\Colorize::class,
],
// You may convert certain images e.g. png to jpeg:
convert: ['image/png' => 'image/jpeg'],
// You may adjust the image quality:
quality: ['image/jpeg' => 90, 'image/webp' => 90],
// You may adjust the supported mime types:
supportedMimeTypes: ['image/png', 'image/jpeg', 'image/gif'], // default
// You may define a custom imager actions class:
//actionFactory: $customActionFactory, // ActionFactoryInterface
);
var_dump($imageProcessor instanceof ImageProcessorInterface);
// bool(true)
// Use the following methods to modify the image processor returning a new instance:
$imageProcessor = $imageProcessor->withActions([
'resize' => ['width' => 300],
]);
$imageProcessor = $imageProcessor->withConvert([
'image/png' => 'image/jpeg',
]);
$imageProcessor = $imageProcessor->withQuality([
'image/jpeg' => 90,
'image/webp' => 90,
]);
use Tobento\App\Media\Exception\ImageProcessException;
use Tobento\Service\Imager\ResourceInterface;
use Tobento\Service\Imager\Response\Encoded;
$encoded = $imageProcessor->processFromResource(
resource: $resource, // ResourceInterface
);
var_dump($encoded instanceof Encoded);
// bool(true)
// throws ImageProcessException if image cannot get processed!
use Psr\Http\Message\StreamInterface;
use Tobento\App\Media\Exception\ImageProcessException;
use Tobento\Service\Imager\Response\Encoded;
$encoded = $imageProcessor->processFromStream(
stream: $stream, // StreamInterface
);
var_dump($encoded instanceof Encoded);
// bool(true)
// throws ImageProcessException if image cannot get processed!
'features' => [
new Feature\FileDisplay(
// define the supported storages:
supportedStorages: ['images'],
// you may change the route uri:
routeUri: '{storage}/{path*}',
routeDomain: 'media.example.com',
),
],
'features' => [
new Feature\FileDisplay(
// define the supported storages:
supportedStorages: ['images'],
// you may change the route uri:
routeUri: '{storage}/{path*}',
// you may define a route domain:
routeDomain: 'media.example.com',
),
],
app/config/media.php
php ap icons:clear
app/config/logging.php
app/config/logging.php
php ap picture:clear
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.