PHP code example of tobento / service-file-storage

1. Go to this page and download the library: Download tobento/service-file-storage 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 / service-file-storage example snippets


use Tobento\Service\FileStorage\FileWriteException;

try {
    $storage->write(
        path: 'folder/file.txt',
        content: 'message',
    );
} catch (FileWriteException $e) {
    //
}

$exists = $storage->exists(path: 'folder/image.jpg');

var_dump($exists);
// bool(true)

use Tobento\Service\FileStorage\FileInterface;
use Tobento\Service\FileStorage\FileNotFoundException;

try {
    $file = $storage
        ->with('stream', 'mimeType')
        ->file(path: 'folder/image.jpg');

    var_dump($file instanceof FileInterface);
    // bool(true)
} catch (FileNotFoundException $e) {
    //
}

use Tobento\Service\FileStorage\FilesInterface;

$files = $storage->with('stream', 'mimeType')->files(
    path: 'folder',
    recursive: false // is default
);

var_dump($files instanceof FilesInterface);
// bool(true)

use Tobento\Service\FileStorage\FileException;

try {
    $storage->delete(path: 'folder/image.jpg');
} catch (FileException $e) {
    // could not delete file
}

use Tobento\Service\FileStorage\FileException;

try {
    $storage->move(from: 'old/image.jpg', to: 'new/image.jpg');
} catch (FileException $e) {
    // could not move file
}

use Tobento\Service\FileStorage\FileException;

try {
    $storage->copy(from: 'old/image.jpg', to: 'new/image.jpg');
} catch (FileException $e) {
    // could not copy file
}

$file = $storage
    ->with(
        'stream',
        'mimeType',
        'size', // not needed if stream is set as it can get size from stream.
        'width', 'height', // ignored if not image.
        'lastModified',
        'url',
    )
    ->file(path: 'folder/image.jpg');

$stream = $file->stream();
$mimeType = $file->mimeType();
$size = $file->size();
$width = $file->width();
$height = $file->height();
$lastModified = $file->lastModified();
$url = $file->url();

use Tobento\Service\FileStorage\FolderException;

try {
    $storage->createFolder(path: 'folder/name');
} catch (FolderException $e) {
    // could not create folder
}

$exists = $storage->folderExists(path: 'folder/name');

var_dump($exists);
// bool(true)

use Tobento\Service\FileStorage\FoldersInterface;

$folders = $storage->folders(
    path: '',
    recursive: false // is default
);

var_dump($folders instanceof FoldersInterface);
// bool(true)

use Tobento\Service\FileStorage\FolderException;

try {
    $storage->deleteFolder(path: 'folder/name');
} catch (FolderException $e) {
    // could not delete folder
}

use Tobento\Service\FileStorage\Storages;
use Tobento\Service\FileStorage\StoragesInterface;

$storages = new Storages();

var_dump($storages instanceof StoragesInterface);
// bool(true)

use Tobento\Service\FileStorage\StorageInterface;

$storages->add($storage); // StorageInterface

use Tobento\Service\FileStorage\StorageInterface;

$storages->register(
    'name',
    function(string $name): StorageInterface {
        // create storage:
        return $storage;
    }
);

use Tobento\Service\FileStorage\StorageInterface;
use Tobento\Service\FileStorage\StorageException;

$storage = $storages->get('name');

var_dump($storage instanceof StorageInterface);
// bool(true)

$storages->get('unknown');
// throws StorageException

var_dump($storages->has('name'));
// bool(false)

use Tobento\Service\FileStorage\Storages;
use Tobento\Service\FileStorage\StorageInterface;
use Tobento\Service\FileStorage\StorageException;

$storages = new Storages();

// add "locale" storage:
$storages->add($storage);

// add default:
$storages->addDefault(name: 'primary', storage: 'local');

// get default storage for the specified name.
$primaryStorage = $storages->default('primary');

var_dump($primaryStorage instanceof StorageInterface);
// bool(true)

var_dump($storages->hasDefault('primary'));
// bool(true)

var_dump($storages->getDefaults());
// array(1) { ["primary"]=> string(5) "local" }

$storages->default('unknown');
// throws StorageException

use Tobento\Service\FileStorage\Flysystem;
use Tobento\Service\FileStorage\StorageInterface;
use Nyholm\Psr7\Factory\Psr17Factory;

$filesystem = new \League\Flysystem\Filesystem(
    adapter: new \League\Flysystem\Local\LocalFilesystemAdapter(
        location: __DIR__.'/root/directory/'
    )
);

$storage = new Flysystem\Storage(
    name: 'local',
    flysystem: $filesystem,
    fileFactory: new Flysystem\FileFactory(
        flysystem: $filesystem,
        streamFactory: new Psr17Factory()
    ),
    type: 'private', // or 'public'
);

var_dump($storage instanceof StorageInterface);
// bool(true)

use Tobento\Service\FileStorage\NullStorage;
use Tobento\Service\FileStorage\StorageInterface;

$storage = new NullStorage(
    name: 'null',
    type: 'private', // or 'public'
);

var_dump($storage instanceof StorageInterface);
// bool(true)

use Tobento\Service\FileStorage\ReadOnlyStorageAdapter;
use Tobento\Service\FileStorage\StorageInterface;

$storage = new ReadOnlyStorageAdapter(
    storage: $storage, // StorageInterface
    
    // You may throw exeptions if files are not found
    // otherwise an "empty" file is returned.
    throw: true, // false is default
);

var_dump($storage instanceof StorageInterface);
// bool(true)

use Tobento\Service\FileStorage\StorageFactoryInterface;
use Tobento\Service\FileStorage\StorageInterface;
use Tobento\Service\FileStorage\StorageException;

interface StorageFactoryInterface
{
    /**
     * Create a new Storage based on the configuration.
     *
     * @param string $name Any storage name.
     * @param array $config Configuration data.
     * @return StorageInterface
     * @throws StorageException
     */
    public function createStorage(string $name, array $config = []): StorageInterface;
}

var_dump($storage->name());
// string(5) "local"

var_dump($storage->type());
// string(6) "public"

var_dump($storage->isPublic());
// bool(true)

var_dump($storage->isPrivate());
// bool(false)

use Tobento\Service\FileStorage\FileInterface;

$file = $storage
    ->with(
        'stream', 'mimeType', 'size', 'width',
        'lastModified', 'url',
    )
    ->file(path: 'folder/image.jpg');
    
var_dump($file instanceof FileInterface);
// bool(true)

var_dump($file->storageName());
// string(5) "local"

// Modify storage name returning a new instance:
var_dump($file->withStorageName(name: 'foo'));
// string(3) "foo"

var_dump($file->path());
// string(16) "folder/image.jpg"

var_dump($file->name());
// string(9) "image.jpg"

var_dump($file->filename());
// string(5) "image"

var_dump($file->extension());
// string(3) "jpg"

var_dump($file->folderPath());
// string(6) "folder"

var_dump($file->stream() instanceof \Psr\Http\Message\StreamInterface);
// bool(true) or NULL

var_dump($file->content());
// string(...) or NULL

var_dump($file->mimeType());
// string(10) "image/jpeg" or NULL

var_dump($file->size());
// int(20042) or NULL

var_dump($file->humanSize());
// string(5) "15 KB"

var_dump($file->width());
// int(450) or NULL

var_dump($file->height());
// int(450) or NULL

var_dump($file->lastModified());
// int(1672822057) or NULL

var_dump($file->url());
// string(40) "https://www.example.com/folder/image.jpg" or NULL

// Modify url returning a new instance:
$file = $file->withUrl('https://www.example.com/folder/image.jpg');

var_dump($file->metadata());
// array(0) { }

var_dump($file->isHtmlImage());
// bool(true)

use Tobento\Service\FileStorage\FilesInterface;

$files = $storage->with('stream', 'mimeType')->files(
    path: 'folder',
    recursive: false // is default
);

var_dump($files instanceof FilesInterface);
// bool(true)

var_dump($files instanceof \IteratorAggregate);
// bool(true)

use Tobento\Service\FileStorage\FileInterface;

$files = $files->filter(
    fn(FileInterface $f): bool => in_array($f->mimeType(), ['image/jpeg'])
);

use Tobento\Service\FileStorage\FileInterface;

$files = $files->sort(
    fn(FileInterface $a, FileInterface $b) => $a->path() <=> $b->path()
);

use Tobento\Service\FileStorage\FileInterface;

foreach($files->all() as $file) {
    var_dump($file instanceof FileInterface);
    // bool(true)
}

// or just
foreach($files as $file) {}

use Tobento\Service\FileStorage\FolderInterface;

foreach($storage->folders(path: 'foo') as $folder) {
    var_dump($folder instanceof FolderInterface);
    // bool(true)
}

var_dump($folder->storageName());
// string(5) "local"

// Modify storage name returning a new instance:
var_dump($folder->withStorageName(name: 'foo'));
// string(3) "foo"

var_dump($folder->path());
// string(7) "foo/bar"

var_dump($folder->parentPath());
// string(3) "foo"

var_dump($folder->name());
// string(3) "bar"

var_dump($folder->lastModified());
// int(1671889402) or NULL

var_dump($folder->metadata());
// array(0) { }

use Tobento\Service\FileStorage\FoldersInterface;

$folders = $storage->folders(path: '');

var_dump($folders instanceof FoldersInterface);
// bool(true)

use Tobento\Service\FileStorage\FolderInterface;

$folders = $folders->filter(
    fn(FolderInterface $f): bool => in_array($f->storageName(), ['local'])
);

use Tobento\Service\FileStorage\FolderInterface;

$folders = $folders->sort(
    fn(FolderInterface $a, FolderInterface $b) => $a->path() <=> $b->path()
);

use Tobento\Service\FileStorage\FolderInterface;

$folder = $folders->first();

// null|FolderInterface

use Tobento\Service\FileStorage\FolderInterface;

$folder = $folders->get(path: 'foo');

// null|FolderInterface

use Tobento\Service\FileStorage\FolderInterface;

foreach($folders->all() as $folder) {
    var_dump($folder instanceof FolderInterface);
    // bool(true)
}

// or just
foreach($folders as $folder) {}

use Tobento\Service\FileStorage\Repository\FileRepository;

$repository = new FileRepository(storage: $storage);

// Configure repository returing a new instance:
$repository = $repository->withStorage($anotherStorage);

$repository = $repository->withRootFolder('images/'); // default = ''

$repository = $repository->withFileAttributes(['size', 'lastModified']);

$repository = $repository->withRecursive(true); // default false

$file = $repository->create([
    'path' => 'images/photo.jpg',
]);

$file = $repository->create([
    'path' => 'docs/readme.txt',
    'content' => 'Hello World',
]);

use Tobento\Service\FileStorage\Repository\FolderRepository;

$repository = new FolderRepository(storage: $storage);

// Configure repository returning a new instance:
$repository = $repository->withStorage($anotherStorage);

$repository = $repository->withRootFolder('images/'); // default = ''

$repository = $repository->withRecursive(true); // default false

$folder = $repository->create([
    'path' => 'images/gallery/',
]);

use Tobento\Service\FileStorage\Repository\FileRepository;
use Tobento\Service\FileStorage\Repository\FolderRepository;
use Tobento\Service\FileStorage\Repository\FileFolderRepository;

$fileRepo = new FileRepository(storage: $storage);
$folderRepo = new FolderRepository(storage: $storage);

$repository = new FileFolderRepository(
    fileRepository: $fileRepo,
    folderRepository: $folderRepo,
);

// Configure repository returning a new instance:
$repository = $repository->withStorage($anotherStorage);

$repository = $repository->withRootFolder('images/'); // default = ''

$repository = $repository->withRecursive(true); // default false

$repository->create([
    'type' => 'folder',
    'path' => 'projects/2025/',
]);

$repository->create([
    'path' => 'docs/readme.txt',
    'content' => 'Hello World',
]);

$repository->create([
    'path' => 'images/photo.jpg',
]);

$repository->create([
    'path' => 'archives/2024/',
]);

use Tobento\App\Boot;
use Tobento\App\Crud\Boot\Crud;
use Tobento\Service\Routing\RouterInterface;

class RoutesBoot extends Boot
{
    public const BOOT = [
        // you may ensure the crud boot:
        Crud::class,
    ];
    
    public function boot(Crud $crud, RouterInterface $router)
    {
        $crud->routeController(
            controller: App\FileStorageController::class,
            whereId: '[\pL\pN _\-%\.]+', // for non-recursive
        );
        
        // Required for recursive paths (folder/file.txt):
        $router->get('{?locale}/files/{id*}', [App\FileStorageController::class, 'show'])
            ->name('files.show');
    }
}

class FileStorageController extends AbstractCrudController
{
    public const RESOURCE_NAME = 'files';

    public function __construct(
        FileStorageRepository $repository,
    ) {
        $this->repository = $repository;
    }

    public function entityIdName(): string
    {
        // The full path is the only reliable unique identifier.
        // In recursive mode, filenames repeat across folders:
        //   "folder1/image.jpg"
        //   "folder2/image.jpg"
        // Using 'name' would cause collisions.
        //
        // Therefore, always use 'path' as the entity ID.
        return 'path';

        // If recursion is disabled, you *may* use 'name' instead:
        // return 'name';
        //
        // But this only works when all files are in a single directory.
    }
    
    public function createEntityFromObject(object $object): EntityInterface
    {
        // Files and Folders:
        $attributes = [
            'path' => $object->path(),
            'name' => $object->name(),
            'last_modified' => $object->lastModified(),
        ];

        // File-specific attributes:
        if ($object instanceof \Tobento\Service\FileStorage\File) {
            $attributes['extension'] = $object->extension();
            $attributes['mimetype'] = $object->mimeType();
            $attributes['size'] = $object->humanSize();
        }

        return new Entity(
            attributes: $attributes,
            idAttributeName: $this->entityIdName(),
        );
    }
}

folder/subfolder/file.txt