.github/workflows/build.yml 0000644 00000001205 15073164670 0011772 0 ustar 00 name: build
on: [push]
jobs:
run:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.3', '7.4', '8.0']
name: Testing on PHP ${{ matrix.php-versions }}
steps:
- uses: actions/checkout@v2
- name: setup
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring,bcmath
tools: phpunit,composer
- name: install deps
run: composer install -o -q
- name: run phpunit
run: vendor/bin/phpunit
- name: run phpstan
run: vendor/bin/phpstan analyze --no-progress --level=5 src/ .gitignore 0000644 00000000102 15073164670 0006536 0 ustar 00 .DS_Store
composer.lock
vendor/
dev/
.idea/
.phpunit.result.cache
LICENSE 0000644 00000002066 15073164670 0005566 0 ustar 00 The MIT License (MIT)
Copyright (c) 2019 Oliver Vogel
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README.md 0000755 00000006632 15073164670 0006046 0 ustar 00 # A class to detect mime types of given contents

Detecting MIME Content-type in PHP is easy with [mime_content_type](https://www.php.net/manual/en/function.mime-content-type.php) or [Fileinfo](https://www.php.net/manual/en/book.fileinfo.php). But Fileinfo as an extension is sometimes not available on the server. The function `mime_content_type` wants a path to the filesystem as argument and doesn't process if we only have a string value. This package makes it easy to detect the mime types of the content of a given file or string, without any extension dependencies. Here's an example:
```php
use Intervention\MimeSniffer\MimeSniffer;
use Intervention\MimeSniffer\Types\ImageJpeg;
// detect given string
$sniffer = MimeSniffer::createFromString($content);
// or detect given file
$sniffer = MimeSniffer::createFromFilename('image.jpg');
// returns object of detected type
$type = $sniffer->getType();
$bool = $type->isBinary(); // check if we have binary data
$bool = $type->isImage(); // check if we are dealing with an image
$bool = $type->isVideo(); // check video data was detected
$bool = $type->isAudio(); // check if we have detected audio data
$bool = $type->isArchive(); // check if an archive was detected
$type = (string) $type; // cast type to string (e.g. "image/jpeg")
// you can also check, if the content matches a specific type
$bool = $sniffer->matches(new ImageJpeg);
// or check, if the content matches an array of types
$bool = $sniffer->matches([ImageJpeg::class, ImageGif::class]);
// or check, if the content matches an array of type objects
$bool = $sniffer->matches([new ImageJpeg, $type]);
```
If your prefer non-static initialization:
```php
use Intervention\MimeSniffer\MimeSniffer;
// create instance with constructor
$sniffer = new MimeSniffer($content);
// with setter for given content
$type = $sniffer->setFromString($other_content)->getType();
// or with setter for filename
$type = $sniffer->setFromFilename('images/image.jpg')->getType();
```
**Currently only the following file types can be detected. More will be added in a next release.**
### Images
- Image encoded as JPEG raw or in the JFIF or Exif file format
- Image file encoded in the Graphics Interchange Format (GIF)
- Image encoded in the Portable Network Graphics format (PNG)
- Image encoded as BMP file, a bitmap format
- Image encoded in High Efficiency Image File Format (HEIC/HEIF)
- Icon encoded in ICO file format
- Image in Google WebP image format
- Scalable Vector Graphics (SVG)
- Tagged Image File Format (TIFF)
- Image encoded Photoshop Document file format (PSD)
### Archives
- GZIP compressed
- ZIP file
- RAR archive
- TAR file
### Videos
- AVI
- MPEG-1 and MPEG-2 video
- MKV media container
### Audio
- MP3 file
- FLAC file
### Other
- PDF document
- OGG media container
- SQLite Database
- application/octet-stream (default binary)
- text/plain (default)
## Installation
Install the package easily via composer:
```bash
composer require intervention/mimesniffer
```
## Contributing
Contributions are welcome. Please note the following guidelines before submiting your pull request.
- Follow [PSR-2](http://www.php-fig.org/psr/psr-2/) coding standards.
- Write tests for new functions and added features
## License
Licensed under the [MIT License](http://opensource.org/licenses/MIT).
Copyright 2019 [Oliver Vogel](https://olivervogel.com/)
composer.json 0000644 00000001430 15073164670 0007275 0 ustar 00 {
"name": "intervention/mimesniffer",
"description": "PHP MIME Type Sniffer",
"homepage": "http://intervention.io/",
"keywords": ["mime", "type", "sniffer", "detector"],
"license": "MIT",
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@olivervogel.com",
"homepage": "https://olivervogel.com/"
}
],
"require": {
"php": "^7.3|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"phpstan/phpstan": "^0.12.11"
},
"autoload": {
"psr-4": {
"Intervention\\MimeSniffer\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Intervention\\MimeSniffer\\Test\\": "tests"
}
},
"minimum-stability": "stable"
}
phpunit.xml 0000644 00000001035 15073164670 0006765 0 ustar 00
./tests/
src/AbstractBinaryType.php 0000644 00000001024 15073164670 0011624 0 ustar 00 pattern, $this->prepareContent($content)) === 1;
}
/**
* Determine if the detected type is an image
*
* @return boolean
*/
public function isImage(): bool
{
return substr($this->name, 0, 5) === 'image';
}
/**
* Determine if the detected type is an video
*
* @return boolean
*/
public function isVideo(): bool
{
return substr($this->name, 0, 5) === 'video';
}
/**
* Determine if the detected type is an audio file
*
* @return boolean
*/
public function isAudio(): bool
{
return substr($this->name, 0, 5) === 'audio';
}
/**
* Determine if the detected type is an archive
*
* @return boolean
*/
public function isArchive(): bool
{
return in_array($this->name, [
'application/zip',
'application/x-rar-compressed',
'application/x-tar',
'application/gzip',
]);
}
/**
* Prepare content (can be extended by child classes)
*
* @param string $content
* @return string
*/
public function prepareContent(string $content): string
{
return substr($content, 0, 1024);
}
/**
* Determine of current type is binary
*
* @return boolean
*/
public function isBinary(): bool
{
return false;
}
/**
* Cast type to string
*
* @return string
*/
public function __toString(): string
{
return $this->name;
}
}
src/Exceptions/NotMatchingException.php 0000644 00000000240 15073164670 0014264 0 ustar 00 setFromString($content);
}
/**
* Create new instance from given string
*
* @param string $content
*
* @return MimeSniffer
*/
public static function createFromString(string $content): MimeSniffer
{
return new self($content);
}
/**
* Load contents of given string into instance
*
* @param string $content
*
* @return MimeSniffer
*/
public function setFromString(string $content): MimeSniffer
{
$this->content = strval($content);
return $this;
}
/**
* Create a new instance and load contents of given filename
*
* @param string $filename
*
* @return MimeSniffer
*/
public static function createFromFilename(string $filename): MimeSniffer
{
return (new self())->setFromFilename($filename);
}
/**
* Load contents of given filename in current instance
*
* @param string $filename
*
* @return MimeSniffer
*/
public function setFromFilename(string $filename): MimeSniffer
{
$fp = fopen($filename, 'r');
$this->setFromString(fread($fp, 1024));
fclose($fp);
return $this;
}
/**
* Return detected type
*
* @return AbstractType
*/
public function getType(): AbstractType
{
foreach ($this->getTypeClassnames() as $classname) {
$type = new $classname();
if ($type->matches($this->content)) {
return $type;
}
}
$binaryType = new Types\ApplicationOctetStream();
if ($this->matches($binaryType)) {
return $binaryType;
}
return new Types\TextPlain();
}
/**
* Determine if content matches the given type
* or any if the given types in array
*
* @param AbstractType|array $types AbstractType or array of AbstractTypes
* @return boolean
*/
public function matches($types): bool
{
if (! is_array($types)) {
$types = [$types];
}
$types = array_map(function ($value) {
if (is_a($value, AbstractType::class)) {
return $value;
}
if (class_exists($value)) {
return new $value();
}
}, $types);
$types = array_filter($types, function ($type) {
return is_a($type, AbstractType::class);
});
foreach ($types as $type) {
if ($type->matches($this->content)) {
return true;
}
}
return false;
}
/**
* Return array of type classnames
*
* @return array
*/
private function getTypeClassnames(): array
{
$files = array_diff(scandir(__DIR__ . '/Types'), ['.', '..']);
$classnames = array_map(function ($filename) {
return "Intervention\\MimeSniffer\\Types\\" . substr($filename, 0, -4);
}, $files);
return array_filter($classnames, function ($classname) {
return ! in_array($classname, [
Types\ApplicationOctetStream::class,
Types\TextPlain::class,
]);
});
}
}
src/Types/ApplicationGzip.php 0000644 00000000556 15073164670 0012264 0 ustar 00 ]*\?>.*)?