PHPackages                             eduvl/laravel-filekit - 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. eduvl/laravel-filekit

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

eduvl/laravel-filekit
=====================

Typed file upload services for Laravel (images, audio, video, generic files) with signed Urls

v0.2.0(3mo ago)011MITPHPPHP ^8.2 || ^8.3 || ^8.4

Since Nov 1Pushed 3mo agoCompare

[ Source](https://github.com/EduardVKS/laravel-filekit)[ Packagist](https://packagist.org/packages/eduvl/laravel-filekit)[ RSS](/packages/eduvl-laravel-filekit/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (7)Versions (4)Used By (0)

Laravel FileKit
===============

[](#laravel-filekit)

> Typed upload services for Laravel: **images**, **audio**, **video** and **generic files** with safe paths, MIME whitelists, and **signed URLs** for private disks.

[![PHP](https://camo.githubusercontent.com/b4b7040ebed38a8e9b5f583e3859fc19d8981d4c5d7bdd18a6cae5e8ba1545c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d3737376262333f6c6f676f3d706870)](#requirements)[![Laravel](https://camo.githubusercontent.com/f6da9cca9d4219df676bf2e580dcbbd29a21c9e7c0f002073f1924c89537fc18/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d313025323025374325323031312d6666326432303f6c6f676f3d6c61726176656c)](#requirements)[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)

---

✨ Features
----------

[](#-features)

- ✅ Upload from `UploadedFile`, **local path**, **HTTP URL**, **data:base64**, or **raw bytes**
- ✅ Per-type **MIME whitelists** and **size limits**
- ✅ **Signed routes** for private disks (`filekit.show`, `filekit.download`)
- ✅ Clean result object: `UploadResult { path, url, disk, mime, size }`
- ✅ Extensible (add your own `VideoService`, etc.)
- ✅ Laravel **auto-discovery** and publishable config

---

📚 Contents
----------

[](#-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Publish Config](#publish-config)
- [Quick Start](#quick-start)
- [API](#api)
- [Signed URLs](#signed-urls)
- [Validation](#validation)
- [Extending](#extending)
- [Security Notes](#security-notes)
- [Testing (Testbench)](#testing-testbench)
- [Troubleshooting](#troubleshooting)
- [Versioning](#versioning)
- [Contributing](#contributing)
- [License](#license)

---

✅ Requirements
--------------

[](#-requirements)

ComponentVersionPHP^8.2 / ^8.3 / ^8.4Laravel10.x or 11.xGuzzle^7.8 (installed automatically)---

📦 Installation
--------------

[](#-installation)

### Packagist (when published)

[](#packagist-when-published)

```
composer require eduvl/laravel-filekit
```

### From GitHub (VCS)

[](#from-github-vcs)

Add to your app’s `composer.json`:

```
"repositories": [
{ "type": "vcs", "url": "https://github.com/eduvl/laravel-filekit" }
]
```

Then:

```
composer require eduvl/laravel-filekit:*@dev
```

### Local path (for development)

[](#local-path-for-development)

```
"repositories": [
{ "type": "path", "url": "../laravel-filekit", "options": { "symlink": true } }
]
```

```
composer require eduvl/laravel-filekit:*@dev
```

> Uses Laravel auto-discovery — no manual provider registration.

---

⚙️ Publish Config
-----------------

[](#️-publish-config)

```
php artisan vendor:publish --provider="EduVl\FileKit\FileKitServiceProvider" --tag=filekit-config
```

This creates `config/filekit.php`:

```
return [
'disk' => env('FILEKIT_DISK', 'public'),

    'base_dirs' => [
        'files'  => 'uploads',
        'images' => 'uploads/images',
        'audio'  => 'uploads/audio',
    ],

    'signed_url_ttl' => env('FILEKIT_SIGNED_TTL', 60), // minutes
    'max_size_bytes' => env('FILEKIT_MAX_SIZE', 50 * 1024 * 1024),

    'allowed' => [
        'images' => [
            'image/jpeg','image/png','image/gif','image/bmp','image/webp',
            'image/svg+xml','image/x-icon','image/tiff','image/heic','image/heif',
        ],
        'audio'  => [
            'audio/mpeg','audio/wav','audio/ogg','audio/webm','audio/aac',
            'audio/flac','audio/midi','audio/amr',
        ],
        'files'  => [
            'application/pdf','application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/vnd.ms-powerpoint',
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            'application/rtf','application/vnd.oasis.opendocument.text',
            'application/vnd.oasis.opendocument.spreadsheet',
            'application/vnd.oasis.opendocument.presentation',
            'application/epub+zip','text/plain','application/json','text/csv',
            'application/zip','application/x-7z-compressed','application/x-rar-compressed',
            'application/x-tar','application/gzip','application/x-bzip2',
            'image/jpeg','image/png','image/webp',
            'video/mp4','video/webm','video/quicktime',
        ],
    ],
];
```

> Using the local **public** disk? Run:
>
> ```
> php artisan storage:link
> ```

---

🚀 Quick Start
-------------

[](#-quick-start)

```
use Illuminate\Http\Request;
use FileKit;

class ProfilePhotoController
{
public function store(Request $request)
{
$request->validate([
'photo' => ['required','image','max:5120'], // 5MB
]);

        $res = FileKit::images()->upload(
            $request->file('photo'),
            directory: 'users/'.auth()->id()
        );

        return response()->json([
            'path' => $res->path, // uploads/images/users/123/uuid.jpg
            'url'  => $res->url,  // public or signed URL
            'mime' => $res->mime, // image/jpeg
            'size' => $res->size, // bytes
        ]);
    }
}
```

---

🧰 API
-----

[](#-api)

Facade → manager → services:

```
FileKit::images(); // ImageService
FileKit::audio();  // AudioService
FileKit::video();  // VideoService
FileKit::files();  // Generic FileService
```

### Upload

[](#upload)

```
/** @var \EduVl\FileKit\Contracts\UploadResult $res */
$res = FileKit::images()->upload(
$input,               // UploadedFile | string (see below)
filename: null,       // optional, e.g. "avatar.jpg"
directory: 'users/42' // subfolder appended to base_dir
);
```

**Allowed `$input` types**

- `UploadedFile` (form upload)
- Local **path** string (`/tmp/x.png`)
- **HTTP URL** (`https://…`) — downloaded via Laravel HTTP Client
- **Data URL** (`data:image/png;base64,…`)
- **Raw bytes** string

### Result object

[](#result-object)

```
$res->path; // disk-relative path
$res->url;  // public URL or temporary signed route
$res->disk; // disk name
$res->mime; // MIME type
$res->size; // bytes
```

### Delete

[](#delete)

```
FileKit::files()->remove($res->path); // true (also true if already missing)
```

### Moving and Copying Files

[](#moving-and-copying-files)

You can move (rename) or copy files inside the same storage disk.

```
use EduVl\FileKit\Services\FileService;

/** @var FileService $files */
$files = app(FileService::class);

$result = $files->move(
    from: 'uploads/tmp/photo.jpg',
    toDirectory: 'avatars',
    toFilename: 'user-10.jpg',
    overwrite: true
);

$result = $files->copy(
    from: 'uploads/tmp/photo.jpg',
    toDirectory: 'avatars',
    toFilename: 'user-10.jpg',
    overwrite: true
);

echo $result->path; // avatars/user-10.jpg
echo $result->url;  // public url or signed route

---

## 🔏 Signed URLs

- **Public** disk → direct `Storage::url($path)`.
- **Private** disk → temporary signed routes:
    - `filekit.show` — inline stream
    - `filekit.download` — attachment

TTL is `filekit.signed_url_ttl` (minutes).

Manual download URL:
```php
use Illuminate\Support\Facades\URL;

$url = URL::temporarySignedRoute(
'filekit.download',
now()->addMinutes(60),
['path' => $res->path]
);
```

---

✅ Validation
------------

[](#-validation)

Still validate requests at the controller level:

```
$request->validate([
'file' => ['required', 'mimetypes:image/jpeg,image/png', 'max:10240'] // 10MB
]);
```

The package also enforces its own MIME whitelist and size caps.

---

🧩 Extending
-----------

[](#-extending)

Example: add **ExcelService** in your app:

```
namespace App\Services;

use EduVl\FileKit\Services\FileService;

class ExcelService extends FileService {}
```

- Add Exel MIME list and base dir in `config/filekit.php`.
- Optionally expose a factory method in your own manager wrapper.

---

🔐 Security Notes
----------------

[](#-security-notes)

- **MIME whitelists** per type
- Filename **sanitization** (no dangerous chars)
- No `../` or absolute paths allowed in `directory`
- **Size limit** (`max_size_bytes`)
- HTTP downloads via Laravel HTTP Client (with timeout)
    **Recommended**: domain allow-list, block local/loopback IPs (SSRF), verify `Content-Length`.

---

🧪 Testing (Testbench)
---------------------

[](#-testing-testbench)

This package targets Laravel; use **Orchestra Testbench** for package tests.

Install (in the package repo):

```
composer require --dev "orchestra/testbench:^9.0"
```

`tests/TestCase.php`

```
