PHPackages                             leasify/nova-s3-multipart-upload - 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. leasify/nova-s3-multipart-upload

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

leasify/nova-s3-multipart-upload
================================

Leasify overtake: A Laravel Nova s3 multipart upload tool.

v1.3.0(4y ago)011.8kMITPHP

Since Oct 16Pushed 3y agoCompare

[ Source](https://github.com/leasify/nova-s3-multipart-upload)[ Packagist](https://packagist.org/packages/leasify/nova-s3-multipart-upload)[ RSS](/packages/leasify-nova-s3-multipart-upload/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (5)Used By (0)

Nova S3 Multipart Upload
========================

[](#nova-s3-multipart-upload)

[![Latest Version on Packagist](https://camo.githubusercontent.com/37e39ec2a36e9ad85766d179776d84b931aa3c6e18760ea54e74067716afb013/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61686d65646b616e64656c2f6e6f76612d73332d6d756c7469706172742d75706c6f61642e737667)](https://github.com/ahmedkandel/nova-s3-multipart-upload) [![Total Downloads](https://camo.githubusercontent.com/333f50275342e371f59e77724afcbc953e2b2858e712939dec37b50326bd7c28/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f61686d65646b616e64656c2f6e6f76612d73332d6d756c7469706172742d75706c6f61642e737667)](https://github.com/ahmedkandel/nova-s3-multipart-upload) [![License](https://camo.githubusercontent.com/a32a630b0dbb5de1491e93917990abea3699018e0129bfa5535b6d03da86ce85/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f61686d65646b616e64656c2f6e6f76612d73332d6d756c7469706172742d75706c6f61642e737667)](https://github.com/ahmedkandel/nova-s3-multipart-upload/blob/master/LICENSE.md)

A Laravel Nova resource tool to upload files directly to Amazon S3. You can (upload | download | delete) single, multiple, small or big files.

[![screenshot](https://github.com/ahmedkandel/nova-s3-multipart-upload/raw/master/docs/screenshot.png?raw=true)](https://github.com/ahmedkandel/nova-s3-multipart-upload/blob/master/docs/screenshot.png?raw=true)

### ⚡ Features

[](#-features)

- **Secure:** No sensitive data will be exposed to the front-end including AWS credentials. The uploaded and downloaded files will never pass through your server for extra protection and performance.
- **Flexible:** File information can be stored in model attributes or as an array under a single model attribute or even as relationship.
- **Solid:** Based on excellent components, [Uppy](https://uppy.io/) file uploader, [Laravel Nova](https://nova.laravel.com/) dashboard and [Amazon S3](https://aws.amazon.com/s3/) storage.
- **Customizable:** Wide range of customization options using chained [methods](#%EF%B8%8F-methods).
- **Image Editor, Custom Meta Fields, Chunked Upload, Webcam Recording, Screen Capture, Authorization, Localization, ...**

### 📌 Installation

[](#-installation)

```
composer require "ahmedkandel/nova-s3-multipart-upload"
```

### 💡 Usage

[](#-usage)

In your Nova resource class add `NovaS3MultipartUpload` tool to fields:

```
use Ahmedkandel\NovaS3MultipartUpload\NovaS3MultipartUpload;

class Post extends Resource
{
    public function fields(Request $request)
    {
        return [
            // ...
            NovaS3MultipartUpload::make('Video'),
        ];
    }
}
```

**NB** the `make` method requires a "human readable" name, it will try to guess the attribute name. You may pass the attribute name as a second argument.

**NB** the attribute name is used to store the file\_path **OR** file/s information in case of `storeAsArray`/`storeAsMultipleArray` **OR** relationship model/s in case of `hasOne`/`hasMany`.

**NB** `hasOne`/`hasMany` methods are valid also for `morphOne`/`morphMany`

---

In your model class add all the attributes that will be filled to `$fillable`:

```
class Post extends Model
{
    protected $fillable = ['video'];
}
```

---

When using `storeAsArray` or `storeAsMultipleArray` methods you will need to cast the attribute to an array in your model class:

```
class Post extends Model
{
    protected $casts = [
        'videos' => 'array',
    ];
}
```

### ⚙️ S3 configuration

[](#️-s3-configuration)

After creating your S3 bucket and connecting it to your Laravel project, You will need an extra step to configure the S3 bucket's "Cross-origin resource sharing (CORS)" with either JSON or XML (this is NOT the "Bucket policy"):

#### JSON

[](#json)

```
[
    {
        "AllowedOrigins": [
            "http://your-domain.com"
        ],
        "AllowedMethods": [
            "GET",
            "PUT"
        ],
        "AllowedHeaders": [
            "Authorization",
            "x-amz-date",
            "x-amz-content-sha256",
            "content-type"
        ],
        "ExposeHeaders": [
            "ETag"
        ],
        "MaxAgeSeconds": 3000
    },
    {
        "AllowedOrigins": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "MaxAgeSeconds": 3000
    }
]
```

#### XML

[](#xml)

```

    http://your-domain.com
    GET
    PUT
    Authorization
    x-amz-date
    x-amz-content-sha256
    content-type
    ETag
    3000

    *
    GET
    3000

```

**NB** please replace `http://your-domain.com` with your front-end domain.

### ✂️ Methods

[](#️-methods)

- **File storage:**

    - `->disk($disk)` Set S3 disk name, default is 's3'.
    - `->path($path)` Set storage path, default is bucket root.
    - `->keepOriginalName()` Keep the file original names, default is to auto generate hashed names "which is recommended".
- **File information:**

    - `->storeName($fileNameColumn)` Stores file\_name in this attribute/column/Key. You can edit the file name before uploading from the uploader panel.
    - `->storeSize($fileSizeColumn)` Stores file\_size (in bytes) in this attribute/column/Key. The size will be formatted (in KB, MB, ...) on the file card.
    - `->storeMeta($array)` Stores other metadata and creates UI to handle them from the uploader panel. The `$array` keys are the attributes/columns/keys. e.g.

        ```
         ->storeMeta(
             [
                 'file_author' => [
                     'name' => 'Author',
                     'placeholder' => 'your name please!',
                     'default' => 'No Author',
                 ],
                 'file_description' => [
                     'name' => 'Description',
                 ],
                 'file_uploaded_at' => [
                     'name' => 'Uploaded At',
                     'default' => now(),
                     'ui' => false,
                 ],
             ]
         )
        ```
- **Model attributes:**

    By default the file\_path is stored in the model attribute specified by the `make` method. Then if any other file information (file\_name, file\_size, metadata) are added they get stored in the corresponding attributes.

    For more flexibility all these attributes could be stored as an associative array under one single model attribute defined by `make` method.

    - `->storeAsArray($fileKeyColumn)` Set the array key that will hold the file\_path.
    - `->storeAsMultipleArray($fileKeyColumn)` Like `storeAsArray` but allow multiple files.

    If you would like to store the file information in separate "child" model that is related to the "main" model attribute defined by `make` method.

    - `->hasOne($fileKeyColumn)` Set the related model attribute that will hold the file\_path, also valid for `morphOne`.
    - `->hasMany($fileKeyColumn)` Like `hasOne` but allow multiple files, also valid for `morphMany`.
    - `->refreshListable()` Refresh listable fields `HasOne` and `HasMany` in your resource detail view each time you upload or delete file.
- **Uploader options:**

    - `->autoProceed()` Start uploading automatically after the first patch of files are selected.
    - `->allowMultipleUploads()` Allow adding more files after uploading the first patch of files.
    - `->restrictions($array)` Rules and conditions to limit the type and/or number of files that can be uploaded. e.g.

        ```
         ->restrictions(
             [
                 'maxFileSize' => 1024 * 1024 * 1024,
                 'minFileSize' => 50 * 1024,
                 'maxTotalFileSize' => 10 * 1024 * 1024 * 1024,
                 'maxNumberOfFiles' => 10,
                 'minNumberOfFiles' => 2,
                 'allowedFileTypes' => [
                     'image/*',
                     'video/*',
                     '.pdf',
                 ],
             ]
         )
        ```
    - `->simultaneousChunks($integer)` The maximum amount of chunks to upload simultaneously.
    - `->chunkSize($integer)` The minimum chunk size in bytes to use when uploading the file.
    - `->panelHeight($integer)` The uploader panel height in pixels.
    - `->fileManagerSelectionType($string)` The type of selection via file manager window ('files', 'folders', 'both'), default is 'files'.
    - `->footerNote($string)` Text to be shown on the footer of the uploader panel. Useful when using `restrictions` to give instructions.
    - `->displayPoweredByUppy()` Display [Uppy team](https://transloadit.com/) credits on the uploader panel.
    - `->translate($array)` Localize the uploader panel. e.g.

        ```
         ->translate(
             [
                 'dropPasteImportBoth' => 'Trascina i file qui, sfoglia %{browseFiles} o %{browseFolders}',
                 'browseFiles' => 'i file',
                 'browseFolders' => 'le cartelle',
                 'myDevice' => 'Dispositivo',
                 'screencast' => 'Schermo',
             ]
         )
        ```

        **NB** you can get a list of available `$array` key from [here](https://github.com/transloadit/uppy/blob/master/packages/%40uppy/locales/src/en_US.js).
- **File card:**

    - `->contentDisposition($array)` How the browser handles the file download, As `['attachment']` or `['inline']` or both `['inline', 'attachment']`, default is `['attachment']`.

### ✔️ Example

[](#️-example)

Uploading multiple files with their (names, sizes, metadata). Then save files information as multiple array in `files` attribute in `User` model.

User model class:

```
class User extends Model
{
    protected $fillable = ['files'];

    protected $casts = [
        'files' => 'array',
    ];
}
```

User resource class:

```
use Ahmedkandel\NovaS3MultipartUpload\NovaS3MultipartUpload;

class User extends Resource
{
    public function fields(Request $request)
    {
        return [
            // ...
            NovaS3MultipartUpload::make('Files')
                ->path($request->user()->id.'-uploads')
                ->storeAsMultipleArray('file_path')
                ->storeName('file_name')
                ->storeSize('file_size')
                ->storeMeta(
                    [
                        'file_author' => [
                            'name' => 'Author',
                            'placeholder' => 'your name please!',
                            'default' => 'No Author',
                        ],
                        'file_description' => [
                            'name' => 'Description',
                        ],
                    ]
                ),
        ];
    }
}
```

Preview:

[![upload](https://github.com/ahmedkandel/nova-s3-multipart-upload/raw/master/docs/upload.gif?raw=true)](https://github.com/ahmedkandel/nova-s3-multipart-upload/blob/master/docs/upload.gif?raw=true)

When files are uploaded the user model files attribute `\App\User::find(1)->files` will have the following value:

```
[
    {
        "file_name": "Video.mkv",
        "file_path": "1-uploads/To5SvZLTyT1XQcUWCTpmqH6GfrgLmoep0tP6EV9n.mkv",
        "file_size": 207683,
        "file_author": "No Author",
        "file_description": null
    },
    {
        "file_name": "Document.pdf",
        "file_path": "1-uploads/RnEBFKa0EqDoKQRkXf27l4dZ7fQ8MTyBofMK202b.pdf",
        "file_size": 77395,
        "file_author": "Ahmed Kandil",
        "file_description": "DDD"
    }
]
```

### 🛂 Authorization

[](#-authorization)

Nova authorize the user to see the resource tool using `->canSee(closure)` method which accepts a Closure that should return `true` or `false`.

We have added more methods to this tool for more granulare control:

- `->canUpload(closure)` allow the user to upload file and show the uploader panel.
- `->canView(closure)` allow the user to list uploaded file and show the files grid.
- `->canDownload(closure)` allow the user to download file and show the download button in the file card.
- `->canDelete(closure)` allow the user to delete file and show the delete button in the file card.

e.g. if you would like to allow the user to upload only if no file attribute is empty:

```
->canUpload(function () {
    return empty($this->model()->video);
})
```

e.g. if you would like to allow the user to delete files in his own model (Post or Video):

```
->canDelete(function () {
    return request()->user()->id === $this->model()->user_id;
})
```

**NB** by default all actions are authorized until you disallow them.

### 🔌 Plugins

[](#-plugins)

- **Image Editor:** enable [Uppy Image Editor](https://uppy.io/docs/image-editor/) plugin using `->useImageEditor($array)` method. The plugin is using the excellent [Cropper.js](https://fengyuanchen.github.io/cropperjs/).

    **Options** the method accepts an array of options:

    ```
     [
     	'autoOpen' => true,
     ]
    ```

    **NB** the editor will be only activated for image files.
- **Webcam:** enable [Uppy Webcam](https://uppy.io/docs/webcam/) plugin using `->useWebcam()` method. Then you can record videos and take pictures to be uploaded.

    **NB** to be able to use the webcam you need https connection.
- **Screen Capture:** enable [Uppy Screen Capture](https://github.com/transloadit/uppy/tree/master/packages/%40uppy/screen-capture/) plugin using `->useScreenCapture()` method. Then you can record your screen or applications to be uploaded.

    **NB** to be able to use the screen capture you need https connection.

### ⚠️ Notes

[](#️-notes)

This package is a resource tool **NOT** a resource field. This means it is only visible under the resource detail view as a panel and can not be inserted in another panel or tab, it must be a direct child of the resource fields array.

**Why?** After a lot of thinking we found that uploading file in the same request of creating a new model is not a good idea. Because the response duration will depend on the file upload progress, which means the user have to wait without any visiual indication hoping that everything will work. So we decided to separate the files (upload | download | delete) process from the model (create | edit) process.

### 📜 Changelog

[](#-changelog)

Please see [CHANGELOG](https://github.com/ahmedkandel/nova-s3-multipart-upload/blob/master/CHANGELOG.md) for more information on what has changed recently.

### 🤝 License

[](#-license)

The MIT License (MIT). Please see [License File](https://github.com/ahmedkandel/nova-s3-multipart-upload/blob/master/LICENSE.md) for more information.

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 80% 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 ~158 days

Total

4

Last Release

1563d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7cc04e320a5076ac210b8e754d2fed618c86afbac64466c357be3031d18054b2?d=identicon)[leasify](/maintainers/leasify)

---

Top Contributors

[![ahmedkandel](https://avatars.githubusercontent.com/u/28398523?v=4)](https://github.com/ahmedkandel "ahmedkandel (12 commits)")[![bryanjamesmiller](https://avatars.githubusercontent.com/u/8781182?v=4)](https://github.com/bryanjamesmiller "bryanjamesmiller (1 commits)")[![mpanius](https://avatars.githubusercontent.com/u/1970673?v=4)](https://github.com/mpanius "mpanius (1 commits)")[![tractorcow](https://avatars.githubusercontent.com/u/936064?v=4)](https://github.com/tractorcow "tractorcow (1 commits)")

---

Tags

laravels3awsuploadnova

### Embed Badge

![Health badge](/badges/leasify-nova-s3-multipart-upload/health.svg)

```
[![Health](https://phpackages.com/badges/leasify-nova-s3-multipart-upload/health.svg)](https://phpackages.com/packages/leasify-nova-s3-multipart-upload)
```

###  Alternatives

[ahmedkandel/nova-s3-multipart-upload

A Laravel Nova s3 multipart upload tool.

2547.2k](/packages/ahmedkandel-nova-s3-multipart-upload)[vinelab/cdn

Content Delivery Network (CDN) Package for Laravel

217240.8k1](/packages/vinelab-cdn)[juhasev/laravelcdn

Content Delivery Network (CDN) Package for Laravel

1820.4k](/packages/juhasev-laravelcdn)[unisharp/s3-presigned

An AWS S3 package for pre-signed upload purpose in Laravel and PHP.

141.8k](/packages/unisharp-s3-presigned)

PHPackages © 2026

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