Custom Usage of Laravel Filemanager

HTML

{{--
@php
  $field = ['tag_icon', 'Label icon image'];
  $value = val($row, $field[0]);
  $cp_data = [
    'field'=>$field, 
    'value'=>$value, 
    'locales' => $locales,
  ];
@endphp
@component('admin.components.form.image', $cp_data)
@endcomponent
--}}

@php
    if(isset($limit) == false){
        $limit = 0;
    }

    if(is_array($value) == true){
        $value = json_encode($value);
    }
@endphp

<div class="form-group lfm">
    <label for="{{$field[0]}}" class="col-md-3 control-label">
        {{$field[1]}}
        @if(isset($field[2]) && $field[2] == true)
        *
        @endif
    </label>
    <div class=" col-md-9">
        <div>
            <!--
                //data-input -> target_input in lfm.js
                var target_input = $('#' + localStorage.getItem('target_input'));
                target_input.val(file_path).trigger('change');

                //data-preview -> target_preview in lfm.js
                var target_preview = $('#' + localStorage.getItem('target_preview'));
                target_preview.attr('src', url).trigger('change');
            -->
            <a data-input="{{$field[0]}}" data-preview="lfm-thumbs" class="btn btn-primary bt_lfm" style="color: #FFF;" data-limit="{{$limit}}">
                <i class="fa fa-picture-o"></i> Choose
            </a>
        </div>
        <div class="lfm-thumbs" data-field-name="{{$field[0]}}">

            <input type="hidden" name="lfm_value" value="{{$value}}">
        </div>
    </div>
</div>

Javascript (lfm_app.js):

$(document).ready(function(){
    lfm_app.init();
});

var lfm_app = function(){

    function init(){

        $('.lfm').each(function(index){
            var $wrap = $(this);
            $wrap.find('.bt_lfm').off('click').on('click', function(){
                var $this = $(this);
                var preview = $this.data('preview');
                var input = $this.data('input');
                var limit = parseInt($this.data('limit'));

                //This callback will override function SetUrl in /vendor/laravel-filemanager/js/lfm.js
                show({type: 'file'}, function(url, path) {
                    var count = image_count(preview, input);
                    if(limit > 0 && count >= limit){
                        alert('You can not choose more images');
                        return false;
                    }

                    append(preview, input, path);
                });
            });

            show_images($wrap);
        });

        $('.lfm').undelegate('.lfm-thumb .remove', 'click')
            .delegate('.lfm-thumb .remove', 'click', function(e){
                e.preventDefault();
                var $this = $(this);
                $this.parent().remove();
            });
    }

    function dirname (path) {
        //  discuss at: http://locutus.io/php/dirname/
        // original by: Ozh
        // improved by: XoraX (http://www.xorax.info)
        //   example 1: dirname('/etc/passwd')
        //   returns 1: '/etc'
        //   example 2: dirname('c:/Temp/x')
        //   returns 2: 'c:/Temp'
        //   example 3: dirname('/dir/test/')
        //   returns 3: '/dir'

        return path.replace(/\\/g, '/')
            .replace(/\/[^/]*\/?$/, '')
    }

    function basename (path, suffix) {
        //  discuss at: http://locutus.io/php/basename/
        // original by: Kevin van Zonneveld (http://kvz.io)
        // improved by: Ash Searle (http://hexmen.com/blog/)
        // improved by: Lincoln Ramsay
        // improved by: djmix
        // improved by: Dmitry Gorelenkov
        //   example 1: basename('/www/site/home.htm', '.htm')
        //   returns 1: 'home'
        //   example 2: basename('ecra.php?p=1')
        //   returns 2: 'ecra.php?p=1'
        //   example 3: basename('/some/path/')
        //   returns 3: 'path'
        //   example 4: basename('/some/path_ext.ext/','.ext')
        //   returns 4: 'path_ext'

        var b = path
        var lastChar = b.charAt(b.length - 1)

        if (lastChar === '/' || lastChar === '\\') {
            b = b.slice(0, -1)
        }

        b = b.replace(/^.*[/\\]/g, '')

        if (typeof suffix === 'string' && b.substr(b.length - suffix.length) === suffix) {
            b = b.substr(0, b.length - suffix.length)
        }

        return b
    }

    function show(options, cb) {
        var route_prefix = (options && options.prefix) ? options.prefix : '/laravel-filemanager';

        window.open(route_prefix + '?type=' + options.type || 'file', 'FileManager', 'width=900,height=600');
        //override SetUrl in lfm.js
        window.SetUrl = cb;
    }

    function image_count(preview, input){
        var $thumb_wrap = $('.' + preview + '[data-field-name="' + input + '"]');
        var $thumbs = $thumb_wrap.find('.lfm-thumb');
        return $thumbs.length;
    }

    function detect_media_type(path){
        var type = 'image';

        var pattern = /\.mp4/i;
        var result = path.match(pattern);
        if(result != null){
            type = 'video';
        }

        return type;
    }

    function append(preview, field_name, path, thumb){
        if(typeof thumb == 'undefined'){
            thumb = path;
        }

        var $thumbs = $('.' + preview + '[data-field-name="' + field_name + '"]');

        var img = '<img src="' + thumb + '">';
        var media_type = detect_media_type(path);
        if(media_type == 'video'){
            img = '<img src="/assets/admin/img/video.png">';
        }

        var $thumb = $('<a class="lfm-thumb" href="' + path + '" target="_blank" data-path="' + path + '">' + 
            '<span href="#" class="remove">X</span>' + 
            img + 
            '</a>'
        );

        $thumbs.append($thumb);
    }

    function images(field_name, preview){
        if(typeof preview == 'undefined'){
            preview = 'lfm-thumbs';
        }

        var $thumbs = $('.' + preview + '[data-field-name="' + field_name + '"]');
        if($thumbs.length == 0){
            return [];
        }

        var arr = [];
        $thumbs.find('.lfm-thumb').each(function(index){
            var $this = $(this);
            arr.push($this.data('path'));
        });

        return arr;
    }

    function image_is_array(value){
        var pattern = /^\[/i;
        var result = value.match(pattern);
        //console.log(result);
        if(result == null){
            return false;
        }

        return true;
    }

    function get_thumb(url){
        var dir = dirname(url);
        var name = basename(url);
        return dir + '/thumbs/' + name;
    }

    function show_images($wrap){
        var $btn = $wrap.find('.bt_lfm');
        var preview = $btn.data('preview');
        var input = $btn.data('input');
            
        var value = $wrap.find('[name="lfm_value"]').val();
        if(value == ''){
            return;
        }

        var is_array = image_is_array(value);
        if(is_array == true){
            value = $.parseJSON(value);
            $.each(value, function(index){
                var thumb = get_thumb(this);
                append(preview, input, this, thumb);
            });
        }else{
            var thumb = get_thumb(value);
            append(preview, input, value, thumb);
        }
    }

    return {
        init: init, 
        show: show, 
        append: append, 
        images: images
    }
}();

Model to handle Image

<?php
namespace App\Models;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Config;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;

// import the Intervention Image Manager Class
use Intervention\Image\ImageManagerStatic as Image;

//use App\Models\ProductColorM;

use Carbon\Carbon;

class ImageM extends Model{
    static $err = '';

    const TYPE_SINGLE = 1;
    const TYPE_MULTIPLE = 2;

    static function save_s3($path){
        if(is_s3($path) == true){
            return true;
        }

        //Relative path -> full path
        $file_path = public_path($path);
        $file = File::get($file_path);
        //logg($path);
        $result = Storage::disk('s3')->put($path, $file, 'public');

        //Handle thumb
        $dir = dirname($file_path) . '/thumbs/';
        if(file_exists($dir) == false){
            mkdir($dir);
        }
        $file_name = basename($file_path);
        $thumb = $dir . $file_name;
        if(file_exists($thumb) == false){
            //Make a new thumb file
            $image = Image::make($file_path);

            $width = $image->width();
            $height = $image->height();
            if($width >= $height){
                $image->resize(null, 150, function($constraint){
                    $constraint->aspectRatio();
                });
            }else{
                $image->resize(150, null, function($constraint){
                    $constraint->aspectRatio();
                });
            }
            
            $image->crop(150, 150)->save($thumb);
        }
        $file = File::get($thumb);
        $path = dirname($path) . '/thumbs/' . $file_name;
        $result = Storage::disk('s3')->put($path, $file, 'public');
        //logg($thumb);

        if($result != true){
            return false;
        }else{
            return true;
        }
    }

    static function get_image_url($req, $field_name, $type=self::TYPE_MULTIPLE){
        $value = $req->input($field_name);
        if($value == false){
            self::$err = 'No image value';
            return false;
        }

        $images = json_decode($value);

        if($type == self::TYPE_SINGLE){
            $image = $images[0];

            $result = self::save_s3($image);
            if($result == false){
                self::$err = 'Failed to save file to S3.' . $image;
                return false;
            }

            return s3_url($image);
        }else if($type == self::TYPE_MULTIPLE){
            $new_images = [];
            foreach ($images as $key => $image) {
                $result = self::save_s3($image);
                if($result == false){
                    self::$err = 'Failed to save file to S3.' . $image;
                    return false;
                }

                $new_images[] = s3_url($image);
            }

            return json_encode($new_images);
        }
    }
}