From 97afc50cfa41106d77ff9e6918ba22ba4c42ba6f Mon Sep 17 00:00:00 2001 From: cuneytsenturk Date: Thu, 28 Dec 2017 17:20:16 +0300 Subject: [PATCH] Attachment system some file --- app/Http/Controllers/Expenses/Bills.php | 43 ++-- app/Http/Controllers/Expenses/Payments.php | 26 +- app/Http/Controllers/Incomes/Invoices.php | 43 ++-- app/Http/Controllers/Incomes/Revenues.php | 26 +- app/Http/Controllers/Items/Items.php | 26 +- app/Models/Income/Invoice.php | 24 +- app/Providers/FormServiceProvider.php | 2 +- app/Traits/Uploads.php | 17 +- composer.json | 3 +- config/app.php | 2 + config/mediable.php | 228 ++++++++++++++++++ ...16_06_27_000000_create_mediable_tables.php | 58 +++++ database/seeds/Roles.php | 1 + .../views/incomes/invoices/edit.blade.php | 2 +- .../views/partials/form/file_group.blade.php | 2 +- routes/web.php | 1 + 16 files changed, 420 insertions(+), 84 deletions(-) create mode 100644 config/mediable.php create mode 100644 database/migrations/2016_06_27_000000_create_mediable_tables.php diff --git a/app/Http/Controllers/Expenses/Bills.php b/app/Http/Controllers/Expenses/Bills.php index 2bf9e84de..c9ca41933 100644 --- a/app/Http/Controllers/Expenses/Bills.php +++ b/app/Http/Controllers/Expenses/Bills.php @@ -128,16 +128,17 @@ class Bills extends Controller $request['amount'] = 0; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'bills'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $bill = Bill::create($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'revenues'); + + $invoice->attachMedia($media, 'attachment'); + } + $taxes = []; + $tax_total = 0; $sub_total = 0; @@ -357,13 +358,6 @@ class Bills extends Controller $request['amount'] = 0; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'bills'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $taxes = []; $tax_total = 0; $sub_total = 0; @@ -460,6 +454,13 @@ class Bills extends Controller $bill->update($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'bills'); + + $bill->syncMedia($media, 'attachment'); + } + // Added bill total total $bill_total = [ 'company_id' => $request['company_id'], @@ -594,15 +595,15 @@ class Bills extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $bill = Bill::find($request['bill_id']); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'payments'); + + $bill->attachMedia($media, 'attachment'); + } + $total_amount = $bill->amount; $amount = (double) $request['amount']; diff --git a/app/Http/Controllers/Expenses/Payments.php b/app/Http/Controllers/Expenses/Payments.php index 205ecb0ca..5df48b396 100644 --- a/app/Http/Controllers/Expenses/Payments.php +++ b/app/Http/Controllers/Expenses/Payments.php @@ -77,13 +77,14 @@ class Payments extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'payments'); - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } + $payment = Payment::create($request->input()); - Payment::create($request->input()); + // Upload attachment + $media = $this->getMedia($request->file('attachment'), 'payments'); + + if ($media) { + $payment->attachMedia($media, 'attachment'); + } $message = trans('messages.success.added', ['type' => trans_choice('general.payments', 1)]); @@ -175,14 +176,15 @@ class Payments extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'payments'); - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $payment->update($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'payments'); + + $payment->syncMedia($media, 'attachment'); + } + $message = trans('messages.success.updated', ['type' => trans_choice('general.payments', 1)]); flash($message)->success(); diff --git a/app/Http/Controllers/Incomes/Invoices.php b/app/Http/Controllers/Incomes/Invoices.php index daafba8a2..40215ef9e 100644 --- a/app/Http/Controllers/Incomes/Invoices.php +++ b/app/Http/Controllers/Incomes/Invoices.php @@ -137,16 +137,17 @@ class Invoices extends Controller $request['amount'] = 0; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'invoices'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $invoice = Invoice::create($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'revenues'); + + $invoice->attachMedia($media, 'attachment'); + } + $taxes = []; + $tax_total = 0; $sub_total = 0; @@ -349,13 +350,6 @@ class Invoices extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'invoices'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $taxes = []; $tax_total = 0; $sub_total = 0; @@ -418,6 +412,13 @@ class Invoices extends Controller $invoice->update($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'invoices'); + + $invoice->syncMedia($media, 'attachment'); + } + // Delete previous invoice totals InvoiceTotal::where('invoice_id', $invoice->id)->delete(); @@ -624,13 +625,6 @@ class Invoices extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'invoices'); - - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $invoice = Invoice::find($request['invoice_id']); $total_amount = $invoice->amount; @@ -669,6 +663,13 @@ class Invoices extends Controller $invoice_payment = InvoicePayment::create($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'invoices'); + + $invoice_payment->attachMedia($media, 'attachment'); + } + $request['status_code'] = $invoice->invoice_status_code; $request['notify'] = 0; diff --git a/app/Http/Controllers/Incomes/Revenues.php b/app/Http/Controllers/Incomes/Revenues.php index 404cfbbd4..a02a8dd83 100644 --- a/app/Http/Controllers/Incomes/Revenues.php +++ b/app/Http/Controllers/Incomes/Revenues.php @@ -79,13 +79,14 @@ class Revenues extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } + $revenue = Revenue::create($request->input()); - Revenue::create($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'revenues'); + + $revenue->syncMedia($media, 'attachment'); + } $message = trans('messages.success.added', ['type' => trans_choice('general.revenues', 1)]); @@ -177,14 +178,15 @@ class Revenues extends Controller $request['currency_code'] = $currency->code; $request['currency_rate'] = $currency->rate; - // Upload attachment - $attachment_path = $this->getUploadedFilePath($request->file('attachment'), 'revenues'); - if ($attachment_path) { - $request['attachment'] = $attachment_path; - } - $revenue->update($request->input()); + // Upload attachment + if ($request->file('attachment')) { + $media = $this->getMedia($request->file('attachment'), 'revenues'); + + $revenue->syncMedia($media, 'attachment'); + } + $message = trans('messages.success.updated', ['type' => trans_choice('general.revenues', 1)]); flash($message)->success(); diff --git a/app/Http/Controllers/Items/Items.php b/app/Http/Controllers/Items/Items.php index 201fe9188..075d2a6c6 100644 --- a/app/Http/Controllers/Items/Items.php +++ b/app/Http/Controllers/Items/Items.php @@ -53,13 +53,14 @@ class Items extends Controller */ public function store(Request $request) { - // Upload picture - $picture_path = $this->getUploadedFilePath($request->file('picture'), 'items'); - if ($picture_path) { - $request['picture'] = $picture_path; - } + $item = Item::create($request->input()); - Item::create($request->input()); + // Upload picture + if ($media) { + $media = $this->getMedia($request->file('picture'), 'items'); + + $item->attachMedia($media, 'picture'); + } $message = trans('messages.success.added', ['type' => trans_choice('general.items', 1)]); @@ -137,14 +138,15 @@ class Items extends Controller */ public function update(Item $item, Request $request) { - // Upload picture - $picture_path = $this->getUploadedFilePath($request->file('picture'), 'items'); - if ($picture_path) { - $request['picture'] = $picture_path; - } - $item->update($request->input()); + // Upload picture + if ($media) { + $media = $this->getMedia($request->file('picture'), 'items'); + + $item->syncMedia($media, 'picture'); + } + $message = trans('messages.success.updated', ['type' => trans_choice('general.items', 1)]); flash($message)->success(); diff --git a/app/Models/Income/Invoice.php b/app/Models/Income/Invoice.php index b80575bc2..e17bbfc6d 100644 --- a/app/Models/Income/Invoice.php +++ b/app/Models/Income/Invoice.php @@ -8,13 +8,21 @@ use App\Traits\DateTime; use App\Traits\Incomes; use Bkwld\Cloner\Cloneable; use Sofa\Eloquence\Eloquence; +use Plank\Mediable\Mediable; class Invoice extends Model { - use Cloneable, Currencies, DateTime, Eloquence, Incomes; + use Cloneable, Currencies, DateTime, Eloquence, Incomes, Mediable; protected $table = 'invoices'; + /** + * The accessors to append to the model's array form. + * + * @var array + */ + protected $appends = ['attachment']; + protected $dates = ['deleted_at', 'invoiced_at', 'due_at']; /** @@ -130,4 +138,18 @@ class Invoice extends Model { $this->attributes['currency_rate'] = (double) $value; } + + /** + * Get the current balance. + * + * @return string + */ + public function getAttachmentAttribute() + { + if (!$this->hasMedia('attachment')) { + return false; + } + + return $this->getMedia('attachment')->first(); + } } diff --git a/app/Providers/FormServiceProvider.php b/app/Providers/FormServiceProvider.php index 666f674d2..680e9c7e6 100644 --- a/app/Providers/FormServiceProvider.php +++ b/app/Providers/FormServiceProvider.php @@ -44,7 +44,7 @@ class FormServiceProvider extends ServiceProvider ]); Form::component('fileGroup', 'partials.form.file_group', [ - 'name', 'text', 'attributes' => [], 'col' => 'col-md-6', + 'name', 'text', 'attributes' => [], 'value' => null, 'col' => 'col-md-6', ]); Form::component('deleteButton', 'partials.form.delete_button', [ diff --git a/app/Traits/Uploads.php b/app/Traits/Uploads.php index 07c1e0648..07c5074ec 100644 --- a/app/Traits/Uploads.php +++ b/app/Traits/Uploads.php @@ -2,6 +2,8 @@ namespace App\Traits; +use MediaUploader; + trait Uploads { @@ -27,4 +29,17 @@ trait Uploads return $path; } -} \ No newline at end of file + + public function getMedia($file, $folder, $company_id = null) + { + if (!$company_id) { + $company_id = session('company_id'); + } + + $path = config('filesystems.disks.uploads.root') . '/' . $company_id . '/' . $folder; + + config(['filesystems.disks.uploads.root' => $path]); + + return MediaUploader::fromSource($file)->upload(); + } +} diff --git a/composer.json b/composer.json index bfe3a069c..a919032fa 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,8 @@ "nwidart/laravel-modules": "1.*", "santigarcor/laratrust": "4.0.*", "sofa/eloquence": "5.4.*", - "tucker-eric/eloquentfilter": "1.1.*" + "tucker-eric/eloquentfilter": "1.1.*", + "plank/laravel-mediable": "2.5.*" }, "require-dev": { "fzaninotto/faker": "1.6.*" diff --git a/config/app.php b/config/app.php index fbfa3c154..e2fce1615 100644 --- a/config/app.php +++ b/config/app.php @@ -203,6 +203,7 @@ return [ Nwidart\Menus\MenusServiceProvider::class, Nwidart\Modules\LaravelModulesServiceProvider::class, Sofa\Eloquence\ServiceProvider::class, + Plank\Mediable\MediableServiceProvider::class, ], @@ -238,6 +239,7 @@ return [ 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, + 'MediaUploader' => Plank\Mediable\MediaUploaderFacade::class, 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, diff --git a/config/mediable.php b/config/mediable.php new file mode 100644 index 000000000..e28f8dd8c --- /dev/null +++ b/config/mediable.php @@ -0,0 +1,228 @@ + Plank\Mediable\Media::class, + + /* + * Filesystem disk to use if none is specified + */ + 'default_disk' => 'uploads', + + /* + * Filesystems that can be used for media storage + * + * Uploader will throw an exception if a disk not in this list is selected + */ + 'allowed_disks' => [ + 'uploads', + ], + + /* + * The maximum file size in bytes for a single uploaded file + */ + 'max_size' => 1024 * 1024 * 10, + + /* + * What to do if a duplicate file is uploaded. + * + * Options include: + * + * * `'increment'`: the new file's name is given an incrementing suffix + * * `'replace'` : the old file and media model is deleted + * * `'error'`: an Exception is thrown + */ + 'on_duplicate' => Plank\Mediable\MediaUploader::ON_DUPLICATE_INCREMENT, + + /* + * Reject files unless both their mime and extension are recognized and both match a single aggregate type + */ + 'strict_type_checking' => false, + + /* + * Reject files whose mime type or extension is not recognized + * if true, files will be given a type of `'other'` + */ + 'allow_unrecognized_types' => false, + + /* + * Only allow files with specific MIME type(s) to be uploaded + */ + 'allowed_mime_types' => [], + + /* + * Only allow files with specific file extension(s) to be uploaded + */ + 'allowed_extensions' => [], + + /* + * Only allow files matching specific aggregate type(s) to be uploaded + */ + 'allowed_aggregate_types' => [], + + /* + * List of aggregate types recognized by the application + * + * Each type should list the MIME types and extensions + * that should be recognized for the type + */ + 'aggregate_types' => [ + Plank\Mediable\Media::TYPE_IMAGE => [ + 'mime_types' => [ + 'image/jpeg', + 'image/png', + 'image/gif', + ], + 'extensions' => [ + 'jpg', + 'jpeg', + 'png', + 'gif', + ] + ], + Plank\Mediable\Media::TYPE_IMAGE_VECTOR => [ + 'mime_types' => [ + 'image/svg+xml', + ], + 'extensions' => [ + 'svg', + ] + ], + Plank\Mediable\Media::TYPE_PDF => [ + 'mime_types' => [ + 'application/pdf', + ], + 'extensions' => [ + 'pdf', + ] + ], + Plank\Mediable\Media::TYPE_AUDIO => [ + 'mime_types' => [ + 'audio/aac', + 'audio/ogg', + 'audio/mpeg', + 'audio/mp3', + 'audio/mpeg', + 'audio/wav' + ], + 'extensions' => [ + 'aac', + 'ogg', + 'oga', + 'mp3', + 'wav', + ] + ], + Plank\Mediable\Media::TYPE_VIDEO => [ + 'mime_types' => [ + 'video/mp4', + 'video/mpeg', + 'video/ogg', + 'video/webm' + ], + 'extensions' => [ + 'mp4', + 'm4v', + 'mov', + 'ogv', + 'webm' + ] + ], + Plank\Mediable\Media::TYPE_ARCHIVE => [ + 'mime_types' => [ + 'application/zip', + 'application/x-compressed-zip', + 'multipart/x-zip', + ], + 'extensions' => [ + 'zip', + ] + ], + Plank\Mediable\Media::TYPE_DOCUMENT => [ + 'mime_types' => [ + 'text/plain', + 'application/plain', + 'text/xml', + 'text/json', + 'application/json', + 'application/msword', + 'application/application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ], + 'extensions' => [ + 'doc', + 'docx', + 'txt', + 'text', + 'xml', + 'json', + ] + ], + Plank\Mediable\Media::TYPE_SPREADSHEET => [ + 'mime_types' => [ + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + ], + 'extensions' => [ + 'xls', + 'xlsx', + ] + ], + Plank\Mediable\Media::TYPE_PRESENTATION => [ + 'mime_types' => + [ + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' + ], + 'extensions' => + [ + 'ppt', + 'pptx', + 'ppsx', + ] + ], + ], + + /* + * List of adapters to use for various source inputs + * + * Adapters can map either to a class or a pattern (regex) + */ + 'source_adapters' => [ + 'class' => [ + Symfony\Component\HttpFoundation\File\UploadedFile::class => Plank\Mediable\SourceAdapters\UploadedFileAdapter::class, + Symfony\Component\HttpFoundation\File\File::class => Plank\Mediable\SourceAdapters\FileAdapter::class, + Psr\Http\Message\StreamInterface::class => Plank\Mediable\SourceAdapters\StreamAdapter::class, + ], + 'pattern' => [ + '^https?://' => Plank\Mediable\SourceAdapters\RemoteUrlAdapter::class, + '^/' => Plank\Mediable\SourceAdapters\LocalPathAdapter::class, + '^[a-zA-Z]:\\' => Plank\Mediable\SourceAdapters\LocalPathAdapter::class + ], + ], + + /* + * List of URL Generators to use for handling various filesystem drivers + * + */ + 'url_generators' => [ + 'local' => Plank\Mediable\UrlGenerators\LocalUrlGenerator::class, + 's3' => Plank\Mediable\UrlGenerators\S3UrlGenerator::class, + ], + + /** + * Should mediable instances automatically reload their media relationships after modification are made to a tag. + * + * If true, will automatically reload media the next time `getMedia()`, `getMediaMatchAll()` or `getAllMediaByTag()` are called. + */ + 'rehydrate_media' => true, + + /** + * Detach associated media when mediable model is soft deleted. + */ + 'detach_on_soft_delete' => true, +]; diff --git a/database/migrations/2016_06_27_000000_create_mediable_tables.php b/database/migrations/2016_06_27_000000_create_mediable_tables.php new file mode 100644 index 000000000..b35c40ecd --- /dev/null +++ b/database/migrations/2016_06_27_000000_create_mediable_tables.php @@ -0,0 +1,58 @@ +increments('id'); + $table->string('disk', 32); + $table->string('directory'); + $table->string('filename'); + $table->string('extension', 32); + $table->string('mime_type', 128); + $table->string('aggregate_type', 32); + $table->integer('size')->unsigned(); + $table->timestamps(); + + $table->index(['disk', 'directory']); + $table->unique(['disk', 'directory', 'filename', 'extension']); + $table->index('aggregate_type'); + }); + + Schema::create('mediables', function (Blueprint $table) { + $table->integer('media_id')->unsigned(); + $table->string('mediable_type'); + $table->integer('mediable_id')->unsigned(); + $table->string('tag'); + $table->integer('order')->unsigned(); + + $table->primary(['media_id', 'mediable_type', 'mediable_id', 'tag']); + $table->index(['mediable_id', 'mediable_type']); + $table->index('tag'); + $table->index('order'); + $table->foreign('media_id')->references('id')->on('media') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('mediables'); + Schema::drop('media'); + } +} diff --git a/database/seeds/Roles.php b/database/seeds/Roles.php index db424e010..736d6b682 100644 --- a/database/seeds/Roles.php +++ b/database/seeds/Roles.php @@ -36,6 +36,7 @@ class Roles extends Seeder 'auth-profile' => 'r,u', 'companies-companies' => 'c,r,u,d', 'common-import' => 'c', + 'common-uploads' => 'd', 'items-items' => 'c,r,u,d', 'incomes-invoices' => 'c,r,u,d', 'incomes-revenues' => 'c,r,u,d', diff --git a/resources/views/incomes/invoices/edit.blade.php b/resources/views/incomes/invoices/edit.blade.php index 5c42c5520..0c49c53c5 100644 --- a/resources/views/incomes/invoices/edit.blade.php +++ b/resources/views/incomes/invoices/edit.blade.php @@ -203,7 +203,7 @@ $('#attachment').fancyfile({ text : '{{ trans('general.form.select.file') }}', style : 'btn-default', - placeholder : 'attachment; ?>' + placeholder : 'attachment->basename; ?>' }); var autocomplete_path = "{{ url('items/items/autocomplete') }}"; diff --git a/resources/views/partials/form/file_group.blade.php b/resources/views/partials/form/file_group.blade.php index 59656ce85..cc110eed1 100644 --- a/resources/views/partials/form/file_group.blade.php +++ b/resources/views/partials/form/file_group.blade.php @@ -1,5 +1,5 @@
{!! Form::label($name, $text, ['class' => 'control-label']) !!} - {!! Form::file($name, null, array_merge(['class' => 'form-control'], $attributes)) !!} + {!! Form::file($name, $value, array_merge(['class' => 'form-control'], $attributes)) !!} {!! $errors->first($name, '

:message

') !!}
diff --git a/routes/web.php b/routes/web.php index 251ee0d1f..91e744610 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,6 +11,7 @@ Route::group(['middleware' => 'language'], function () { Route::group(['prefix' => 'uploads'], function () { Route::get('{folder}/{file}', 'Common\Uploads@get'); Route::get('{folder}/{file}/download', 'Common\Uploads@download'); + Route::get('{folder}/{file}/destroy', 'Common\Uploads@destroy'); }); Route::group(['middleware' => ['adminmenu', 'permission:read-admin-panel']], function () {