PHPackages                             itstructure/laravel-media-file-uploader - 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. itstructure/laravel-media-file-uploader

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

itstructure/laravel-media-file-uploader
=======================================

Media file uploader for laravel framework

1.0.6(6mo ago)0125MITPHPPHP &gt;=7.2.5

Since Jul 14Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/itstructure/laravel-media-file-uploader)[ Packagist](https://packagist.org/packages/itstructure/laravel-media-file-uploader)[ RSS](/packages/itstructure-laravel-media-file-uploader/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (7)Dependencies (2)Versions (9)Used By (0)

Laravel Media File Uploader - MFU
=================================

[](#laravel-media-file-uploader---mfu)

[![Latest Stable Version](https://camo.githubusercontent.com/4018b84ddb4b407abc2d2d8209df0ee7a5c183b5846b9bcccaedc7553ca79351/68747470733a2f2f706f7365722e707567782e6f72672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f762f737461626c65)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)[![Latest Unstable Version](https://camo.githubusercontent.com/69985266e12ff70481f46cba73ee0b687b353d6903b8cf6f73c1944cb0de71e4/68747470733a2f2f706f7365722e707567782e6f72672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f762f756e737461626c65)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)[![License](https://camo.githubusercontent.com/94f2e8131ca9e96536b3da37f4927106ec4ca7c57884f2eb78a6a9ac086765bd/68747470733a2f2f706f7365722e707567782e6f72672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f6c6963656e7365)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)[![Total Downloads](https://camo.githubusercontent.com/54020fc3608abf924d2181fd0c100541fad5043e8c3b8f2df47fd7480a402816/68747470733a2f2f706f7365722e707567782e6f72672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f646f776e6c6f616473)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)[![Build Status](https://camo.githubusercontent.com/7ce92b166585e5138f32de5b152b52c8970476e3e44d912a96fdffbb954322a5/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f6261646765732f6275696c642e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/build-status/main)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/7b11bf13bcc49cb6369c0a9d41e45f27bedc7925aa802bd5d945a2a96968f11c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f69747374727563747572652f6c61726176656c2d6d656469612d66696c652d75706c6f616465722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/?branch=main)

1 Introduction
--------------

[](#1-introduction)

This package is to upload different media files to Local or remote Amazon S3 storage.

[![MFU logotip](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_logotip.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_logotip.png)

2 Requirements
--------------

[](#2-requirements)

- laravel 6+ | 7+ | 8+ | 9+ | 10+ | 11+ | 12+
- Bootstrap 4 for styling
- JQuery
- php &gt;= 7.2.5
- composer 2
- One of the next php extensions: GD|Imagick|Gmagick

3 Installation
--------------

[](#3-installation)

### 3.1 Install package

[](#31-install-package)

#### General from remote Packagist repository

[](#general-from-remote-packagist-repository)

Run the composer command:

`composer require itstructure/laravel-media-file-uploader "^1.0.6"`

#### If you are testing this package from a local server directory

[](#if-you-are-testing-this-package-from-a-local-server-directory)

In application `composer.json` file set the repository, as in example:

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

Here,

**../laravel-media-file-uploader** - directory path, which has the same directory level as application and contains MFU package.

Then run command:

`composer require itstructure/laravel-media-file-uploader:dev-main --prefer-source`

### 3.3 Publish files - Required part

[](#33-publish-files---required-part)

- To publish config run command:

    `php artisan uploader:publish --only=config`

    It stores config file to `config` folder.

    Else you can use `--force` argument to rewrite already published file.
- To publish migrations run command:

    `php artisan uploader:publish --only=migrations`

    It stores migration files to `database/migrations` folder.

    Else you can use `--force` argument to rewrite already published files.
- To publish assets (js and css) run command:

    `php artisan uploader:publish --only=assets`

    It stores js and css files to `public/vendor/uploader` folder.

    Else you can use `--force` argument to rewrite already published files.

### 3.4 Publish files - Custom part

[](#34-publish-files---custom-part)

- To publish views run command:

    `php artisan uploader:publish --only=views`

    It stores view files to `resources/views/vendor/uploader` folder.

    Else you can use `--force` argument to rewrite already published file.
- To publish translations run command:

    `php artisan uploader:publish --only=lang`

    It stores translation files to `resources/lang/vendor/uploader` folder.

    Else you can use `--force` argument to rewrite already published file.

### 3.5 Publish files - All parts if needed

[](#35-publish-files---all-parts-if-needed)

- To publish all parts run command without `only` argument:

    `php artisan uploader:publish`

    Else you can use `--force` argument to rewrite already published files.

### 3.6 Run migrations

[](#36-run-migrations)

- Run command:

`php artisan migrate`

4 Configure
-----------

[](#4-configure)

### 4.1 Set default filesystem disk

[](#41-set-default-filesystem-disk)

In a config file `filesystems.php` set the next custom settings (set default disk which you wish) and create needed base upload folder:

```
'default' => env('FILESYSTEM_DISK', 'local'),

'disks' => [
    'local' => [
        'driver' => 'local',
        'root' => storage_path('app/uploads'),
        'throw' => false,
        'url' => env('APP_URL') . '/storage/',
    ],
    's3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'endpoint' => env('AWS_ENDPOINT'),
        'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
        'throw' => false,
        'visibility' => 'public',
    ],
],

'links' => [
    public_path('storage') => storage_path('app/uploads'),
],
```

Run command to create symbolic links:

`php artisan storage:link`

### 4.2 Set assets

[](#42-set-assets)

**Pay Attention! This option is needed just in the next cases:**

- If you use a **File setter** in your app html forms (see **5.3 Digging deeper** / **5.3.3 Use FileSetter** point).
- If you use an **Album editor** (see in **5.1 Routes part**).

**Make sure** you use a **Bootstrap 4** for styling and **JQuery** in your application.

#### 4.2.1 Custom body layout case

[](#421-custom-body-layout-case)

So, set the next css assets between `head` tags of your app layout:

```

```

Set the next js asset at the end of the `body` tag of your app layout:

```

```

Note: `vendor/uploader/js/jquery.min.js` is required just if **JQuery** is absent in your application.

#### 4.2.2 If you use [AdminLTE](https://github.com/jeroennoten/Laravel-AdminLTE) package in your project

[](#422-if-you-use-adminlte-package-in-your-project)

```
'plugins' => [
    'Uploader' => [
        'active' => true,
        'files' => [
            [
                'type' => 'css',
                'asset' => true,
                'location' => '/vendor/uploader/css/modal.css',
            ],
            [
                'type' => 'css',
                'asset' => true,
                'location' => '/vendor/uploader/css/file-area.css',
            ],
            [
                'type' => 'js',
                'asset' => true,
                'location' => '/vendor/uploader/js/file-setter.js',
            ],
        ],
    ],
]
```

Pay attention: Not recommended using of `asset()` in AdminLTE config file, because it may cause an error with **UrlGenerator.php** when you will run fore example `composer install` later.

### 4.3 Change `uploader.php` config file.

[](#43-change-uploaderphp-config-file)

This file is **intuitive**.

But at this stage, pay attention to the next important options:

- Routing middlewares. By default it is empty array, you can set for example like this:

    ```
    'routing' => [
        'middlewares' => ['auth'],
    ],
    ```

    This middlewares will be applied in the `routes/uploader.php`.
- Albums layout (**Needed if you use Album editor**). By default it is empty string, you can set for example like this:

    ```
    'albums' => [
        'layout' => 'adminlte::page', // In case if you use AdminLTE. Or you can set your special layout.
    ],
    ```

5 Usage
-------

[](#5-usage)

### 5.1 Routes part

[](#51-routes-part)

There are already integrated base MFU routes to manage **files** and **albums**. See in `routes/uploader.php` package file.

The next routes are available by default:

- **Uploading section**

    For GET request method

    - `http://example-domain.com/uploader/file/download/{id}` (Name: **uploader\_file\_download**)

    For POST request method

    - `http://example-domain.com/uploader/file/upload` (Name: **uploader\_file\_upload**)

        - Required request field is **file**.
        - Optional/required request meta data fields: **\[data\]alt**, **\[data\]title**, **\[data\]description**, **\[data\]owner\_id**, **\[data\]owner\_name**, **\[data\]owner\_attribute**, **\[data\]needed\_file\_type**, **\[data\]sub\_dir**.
    - `http://example-domain.com/uploader/file/update` (Name: **uploader\_file\_update**)

        - Required request field is **id**.
        - Optional request field is **file**.
        - Optional/required request meta data fields: **\[data\]alt**, **\[data\]title**, **\[data\]description**, **\[data\]needed\_file\_type**, **\[data\]sub\_dir**.
    - `http://example-domain.com/uploader/file/delete` (Name: **uploader\_file\_delete**)

        - Required request field is **id**.
    - `http://example-domain.com/uploader/file/preview` (Name: **uploader\_file\_preview**)

        - Required request field is **id**.
        - Optional request field is **location**. See more for **preview** option in config `uploader.php` (there are some html attributes for concrete file types and their previews). If not set, returned preview will be with html attributes according with `Previewer::LOCATION_FILE_INFO`. Also if it is an image, `Previewer` will return an image with sizes, according with **thumbAlias** option in config. If **thumbAlias** is not set or there is no such location, `Previewer` will return image with sizes according with `SaveProcessor::THUMB_ALIAS_SMALL`.

    Notes:

    - If uploading file is an **image**, then additional thumbnails will be created according with their settings in **thumbSizes** config option.
    - Requirement/optionality for request meta data fields is set in **metaDataValidationRules** option of config `uploader.php` file.
    - If **checkExtensionByFileType** option is **true**, then **\[data\]needed\_file\_type** is required automatically.
- **Managing section**

    For GET request method

    - `http://example-domain.com/uploader/managers/file-list` (Name: **uploader\_file\_list\_manager**)
    - `http://example-domain.com/uploader/managers/file-upload` (Name: **uploader\_file\_upload\_manager**)
    - `http://example-domain.com/uploader/managers/file-edit/{id}` (Name: **uploader\_file\_edit\_manager**)

    For POST request method

    - `http://example-domain.com/uploader/managers/file-list/delete` (Name: **uploader\_file\_list\_delete**)
        - Required request field is **items** - it is an array of file's ID's.
- **Album editor section**

    - Image albums

        For GET request method

        - `http://example-domain.com/uploader/albums/image/list` (Name: **uploader\_image\_album\_list**)
        - `http://example-domain.com/uploader/albums/image/create` (Name: **uploader\_image\_album\_create**)
        - `http://example-domain.com/uploader/albums/image/edit/{id}` (Name: **uploader\_image\_album\_edit**)
        - `http://example-domain.com/uploader/albums/image/view/{id}` (Name: **uploader\_image\_album\_view**)

        For POST request method

        - `http://example-domain.com/uploader/albums/image/store` (Name: **uploader\_image\_album\_store**)
        - `http://example-domain.com/uploader/albums/image/update/{id}` (Name: **uploader\_image\_album\_update**)
        - `http://example-domain.com/uploader/albums/image/delete` (Name: **uploader\_image\_album\_delete**)
    - Audio albums

        For GET request method

        - `http://example-domain.com/uploader/albums/audio/list` (Name: **uploader\_audio\_album\_list**)
        - `http://example-domain.com/uploader/albums/audio/create` (Name: **uploader\_audio\_album\_create**)
        - `http://example-domain.com/uploader/albums/audio/edit/{id}` (Name: **uploader\_audio\_album\_edit**)
        - `http://example-domain.com/uploader/albums/audio/view/{id}` (Name: **uploader\_audio\_album\_view**)

        For POST request method

        - `http://example-domain.com/uploader/albums/audio/store` (Name: **uploader\_audio\_album\_store**)
        - `http://example-domain.com/uploader/albums/audio/update/{id}` (Name: **uploader\_audio\_album\_update**)
        - `http://example-domain.com/uploader/albums/audio/delete` (Name: **uploader\_audio\_album\_delete**)
    - Video albums

        For GET request method

        - `http://example-domain.com/uploader/albums/video/list` (Name: **uploader\_video\_album\_list**)
        - `http://example-domain.com/uploader/albums/video/create` (Name: **uploader\_video\_album\_create**)
        - `http://example-domain.com/uploader/albums/video/edit/{id}` (Name: **uploader\_video\_album\_edit**)
        - `http://example-domain.com/uploader/albums/video/view/{id}` (Name: **uploader\_video\_album\_view**)

        For POST request method

        - `http://example-domain.com/uploader/albums/video/store` (Name: **uploader\_video\_album\_store**)
        - `http://example-domain.com/uploader/albums/video/update/{id}` (Name: **uploader\_video\_album\_update**)
        - `http://example-domain.com/uploader/albums/video/delete` (Name: **uploader\_video\_album\_delete**)
    - Application albums

        For GET request method

        - `http://example-domain.com/uploader/albums/application/list` (Name: **uploader\_application\_album\_list**)
        - `http://example-domain.com/uploader/albums/application/create` (Name: **uploader\_application\_album\_create**)
        - `http://example-domain.com/uploader/albums/application/edit/{id}` (Name: **uploader\_application\_album\_edit**)
        - `http://example-domain.com/uploader/albums/application/view/{id}` (Name: **uploader\_application\_album\_view**)

        For POST request method

        - `http://example-domain.com/uploader/albums/application/store` (Name: **uploader\_application\_album\_store**)
        - `http://example-domain.com/uploader/albums/application/update/{id}` (Name: **uploader\_application\_album\_update**)
        - `http://example-domain.com/uploader/albums/application/delete` (Name: **uploader\_application\_album\_delete**)
    - Word albums

        For GET request method

        - `http://example-domain.com/uploader/albums/word/list` (Name: **uploader\_word\_album\_list**)
        - `http://example-domain.com/uploader/albums/word/create` (Name: **uploader\_word\_album\_create**)
        - `http://example-domain.com/uploader/albums/word/edit/{id}` (Name: **uploader\_word\_album\_edit**)
        - `http://example-domain.com/uploader/albums/word/view/{id}` (Name: **uploader\_word\_album\_view**)

        For POST request method

        - `http://example-domain.com/uploader/albums/word/store` (Name: **uploader\_word\_album\_store**)
        - `http://example-domain.com/uploader/albums/word/update/{id}` (Name: **uploader\_word\_album\_update**)
        - `http://example-domain.com/uploader/albums/word/delete` (Name: **uploader\_word\_album\_delete**)

            .........................................................

            ................Next albums...............

            .........................................................

**E.t.c...** See in `routes/uploader.php` package file the next albums routes for **Excel**, **Visio**, **PowerPoint**, **PDF**, **Text**, **Other** albums. They have similar principle.

**Album editor** POST request method fields are equal for all albums:

- Required request fields for store: **title**, **description**.
- Required request fields for update: **title**, **description**. Field **id** is in route url.
- Required request field for delete: **items** - it is an array of album's ID's.

### 5.2 Easy quick way

[](#52-easy-quick-way)

#### 5.2.1 Access to File list manager

[](#521-access-to-file-list-manager)

- Go directly to **uploader\_file\_list\_manager** route: `http://example-domain.com/uploader/managers/file-list`
- Go to File list using **iframe**:

```

```

[![MFU file list manager](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_file_list_manager.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_list_manager.png)

#### 5.2.2 Access to File upload manager

[](#522-access-to-file-upload-manager)

If to click on green **Uploader** button in a file list manager, you will go to **uploader\_file\_upload\_manager** route: `http://example-domain.com/uploader/managers/file-upload`.

[![MFU file upload manager](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_file_upload_manager.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_upload_manager.png)

#### 5.2.3 Access to File edit manager

[](#523-access-to-file-edit-manager)

If to click on green edition button in a file list manager, you will go to **uploader\_file\_edit\_manager** route: `http://example-domain.com/uploader/managers/file-edit/{id}`:

```
route('uploader_file_edit_manager', ['id' => 1])
```

[![MFU file edit manager](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_file_edit_manager.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_edit_manager.png)

#### 5.2.4 Access to Media file preview

[](#524-access-to-media-file-preview)

If you have got a media file entry `$mediaFile` by `Itstructure\MFU\Models\Mediafile` model entity:

```

    {!! \Itstructure\MFU\Facades\Previewer::getPreviewHtml($mediaFile, \Itstructure\MFU\Services\Previewer::LOCATION_FILE_INFO) !!}

```

Here you can use some of the next options:

`\Itstructure\MFU\Services\Previewer::LOCATION_FILE_ITEM``\Itstructure\MFU\Services\Previewer::LOCATION_FILE_INFO``\Itstructure\MFU\Services\Previewer::LOCATION_EXISTING`

#### 5.2.5 Download Media file

[](#525-download-media-file)

Use route:

```
route('uploader_file_download', ['id' => 1])
```

#### 5.2.6 Access to Album Editor

[](#526-access-to-album-editor)

Simply use albums routes, described above in **Album editor section** of **5.1 Routes part**.

But pay attention! You must set a layout for album editor:

```
'albums' => [
    'layout' => 'adminlte::page',
],
```

Value `adminlte::page` is for case if you use [AdminLTE](https://github.com/jeroennoten/Laravel-AdminLTE). Or you can set your special layout.

Image album list example looks like this:

[![MFU album list](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_album_list.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_album_list.png)

Image album edition page example looks like this:

[![MFU album edit](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_album_edit.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_album_edit.png)

### 5.3 Digging deeper

[](#53-digging-deeper)

#### 5.3.1 Data base structure

[](#531-data-base-structure)

[![MFU db](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_db.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_db.png)

#### 5.3.2 Short architecture structure and request way for uploading process in simple words

[](#532-short-architecture-structure-and-request-way-for-uploading-process-in-simple-words)

1. Call `UploadController` method.
2. Call static method from `Itstructure\MFU\Facades\Uploader` facade in controller method.
3. Get instance of Uploader service `Itstructure\MFU\Services\Uploader::getInstance($config)` and call here a facade's method.
4. Get instance of needed processor, with set config data from service to this:

    `Itstructure\MFU\Processors\UploadProcessor` or

    `Itstructure\MFU\Processors\UpdateProcessor` or

    `Itstructure\MFU\Processors\DeleteProcessor`.
5. Set process parameters and then call it's `run()` method.

See inside core.

#### 5.3.3 Use FileSetter

[](#533-use-filesetter)

FileSetter is needed to set **file id** in to the form field and file **preview** to special container before sending request to controller during saving some entity: Page, Catalog, Product e.t.c.

Example FileSetter using for **thumbnail**:

```
@php
    $thumbModel = isset($model) ? $model->getThumbnailModel() : null;
@endphp

    @if(!empty($thumbModel))

            {!! \Itstructure\MFU\Facades\Previewer::getPreviewHtml($thumbModel, \Itstructure\MFU\Services\Previewer::LOCATION_FILE_INFO) !!}

    @endif

    @if(!empty($thumbModel))
        {{ $thumbModel->title }}
    @endif

    @if(!empty($thumbModel))
        {{ $thumbModel->description }}
    @endif

@php
    $fileSetterConfig = [
        'attribute' => Itstructure\MFU\Processors\SaveProcessor::FILE_TYPE_THUMB,
        'value' => !empty($thumbModel) ? $thumbModel->id : null,
        'openButtonName' => trans('uploader::main.set_thumbnail'),
        'clearButtonName' => trans('uploader::main.clear'),
        'mediafileContainerId' => isset($model) ? 'thumbnail_container_' . $model->id : 'thumbnail_container',
        'titleContainerId' => isset($model) ? 'thumbnail_title_' . $model->id : 'thumbnail_title',
        'descriptionContainerId' => isset($model) ? 'thumbnail_description_' . $model->id : 'thumbnail_description',
        //'callbackBeforeInsert' => 'function (e, v) {console.log(e, v);}',//Custom
        'neededFileType' => Itstructure\MFU\Processors\SaveProcessor::FILE_TYPE_THUMB,
        'subDir' => isset($model) ? $model->getTable() : null
    ];

    $ownerConfig = isset($ownerParams) && is_array($ownerParams) ? array_merge([
        'ownerAttribute' => Itstructure\MFU\Processors\SaveProcessor::FILE_TYPE_THUMB
    ], $ownerParams) : [];

    $fileSetterConfig = array_merge($fileSetterConfig, $ownerConfig);
@endphp
@fileSetter($fileSetterConfig)
```

Visually it looks like that:

[![MFU file setter](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_file_setter.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_setter.png)

If to click on **Set thumbnail** button, then file list manager will be opened, but with additional button "V":

[![MFU file list with file setter button](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_file_list_with_setter_button.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_list_with_setter_button.png)

This button is to choose a concrete file and insert it's preview in to the `thumbnail_container` and it's ID in to the automatically rendered form field by `attribute` option.

See next point **5.3.4** to understand how this selected file can be linked with a parent owner, like for example: Page, Product e.t.c...

#### 5.3.4 Link media files with parent owner

[](#534-link-media-files-with-parent-owner)

For example you use `Product` eloquent model, which contains **albums** and **media files** both.

Albums and media files can be linked with Product, after Product is saved, through `owners_albums` and `owners_mediafiles` DB relations.

This relations are set by `BehaviorMediafile` and `BehaviorAlbum` classes automatically.

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Itstructure\MFU\Interfaces\BeingOwnerInterface;
use Itstructure\MFU\Behaviors\Owner\{BehaviorMediafile, BehaviorAlbum};
use Itstructure\MFU\Processors\SaveProcessor;
use Itstructure\MFU\Models\Albums\AlbumTyped;
use Itstructure\MFU\Traits\{OwnerBehavior, Thumbnailable};

class Product extends Model implements BeingOwnerInterface
{
    use Thumbnailable, OwnerBehavior;

    protected $table = 'products';

    protected $fillable = ['title', 'alias', 'description', 'price', 'category_id'];

    public function getItsName(): string
    {
        return $this->getTable();
    }

    public function getPrimaryKey()
    {
        return $this->getKey();
    }

    public static function getBehaviorMadiafileAttributes(): array
    {
        return [SaveProcessor::FILE_TYPE_THUMB, SaveProcessor::FILE_TYPE_IMAGE];
    }

    public static function getBehaviorAlbumAttributes(): array
    {
        return [AlbumTyped::ALBUM_TYPE_IMAGE];
    }

    public static function getBehaviorAttributes(): array
    {
        return array_merge(static::getBehaviorMadiafileAttributes(), static::getBehaviorAlbumAttributes());
    }

    protected static function booted(): void
    {
        $behaviorMediafile = BehaviorMediafile::getInstance(static::getBehaviorMadiafileAttributes());
        $behaviorAlbum = BehaviorAlbum::getInstance(static::getBehaviorAlbumAttributes());

        static::saved(function (Model $ownerModel) use ($behaviorMediafile, $behaviorAlbum) {
            if ($ownerModel->wasRecentlyCreated) {
                $behaviorMediafile->link($ownerModel);
                $behaviorAlbum->link($ownerModel);
            } else {
                $behaviorMediafile->refresh($ownerModel);
                $behaviorAlbum->refresh($ownerModel);
            }
        });

        static::deleted(function (Model $ownerModel) use ($behaviorMediafile, $behaviorAlbum) {
            $behaviorMediafile->clear($ownerModel);
            $behaviorAlbum->clear($ownerModel);
        });
    }
}
```

The main rules:

- It is very important to be implemented from `BeingOwnerInterface`!
- It is very important to use `OwnerBehavior` trait. Some required BASE methods by `BeingOwnerInterface` are already existing in this trait.
- It is very important to make the next methods: `getItsName()`, `getPrimaryKey()`.
- It is very important to add method `booted()` with behaviour instances.
- It is very important to set `getBehaviorAttributes()` with attributes list, which are used in a blade form for **FileSetter**!

See deeper in to core and imagine how it works :-)

Go next...

It is very important to use MFU blade partials correctly in your application blade forms!

Short cut example for the blade form with using

`uploader::partials.thumbnail`,

`uploader::partials.new-mediafiles`,

`uploader::partials.existing-mediafiles`,

`uploader::partials.albums-form-list`:

```

        @include('uploader::partials.thumbnail', ['model' => $model ?? null, 'ownerParams' => $ownerParams ?? null])

            Title

            @if ($errors->has('title'))

                    {{ $errors->first('title') }}

            @endif

..........

..........

{{ trans('uploader::main.new_files') }}

    @include('uploader::partials.new-mediafiles', [
        'fileType' => \Itstructure\MFU\Processors\SaveProcessor::FILE_TYPE_IMAGE,
        'ownerParams' => $ownerParams ?? null
    ])

@if(!empty($edition))

    {{ trans('uploader::main.existing_files') }}

        @include('uploader::partials.existing-mediafiles', [
            'edition' => true,
            'fileType' => \Itstructure\MFU\Processors\SaveProcessor::FILE_TYPE_IMAGE,
            'ownerParams' => $ownerParams ?? null,
            'mediaFiles' => $mediaFiles ?? []
        ])

@endif

@if(!empty($allImageAlbums) && !$allImageAlbums->isEmpty())

    {{ trans('uploader::main.image_albums') }}

        @include('uploader::partials.albums-form-list', [
            'albums' => $allImageAlbums,
            'edition' => true
        ])

@endif

Create

```

To clarify:

By `fileType` there will be set a field `image[]`, which will be set by `fill()` method in `Itstructure\MFU\Traits\OwnerBehavior` trait using `getBehaviorAttributes()`, and then it's value will be put in to the `BehaviorMediafile` object during `booted()` calling after for example `Product` is saved. Then a table `owners_mediafiles` will be filled. Link between `Product` and `Mediafile` will be created.

Product edition page example looks like this:

[![MFU product edit](https://github.com/itstructure/laravel-media-file-uploader/raw/main/mfu_product_edit.png)](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_product_edit.png)

To see more, how that example works in global, see real example here: [Laravel Microshop](https://github.com/itstructure/laravel-microshop).

I hope you will be happy with this package. Good luck with your development!

With all respect, Andrey!

License
-------

[](#license)

Copyright © 2024-2025 Andrey Girnik .

Licensed under the [MIT license](http://opensource.org/licenses/MIT). See LICENSE.txt for details.

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance66

Regular maintenance activity

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 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 ~78 days

Recently: every ~116 days

Total

7

Last Release

200d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/31563329?v=4)[Andrey Girnik](/maintainers/itstructure)[@itstructure](https://github.com/itstructure)

---

Top Contributors

[![itstructure](https://avatars.githubusercontent.com/u/31563329?v=4)](https://github.com/itstructure "itstructure (46 commits)")

---

Tags

audiofileimagelaravelofficepdfuploaduploadervideolaravelimageaudiovideofilemediauploadpicture

### Embed Badge

![Health badge](/badges/itstructure-laravel-media-file-uploader/health.svg)

```
[![Health](https://phpackages.com/badges/itstructure-laravel-media-file-uploader/health.svg)](https://phpackages.com/packages/itstructure-laravel-media-file-uploader)
```

###  Alternatives

[mostafaznv/larupload

Larupload is a ORM based file uploader for laravel to upload image, video, audio and other known files.

73403.7k3](/packages/mostafaznv-larupload)[digital-creative/nova-filepond

A Nova field for uploading File, Image and Video using filepond.

5568.0k1](/packages/digital-creative-nova-filepond)[itskodinger/midia

Simple Media manager for your Laravel project

1415.8k](/packages/itskodinger-midia)

PHPackages © 2026

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