PHPackages                             68publishers/file-storage - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. 68publishers/file-storage

ActiveLibrary[File &amp; Storage](/categories/file-storage)

68publishers/file-storage
=========================

File management based on Flysystem with an integration into Nette Framework.

v1.4.1(2mo ago)12.8k↓47.5%2MITPHPPHP ^8.1CI passing

Since Jan 28Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/68publishers/file-storage)[ Packagist](https://packagist.org/packages/68publishers/file-storage)[ RSS](/packages/68publishers-file-storage/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (40)Versions (16)Used By (2)

File Storage
============

[](#file-storage)

📁 File management based on [Flysystem](https://github.com/thephpleague/flysystem) with an integration into [Nette Framework](https://nette.org).

[![Checks](https://camo.githubusercontent.com/7ad0cc6a4ec848b2dd7c6b1e0b3e4af247f86b1db3af8f0568fb78543cfa4792/68747470733a2f2f62616467656e2e6e65742f6769746875622f636865636b732f36387075626c6973686572732f66696c652d73746f726167652f6d6173746572)](https://github.com/68publishers/file-storage/actions)[![Coverage Status](https://camo.githubusercontent.com/5e452a402feb2c97c63d5adab8e8f8af1e21c5ec25660045f870eff60d1734c4/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f36387075626c6973686572732f66696c652d73746f726167652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/68publishers/file-storage?branch=master)[![Total Downloads](https://camo.githubusercontent.com/349e60a13b53557fd18aef3917a97722d891d074c7cf585a7b8035e232e0c97d/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f64742f36387075626c6973686572732f66696c652d73746f72616765)](https://packagist.org/packages/68publishers/file-storage)[![Latest Version](https://camo.githubusercontent.com/4f807a621bc01315ae7f7307e498d8e00202a8fc1ba7bc238e9845ef552d498f/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f762f36387075626c6973686572732f66696c652d73746f72616765)](https://packagist.org/packages/68publishers/file-storage)[![PHP Version](https://camo.githubusercontent.com/54c1eff5a6dfd4580323a31a4bbf62006928025ebc735fd75ff331c3e5760bb0/68747470733a2f2f62616467656e2e6e65742f7061636b61676973742f7068702f36387075626c6973686572732f66696c652d73746f72616765)](https://packagist.org/packages/68publishers/file-storage)

Installation
------------

[](#installation)

The best way to install 68publishers/file-storage is using Composer:

```
$ composer require 68publishers/file-storage
```

Integration into Nette Framework
--------------------------------

[](#integration-into-nette-framework)

With this extension, you can register more storages with different roots, filesystem adapters etc. The first registered storage is also considered as the default storage.

### Configuration example

[](#configuration-example)

```
extensions:
    68publishers.file_storage: SixtyEightPublishers\FileStorage\Bridge\Nette\DI\FileStorageExtension

68publishers.file_storage:
    storages:
        default:
            config:
                base_path: /data/files
            filesystem:
                adapter: League\Flysystem\Local\LocalFilesystemAdapter(%wwwDir%/data/files)
                config: [] # an optional config for filesystem adapter
            assets:
                path/to/file.png: my/file.png # single file copying
                path/to/directory: my-directory # copy whole directory
        s3:
            config:
                host: https://my-bucket.s3.amazonaws.com
            filesystem:
                adapter: League\Flysystem\AwsS3V3\AwsS3V3Adapter(@s3client, my-bucket)
```

#### Storage config options

[](#storage-config-options)

nametypedefaultdescriptionbase\_pathstring`''`Base path to a directory where the files are accessible.hostnull or string`null`Hostname, use if the files are not stored locally or if you want to generate an absolute links.version\_parameter\_namestring`_v`Name of a version parameter in URL.### Basic usage

[](#basic-usage)

Generated DI Container will contain an autowired services of type `FileStorageProviderInterface` and `FileStorageInterface` (the default storage).

```
use Nette\DI\Container;
use SixtyEightPublishers\FileStorage\FileStorageInterface;
use SixtyEightPublishers\FileStorage\FileStorageProviderInterface;

/** @var Container $container */

$defaultStorage = $container->getByType(FileStorageInterface::class);

$provider = $container->getByType(FileStorageProviderInterface::class);

$defaultStorage = $provider->get();
# or $defaultStorage = $provider->get('default');
$s3storage = $provider->get('s3');
```

#### Persisting files

[](#persisting-files)

```
use SixtyEightPublishers\FileStorage\FileStorageInterface;

/** @var FileStorageInterface $storage */

# Create a resource from file or url:
$resource = $storage->createResourceFromFile(
    $storage->createPathInfo('test/invoice.pdf'),
    __DIR__ . '/path/to/invoice.pdf'
);

$storage->save($resource);

# Create resource from file that is stored in storage:
$resource = $storage->createResource(
    $storage->createPathInfo('test/invoice.pdf')
);

# copy to the new location
$storage->save($resource->withPathInfo(
    $storage->createPathInfo('test/invoice-2.pdf')
));
```

#### Check a file existence

[](#check-a-file-existence)

```
use SixtyEightPublishers\FileStorage\FileStorageInterface;

/** @var FileStorageInterface $storage */

if ($storage->exists($storage->createPathInfo('test/invoice.pdf'))) {
    echo 'file exists!';
}
```

#### Deleting files

[](#deleting-files)

```
use SixtyEightPublishers\FileStorage\FileStorageInterface;

/** @var FileStorageInterface $storage */

$storage->delete($storage->createPathInfo('test/invoice.pdf'));
```

#### Create links to files

[](#create-links-to-files)

```
use SixtyEightPublishers\FileStorage\FileStorageInterface;

/** @var FileStorageInterface $storage */

# /data/files/test/invoice.pdf
echo $storage->link($storage->createPathInfo('test/invoice.pdf'));

# or

$fileInfo = $storage->createFileInfo($storage->createPathInfo('test/invoice.pdf'));

echo $fileInfo->link();
```

#### Cleaning the storage

[](#cleaning-the-storage)

```
use Nette\DI\Container;
use SixtyEightPublishers\FileStorage\FileStorageProviderInterface;
use SixtyEightPublishers\FileStorage\Cleaner\StorageCleanerInterface;

/** @var Container $container */

$cleaner = $container->getByType(StorageCleanerInterface::class);
$provider = $container->getByType(FileStorageProviderInterface::class);
$storage = $provider->get('default');

# get files count in the specific namespace:
$cleaner->getCount($storage->getFilesystem(), [
    StorageCleanerInterface::OPTION_NAMESPACE => 'test',
]);

# get files count in the whole storage:
$cleaner->getCount($storage->getFilesystem());

# remove files in the specific namespace:
$cleaner->clean($storage->getFilesystem(), [
    StorageCleanerInterface::OPTION_NAMESPACE => 'test',
]);

# clean the whole storage:
$cleaner->clean($storage->getFilesystem());
```

#### Assets copying

[](#assets-copying)

```
use Nette\DI\Container;
use SixtyEightPublishers\FileStorage\FileStorageProviderInterface;
use SixtyEightPublishers\FileStorage\Asset\AssetsCopierInterface;

/** @var Container $container */

$copier = $container->getByType(AssetsCopierInterface::class);
$provider = $container->getByType(FileStorageProviderInterface::class);

# Copies assets defined in the configuration
$copier->copy($provider->get('default'));
$copier->copy($provider->get('s3'));
```

Assets can be defined in the configuration under each storage separately but compiler extensions can define other assets:

```
use Nette\DI\CompilerExtension;
use SixtyEightPublishers\FileStorage\Bridge\Nette\DI\Assets;
use SixtyEightPublishers\FileStorage\Bridge\Nette\DI\AssetsProviderInterface;

final class MyCompilerExtension extends CompilerExtension implements AssetsProviderInterface
{
    public function provideAssets() : array
    {
        return [
            new Assets('s3', [
                'path/to/file1.jpeg' => 'namespace/file1.jpeg',
                'path/to/file2.jpeg' => 'namespace/file2.jpeg',
            ]),
        ];
    }
}
```

### Usage with Doctrine ORM

[](#usage-with-doctrine-orm)

The package provides custom Doctrine DBAL type `file_info`. You can register it manually in this way:

```
use Doctrine\DBAL\Types\Type;
use SixtyEightPublishers\FileStorage\FileStorageProviderInterface;
use SixtyEightPublishers\FileStorage\Bridge\Doctrine\DbalType\FileInfoType;

/** @var FileStorageProviderInterface $fileStorageProvider */

Type::addType(FileInfoType::NAME, FileInfoType::class);

# this line is important:
Type::getType(FileInfoType::NAME)->setFileStorageProvider($fileStorageProvider);
```

Or you can use a compiler extension `FileStorageDoctrineExtension`. The extension requires an integration of package [68publishers/doctrine-bridge](https://github.com/68publishers/doctrine-bridge).

```
extensions:
    68publishers.file_storage.doctrine: SixtyEightPublishers\FileStorage\Bridge\Nette\DI\FileStorageDoctrineExtension

68publishers.file_storage.doctrine:
    type_name: file_info # default
```

#### Example entity and persistence

[](#example-entity-and-persistence)

```
use Doctrine\ORM\Mapping as ORM;
use SixtyEightPublishers\FileStorage\FileInfoInterface;

/**
 * @ORM\Entity
 */
class File
{
    # ID and other columns

    /**
     * @ORM\Column(type="file_info")
     */
    private FileInfoInterface $source;

    public function __construct(FileInfoInterface $source)
    {
        $this->source = $source;
    }

    public function getSource(): FileInfoInterface
    {
        return $this->source;
    }
}
```

```
use Doctrine\ORM\EntityManagerInterface;
use SixtyEightPublishers\FileStorage\FileStorageInterface;

/** @var EntityManagerInterface $em */
/** @var FileStorageInterface $storage */

$pathInfo = $storage->createPathInfo('test/avatar.png');
$resource = $storage->createResourceFromFile($pathInfo, __DIR__ . '/path/to/uploaded/file.png');

$storage->save($resource);

$pathInfo = $pathInfo->withVersion(time());
$entity = new File($storage->createFileInfo($pathInfo));

$em->persist($entity);
$em->flush();

# /data/files/test/avatar.png?_v=1611837352
echo (string) $entity->getSource();
```

### Usage with Latte

[](#usage-with-latte)

```
extensions:
    68publishers.file_storage.latte: SixtyEightPublishers\FileStorage\Bridge\Nette\DI\FileStorageLatteExtension
```

```
{varType SixtyEightPublishers\FileStorage\FileInfoInterface $fileInfo}

{* method FileInfo::__toString() calls ::link() internally so both lines are the same: *}
Download a file
Download a file

{* Create FileInfo from string *}
Download a file
```

### Symfony Console commands

[](#symfony-console-commands)

```
extensions:
    68publishers.file_storage.console: SixtyEightPublishers\FileStorage\Bridge\Nette\DI\FileStorageConsoleExtension
```

Clean storage command:

```
$ bin/console file-storage:clean [] [--namespace ]
```

Copy storage assets:

```
$ bin/console file-storage:copy-assets []
```

Contributing
------------

[](#contributing)

Before opening a pull request, please check your changes using the following commands

```
$ make init # to pull and start all docker images

$ make cs.check
$ make stan
$ make tests.all
```

###  Health Score

51

—

FairBetter than 96% of packages

Maintenance85

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~155 days

Recently: every ~143 days

Total

13

Last Release

75d ago

Major Versions

v0.2.0 → v1.0.02022-12-29

PHP version history (2 changes)v0.1PHP ^7.3

v0.2.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/609005caba54757716c3c037c381376ab298714003da87c9e20aa8c501c97df8?d=identicon)[Jelen](/maintainers/Jelen)

---

Top Contributors

[![tg666](https://avatars.githubusercontent.com/u/24430186?v=4)](https://github.com/tg666 "tg666 (25 commits)")

---

Tags

nettefilefilesstorage68publishers

###  Code Quality

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/68publishers-file-storage/health.svg)

```
[![Health](https://phpackages.com/badges/68publishers-file-storage/health.svg)](https://phpackages.com/packages/68publishers-file-storage)
```

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k639.1M2.2k](/packages/league-flysystem)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.6k263.6M790](/packages/league-flysystem-aws-s3-v3)[league/flysystem-sftp-v3

SFTP filesystem adapter for Flysystem.

6129.6M91](/packages/league-flysystem-sftp-v3)[league/flysystem-async-aws-s3

AsyncAws S3 filesystem adapter for Flysystem.

2610.5M31](/packages/league-flysystem-async-aws-s3)[djurovicigoor/lara-files

Lara-files is a package which will make it easier to work with files. Package has built-in support for DigitalOcean spaces and Amazon S3.

1196.5k](/packages/djurovicigoor-lara-files)[zing/laravel-flysystem-obs

Flysystem Adapter for OBS

1211.2k](/packages/zing-laravel-flysystem-obs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
