{"id":20523101,"url":"https://github.com/itstructure/laravel-media-file-uploader","last_synced_at":"2026-02-13T04:13:41.448Z","repository":{"id":215054674,"uuid":"737998081","full_name":"itstructure/laravel-media-file-uploader","owner":"itstructure","description":"Uploader of different files","archived":false,"fork":false,"pushed_at":"2025-02-27T17:16:49.000Z","size":2444,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-09T01:47:14.672Z","etag":null,"topics":["audio","file","image","laravel","office","pdf","upload","uploader","video"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itstructure.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-02T07:03:34.000Z","updated_at":"2025-02-27T17:15:54.000Z","dependencies_parsed_at":"2024-01-02T08:42:32.005Z","dependency_job_id":"854a28bb-7037-408a-981b-dabcce1dc458","html_url":"https://github.com/itstructure/laravel-media-file-uploader","commit_stats":null,"previous_names":["itstructure/laravel-media-file-uploader"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itstructure%2Flaravel-media-file-uploader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itstructure%2Flaravel-media-file-uploader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itstructure%2Flaravel-media-file-uploader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itstructure%2Flaravel-media-file-uploader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itstructure","download_url":"https://codeload.github.com/itstructure/laravel-media-file-uploader/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253176440,"owners_count":21866142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","file","image","laravel","office","pdf","upload","uploader","video"],"created_at":"2024-11-15T22:37:56.357Z","updated_at":"2026-02-13T04:13:41.439Z","avatar_url":"https://github.com/itstructure.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Media File Uploader - MFU\n\n[![Latest Stable Version](https://poser.pugx.org/itstructure/laravel-media-file-uploader/v/stable)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)\n[![Latest Unstable Version](https://poser.pugx.org/itstructure/laravel-media-file-uploader/v/unstable)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)\n[![License](https://poser.pugx.org/itstructure/laravel-media-file-uploader/license)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)\n[![Total Downloads](https://poser.pugx.org/itstructure/laravel-media-file-uploader/downloads)](https://packagist.org/packages/itstructure/laravel-media-file-uploader)\n[![Build Status](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/badges/build.png?b=main)](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/build-status/main)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/badges/quality-score.png?b=main)](https://scrutinizer-ci.com/g/itstructure/laravel-media-file-uploader/?branch=main)\n\n## 1 Introduction\n\nThis package is to upload different media files to Local or remote Amazon S3 storage.\n\n![MFU logotip](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_logotip.png)\n\n## 2 Requirements\n- laravel 6+ | 7+ | 8+ | 9+ | 10+ | 11+ | 12+\n- Bootstrap 4 for styling\n- JQuery\n- php \u003e= 7.2.5\n- composer 2\n- One of the next php extensions: GD|Imagick|Gmagick\n\n## 3 Installation\n\n### 3.1 Install package\n\n#### General from remote Packagist repository\n\nRun the composer command:\n\n`composer require itstructure/laravel-media-file-uploader \"^1.0.6\"`\n\n#### If you are testing this package from a local server directory\n\nIn application `composer.json` file set the repository, as in example:\n\n```json\n\"repositories\": [\n    {\n        \"type\": \"path\",\n        \"url\": \"../laravel-media-file-uploader\",\n        \"options\": {\n            \"symlink\": true\n        }\n    }\n],\n```\n\nHere,\n\n**../laravel-media-file-uploader** - directory path, which has the same directory level as application and contains MFU package.\n\nThen run command:\n\n`composer require itstructure/laravel-media-file-uploader:dev-main --prefer-source`\n\n### 3.3 Publish files - Required part\n    \n- To publish config run command:\n\n    `php artisan uploader:publish --only=config`\n    \n    It stores config file to `config` folder.\n    \n    Else you can use `--force` argument to rewrite already published file.\n    \n- To publish migrations run command:\n            \n    `php artisan uploader:publish --only=migrations`\n    \n    It stores migration files to `database/migrations` folder.\n    \n    Else you can use `--force` argument to rewrite already published files.\n\n- To publish assets (js and css) run command:\n\n    `php artisan uploader:publish --only=assets`\n    \n    It stores js and css files to `public/vendor/uploader` folder.\n    \n    Else you can use `--force` argument to rewrite already published files.\n\n### 3.4 Publish files - Custom part\n\n- To publish views run command:\n\n    `php artisan uploader:publish --only=views`\n    \n    It stores view files to `resources/views/vendor/uploader` folder.\n    \n    Else you can use `--force` argument to rewrite already published file.\n    \n- To publish translations run command:\n                \n    `php artisan uploader:publish --only=lang`\n    \n    It stores translation files to `resources/lang/vendor/uploader` folder.\n    \n    Else you can use `--force` argument to rewrite already published file.\n\n### 3.5 Publish files - All parts if needed\n    \n- To publish all parts run command without `only` argument:\n\n    `php artisan uploader:publish`\n    \n    Else you can use `--force` argument to rewrite already published files.\n\n### 3.6 Run migrations\n\n- Run command:\n\n`php artisan migrate`\n\n## 4 Configure\n\n### 4.1 Set default filesystem disk\n\nIn a config file `filesystems.php` set the next custom settings (set default disk which you wish) and create needed base upload folder:\n\n```php\n'default' =\u003e env('FILESYSTEM_DISK', 'local'),\n\n'disks' =\u003e [\n    'local' =\u003e [\n        'driver' =\u003e 'local',\n        'root' =\u003e storage_path('app/uploads'),\n        'throw' =\u003e false,\n        'url' =\u003e env('APP_URL') . '/storage/',\n    ],\n    's3' =\u003e [\n        'driver' =\u003e 's3',\n        'key' =\u003e env('AWS_ACCESS_KEY_ID'),\n        'secret' =\u003e env('AWS_SECRET_ACCESS_KEY'),\n        'region' =\u003e env('AWS_DEFAULT_REGION'),\n        'bucket' =\u003e env('AWS_BUCKET'),\n        'url' =\u003e env('AWS_URL'),\n        'endpoint' =\u003e env('AWS_ENDPOINT'),\n        'use_path_style_endpoint' =\u003e env('AWS_USE_PATH_STYLE_ENDPOINT', false),\n        'throw' =\u003e false,\n        'visibility' =\u003e 'public',\n    ],\n],\n\n'links' =\u003e [\n    public_path('storage') =\u003e storage_path('app/uploads'),\n],\n```\n\nRun command to create symbolic links:\n\n`php artisan storage:link`\n\n### 4.2 Set assets\n\n**Pay Attention! This option is needed just in the next cases:**\n\n- If you use a **File setter** in your app html forms (see **5.3 Digging deeper** / **5.3.3 Use FileSetter** point).\n\n- If you use an **Album editor** (see in **5.1 Routes part**).\n\n**Make sure** you use a **Bootstrap 4** for styling and **JQuery** in your application.\n\n#### 4.2.1 Custom body layout case\n\nSo, set the next css assets between `head` tags of your app layout:\n```html\n\u003clink rel=\"stylesheet\" href=\"{{ asset('vendor/uploader/css/modal.css') }}\"\u003e\n\u003clink rel=\"stylesheet\" href=\"{{ asset('vendor/uploader/css/file-area.css') }}\"\u003e\n```\n\nSet the next js asset at the end of the `body` tag of your app layout:\n```html\n\u003cscript src=\"{{ asset('vendor/uploader/js/jquery.min.js') }}\"\u003e\u003c/script\u003e\n\u003cscript src=\"{{ asset('vendor/uploader/js/file-setter.js') }}\"\u003e\u003c/script\u003e\n```\n\nNote: `vendor/uploader/js/jquery.min.js` is required just if **JQuery** is absent in your application.\n\n#### 4.2.2 If you use [AdminLTE](https://github.com/jeroennoten/Laravel-AdminLTE) package in your project\n\n```php\n'plugins' =\u003e [\n    'Uploader' =\u003e [\n        'active' =\u003e true,\n        'files' =\u003e [\n            [\n                'type' =\u003e 'css',\n                'asset' =\u003e true,\n                'location' =\u003e '/vendor/uploader/css/modal.css',\n            ],\n            [\n                'type' =\u003e 'css',\n                'asset' =\u003e true,\n                'location' =\u003e '/vendor/uploader/css/file-area.css',\n            ],\n            [\n                'type' =\u003e 'js',\n                'asset' =\u003e true,\n                'location' =\u003e '/vendor/uploader/js/file-setter.js',\n            ],\n        ],\n    ],\n]\n```\n\nPay 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.\n\n### 4.3 Change `uploader.php` config file.\n\nThis file is **intuitive**.\n\nBut at this stage, pay attention to the next important options:\n\n- Routing middlewares. By default it is empty array, you can set for example like this:\n\n    ```php\n    'routing' =\u003e [\n        'middlewares' =\u003e ['auth'],\n    ],\n    ```\n    \n    This middlewares will be applied in the `routes/uploader.php`.\n\n- Albums layout (**Needed if you use Album editor**). By default it is empty string, you can set for example like this:\n\n    ```php\n    'albums' =\u003e [\n        'layout' =\u003e 'adminlte::page', // In case if you use AdminLTE. Or you can set your special layout.\n    ],\n    ```\n\n## 5 Usage\n\n### 5.1 Routes part\n\nThere are already integrated base MFU routes to manage **files** and **albums**. See in `routes/uploader.php` package file.\n\nThe next routes are available by default:\n\n- **Uploading section**\n\n    For GET request method\n\n    - `http://example-domain.com/uploader/file/download/{id}` (Name: **uploader_file_download**)\n\n    For POST request method\n\n    - `http://example-domain.com/uploader/file/upload` (Name: **uploader_file_upload**)\n        - Required request field is **file**.\n        - 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**.\n        \n    - `http://example-domain.com/uploader/file/update` (Name: **uploader_file_update**)\n        - Required request field is **id**.\n        - Optional request field is **file**.\n        - Optional/required request meta data fields: **[data]alt**, **[data]title**, **[data]description**, **[data]needed_file_type**, **[data]sub_dir**.\n        \n    - `http://example-domain.com/uploader/file/delete` (Name: **uploader_file_delete**)\n        - Required request field is **id**.\n        \n    - `http://example-domain.com/uploader/file/preview` (Name: **uploader_file_preview**)\n        - Required request field is **id**.\n        - 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`.\n        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`.\n\n    Notes:\n    - If uploading file is an **image**, then additional thumbnails will be created according with their settings in **thumbSizes** config option.\n    - Requirement/optionality for request meta data fields is set in **metaDataValidationRules** option of config `uploader.php` file.\n    - If **checkExtensionByFileType** option is **true**, then **[data]needed_file_type** is required automatically.\n    \n- **Managing section**\n\n    For GET request method\n\n    - `http://example-domain.com/uploader/managers/file-list` (Name: **uploader_file_list_manager**)\n    - `http://example-domain.com/uploader/managers/file-upload` (Name: **uploader_file_upload_manager**)\n    - `http://example-domain.com/uploader/managers/file-edit/{id}` (Name: **uploader_file_edit_manager**)\n\n    For POST request method\n\n    - `http://example-domain.com/uploader/managers/file-list/delete` (Name: **uploader_file_list_delete**)\n        - Required request field is **items** - it is an array of file's ID's.\n\n- **Album editor section**\n    \n    - Image albums\n    \n        For GET request method\n    \n        - `http://example-domain.com/uploader/albums/image/list` (Name: **uploader_image_album_list**)\n        - `http://example-domain.com/uploader/albums/image/create` (Name: **uploader_image_album_create**)\n        - `http://example-domain.com/uploader/albums/image/edit/{id}` (Name: **uploader_image_album_edit**)\n        - `http://example-domain.com/uploader/albums/image/view/{id}` (Name: **uploader_image_album_view**)\n        \n        For POST request method\n        \n        - `http://example-domain.com/uploader/albums/image/store` (Name: **uploader_image_album_store**)\n        - `http://example-domain.com/uploader/albums/image/update/{id}` (Name: **uploader_image_album_update**)\n        - `http://example-domain.com/uploader/albums/image/delete` (Name: **uploader_image_album_delete**)\n\n    - Audio albums\n        \n        For GET request method\n    \n        - `http://example-domain.com/uploader/albums/audio/list` (Name: **uploader_audio_album_list**)\n        - `http://example-domain.com/uploader/albums/audio/create` (Name: **uploader_audio_album_create**)\n        - `http://example-domain.com/uploader/albums/audio/edit/{id}` (Name: **uploader_audio_album_edit**)\n        - `http://example-domain.com/uploader/albums/audio/view/{id}` (Name: **uploader_audio_album_view**)\n        \n        For POST request method\n        \n        - `http://example-domain.com/uploader/albums/audio/store` (Name: **uploader_audio_album_store**)\n        - `http://example-domain.com/uploader/albums/audio/update/{id}` (Name: **uploader_audio_album_update**)\n        - `http://example-domain.com/uploader/albums/audio/delete` (Name: **uploader_audio_album_delete**)\n        \n    - Video albums\n           \n        For GET request method\n        \n        - `http://example-domain.com/uploader/albums/video/list` (Name: **uploader_video_album_list**)\n        - `http://example-domain.com/uploader/albums/video/create` (Name: **uploader_video_album_create**)\n        - `http://example-domain.com/uploader/albums/video/edit/{id}` (Name: **uploader_video_album_edit**)\n        - `http://example-domain.com/uploader/albums/video/view/{id}` (Name: **uploader_video_album_view**)\n        \n        For POST request method\n        \n        - `http://example-domain.com/uploader/albums/video/store` (Name: **uploader_video_album_store**)\n        - `http://example-domain.com/uploader/albums/video/update/{id}` (Name: **uploader_video_album_update**)\n        - `http://example-domain.com/uploader/albums/video/delete` (Name: **uploader_video_album_delete**)\n        \n    - Application albums\n               \n        For GET request method\n        \n        - `http://example-domain.com/uploader/albums/application/list` (Name: **uploader_application_album_list**)\n        - `http://example-domain.com/uploader/albums/application/create` (Name: **uploader_application_album_create**)\n        - `http://example-domain.com/uploader/albums/application/edit/{id}` (Name: **uploader_application_album_edit**)\n        - `http://example-domain.com/uploader/albums/application/view/{id}` (Name: **uploader_application_album_view**)\n        \n        For POST request method\n        \n        - `http://example-domain.com/uploader/albums/application/store` (Name: **uploader_application_album_store**)\n        - `http://example-domain.com/uploader/albums/application/update/{id}` (Name: **uploader_application_album_update**)\n        - `http://example-domain.com/uploader/albums/application/delete` (Name: **uploader_application_album_delete**)\n        \n    - Word albums\n                   \n        For GET request method\n        \n        - `http://example-domain.com/uploader/albums/word/list` (Name: **uploader_word_album_list**)\n        - `http://example-domain.com/uploader/albums/word/create` (Name: **uploader_word_album_create**)\n        - `http://example-domain.com/uploader/albums/word/edit/{id}` (Name: **uploader_word_album_edit**)\n        - `http://example-domain.com/uploader/albums/word/view/{id}` (Name: **uploader_word_album_view**)\n        \n        For POST request method\n        \n        - `http://example-domain.com/uploader/albums/word/store` (Name: **uploader_word_album_store**)\n        - `http://example-domain.com/uploader/albums/word/update/{id}` (Name: **uploader_word_album_update**)\n        - `http://example-domain.com/uploader/albums/word/delete` (Name: **uploader_word_album_delete**)\n\n            \n            .........................................................\n            \n            ................Next albums...............\n            \n            .........................................................\n\n            \n**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.\n\n**Album editor** POST request method fields are equal for all albums:\n\n- Required request fields for store: **title**, **description**.\n- Required request fields for update: **title**, **description**. Field **id** is in route url.\n- Required request field for delete: **items** - it is an array of album's ID's.\n\n\n### 5.2 Easy quick way\n\n#### 5.2.1 Access to File list manager\n\n- Go directly to **uploader_file_list_manager** route: `http://example-domain.com/uploader/managers/file-list`\n\n- Go to File list using **iframe**:\n\n```blade\n\u003csection class=\"content container-fluid\"\u003e\n    \u003cdiv class=\"row\"\u003e\n        \u003cdiv class=\"col-12 mt-1\"\u003e\n            \u003ciframe src=\"{{ route('uploader_file_list_manager') }}\" frameborder=\"0\" style=\"width: 100%; min-height: 800px\"\u003e\u003c/iframe\u003e\n        \u003c/div\u003e\n    \u003c/div\u003e\n\u003c/section\u003e\n```\n\n![MFU file list manager](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_list_manager.png)\n\n#### 5.2.2 Access to File upload manager\n\nIf 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`.\n\n![MFU file upload manager](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_upload_manager.png)\n\n#### 5.2.3 Access to File edit manager\n\nIf 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}`:\n\n```php\nroute('uploader_file_edit_manager', ['id' =\u003e 1])\n```\n\n![MFU file edit manager](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_edit_manager.png)\n\n#### 5.2.4 Access to Media file preview\n\nIf you have got a media file entry `$mediaFile` by `Itstructure\\MFU\\Models\\Mediafile` model entity:\n\n```php\n\u003ca href=\"{{ $mediaFile-\u003egetOriginalUrl() }}\" target=\"_blank\"\u003e\n    {!! \\Itstructure\\MFU\\Facades\\Previewer::getPreviewHtml($mediaFile, \\Itstructure\\MFU\\Services\\Previewer::LOCATION_FILE_INFO) !!}\n\u003c/a\u003e\n```\n\nHere you can use some of the next options:\n\n`\\Itstructure\\MFU\\Services\\Previewer::LOCATION_FILE_ITEM`\n`\\Itstructure\\MFU\\Services\\Previewer::LOCATION_FILE_INFO`\n`\\Itstructure\\MFU\\Services\\Previewer::LOCATION_EXISTING`\n\n#### 5.2.5 Download Media file\n\nUse route:\n\n```php\nroute('uploader_file_download', ['id' =\u003e 1])\n```\n\n#### 5.2.6 Access to Album Editor\n\nSimply use albums routes, described above in **Album editor section** of **5.1 Routes part**.\n\nBut pay attention! You must set a layout for album editor:\n\n```php\n'albums' =\u003e [\n    'layout' =\u003e 'adminlte::page',\n],\n```\n\nValue `adminlte::page` is for case if you use [AdminLTE](https://github.com/jeroennoten/Laravel-AdminLTE). Or you can set your special layout.\n\nImage album list example looks like this:\n\n![MFU album list](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_album_list.png)\n\nImage album edition page example looks like this:\n\n![MFU album edit](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_album_edit.png)\n\n### 5.3 Digging deeper\n\n#### 5.3.1 Data base structure\n\n![MFU db](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_db.png)\n\n#### 5.3.2 Short architecture structure and request way for uploading process in simple words\n\n1. Call `UploadController` method.\n2. Call static method from `Itstructure\\MFU\\Facades\\Uploader` facade in controller method.\n3. Get instance of Uploader service `Itstructure\\MFU\\Services\\Uploader::getInstance($config)` and call here a facade's method.\n4. Get instance of needed processor, with set config data from service to this:\n\n    `Itstructure\\MFU\\Processors\\UploadProcessor` or \n    \n    `Itstructure\\MFU\\Processors\\UpdateProcessor` or \n    \n    `Itstructure\\MFU\\Processors\\DeleteProcessor`.\n\n5. Set process parameters and then call it's `run()` method.\n\nSee inside core.\n\n#### 5.3.3 Use FileSetter\n\nFileSetter 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.\n\nExample FileSetter using for **thumbnail**:\n\n```blade\n@php\n    $thumbModel = isset($model) ? $model-\u003egetThumbnailModel() : null;\n@endphp\n\u003cdiv id=\"{{ isset($model) ? 'thumbnail_container_' . $model-\u003eid : 'thumbnail_container' }}\"\u003e\n    @if(!empty($thumbModel))\n        \u003ca href=\"{{ $thumbModel-\u003egetOriginalUrl() }}\" target=\"_blank\"\u003e\n            {!! \\Itstructure\\MFU\\Facades\\Previewer::getPreviewHtml($thumbModel, \\Itstructure\\MFU\\Services\\Previewer::LOCATION_FILE_INFO) !!}\n        \u003c/a\u003e\n    @endif\n\u003c/div\u003e\n\u003cdiv id=\"{{ isset($model) ? 'thumbnail_title_' . $model-\u003eid : 'thumbnail_title' }}\"\u003e\n    @if(!empty($thumbModel))\n        {{ $thumbModel-\u003etitle }}\n    @endif\n\u003c/div\u003e\n\u003cdiv id=\"{{ isset($model) ? 'thumbnail_description_' . $model-\u003eid : 'thumbnail_description' }}\"\u003e\n    @if(!empty($thumbModel))\n        {{ $thumbModel-\u003edescription }}\n    @endif\n\u003c/div\u003e\n@php\n    $fileSetterConfig = [\n        'attribute' =\u003e Itstructure\\MFU\\Processors\\SaveProcessor::FILE_TYPE_THUMB,\n        'value' =\u003e !empty($thumbModel) ? $thumbModel-\u003eid : null,\n        'openButtonName' =\u003e trans('uploader::main.set_thumbnail'),\n        'clearButtonName' =\u003e trans('uploader::main.clear'),\n        'mediafileContainerId' =\u003e isset($model) ? 'thumbnail_container_' . $model-\u003eid : 'thumbnail_container',\n        'titleContainerId' =\u003e isset($model) ? 'thumbnail_title_' . $model-\u003eid : 'thumbnail_title',\n        'descriptionContainerId' =\u003e isset($model) ? 'thumbnail_description_' . $model-\u003eid : 'thumbnail_description',\n        //'callbackBeforeInsert' =\u003e 'function (e, v) {console.log(e, v);}',//Custom\n        'neededFileType' =\u003e Itstructure\\MFU\\Processors\\SaveProcessor::FILE_TYPE_THUMB,\n        'subDir' =\u003e isset($model) ? $model-\u003egetTable() : null\n    ];\n\n    $ownerConfig = isset($ownerParams) \u0026\u0026 is_array($ownerParams) ? array_merge([\n        'ownerAttribute' =\u003e Itstructure\\MFU\\Processors\\SaveProcessor::FILE_TYPE_THUMB\n    ], $ownerParams) : [];\n\n    $fileSetterConfig = array_merge($fileSetterConfig, $ownerConfig);\n@endphp\n@fileSetter($fileSetterConfig)\n```\n\nVisually it looks like that:\n\n![MFU file setter](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_setter.png)\n\nIf to click on **Set thumbnail** button, then file list manager will be opened, but with additional button \"V\":\n\n![MFU file list with file setter button](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_file_list_with_setter_button.png)\n\nThis 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.\n\nSee 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...\n\n#### 5.3.4 Link media files with parent owner\n\nFor example you use `Product` eloquent model, which contains **albums** and **media files** both.\n\nAlbums and media files can be linked with Product, after Product is saved, through `owners_albums` and `owners_mediafiles` DB relations.\n\nThis relations are set by `BehaviorMediafile` and `BehaviorAlbum` classes automatically.\n\n```php\n\nnamespace App\\Models;\n    \nuse Illuminate\\Database\\Eloquent\\Model;\nuse Itstructure\\MFU\\Interfaces\\BeingOwnerInterface;\nuse Itstructure\\MFU\\Behaviors\\Owner\\{BehaviorMediafile, BehaviorAlbum};\nuse Itstructure\\MFU\\Processors\\SaveProcessor;\nuse Itstructure\\MFU\\Models\\Albums\\AlbumTyped;\nuse Itstructure\\MFU\\Traits\\{OwnerBehavior, Thumbnailable};\n    \nclass Product extends Model implements BeingOwnerInterface\n{\n    use Thumbnailable, OwnerBehavior;\n    \n    protected $table = 'products';\n    \n    protected $fillable = ['title', 'alias', 'description', 'price', 'category_id'];\n    \n    public function getItsName(): string\n    {\n        return $this-\u003egetTable();\n    }\n    \n    public function getPrimaryKey()\n    {\n        return $this-\u003egetKey();\n    }\n    \n    public static function getBehaviorMadiafileAttributes(): array\n    {\n        return [SaveProcessor::FILE_TYPE_THUMB, SaveProcessor::FILE_TYPE_IMAGE];\n    }\n    \n    public static function getBehaviorAlbumAttributes(): array\n    {\n        return [AlbumTyped::ALBUM_TYPE_IMAGE];\n    }\n    \n    public static function getBehaviorAttributes(): array\n    {\n        return array_merge(static::getBehaviorMadiafileAttributes(), static::getBehaviorAlbumAttributes());\n    }\n    \n    protected static function booted(): void\n    {\n        $behaviorMediafile = BehaviorMediafile::getInstance(static::getBehaviorMadiafileAttributes());\n        $behaviorAlbum = BehaviorAlbum::getInstance(static::getBehaviorAlbumAttributes());\n    \n        static::saved(function (Model $ownerModel) use ($behaviorMediafile, $behaviorAlbum) {\n            if ($ownerModel-\u003ewasRecentlyCreated) {\n                $behaviorMediafile-\u003elink($ownerModel);\n                $behaviorAlbum-\u003elink($ownerModel);\n            } else {\n                $behaviorMediafile-\u003erefresh($ownerModel);\n                $behaviorAlbum-\u003erefresh($ownerModel);\n            }\n        });\n    \n        static::deleted(function (Model $ownerModel) use ($behaviorMediafile, $behaviorAlbum) {\n            $behaviorMediafile-\u003eclear($ownerModel);\n            $behaviorAlbum-\u003eclear($ownerModel);\n        });\n    }\n}\n```\n\nThe main rules:\n\n- It is very important to be implemented from `BeingOwnerInterface`!\n\n- It is very important to use `OwnerBehavior` trait. Some required BASE methods by `BeingOwnerInterface` are already existing in this trait.\n\n- It is very important to make the next methods: `getItsName()`, `getPrimaryKey()`.\n\n- It is very important to add method `booted()` with behaviour instances.\n\n- It is very important to set `getBehaviorAttributes()` with attributes list, which are used in a blade form for **FileSetter**!\n\nSee deeper in to core and imagine how it works :-)\n\nGo next...\n\nIt is very important to use MFU blade partials correctly in your application blade forms!\n\nShort cut example for the blade form with using\n\n`uploader::partials.thumbnail`,\n\n`uploader::partials.new-mediafiles`,\n\n`uploader::partials.existing-mediafiles`, \n\n`uploader::partials.albums-form-list`:\n\n```blade\n\u003cform action=\"{{ route('admin_product_store') }}\" method=\"post\"\u003e\n\n\u003cdiv class=\"row\"\u003e\n    \u003cdiv class=\"col-12 col-sm-10 col-md-8 col-lg-6 col-xl-4\"\u003e\n        @include('uploader::partials.thumbnail', ['model' =\u003e $model ?? null, 'ownerParams' =\u003e $ownerParams ?? null])\n    \u003c/div\u003e\n\u003c/div\u003e\n\n\u003cdiv class=\"row\"\u003e\n    \u003cdiv class=\"col-12 col-sm-10 col-md-8 col-lg-6 col-xl-4\"\u003e\n        \u003cdiv class=\"form-group\"\u003e\n            \u003clabel for=\"id_title\"\u003eTitle\u003c/label\u003e\n            \u003cinput id=\"id_title\" type=\"text\" class=\"form-control @if ($errors-\u003ehas('title')) is-invalid @endif\"\n                   name=\"title\" value=\"{{ old('title', !empty($model) ? $model-\u003etitle : null) }}\" required autofocus\u003e\n            @if ($errors-\u003ehas('title'))\n                \u003cdiv class=\"invalid-feedback\"\u003e\n                    \u003cstrong\u003e{{ $errors-\u003efirst('title') }}\u003c/strong\u003e\n                \u003c/div\u003e\n            @endif\n        \u003c/div\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n..........\n\n..........\n\n\u003chr /\u003e\n\u003ch5\u003e{{ trans('uploader::main.new_files') }}\u003c/h5\u003e\n\u003cdiv class=\"row mb-3\"\u003e\n    @include('uploader::partials.new-mediafiles', [\n        'fileType' =\u003e \\Itstructure\\MFU\\Processors\\SaveProcessor::FILE_TYPE_IMAGE,\n        'ownerParams' =\u003e $ownerParams ?? null\n    ])\n\u003c/div\u003e\n\n@if(!empty($edition))\n    \u003chr /\u003e\n    \u003ch5\u003e{{ trans('uploader::main.existing_files') }}\u003c/h5\u003e\n    \u003cdiv class=\"row mb-3\"\u003e\n        @include('uploader::partials.existing-mediafiles', [\n            'edition' =\u003e true,\n            'fileType' =\u003e \\Itstructure\\MFU\\Processors\\SaveProcessor::FILE_TYPE_IMAGE,\n            'ownerParams' =\u003e $ownerParams ?? null,\n            'mediaFiles' =\u003e $mediaFiles ?? []\n        ])\n    \u003c/div\u003e\n@endif\n\n@if(!empty($allImageAlbums) \u0026\u0026 !$allImageAlbums-\u003eisEmpty())\n    \u003chr /\u003e\n    \u003ch5\u003e{{ trans('uploader::main.image_albums') }}\u003c/h5\u003e\n    \u003cdiv class=\"row mb-3\"\u003e\n        @include('uploader::partials.albums-form-list', [\n            'albums' =\u003e $allImageAlbums,\n            'edition' =\u003e true\n        ])\n    \u003c/div\u003e\n@endif\n\n\u003cbutton class=\"btn btn-primary\" type=\"submit\"\u003eCreate\u003c/button\u003e\n\u003cinput type=\"hidden\" value=\"{!! csrf_token() !!}\" name=\"_token\"\u003e\n\n\u003c/form\u003e\n```\n\nTo clarify:\n\nBy `fileType` there will be set a field `image[]`, which will be set by `fill()` method in `Itstructure\\MFU\\Traits\\OwnerBehavior` trait using `getBehaviorAttributes()`, \nand 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. \nLink between `Product` and `Mediafile` will be created.\n\nProduct edition page example looks like this:\n\n![MFU product edit](https://github.com/itstructure/laravel-media-file-uploader/blob/main/mfu_product_edit.png)\n\nTo see more, how that example works in global, see real example here: [Laravel Microshop](https://github.com/itstructure/laravel-microshop).\n\nI hope you will be happy with this package. Good luck with your development!\n\nWith all respect, Andrey!\n\n## License\n\nCopyright © 2024-2025 Andrey Girnik girnikandrey@gmail.com.\n\nLicensed under the [MIT license](http://opensource.org/licenses/MIT). See LICENSE.txt for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitstructure%2Flaravel-media-file-uploader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitstructure%2Flaravel-media-file-uploader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitstructure%2Flaravel-media-file-uploader/lists"}