Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bocharsky-bw/FileNamingResolver
:open_file_folder: A lightweight library which helps to resolve a file/directory naming of uploaded files using various naming strategies.
https://github.com/bocharsky-bw/FileNamingResolver
Last synced: 2 months ago
JSON representation
:open_file_folder: A lightweight library which helps to resolve a file/directory naming of uploaded files using various naming strategies.
- Host: GitHub
- URL: https://github.com/bocharsky-bw/FileNamingResolver
- Owner: bocharsky-bw
- License: mit
- Created: 2015-12-13T19:47:06.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2016-11-15T21:44:04.000Z (about 8 years ago)
- Last Synced: 2024-11-10T00:51:45.608Z (2 months ago)
- Language: PHP
- Homepage:
- Size: 43 KB
- Stars: 110
- Watchers: 6
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FileNamingResolver
A lightweight library which helps to resolve a file/directory naming of uploaded files
using various naming strategies.> This library solves only naming things and do *nothing* with any files or
directories directly. If you are looking for some filesystem abstraction
layer - looks closer to [Gaufrette][5], [symfony/filesystem][6] or [Flysystem][7]
libraries.[![Travis Status](https://img.shields.io/travis/bocharsky-bw/FileNamingResolver/master.svg?style=flat-square)](https://travis-ci.org/bocharsky-bw/FileNamingResolver)
[![HHVM Status](https://img.shields.io/hhvm/bocharsky-bw/file-naming-resolver/master.svg?style=flat-square)](http://hhvm.h4cc.de/package/bocharsky-bw/file-naming-resolver)
[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/bocharsky-bw/FileNamingResolver.svg?style=flat-square)](https://scrutinizer-ci.com/g/bocharsky-bw/FileNamingResolver/?branch=master)
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/bocharsky-bw/FileNamingResolver.svg?style=flat-square)](https://scrutinizer-ci.com/g/bocharsky-bw/FileNamingResolver/?branch=master)
[![Software License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/bocharsky-bw/FileNamingResolver/blob/master/LICENSE)
[![Latest Version](https://img.shields.io/packagist/v/bocharsky-bw/file-naming-resolver.svg?style=flat-square)](https://packagist.org/packages/bocharsky-bw/file-naming-resolver)[![SensioLabsInsight](https://insight.sensiolabs.com/projects/5a4cfa0f-22b1-4d76-adb3-373017f21ee8/big.png)](https://insight.sensiolabs.com/projects/5a4cfa0f-22b1-4d76-adb3-373017f21ee8)
## Contents
* [Requirements](#requirements)
* [Installation](#installation)
* [Usage](#usage)
* [FileInfo](#fileinfo)
* [Strategy list](#strategy-list)
* [AggregateNamingStrategy](#aggregatenamingstrategy)
* [CallbackNamingStrategy](#callbacknamingstrategy)
* [ContentHashNamingStrategy](#contenthashnamingstrategy)
* [DatetimeNamingStrategy](#datetimenamingstrategy)
* [HashNamingStrategy](#hashnamingstrategy)
* [Example](#example)
* [Contribution](#contribution)## Requirements
This library is standalone without any dependencies. To use it in your project
ensure you correspond to the next requirements:* PHP `5.3` or higher
## Installation
The preferred way to install this package is to use [Composer][3]:
```bash
$ composer require bocharsky-bw/file-naming-resolver
```If you don't use `Composer` - register this package in your autoloader manually
following [PSR-4][4] autoloader standard or simply download this library and
`require` the necessary files directly in your scripts:```php
require_once __DIR__ . '/path/to/library/src/FileNamingResolver.php';
// and other files you intend to use...
```## Usage
First of all, before using file naming resolver, you should determine which naming
strategy to use. You can use different strategies out-of-the-box or easily create
your own one by implementing the `NamingStrategyInterface` interface or extends the
`AbstractNamingStrategy` class which already implemented it for you.```php
// don't forget to use namespaces
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\HashNamingStrategy;// First of all, upload new file or use any uploaded file on the your server
// Create source FileInfo object from FQFN of uploaded file
$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');// Create at least one naming strategy object
$hashStrategy = new HashNamingStrategy();// Create file naming resolver and pass naming strategy to it
$namingResolver = new FileNamingResolver($hashStrategy);// Resolve new name using specified naming strategy
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/4e/d3/a51a07c8e89ff8f228075b7fc76b.jpg// Use rename() / move_uploaded_file() built-in functions, Gaufrette or any other filesystem
// abstraction library to move uploaded file to the directory according to suggested pathname.
```> **NOTE:** In all examples hereinafter the `__DIR__` equals to `/var/www/html/web`.
## FileInfo
The `FileNamingResolver\FileInfo` class extends `\SplFileInfo` object. For more info
check the [SplFileInfo][10]. Below shown list of frequently used getters of this class:```php
$fileInfo = new FileInfo('/var/www/html/web/uploads/products/image.jpg');echo $fileInfo->toString(); // '/var/www/html/web/uploads/products/image.jpg'
echo $fileInfo->getPathname(); // '/var/www/html/web/uploads/products/image.jpg'
echo $fileInfo->getPath(); // '/var/www/html/web/uploads/products'
echo $fileInfo->getFilename(); // 'image.jpg'
echo $fileInfo->getBasename(); // 'image'
echo $fileInfo->getExtension(); // 'jpg'
echo $fileInfo->getPathRelativeTo('/var/www/html/web'); // 'uploads/products'
echo $fileInfo->getPathnameRelativeTo('/var/www/html/web'); // 'uploads/products/image.jpg'
```## Strategy list
### AggregateNamingStrategy
This naming strategy allows to use as many naming strategies as you need at once.
Its aggregate results. Each new result pathname based on the previous one.```php
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\AggregateNamingStrategy;
use FileNamingResolver\NamingStrategy\DatetimeNamingStrategy;
use FileNamingResolver\NamingStrategy\HashNamingStrategy;$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');
$datetimeStrategy = new DatetimeNamingStrategy();
$hashStrategy = new HashNamingStrategy();
// Create an aggregate naming strategy object
$strategies = [
$datetimeStrategy,
$hashStrategy,
// and so on as many as you need...
];
$aggregateStrategy = new AggregateNamingStrategy($strategies);$namingResolver = new FileNamingResolver($aggregateStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/2015/12/9c/98/87cbf44f53c9f6fa08f44ce705c8.jpg
```To reverse applying order of strategies pass `true` as second parameter to the
constructor of `AggregateNamingStrategy` class:```php
$aggregateStrategy = new AggregateNamingStrategy($strategies, AggregateNamingStrategy::MODE_REVERSE);$namingResolver = new FileNamingResolver($aggregateStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/a0/cb/2015/12/11-23-35-039900.jpg
```### CallbackNamingStrategy
This naming strategy allows create a custom naming logic using custom callbacks.
```php
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\CallbackNamingStrategy;$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');
// Create a custom callback naming strategy object
$callbackStrategy = new CallbackNamingStrategy(function (FileInfo $srcFileInfo) {
$dstFileInfo = $srcFileInfo
// Add 'products' suffix to the path
->changePath($srcFileInfo->getPath().FileInfo::SEPARATOR_DIRECTORY.'products')
// Generate custom basename of the file without extension
->changeBasename(time().'-'.uniqid()) // comment this line to keep original basename
// or do whatever custom naming logic you want here...
;return $dstFileInfo;
});$namingResolver = new FileNamingResolver($callbackStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/products/1450004778-566d512a32d2c.jpg
```### ContentHashNamingStrategy
The naming behavior of hash naming strategy looks like [Twig][8] naming of cached files.
```php
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\ContentHashNamingStrategy;$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');
// Create a hash naming strategy object
$contentHashStrategy = new ContentHashNamingStrategy(
// Hashing algorithm, by default: 'md5'
ContentHashNamingStrategy::ALGORITHM_SHA1, // 'sha1'
// Count of parts for explode, by default: 2
3,
// Length of each exploded part, by default: 2
3,
// Keep full filename for easy searching
true
);$namingResolver = new FileNamingResolver($contentHashStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/4ed/3a5/1a0/4ed3a51a07c8e89ff8f228075b7fc76b.jpg
```> **NOTE:** Be sure that source file *really* exist before using `ContentHashNamingStrategy`
otherwise an `InvalidArgumentException` will be thrown. You probably need to use a `isFile()`
method on `FileInfo` object to be sure that file exists. It's necessary because this naming
strategy try to hash a *real* file content.### DatetimeNamingStrategy
The naming behavior of datetime naming strategy looks like [WordPress][9] naming
of uploaded media files.```php
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\DatetimeNamingStrategy;$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');
// Create a datetime naming strategy object
$datetimeStrategy = new DatetimeNamingStrategy(
// DateTime format for directories, by default: 'Y/m'
DateTimeNamingStrategy::FORMAT_DIR_YEAR_MONTH_DAY, // 'Y/m/d'
// DateTime format for files, by default: 'H-i-s-u'
DateTimeNamingStrategy::FORMAT_FILE_TIMESTAMP_MICROSECONDS // 'U-u'
);$namingResolver = new FileNamingResolver($datetimeStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/2015/12/13/1450004392-907500.jpg
```### HashNamingStrategy
The naming behavior of hash naming strategy looks like [Twig][8] naming of cached files.
```php
use FileNamingResolver\FileInfo;
use FileNamingResolver\FileNamingResolver;
use FileNamingResolver\NamingStrategy\HashNamingStrategy;$srcFileInfo = new FileInfo(__DIR__.'/uploads/image.jpg');
// Create a hash naming strategy object
$hashStrategy = new HashNamingStrategy(
// Hashing algorithm, by default: 'md5'
HashNamingStrategy::ALGORITHM_SHA1, // 'sha1'
// Count of parts for explode, by default: 2
3,
// Length of each exploded part, by default: 2
3,
// Keep full filename for easy searching
true
);$namingResolver = new FileNamingResolver($hashStrategy);
$dstFileInfo = $namingResolver->resolve($srcFileInfo);
echo $dstFileInfo->toString(); // /var/www/html/web/uploads/4ed/3a5/1a0/4ed3a51a07c8e89ff8f228075b7fc76b.jpg
```## Example
There is a full working example how to upload files with a simple HTML form and
built-in PHP functions using FileNamingResolver library.```php
resolve($dstFileInfo); // apply specified naming strategy to the destination file// Change extension based on mime type of uploaded file
// WARNING: Could be skipped if you want to base on original extension in $_FILES['attachment']['name'] but it could cause some security issues!
switch ($_FILES['attachment']['type']) {
case 'image/jpeg':
$extension = 'jpg';
break;case 'image/png':
$extension = 'png';
break;default:
$extension = 'bin';}
// The FileInfo object is immutable so changeExtension() creates a new object.
// Don't forget to override previous variable
$dstFileInfo = $dstFileInfo->changeExtension($extension);// create non-existent directories for the destination file
if (false === is_dir($dstFileInfo->getPath())) {
if (false === mkdir($dstFileInfo->getPath(), 0777, true)) {
throw new RuntimeException('Unable to create a directory for the destination file.');
}
}
// move uploaded file according to the destination pathname
if (false === move_uploaded_file($_FILES['attachment']['tmp_name'], $dstFileInfo->toString())) {
throw new RuntimeException('Unable to move an uploaded file to the specified directory.');
}// Do whatever you want after successful uploading (i.e redirect user after success uploading)
echo sprintf(
'File "%s" successfully uploaded to the "%s" web directory! :)',
$dstFileInfo->getFilename(),
$dstFileInfo->getPathRelativeTo(WEB_ROOT_DIR) // get path relative to the web directory
);
}
}?>
```
## Contribution
Feel free to submit an [Issue][1] or create a [Pull Request][2] if you find
a bug or just want to propose an improvement suggestion.In order to propose a new feature, the best way is to submit an [Issue][1]
and discuss it first.[Move UP](#filenamingresolver)
[1]: https://github.com/bocharsky-bw/FileNamingResolver/issues
[2]: https://github.com/bocharsky-bw/FileNamingResolver/pulls
[3]: https://getcomposer.org/
[4]: http://www.php-fig.org/psr/psr-4/
[5]: https://github.com/KnpLabs/Gaufrette
[6]: https://github.com/symfony/filesystem
[7]: https://github.com/thephpleague/flysystem
[8]: https://github.com/twigphp/Twig
[9]: https://github.com/wordpress/wordpress
[10]: http://php.net/manual/en/class.splfileinfo.php