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:
parent
7b926980f1
commit
4e9bc0552d
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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,
|
||||
]);
|
||||
}
|
||||
}
|
@ -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 [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ class DownloadMultipleDocumentsRequest extends FormRequest
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->can('view', $this->document);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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": {
|
||||
|
2
public/vendor/livewire/livewire.js
vendored
2
public/vendor/livewire/livewire.js
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/livewire.js.map
vendored
2
public/vendor/livewire/livewire.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@ -1 +1 @@
|
||||
{"/livewire.js":"/livewire.js?id=470956373e3454996f6b"}
|
||||
{"/livewire.js":"/livewire.js?id=d7d975b5d122717a1ee0"}
|
@ -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>
|
@ -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
|
@ -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>
|
@ -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');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user