1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Rename "Downloads" to "Documents":

- Remove Livewire auto-publish from composer.json
- Replace old DocumentController with DownloadsController
- Rename DownloadsTable & downloads-table to DocumentsTable & documents-table
- New ShowDocumentRequest for displaying documents
- Change authorize() with DownloadMultipleDocumentsRequest
- Change route in PortalComposer
- Update Livewire assets
- Remove old documents routes
This commit is contained in:
Benjamin Beganović 2020-09-28 12:04:34 +02:00
parent 7b926980f1
commit 4e9bc0552d
14 changed files with 124 additions and 202 deletions

View File

@ -1,4 +1,5 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
@ -12,124 +13,64 @@
namespace App\Http\Controllers\ClientPortal;
use App\Http\Controllers\Controller;
use App\Http\Requests\ClientPortal\StoreDocumentRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Http\Requests\ClientPortal\Documents\ShowDocumentRequest;
use App\Http\Requests\Document\DownloadMultipleDocumentsRequest;
use App\Models\Document;
use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Facades\Storage;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
class DocumentController extends Controller
{
use MakesHash;
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
return render('documents.index');
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function create()
public function show(ShowDocumentRequest $request, Document $document)
{
//
return render('documents.show', [
'document' => $document,
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(StoreDocumentRequest $request)
public function download(ShowDocumentRequest $request, Document $document)
{
$contact = auth()->user();
Storage::makeDirectory('public/'.$contact->client->client_hash, 0775);
$path = Storage::putFile('public/'.$contact->client->client_hash, $request->file('file'));
$contact = auth()->user();
$contact->avatar_size = $request->file('file')->getSize();
$contact->avatar_type = $request->file('file')->getClientOriginalExtension();
$contact->avatar = Storage::url($path);
$contact->save();
return response()->json($contact);
/*
[2019-08-07 05:50:23] local.ERROR: array (
'_token' => '7KoEVRjB2Fq8XBVFRUFbhQFjKm4rY9h0AGSlpdj3',
'is_avatar' => '1',
'q' => '/client/document',
'file' =>
Illuminate\Http\UploadedFile::__set_state(array(
'test' => false,
'originalName' => 'family.jpg',
'mimeType' => 'image/jpeg',
'error' => 0,
'hashName' => NULL,
)),
)
*/
return Storage::disk($document->disk)->download($document->url, $document->name);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
{
//
}
$documents = Document::whereIn('id', $this->transformKeys($request->file_hash))
->where('company_id', auth('contact')->user()->company->id)
->get();
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
$documents->map(function ($document) {
if (auth()->user('contact')->client->id != $document->documentable->id) {
abort(401);
}
});
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
$options = new Archive();
/**
* Remove the specified resource from storage.
*
* @return \Illuminate\Http\Response
*/
public function destroy()
{
$contact = auth()->user();
$options->setSendHttpHeaders(true);
$file = basename($contact->avatar);
$image_path = 'public/'.$contact->client->client_hash.'/'.$file;
$zip = new ZipStream('files.zip', $options);
Storage::delete($image_path);
foreach ($documents as $document) {
$zip->addFileFromPath(basename($document->filePath()), TempFile::path($document->filePath()));
}
$contact->avatar = '';
$contact->avatar_type = '';
$contact->avatar_size = '';
$contact->save();
return response()->json($contact);
$zip->finish();
}
}

View File

@ -1,76 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers\ClientPortal;
use App\Http\Controllers\Controller;
use App\Http\Requests\Document\DownloadMultipleDocumentsRequest;
use App\Http\Requests\Document\ShowDocumentRequest;
use App\Models\Document;
use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Facades\Storage;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
class DownloadController extends Controller
{
use MakesHash;
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
return render('downloads.index');
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show(ShowDocumentRequest $request, Document $download)
{
return render('downloads.show', [
'document' => $download,
]);
}
/**
* @param \App\Http\Requests\Document\ShowDocumentRequest $request
* @param \App\Models\Document $download
* @param bool $bulk
* @return mixed
*/
public function download(ShowDocumentRequest $request, Document $download)
{
return Storage::disk($download->disk)->download($download->url, $download->name);
}
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
{
$documents = Document::whereIn('id', $this->transformKeys($request->file_hash))
->where('company_id', auth('contact')->user()->company->id)
->get();
$options = new Archive();
$options->setSendHttpHeaders(true);
$zip = new ZipStream('files.zip', $options);
foreach ($documents as $document) {
$zip->addFileFromPath(basename($document->filePath()), TempFile::path($document->filePath()));
}
$zip->finish();
}
}

View File

@ -1,5 +1,15 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Livewire;
use App\Models\Document;
@ -7,16 +17,23 @@ use App\Utils\Traits\WithSorting;
use Livewire\Component;
use Livewire\WithPagination;
class DownloadsTable extends Component
class DocumentsTable extends Component
{
use WithPagination, WithSorting;
public $client;
public $per_page = 10;
public $status = [
'resources',
];
public function mount($client)
{
$this->client = $client;
}
public function statusChange($status)
{
if (in_array($status, $this->status)) {
@ -28,8 +45,7 @@ class DownloadsTable extends Component
public function render()
{
// $query = auth('contact')->user()->client->documents();
$query = Document::query();
$query = $this->client->documents();
if (in_array('resources', $this->status) && ! in_array('client', $this->status)) {
$query = $query->where('documentable_type', '!=', \App\Models\Client::class);
@ -40,12 +56,12 @@ class DownloadsTable extends Component
}
$query = $query
// ->where('is_public', true)
->where('is_public', true)
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
->paginate($this->per_page);
return render('components.livewire.downloads-table', [
'downloads' => $query,
return render('components.livewire.documents-table', [
'documents' => $query,
]);
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Requests\ClientPortal\Documents;
use App\Models\Document;
use App\Utils\Traits\MakesHash;
use Illuminate\Foundation\Http\FormRequest;
class ShowDocumentRequest extends FormRequest
{
use MakesHash;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->user('contact')->client->id === $this->document->documentable->id;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}

View File

@ -23,7 +23,7 @@ class DownloadMultipleDocumentsRequest extends FormRequest
*/
public function authorize()
{
return auth()->user()->can('view', $this->document);
return true;
}
/**

View File

@ -65,7 +65,7 @@ class PortalComposer
$data[] = ['title' => ctrans('texts.quotes'), 'url' => 'client.quotes.index', 'icon' => 'align-left'];
$data[] = ['title' => ctrans('texts.credits'), 'url' => 'client.credits.index', 'icon' => 'credit-card'];
$data[] = ['title' => ctrans('texts.payment_methods'), 'url' => 'client.payment_methods.index', 'icon' => 'shield'];
$data[] = ['title' => ctrans('texts.documents'), 'url' => 'client.downloads.index', 'icon' => 'download'];
$data[] = ['title' => ctrans('texts.documents'), 'url' => 'client.documents.index', 'icon' => 'download'];
return $data;
}

View File

@ -102,8 +102,7 @@
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi",
"@php artisan vendor:publish --force --tag=livewire:assets --ansi"
"@php artisan package:discover --ansi"
]
},
"config": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"/livewire.js":"/livewire.js?id=470956373e3454996f6b"}
{"/livewire.js":"/livewire.js?id=d7d975b5d122717a1ee0"}

View File

@ -59,30 +59,30 @@
</tr>
</thead>
<tbody>
@forelse($downloads as $download)
@forelse($documents as $document)
<tr class="bg-white group hover:bg-gray-100">
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
<input type="checkbox" class="form-checkbox cursor-pointer" onchange="appendToElement('multiple-downloads', '{{ $download->hashed_id }}')" />
<input type="checkbox" class="form-checkbox cursor-pointer" onchange="appendToElement('multiple-downloads', '{{ $document->hashed_id }}')" />
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
{{ Illuminate\Support\Str::limit($download->name, 20) }}
{{ Illuminate\Support\Str::limit($document->name, 20) }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
{{ ((new \ReflectionClass($download->documentable))->getShortName()) }}
{{ ((new \ReflectionClass($document->documentable))->getShortName()) }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
{{ App\Models\Document::$types[$download->type]['mime'] }}
{{ App\Models\Document::$types[$document->type]['mime'] }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
{{ $download->size / 1000 }} kB
{{ $document->size / 1000 }} kB
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
<a href="{{ route('client.downloads.download', $download->hashed_id) }}" class="text-black hover:text-blue-600">
<a href="{{ route('client.documents.download', $document->hashed_id) }}" class="text-black hover:text-blue-600">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-download-cloud"><polyline points="8 17 12 21 16 17"></polyline><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path></svg>
</a>
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
<a href="{{ route('client.downloads.show', $download->hashed_id) }}" class="button-link">
<a href="{{ route('client.documents.show', $document->hashed_id) }}" class="button-link">
{{ ctrans('texts.view') }}
</a>
</td>
@ -99,11 +99,11 @@
</div>
</div>
<div class="flex justify-center md:justify-between mt-6 mb-6">
@if($downloads->total() > 0)
@if($documents->total() > 0)
<span class="text-gray-700 text-sm hidden md:block">
{{ ctrans('texts.showing_x_of', ['first' => $downloads->firstItem(), 'last' => $downloads->lastItem(), 'total' => $downloads->total()]) }}
{{ ctrans('texts.showing_x_of', ['first' => $documents->firstItem(), 'last' => $documents->lastItem(), 'total' => $documents->total()]) }}
</span>
@endif
{{ $downloads->links() }}
{{ $documents->links() }}
</div>
</div>

View File

@ -10,8 +10,8 @@
@endsection
@section('body')
<form action="{{ route('client.downloads.multiple') }}" method="post" id="multiple-downloads">
<form action="{{ route('client.documents.download_multiple') }}" method="post" id="multiple-downloads">
@csrf
</form>
@livewire('downloads-table')
@livewire('documents-table', ['client' => $client])
@endsection

View File

@ -22,7 +22,7 @@
</dt>
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2 flex items-center">
{{ Illuminate\Support\Str::limit($document->name, 40) }}
<a href="{{ route('client.downloads.download', $document->hashed_id) }}" class="ml-2 text-black hover:text-blue-600" download>
<a href="{{ route('client.documents.download', $document->hashed_id) }}" class="ml-2 text-black hover:text-blue-600" download>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-download-cloud">
<polyline points="8 17 12 21 16 17"></polyline>
<line x1="12" y1="12" x2="12" y2="21"></line>

View File

@ -57,14 +57,12 @@ Route::group(['middleware' => ['auth:contact', 'locale'], 'prefix' => 'client',
Route::resource('credits', 'ClientPortal\CreditController')->only('index', 'show');
Route::post('document', 'ClientPortal\DocumentController@store')->name('document.store');
Route::delete('document', 'ClientPortal\DocumentController@destroy')->name('document.destroy');
Route::get('client/switch_company/{contact}', 'ClientPortal\SwitchCompanyController')->name('switch_company');
Route::post('downloads/multiple', 'ClientPortal\DownloadController@downloadMultiple')->name('downloads.multiple');
Route::get('downloads/{download}/download', 'ClientPortal\DownloadController@download')->name('downloads.download');
Route::resource('downloads', 'ClientPortal\DownloadController')->only(['index', 'show']);
Route::post('documents/download_multiple', 'ClientPortal\DocumentController@downloadMultiple')->name('documents.download_multiple');
Route::get('documents/{document}/download', 'ClientPortal\DocumentController@download')->name('documents.download');
Route::resource('documents', 'ClientPortal\DocumentController')->only(['index', 'show']);
Route::post('upload', 'ClientPortal\UploadController')->name('upload.store');