mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-08-07 23:03:00 +03:00
Apply fixes from StyleCI
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Api\ListingResponseBuilder;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
@@ -7,7 +9,6 @@ use Illuminate\Http\JsonResponse;
|
||||
|
||||
abstract class ApiController extends Controller
|
||||
{
|
||||
|
||||
protected $rules = [];
|
||||
|
||||
/**
|
||||
@@ -17,6 +18,7 @@ abstract class ApiController extends Controller
|
||||
protected function apiListingResponse(Builder $query, array $fields): JsonResponse
|
||||
{
|
||||
$listing = new ListingResponseBuilder($query, request(), $fields);
|
||||
|
||||
return $listing->toResponse();
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,11 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Api\ApiDocsGenerator;
|
||||
|
||||
class ApiDocsController extends ApiController
|
||||
{
|
||||
|
||||
/**
|
||||
* Load the docs page for the API.
|
||||
*/
|
||||
@@ -12,6 +13,7 @@ class ApiDocsController extends ApiController
|
||||
{
|
||||
$docs = ApiDocsGenerator::generateConsideringCache();
|
||||
$this->setPageTitle(trans('settings.users_api_tokens_docs'));
|
||||
|
||||
return view('api-docs.index', [
|
||||
'docs' => $docs,
|
||||
]);
|
||||
@@ -23,6 +25,7 @@ class ApiDocsController extends ApiController
|
||||
public function json()
|
||||
{
|
||||
$docs = ApiDocsGenerator::generateConsideringCache();
|
||||
|
||||
return response()->json($docs);
|
||||
}
|
||||
}
|
||||
|
@@ -1,27 +1,26 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Exceptions\NotifyException;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class BookApiController extends ApiController
|
||||
{
|
||||
|
||||
protected $bookRepo;
|
||||
|
||||
protected $rules = [
|
||||
'create' => [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'tags' => 'array',
|
||||
'tags' => 'array',
|
||||
],
|
||||
'update' => [
|
||||
'name' => 'string|min:1|max:255',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'tags' => 'array',
|
||||
'tags' => 'array',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -36,6 +35,7 @@ class BookApiController extends ApiController
|
||||
public function list()
|
||||
{
|
||||
$books = Book::visible();
|
||||
|
||||
return $this->apiListingResponse($books, [
|
||||
'id', 'name', 'slug', 'description', 'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by', 'image_id',
|
||||
]);
|
||||
@@ -43,6 +43,7 @@ class BookApiController extends ApiController
|
||||
|
||||
/**
|
||||
* Create a new book in the system.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Request $request)
|
||||
@@ -51,6 +52,7 @@ class BookApiController extends ApiController
|
||||
$requestData = $this->validate($request, $this->rules['create']);
|
||||
|
||||
$book = $this->bookRepo->create($requestData);
|
||||
|
||||
return response()->json($book);
|
||||
}
|
||||
|
||||
@@ -60,11 +62,13 @@ class BookApiController extends ApiController
|
||||
public function read(string $id)
|
||||
{
|
||||
$book = Book::visible()->with(['tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy'])->findOrFail($id);
|
||||
|
||||
return response()->json($book);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the details of a single book.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
@@ -81,6 +85,7 @@ class BookApiController extends ApiController
|
||||
/**
|
||||
* Delete a single book.
|
||||
* This will typically send the book to the recycle bin.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(string $id)
|
||||
@@ -89,6 +94,7 @@ class BookApiController extends ApiController
|
||||
$this->checkOwnablePermission('book-delete', $book);
|
||||
|
||||
$this->bookRepo->destroy($book);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
@@ -15,23 +17,27 @@ class BookExportApiController extends ApiController
|
||||
|
||||
/**
|
||||
* Export a book as a PDF file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportPdf(int $id)
|
||||
{
|
||||
$book = Book::visible()->findOrFail($id);
|
||||
$pdfContent = $this->exportFormatter->bookToPdf($book);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $book->slug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a book as a contained HTML file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportHtml(int $id)
|
||||
{
|
||||
$book = Book::visible()->findOrFail($id);
|
||||
$htmlContent = $this->exportFormatter->bookToContainedHtml($book);
|
||||
|
||||
return $this->downloadResponse($htmlContent, $book->slug . '.html');
|
||||
}
|
||||
|
||||
@@ -42,6 +48,7 @@ class BookExportApiController extends ApiController
|
||||
{
|
||||
$book = Book::visible()->findOrFail($id);
|
||||
$textContent = $this->exportFormatter->bookToPlainText($book);
|
||||
|
||||
return $this->downloadResponse($textContent, $book->slug . '.txt');
|
||||
}
|
||||
|
||||
@@ -52,6 +59,7 @@ class BookExportApiController extends ApiController
|
||||
{
|
||||
$book = Book::visible()->findOrFail($id);
|
||||
$markdown = $this->exportFormatter->bookToMarkdown($book);
|
||||
|
||||
return $this->downloadResponse($markdown, $book->slug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Entities\Repos\BookshelfRepo;
|
||||
use BookStack\Entities\Models\Bookshelf;
|
||||
use BookStack\Entities\Repos\BookshelfRepo;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -9,7 +11,6 @@ use Illuminate\Validation\ValidationException;
|
||||
|
||||
class BookshelfApiController extends ApiController
|
||||
{
|
||||
|
||||
/**
|
||||
* @var BookshelfRepo
|
||||
*/
|
||||
@@ -17,14 +18,14 @@ class BookshelfApiController extends ApiController
|
||||
|
||||
protected $rules = [
|
||||
'create' => [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'books' => 'array',
|
||||
'books' => 'array',
|
||||
],
|
||||
'update' => [
|
||||
'name' => 'string|min:1|max:255',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'books' => 'array',
|
||||
'books' => 'array',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -42,6 +43,7 @@ class BookshelfApiController extends ApiController
|
||||
public function list()
|
||||
{
|
||||
$shelves = Bookshelf::visible();
|
||||
|
||||
return $this->apiListingResponse($shelves, [
|
||||
'id', 'name', 'slug', 'description', 'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by', 'image_id',
|
||||
]);
|
||||
@@ -51,6 +53,7 @@ class BookshelfApiController extends ApiController
|
||||
* Create a new shelf in the system.
|
||||
* An array of books IDs can be provided in the request. These
|
||||
* will be added to the shelf in the same order as provided.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Request $request)
|
||||
@@ -73,8 +76,9 @@ class BookshelfApiController extends ApiController
|
||||
'tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy',
|
||||
'books' => function (BelongsToMany $query) {
|
||||
$query->visible()->get(['id', 'name', 'slug']);
|
||||
}
|
||||
},
|
||||
])->findOrFail($id);
|
||||
|
||||
return response()->json($shelf);
|
||||
}
|
||||
|
||||
@@ -83,6 +87,7 @@ class BookshelfApiController extends ApiController
|
||||
* An array of books IDs can be provided in the request. These
|
||||
* will be added to the shelf in the same order as provided and overwrite
|
||||
* any existing book assignments.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
@@ -94,14 +99,14 @@ class BookshelfApiController extends ApiController
|
||||
$bookIds = $request->get('books', null);
|
||||
|
||||
$shelf = $this->bookshelfRepo->update($shelf, $requestData, $bookIds);
|
||||
|
||||
return response()->json($shelf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Delete a single shelf.
|
||||
* This will typically send the shelf to the recycle bin.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(string $id)
|
||||
@@ -110,6 +115,7 @@ class BookshelfApiController extends ApiController
|
||||
$this->checkOwnablePermission('bookshelf-delete', $shelf);
|
||||
|
||||
$this->bookshelfRepo->destroy($shelf);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Entities\Repos\ChapterRepo;
|
||||
use BookStack\Facades\Activity;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -14,16 +14,16 @@ class ChapterApiController extends ApiController
|
||||
|
||||
protected $rules = [
|
||||
'create' => [
|
||||
'book_id' => 'required|integer',
|
||||
'name' => 'required|string|max:255',
|
||||
'book_id' => 'required|integer',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'tags' => 'array',
|
||||
'tags' => 'array',
|
||||
],
|
||||
'update' => [
|
||||
'book_id' => 'integer',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'book_id' => 'integer',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'tags' => 'array',
|
||||
'tags' => 'array',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -41,6 +41,7 @@ class ChapterApiController extends ApiController
|
||||
public function list()
|
||||
{
|
||||
$chapters = Chapter::visible();
|
||||
|
||||
return $this->apiListingResponse($chapters, [
|
||||
'id', 'book_id', 'name', 'slug', 'description', 'priority',
|
||||
'created_at', 'updated_at', 'created_by', 'updated_by', 'owned_by',
|
||||
@@ -59,6 +60,7 @@ class ChapterApiController extends ApiController
|
||||
$this->checkOwnablePermission('chapter-create', $book);
|
||||
|
||||
$chapter = $this->chapterRepo->create($request->all(), $book);
|
||||
|
||||
return response()->json($chapter->load(['tags']));
|
||||
}
|
||||
|
||||
@@ -70,6 +72,7 @@ class ChapterApiController extends ApiController
|
||||
$chapter = Chapter::visible()->with(['tags', 'createdBy', 'updatedBy', 'ownedBy', 'pages' => function (HasMany $query) {
|
||||
$query->visible()->get(['id', 'name', 'slug']);
|
||||
}])->findOrFail($id);
|
||||
|
||||
return response()->json($chapter);
|
||||
}
|
||||
|
||||
@@ -82,6 +85,7 @@ class ChapterApiController extends ApiController
|
||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
||||
|
||||
$updatedChapter = $this->chapterRepo->update($chapter, $request->all());
|
||||
|
||||
return response()->json($updatedChapter->load(['tags']));
|
||||
}
|
||||
|
||||
@@ -95,6 +99,7 @@ class ChapterApiController extends ApiController
|
||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
||||
|
||||
$this->chapterRepo->destroy($chapter);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
@@ -18,23 +20,27 @@ class ChapterExportApiController extends ApiController
|
||||
|
||||
/**
|
||||
* Export a chapter as a PDF file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportPdf(int $id)
|
||||
{
|
||||
$chapter = Chapter::visible()->findOrFail($id);
|
||||
$pdfContent = $this->exportFormatter->chapterToPdf($chapter);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $chapter->slug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a chapter as a contained HTML file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportHtml(int $id)
|
||||
{
|
||||
$chapter = Chapter::visible()->findOrFail($id);
|
||||
$htmlContent = $this->exportFormatter->chapterToContainedHtml($chapter);
|
||||
|
||||
return $this->downloadResponse($htmlContent, $chapter->slug . '.html');
|
||||
}
|
||||
|
||||
@@ -45,6 +51,7 @@ class ChapterExportApiController extends ApiController
|
||||
{
|
||||
$chapter = Chapter::visible()->findOrFail($id);
|
||||
$textContent = $this->exportFormatter->chapterToPlainText($chapter);
|
||||
|
||||
return $this->downloadResponse($textContent, $chapter->slug . '.txt');
|
||||
}
|
||||
|
||||
@@ -55,6 +62,7 @@ class ChapterExportApiController extends ApiController
|
||||
{
|
||||
$chapter = Chapter::visible()->findOrFail($id);
|
||||
$markdown = $this->exportFormatter->chapterToMarkdown($chapter);
|
||||
|
||||
return $this->downloadResponse($markdown, $chapter->slug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -16,20 +16,20 @@ class PageApiController extends ApiController
|
||||
|
||||
protected $rules = [
|
||||
'create' => [
|
||||
'book_id' => 'required_without:chapter_id|integer',
|
||||
'book_id' => 'required_without:chapter_id|integer',
|
||||
'chapter_id' => 'required_without:book_id|integer',
|
||||
'name' => 'required|string|max:255',
|
||||
'html' => 'required_without:markdown|string',
|
||||
'markdown' => 'required_without:html|string',
|
||||
'tags' => 'array',
|
||||
'name' => 'required|string|max:255',
|
||||
'html' => 'required_without:markdown|string',
|
||||
'markdown' => 'required_without:html|string',
|
||||
'tags' => 'array',
|
||||
],
|
||||
'update' => [
|
||||
'book_id' => 'required|integer',
|
||||
'book_id' => 'required|integer',
|
||||
'chapter_id' => 'required|integer',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'html' => 'string',
|
||||
'markdown' => 'string',
|
||||
'tags' => 'array',
|
||||
'name' => 'string|min:1|max:255',
|
||||
'html' => 'string',
|
||||
'markdown' => 'string',
|
||||
'tags' => 'array',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -44,6 +44,7 @@ class PageApiController extends ApiController
|
||||
public function list()
|
||||
{
|
||||
$pages = Page::visible();
|
||||
|
||||
return $this->apiListingResponse($pages, [
|
||||
'id', 'book_id', 'chapter_id', 'name', 'slug', 'priority',
|
||||
'draft', 'template',
|
||||
@@ -89,6 +90,7 @@ class PageApiController extends ApiController
|
||||
public function read(string $id)
|
||||
{
|
||||
$page = $this->pageRepo->getById($id, []);
|
||||
|
||||
return response()->json($page->forJsonDisplay());
|
||||
}
|
||||
|
||||
@@ -107,12 +109,13 @@ class PageApiController extends ApiController
|
||||
$parent = null;
|
||||
if ($request->has('chapter_id')) {
|
||||
$parent = Chapter::visible()->findOrFail($request->get('chapter_id'));
|
||||
} else if ($request->has('book_id')) {
|
||||
} elseif ($request->has('book_id')) {
|
||||
$parent = Book::visible()->findOrFail($request->get('book_id'));
|
||||
}
|
||||
|
||||
if ($parent && !$parent->matches($page->getParent())) {
|
||||
$this->checkOwnablePermission('page-delete', $page);
|
||||
|
||||
try {
|
||||
$this->pageRepo->move($page, $parent->getType() . ':' . $parent->id);
|
||||
} catch (Exception $exception) {
|
||||
@@ -125,6 +128,7 @@ class PageApiController extends ApiController
|
||||
}
|
||||
|
||||
$updatedPage = $this->pageRepo->update($page, $request->all());
|
||||
|
||||
return response()->json($updatedPage->forJsonDisplay());
|
||||
}
|
||||
|
||||
@@ -138,6 +142,7 @@ class PageApiController extends ApiController
|
||||
$this->checkOwnablePermission('page-delete', $page);
|
||||
|
||||
$this->pageRepo->destroy($page);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers\Api;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Api;
|
||||
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
@@ -15,23 +17,27 @@ class PageExportApiController extends ApiController
|
||||
|
||||
/**
|
||||
* Export a page as a PDF file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportPdf(int $id)
|
||||
{
|
||||
$page = Page::visible()->findOrFail($id);
|
||||
$pdfContent = $this->exportFormatter->pageToPdf($page);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $page->slug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a page as a contained HTML file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function exportHtml(int $id)
|
||||
{
|
||||
$page = Page::visible()->findOrFail($id);
|
||||
$htmlContent = $this->exportFormatter->pageToContainedHtml($page);
|
||||
|
||||
return $this->downloadResponse($htmlContent, $page->slug . '.html');
|
||||
}
|
||||
|
||||
@@ -42,6 +48,7 @@ class PageExportApiController extends ApiController
|
||||
{
|
||||
$page = Page::visible()->findOrFail($id);
|
||||
$textContent = $this->exportFormatter->pageToPlainText($page);
|
||||
|
||||
return $this->downloadResponse($textContent, $page->slug . '.txt');
|
||||
}
|
||||
|
||||
@@ -52,6 +59,7 @@ class PageExportApiController extends ApiController
|
||||
{
|
||||
$page = Page::visible()->findOrFail($id);
|
||||
$markdown = $this->exportFormatter->pageToMarkdown($page);
|
||||
|
||||
return $this->downloadResponse($markdown, $page->slug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Exceptions\FileUploadException;
|
||||
@@ -25,9 +27,9 @@ class AttachmentController extends Controller
|
||||
$this->pageRepo = $pageRepo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Endpoint at which attachments are uploaded to.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
@@ -35,7 +37,7 @@ class AttachmentController extends Controller
|
||||
{
|
||||
$this->validate($request, [
|
||||
'uploaded_to' => 'required|integer|exists:pages,id',
|
||||
'file' => 'required|file'
|
||||
'file' => 'required|file',
|
||||
]);
|
||||
|
||||
$pageId = $request->get('uploaded_to');
|
||||
@@ -57,12 +59,13 @@ class AttachmentController extends Controller
|
||||
|
||||
/**
|
||||
* Update an uploaded attachment.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function uploadUpdate(Request $request, $attachmentId)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'file' => 'required|file'
|
||||
'file' => 'required|file',
|
||||
]);
|
||||
|
||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||
@@ -83,6 +86,7 @@ class AttachmentController extends Controller
|
||||
|
||||
/**
|
||||
* Get the update form for an attachment.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function getUpdateForm(string $attachmentId)
|
||||
@@ -104,15 +108,16 @@ class AttachmentController extends Controller
|
||||
{
|
||||
/** @var Attachment $attachment */
|
||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||
|
||||
try {
|
||||
$this->validate($request, [
|
||||
'attachment_edit_name' => 'required|string|min:1|max:255',
|
||||
'attachment_edit_url' => 'string|min:1|max:255|safe_url'
|
||||
'attachment_edit_url' => 'string|min:1|max:255|safe_url',
|
||||
]);
|
||||
} catch (ValidationException $exception) {
|
||||
return response()->view('attachments.manager-edit-form', array_merge($request->only(['attachment_edit_name', 'attachment_edit_url']), [
|
||||
'attachment' => $attachment,
|
||||
'errors' => new MessageBag($exception->errors()),
|
||||
'errors' => new MessageBag($exception->errors()),
|
||||
]), 422);
|
||||
}
|
||||
|
||||
@@ -132,6 +137,7 @@ class AttachmentController extends Controller
|
||||
|
||||
/**
|
||||
* Attach a link to a page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function attachLink(Request $request)
|
||||
@@ -141,8 +147,8 @@ class AttachmentController extends Controller
|
||||
try {
|
||||
$this->validate($request, [
|
||||
'attachment_link_uploaded_to' => 'required|integer|exists:pages,id',
|
||||
'attachment_link_name' => 'required|string|min:1|max:255',
|
||||
'attachment_link_url' => 'required|string|min:1|max:255|safe_url'
|
||||
'attachment_link_name' => 'required|string|min:1|max:255',
|
||||
'attachment_link_url' => 'required|string|min:1|max:255|safe_url',
|
||||
]);
|
||||
} catch (ValidationException $exception) {
|
||||
return response()->view('attachments.manager-link-form', array_merge($request->only(['attachment_link_name', 'attachment_link_url']), [
|
||||
@@ -172,6 +178,7 @@ class AttachmentController extends Controller
|
||||
{
|
||||
$page = $this->pageRepo->getById($pageId);
|
||||
$this->checkOwnablePermission('page-view', $page);
|
||||
|
||||
return view('attachments.manager-list', [
|
||||
'attachments' => $page->attachments->all(),
|
||||
]);
|
||||
@@ -179,6 +186,7 @@ class AttachmentController extends Controller
|
||||
|
||||
/**
|
||||
* Update the attachment sorting.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
@@ -192,11 +200,13 @@ class AttachmentController extends Controller
|
||||
|
||||
$attachmentOrder = $request->get('order');
|
||||
$this->attachmentService->updateFileOrderWithinPage($attachmentOrder, $pageId);
|
||||
|
||||
return response()->json(['message' => trans('entities.attachments_order_updated')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attachment from storage.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
@@ -204,6 +214,7 @@ class AttachmentController extends Controller
|
||||
{
|
||||
/** @var Attachment $attachment */
|
||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||
|
||||
try {
|
||||
$page = $this->pageRepo->getById($attachment->uploaded_to);
|
||||
} catch (NotFoundException $exception) {
|
||||
@@ -222,11 +233,13 @@ class AttachmentController extends Controller
|
||||
if ($request->get('open') === 'true') {
|
||||
return $this->inlineDownloadResponse($attachmentContents, $fileName);
|
||||
}
|
||||
|
||||
return $this->downloadResponse($attachmentContents, $fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific attachment in the system.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(string $attachmentId)
|
||||
@@ -235,6 +248,7 @@ class AttachmentController extends Controller
|
||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||
$this->checkOwnablePermission('attachment-delete', $attachment);
|
||||
$this->attachmentService->deleteFile($attachment);
|
||||
|
||||
return response()->json(['message' => trans('entities.attachments_deleted')]);
|
||||
}
|
||||
}
|
||||
|
@@ -8,19 +8,18 @@ use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AuditLogController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->checkPermission('settings-manage');
|
||||
$this->checkPermission('users-manage');
|
||||
|
||||
$listDetails = [
|
||||
'order' => $request->get('order', 'desc'),
|
||||
'event' => $request->get('event', ''),
|
||||
'sort' => $request->get('sort', 'created_at'),
|
||||
'order' => $request->get('order', 'desc'),
|
||||
'event' => $request->get('event', ''),
|
||||
'sort' => $request->get('sort', 'created_at'),
|
||||
'date_from' => $request->get('date_from', ''),
|
||||
'date_to' => $request->get('date_to', ''),
|
||||
'user' => $request->get('user', ''),
|
||||
'date_to' => $request->get('date_to', ''),
|
||||
'user' => $request->get('user', ''),
|
||||
];
|
||||
|
||||
$query = Activity::query()
|
||||
@@ -28,7 +27,7 @@ class AuditLogController extends Controller
|
||||
'entity' => function ($query) {
|
||||
$query->withTrashed();
|
||||
},
|
||||
'user'
|
||||
'user',
|
||||
])
|
||||
->orderBy($listDetails['sort'], $listDetails['order']);
|
||||
|
||||
@@ -51,9 +50,10 @@ class AuditLogController extends Controller
|
||||
|
||||
$types = DB::table('activities')->select('type')->distinct()->pluck('type');
|
||||
$this->setPageTitle(trans('settings.audit'));
|
||||
|
||||
return view('settings.audit', [
|
||||
'activities' => $activities,
|
||||
'listDetails' => $listDetails,
|
||||
'activities' => $activities,
|
||||
'listDetails' => $listDetails,
|
||||
'activityTypes' => $types,
|
||||
]);
|
||||
}
|
||||
|
@@ -31,7 +31,6 @@ class ConfirmEmailController extends Controller
|
||||
$this->userRepo = $userRepo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the page to tell the user to check their email
|
||||
* and confirm their address.
|
||||
@@ -44,6 +43,7 @@ class ConfirmEmailController extends Controller
|
||||
/**
|
||||
* Shows a notice that a user's email address has not been confirmed,
|
||||
* Also has the option to re-send the confirmation email.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showAwaiting()
|
||||
@@ -53,10 +53,13 @@ class ConfirmEmailController extends Controller
|
||||
|
||||
/**
|
||||
* Confirms an email via a token and logs the user into the system.
|
||||
*
|
||||
* @param $token
|
||||
* @return RedirectResponse|Redirector
|
||||
*
|
||||
* @throws ConfirmationEmailException
|
||||
* @throws Exception
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
public function confirm($token)
|
||||
{
|
||||
@@ -65,6 +68,7 @@ class ConfirmEmailController extends Controller
|
||||
} catch (Exception $exception) {
|
||||
if ($exception instanceof UserTokenNotFoundException) {
|
||||
$this->showErrorNotification(trans('errors.email_confirmation_invalid'));
|
||||
|
||||
return redirect('/register');
|
||||
}
|
||||
|
||||
@@ -72,6 +76,7 @@ class ConfirmEmailController extends Controller
|
||||
$user = $this->userRepo->getById($exception->userId);
|
||||
$this->emailConfirmationService->sendConfirmation($user);
|
||||
$this->showErrorNotification(trans('errors.email_confirmation_expired'));
|
||||
|
||||
return redirect('/register/confirm');
|
||||
}
|
||||
|
||||
@@ -91,16 +96,17 @@ class ConfirmEmailController extends Controller
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resend the confirmation email
|
||||
* Resend the confirmation email.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function resend(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'email' => 'required|email|exists:users,email'
|
||||
'email' => 'required|email|exists:users,email',
|
||||
]);
|
||||
$user = $this->userRepo->getByEmail($request->get('email'));
|
||||
|
||||
@@ -108,10 +114,12 @@ class ConfirmEmailController extends Controller
|
||||
$this->emailConfirmationService->sendConfirmation($user);
|
||||
} catch (Exception $e) {
|
||||
$this->showErrorNotification(trans('auth.email_confirm_send_error'));
|
||||
|
||||
return redirect('/register/confirm');
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('auth.email_confirm_resent'));
|
||||
|
||||
return redirect('/register/confirm');
|
||||
}
|
||||
}
|
||||
|
@@ -34,11 +34,11 @@ class ForgotPasswordController extends Controller
|
||||
$this->middleware('guard:standard');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a reset link to the given user.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
@@ -59,6 +59,7 @@ class ForgotPasswordController extends Controller
|
||||
if ($response === Password::RESET_LINK_SENT || $response === Password::INVALID_USER) {
|
||||
$message = trans('auth.reset_password_sent', ['email' => $request->get('email')]);
|
||||
$this->showSuccessNotification($message);
|
||||
|
||||
return back()->with('status', trans($response));
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,7 @@ class LoginController extends Controller
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Redirection paths
|
||||
* Redirection paths.
|
||||
*/
|
||||
protected $redirectTo = '/';
|
||||
protected $redirectPath = '/';
|
||||
@@ -74,8 +74,8 @@ class LoginController extends Controller
|
||||
|
||||
if ($request->has('email')) {
|
||||
session()->flashInput([
|
||||
'email' => $request->get('email'),
|
||||
'password' => (config('app.env') === 'demo') ? $request->get('password', '') : ''
|
||||
'email' => $request->get('email'),
|
||||
'password' => (config('app.env') === 'demo') ? $request->get('password', '') : '',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -89,18 +89,19 @@ class LoginController extends Controller
|
||||
}
|
||||
|
||||
return view('auth.login', [
|
||||
'socialDrivers' => $socialDrivers,
|
||||
'authMethod' => $authMethod,
|
||||
'socialDrivers' => $socialDrivers,
|
||||
'authMethod' => $authMethod,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
@@ -115,6 +116,7 @@ class LoginController extends Controller
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
Activity::logFailedLogin($username);
|
||||
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
@@ -124,6 +126,7 @@ class LoginController extends Controller
|
||||
}
|
||||
} catch (LoginAttemptException $exception) {
|
||||
Activity::logFailedLogin($username);
|
||||
|
||||
return $this->sendLoginAttemptExceptionResponse($exception, $request);
|
||||
}
|
||||
|
||||
@@ -133,14 +136,16 @@ class LoginController extends Controller
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
Activity::logFailedLogin($username);
|
||||
|
||||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has been authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $user
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param mixed $user
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function authenticated(Request $request, $user)
|
||||
@@ -155,16 +160,18 @@ class LoginController extends Controller
|
||||
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
|
||||
return redirect()->intended($this->redirectPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the user login request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function validateLogin(Request $request)
|
||||
{
|
||||
@@ -203,10 +210,11 @@ class LoginController extends Controller
|
||||
/**
|
||||
* Get the failed login response instance.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function sendFailedLoginResponse(Request $request)
|
||||
{
|
||||
|
@@ -64,20 +64,22 @@ class RegisterController extends Controller
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => 'required|min:2|max:255',
|
||||
'email' => 'required|email|max:255|unique:users',
|
||||
'name' => 'required|min:2|max:255',
|
||||
'email' => 'required|email|max:255|unique:users',
|
||||
'password' => 'required|min:8',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
public function getRegister()
|
||||
{
|
||||
$this->registrationService->ensureRegistrationAllowed();
|
||||
$socialDrivers = $this->socialAuthService->getActiveDrivers();
|
||||
|
||||
return view('auth.register', [
|
||||
'socialDrivers' => $socialDrivers,
|
||||
]);
|
||||
@@ -85,6 +87,7 @@ class RegisterController extends Controller
|
||||
|
||||
/**
|
||||
* Handle a registration request for the application.
|
||||
*
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
public function postRegister(Request $request)
|
||||
@@ -102,23 +105,27 @@ class RegisterController extends Controller
|
||||
if ($exception->getMessage()) {
|
||||
$this->showErrorNotification($exception->getMessage());
|
||||
}
|
||||
|
||||
return redirect($exception->redirectLocation);
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('auth.register_success'));
|
||||
|
||||
return redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
* @param array $data
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
return User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => Hash::make($data['password']),
|
||||
]);
|
||||
}
|
||||
|
@@ -40,7 +40,8 @@ class ResetPasswordController extends Controller
|
||||
* Get the response for a successful password reset.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $response
|
||||
* @param string $response
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function sendResetResponse(Request $request, $response)
|
||||
@@ -48,6 +49,7 @@ class ResetPasswordController extends Controller
|
||||
$message = trans('auth.reset_password_success');
|
||||
$this->showSuccessNotification($message);
|
||||
$this->logActivity(ActivityType::AUTH_PASSWORD_RESET_UPDATE, user());
|
||||
|
||||
return redirect($this->redirectPath())
|
||||
->with('status', trans($response));
|
||||
}
|
||||
@@ -55,8 +57,9 @@ class ResetPasswordController extends Controller
|
||||
/**
|
||||
* Get the response for a failed password reset.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function sendResetFailedResponse(Request $request, $response)
|
||||
|
@@ -7,7 +7,6 @@ use BookStack\Http\Controllers\Controller;
|
||||
|
||||
class Saml2Controller extends Controller
|
||||
{
|
||||
|
||||
protected $samlService;
|
||||
|
||||
/**
|
||||
@@ -50,8 +49,9 @@ class Saml2Controller extends Controller
|
||||
public function metadata()
|
||||
{
|
||||
$metaData = $this->samlService->metadata();
|
||||
|
||||
return response()->make($metaData, 200, [
|
||||
'Content-Type' => 'text/xml'
|
||||
'Content-Type' => 'text/xml',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ class Saml2Controller extends Controller
|
||||
{
|
||||
$requestId = session()->pull('saml2_logout_request_id', null);
|
||||
$redirect = $this->samlService->processSlsResponse($requestId) ?? '/';
|
||||
|
||||
return redirect($redirect);
|
||||
}
|
||||
|
||||
@@ -77,6 +78,7 @@ class Saml2Controller extends Controller
|
||||
$user = $this->samlService->processAcsResponse($requestId);
|
||||
if ($user === null) {
|
||||
$this->showErrorNotification(trans('errors.saml_fail_authed', ['system' => config('saml2.name')]));
|
||||
|
||||
return redirect('/login');
|
||||
}
|
||||
|
||||
|
@@ -18,7 +18,6 @@ use Laravel\Socialite\Contracts\User as SocialUser;
|
||||
|
||||
class SocialController extends Controller
|
||||
{
|
||||
|
||||
protected $socialAuthService;
|
||||
protected $registrationService;
|
||||
|
||||
@@ -34,16 +33,19 @@ class SocialController extends Controller
|
||||
|
||||
/**
|
||||
* Redirect to the relevant social site.
|
||||
*
|
||||
* @throws SocialDriverNotConfigured
|
||||
*/
|
||||
public function login(string $socialDriver)
|
||||
{
|
||||
session()->put('social-callback', 'login');
|
||||
|
||||
return $this->socialAuthService->startLogIn($socialDriver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the social site for authentication intended to register.
|
||||
*
|
||||
* @throws SocialDriverNotConfigured
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
@@ -51,11 +53,13 @@ class SocialController extends Controller
|
||||
{
|
||||
$this->registrationService->ensureRegistrationAllowed();
|
||||
session()->put('social-callback', 'register');
|
||||
|
||||
return $this->socialAuthService->startRegister($socialDriver);
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback for social login services.
|
||||
*
|
||||
* @throws SocialSignInException
|
||||
* @throws SocialDriverNotConfigured
|
||||
* @throws UserRegistrationException
|
||||
@@ -70,7 +74,7 @@ class SocialController extends Controller
|
||||
if ($request->has('error') && $request->has('error_description')) {
|
||||
throw new SocialSignInException(trans('errors.social_login_bad_response', [
|
||||
'socialAccount' => $socialDriver,
|
||||
'error' => $request->get('error_description'),
|
||||
'error' => $request->get('error_description'),
|
||||
]), '/login');
|
||||
}
|
||||
|
||||
@@ -85,6 +89,7 @@ class SocialController extends Controller
|
||||
if ($this->socialAuthService->driverAutoRegisterEnabled($socialDriver)) {
|
||||
return $this->socialRegisterCallback($socialDriver, $socialUser);
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
@@ -103,11 +108,13 @@ class SocialController extends Controller
|
||||
{
|
||||
$this->socialAuthService->detachSocialAccount($socialDriver);
|
||||
session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => Str::title($socialDriver)]));
|
||||
|
||||
return redirect(user()->getEditUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new user after a registration callback.
|
||||
*
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
protected function socialRegisterCallback(string $socialDriver, SocialUser $socialUser)
|
||||
@@ -118,9 +125,9 @@ class SocialController extends Controller
|
||||
|
||||
// Create an array of the user data to create a new user instance
|
||||
$userData = [
|
||||
'name' => $socialUser->getName(),
|
||||
'email' => $socialUser->getEmail(),
|
||||
'password' => Str::random(32)
|
||||
'name' => $socialUser->getName(),
|
||||
'email' => $socialUser->getEmail(),
|
||||
'password' => Str::random(32),
|
||||
];
|
||||
|
||||
// Take name from email address if empty
|
||||
@@ -134,6 +141,7 @@ class SocialController extends Controller
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
|
||||
$this->showSuccessNotification(trans('auth.register_success'));
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ class UserInviteController extends Controller
|
||||
|
||||
/**
|
||||
* Show the page for the user to set the password for their account.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function showSetPassword(string $token)
|
||||
@@ -51,12 +52,13 @@ class UserInviteController extends Controller
|
||||
|
||||
/**
|
||||
* Sets the password for an invited user and then grants them access.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setPassword(Request $request, string $token)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'password' => 'required|min:8'
|
||||
'password' => 'required|min:8',
|
||||
]);
|
||||
|
||||
try {
|
||||
@@ -81,8 +83,10 @@ class UserInviteController extends Controller
|
||||
|
||||
/**
|
||||
* Check and validate the exception thrown when checking an invite token.
|
||||
* @return RedirectResponse|Redirector
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return RedirectResponse|Redirector
|
||||
*/
|
||||
protected function handleTokenException(Exception $exception)
|
||||
{
|
||||
@@ -92,6 +96,7 @@ class UserInviteController extends Controller
|
||||
|
||||
if ($exception instanceof UserTokenExpiredException) {
|
||||
$this->showErrorNotification(trans('errors.invite_token_expired'));
|
||||
|
||||
return redirect('/password/email');
|
||||
}
|
||||
|
||||
|
@@ -1,13 +1,15 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use Activity;
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Actions\View;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Models\Bookshelf;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Tools\PermissionsUpdater;
|
||||
use BookStack\Entities\Tools\ShelfContext;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@@ -15,7 +17,6 @@ use Throwable;
|
||||
|
||||
class BookController extends Controller
|
||||
{
|
||||
|
||||
protected $bookRepo;
|
||||
protected $entityContextManager;
|
||||
|
||||
@@ -42,14 +43,15 @@ class BookController extends Controller
|
||||
$this->entityContextManager->clearShelfContext();
|
||||
|
||||
$this->setPageTitle(trans('entities.books'));
|
||||
|
||||
return view('books.index', [
|
||||
'books' => $books,
|
||||
'books' => $books,
|
||||
'recents' => $recents,
|
||||
'popular' => $popular,
|
||||
'new' => $new,
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
'new' => $new,
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -67,13 +69,15 @@ class BookController extends Controller
|
||||
}
|
||||
|
||||
$this->setPageTitle(trans('entities.books_create'));
|
||||
|
||||
return view('books.create', [
|
||||
'bookshelf' => $bookshelf
|
||||
'bookshelf' => $bookshelf,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created book in storage.
|
||||
*
|
||||
* @throws ImageUploadException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
@@ -81,9 +85,9 @@ class BookController extends Controller
|
||||
{
|
||||
$this->checkPermission('book-create-all');
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
]);
|
||||
|
||||
$bookshelf = null;
|
||||
@@ -118,12 +122,13 @@ class BookController extends Controller
|
||||
}
|
||||
|
||||
$this->setPageTitle($book->getShortName());
|
||||
|
||||
return view('books.show', [
|
||||
'book' => $book,
|
||||
'current' => $book,
|
||||
'bookChildren' => $bookChildren,
|
||||
'book' => $book,
|
||||
'current' => $book,
|
||||
'bookChildren' => $bookChildren,
|
||||
'bookParentShelves' => $bookParentShelves,
|
||||
'activity' => Activity::entityActivity($book, 20, 1)
|
||||
'activity' => Activity::entityActivity($book, 20, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -135,11 +140,13 @@ class BookController extends Controller
|
||||
$book = $this->bookRepo->getBySlug($slug);
|
||||
$this->checkOwnablePermission('book-update', $book);
|
||||
$this->setPageTitle(trans('entities.books_edit_named', ['bookName'=>$book->getShortName()]));
|
||||
|
||||
return view('books.edit', ['book' => $book, 'current' => $book]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified book in storage.
|
||||
*
|
||||
* @throws ImageUploadException
|
||||
* @throws ValidationException
|
||||
* @throws Throwable
|
||||
@@ -149,9 +156,9 @@ class BookController extends Controller
|
||||
$book = $this->bookRepo->getBySlug($slug);
|
||||
$this->checkOwnablePermission('book-update', $book);
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
]);
|
||||
|
||||
$book = $this->bookRepo->update($book, $request->all());
|
||||
@@ -169,11 +176,13 @@ class BookController extends Controller
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$this->checkOwnablePermission('book-delete', $book);
|
||||
$this->setPageTitle(trans('entities.books_delete_named', ['bookName' => $book->getShortName()]));
|
||||
|
||||
return view('books.delete', ['book' => $book, 'current' => $book]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified book from the system.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function destroy(string $bookSlug)
|
||||
@@ -201,6 +210,7 @@ class BookController extends Controller
|
||||
|
||||
/**
|
||||
* Set the restrictions for this book.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug)
|
||||
@@ -211,6 +221,7 @@ class BookController extends Controller
|
||||
$permissionsUpdater->updateFromPermissionsForm($book, $request);
|
||||
|
||||
$this->showSuccessNotification(trans('entities.books_permissions_updated'));
|
||||
|
||||
return redirect($book->getUrl());
|
||||
}
|
||||
}
|
||||
|
@@ -2,13 +2,12 @@
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
use Throwable;
|
||||
|
||||
class BookExportController extends Controller
|
||||
{
|
||||
|
||||
protected $bookRepo;
|
||||
protected $exportFormatter;
|
||||
|
||||
@@ -23,23 +22,27 @@ class BookExportController extends Controller
|
||||
|
||||
/**
|
||||
* Export a book as a PDF file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function pdf(string $bookSlug)
|
||||
{
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$pdfContent = $this->exportFormatter->bookToPdf($book);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $bookSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a book as a contained HTML file.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function html(string $bookSlug)
|
||||
{
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$htmlContent = $this->exportFormatter->bookToContainedHtml($book);
|
||||
|
||||
return $this->downloadResponse($htmlContent, $bookSlug . '.html');
|
||||
}
|
||||
|
||||
@@ -50,6 +53,7 @@ class BookExportController extends Controller
|
||||
{
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$textContent = $this->exportFormatter->bookToPlainText($book);
|
||||
|
||||
return $this->downloadResponse($textContent, $bookSlug . '.txt');
|
||||
}
|
||||
|
||||
@@ -60,6 +64,7 @@ class BookExportController extends Controller
|
||||
{
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$textContent = $this->exportFormatter->bookToMarkdown($book);
|
||||
|
||||
return $this->downloadResponse($textContent, $bookSlug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -4,15 +4,14 @@ namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Exceptions\SortOperationException;
|
||||
use BookStack\Facades\Activity;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BookSortController extends Controller
|
||||
{
|
||||
|
||||
protected $bookRepo;
|
||||
|
||||
public function __construct(BookRepo $bookRepo)
|
||||
@@ -31,6 +30,7 @@ class BookSortController extends Controller
|
||||
$bookChildren = (new BookContents($book))->getTree(false);
|
||||
|
||||
$this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()]));
|
||||
|
||||
return view('books.sort', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ class BookSortController extends Controller
|
||||
{
|
||||
$book = $this->bookRepo->getBySlug($bookSlug);
|
||||
$bookChildren = (new BookContents($book))->getTree();
|
||||
|
||||
return view('books.sort-box', ['book' => $book, 'bookChildren' => $bookChildren]);
|
||||
}
|
||||
|
||||
|
@@ -1,22 +1,22 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use Activity;
|
||||
use BookStack\Actions\View;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Repos\BookshelfRepo;
|
||||
use BookStack\Entities\Tools\PermissionsUpdater;
|
||||
use BookStack\Entities\Tools\ShelfContext;
|
||||
use BookStack\Entities\Repos\BookshelfRepo;
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Uploads\ImageRepo;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Views;
|
||||
|
||||
class BookshelfController extends Controller
|
||||
{
|
||||
|
||||
protected $bookshelfRepo;
|
||||
protected $entityContextManager;
|
||||
protected $imageRepo;
|
||||
@@ -37,7 +37,7 @@ class BookshelfController extends Controller
|
||||
$sort = setting()->getForCurrentUser('bookshelves_sort', 'name');
|
||||
$order = setting()->getForCurrentUser('bookshelves_sort_order', 'asc');
|
||||
$sortOptions = [
|
||||
'name' => trans('common.sort_name'),
|
||||
'name' => trans('common.sort_name'),
|
||||
'created_at' => trans('common.sort_created_at'),
|
||||
'updated_at' => trans('common.sort_updated_at'),
|
||||
];
|
||||
@@ -49,14 +49,15 @@ class BookshelfController extends Controller
|
||||
|
||||
$this->entityContextManager->clearShelfContext();
|
||||
$this->setPageTitle(trans('entities.shelves'));
|
||||
|
||||
return view('shelves.index', [
|
||||
'shelves' => $shelves,
|
||||
'recents' => $recents,
|
||||
'popular' => $popular,
|
||||
'new' => $new,
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
'shelves' => $shelves,
|
||||
'recents' => $recents,
|
||||
'popular' => $popular,
|
||||
'new' => $new,
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
'sortOptions' => $sortOptions,
|
||||
]);
|
||||
}
|
||||
@@ -69,11 +70,13 @@ class BookshelfController extends Controller
|
||||
$this->checkPermission('bookshelf-create-all');
|
||||
$books = Book::hasPermission('update')->get();
|
||||
$this->setPageTitle(trans('entities.shelves_create'));
|
||||
|
||||
return view('shelves.create', ['books' => $books]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created bookshelf in storage.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws ImageUploadException
|
||||
*/
|
||||
@@ -81,9 +84,9 @@ class BookshelfController extends Controller
|
||||
{
|
||||
$this->checkPermission('bookshelf-create-all');
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
]);
|
||||
|
||||
$bookIds = explode(',', $request->get('books', ''));
|
||||
@@ -95,6 +98,7 @@ class BookshelfController extends Controller
|
||||
|
||||
/**
|
||||
* Display the bookshelf of the given slug.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function show(string $slug)
|
||||
@@ -115,13 +119,14 @@ class BookshelfController extends Controller
|
||||
$view = setting()->getForCurrentUser('bookshelf_view_type');
|
||||
|
||||
$this->setPageTitle($shelf->getShortName());
|
||||
|
||||
return view('shelves.show', [
|
||||
'shelf' => $shelf,
|
||||
'shelf' => $shelf,
|
||||
'sortedVisibleShelfBooks' => $sortedVisibleShelfBooks,
|
||||
'view' => $view,
|
||||
'activity' => Activity::entityActivity($shelf, 20, 1),
|
||||
'order' => $order,
|
||||
'sort' => $sort
|
||||
'view' => $view,
|
||||
'activity' => Activity::entityActivity($shelf, 20, 1),
|
||||
'order' => $order,
|
||||
'sort' => $sort,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -137,6 +142,7 @@ class BookshelfController extends Controller
|
||||
$books = Book::hasPermission('update')->whereNotIn('id', $shelfBookIds)->get();
|
||||
|
||||
$this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $shelf->getShortName()]));
|
||||
|
||||
return view('shelves.edit', [
|
||||
'shelf' => $shelf,
|
||||
'books' => $books,
|
||||
@@ -145,6 +151,7 @@ class BookshelfController extends Controller
|
||||
|
||||
/**
|
||||
* Update the specified bookshelf in storage.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws ImageUploadException
|
||||
* @throws NotFoundException
|
||||
@@ -154,12 +161,11 @@ class BookshelfController extends Controller
|
||||
$shelf = $this->bookshelfRepo->getBySlug($slug);
|
||||
$this->checkOwnablePermission('bookshelf-update', $shelf);
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
'image' => 'nullable|' . $this->getImageValidationRules(),
|
||||
]);
|
||||
|
||||
|
||||
$bookIds = explode(',', $request->get('books', ''));
|
||||
$shelf = $this->bookshelfRepo->update($shelf, $request->all(), $bookIds);
|
||||
$resetCover = $request->has('image_reset');
|
||||
@@ -169,7 +175,7 @@ class BookshelfController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the page to confirm deletion
|
||||
* Shows the page to confirm deletion.
|
||||
*/
|
||||
public function showDelete(string $slug)
|
||||
{
|
||||
@@ -177,11 +183,13 @@ class BookshelfController extends Controller
|
||||
$this->checkOwnablePermission('bookshelf-delete', $shelf);
|
||||
|
||||
$this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $shelf->getShortName()]));
|
||||
|
||||
return view('shelves.delete', ['shelf' => $shelf]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified bookshelf from storage.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function destroy(string $slug)
|
||||
@@ -218,6 +226,7 @@ class BookshelfController extends Controller
|
||||
$permissionsUpdater->updateFromPermissionsForm($shelf, $request);
|
||||
|
||||
$this->showSuccessNotification(trans('entities.shelves_permissions_updated'));
|
||||
|
||||
return redirect($shelf->getUrl());
|
||||
}
|
||||
|
||||
@@ -231,6 +240,7 @@ class BookshelfController extends Controller
|
||||
|
||||
$updateCount = $this->bookshelfRepo->copyDownPermissions($shelf);
|
||||
$this->showSuccessNotification(trans('entities.shelves_copy_permission_success', ['count' => $updateCount]));
|
||||
|
||||
return redirect($shelf->getUrl());
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\View;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Repos\ChapterRepo;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Tools\NextPreviousContentLocator;
|
||||
use BookStack\Entities\Tools\PermissionsUpdater;
|
||||
use BookStack\Exceptions\MoveOperationException;
|
||||
@@ -14,7 +16,6 @@ use Throwable;
|
||||
|
||||
class ChapterController extends Controller
|
||||
{
|
||||
|
||||
protected $chapterRepo;
|
||||
|
||||
/**
|
||||
@@ -34,17 +35,19 @@ class ChapterController extends Controller
|
||||
$this->checkOwnablePermission('chapter-create', $book);
|
||||
|
||||
$this->setPageTitle(trans('entities.chapters_create'));
|
||||
|
||||
return view('chapters.create', ['book' => $book, 'current' => $book]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created chapter in storage.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request, string $bookSlug)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255'
|
||||
'name' => 'required|string|max:255',
|
||||
]);
|
||||
|
||||
$book = Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
|
||||
@@ -69,14 +72,15 @@ class ChapterController extends Controller
|
||||
View::incrementFor($chapter);
|
||||
|
||||
$this->setPageTitle($chapter->getShortName());
|
||||
|
||||
return view('chapters.show', [
|
||||
'book' => $chapter->book,
|
||||
'chapter' => $chapter,
|
||||
'current' => $chapter,
|
||||
'book' => $chapter->book,
|
||||
'chapter' => $chapter,
|
||||
'current' => $chapter,
|
||||
'sidebarTree' => $sidebarTree,
|
||||
'pages' => $pages,
|
||||
'next' => $nextPreviousLocator->getNext(),
|
||||
'previous' => $nextPreviousLocator->getPrevious(),
|
||||
'pages' => $pages,
|
||||
'next' => $nextPreviousLocator->getNext(),
|
||||
'previous' => $nextPreviousLocator->getPrevious(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -89,11 +93,13 @@ class ChapterController extends Controller
|
||||
$this->checkOwnablePermission('chapter-update', $chapter);
|
||||
|
||||
$this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
|
||||
|
||||
return view('chapters.edit', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified chapter in storage.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function update(Request $request, string $bookSlug, string $chapterSlug)
|
||||
@@ -108,6 +114,7 @@ class ChapterController extends Controller
|
||||
|
||||
/**
|
||||
* Shows the page to confirm deletion of this chapter.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showDelete(string $bookSlug, string $chapterSlug)
|
||||
@@ -116,11 +123,13 @@ class ChapterController extends Controller
|
||||
$this->checkOwnablePermission('chapter-delete', $chapter);
|
||||
|
||||
$this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
|
||||
|
||||
return view('chapters.delete', ['book' => $chapter->book, 'chapter' => $chapter, 'current' => $chapter]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified chapter from storage.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -136,6 +145,7 @@ class ChapterController extends Controller
|
||||
|
||||
/**
|
||||
* Show the page for moving a chapter.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showMove(string $bookSlug, string $chapterSlug)
|
||||
@@ -147,12 +157,13 @@ class ChapterController extends Controller
|
||||
|
||||
return view('chapters.move', [
|
||||
'chapter' => $chapter,
|
||||
'book' => $chapter->book
|
||||
'book' => $chapter->book,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the move action for a chapter.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function move(Request $request, string $bookSlug, string $chapterSlug)
|
||||
@@ -170,15 +181,18 @@ class ChapterController extends Controller
|
||||
$newBook = $this->chapterRepo->move($chapter, $entitySelection);
|
||||
} catch (MoveOperationException $exception) {
|
||||
$this->showErrorNotification(trans('errors.selected_book_not_found'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('entities.chapter_move_success', ['bookName' => $newBook->name]));
|
||||
|
||||
return redirect($chapter->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Restrictions view.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showPermissions(string $bookSlug, string $chapterSlug)
|
||||
@@ -193,6 +207,7 @@ class ChapterController extends Controller
|
||||
|
||||
/**
|
||||
* Set the restrictions for this chapter.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function permissions(Request $request, PermissionsUpdater $permissionsUpdater, string $bookSlug, string $chapterSlug)
|
||||
@@ -203,6 +218,7 @@ class ChapterController extends Controller
|
||||
$permissionsUpdater->updateFromPermissionsForm($chapter, $request);
|
||||
|
||||
$this->showSuccessNotification(trans('entities.chapters_permissions_success'));
|
||||
|
||||
return redirect($chapter->getUrl());
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
use BookStack\Entities\Repos\ChapterRepo;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use Throwable;
|
||||
|
||||
class ChapterExportController extends Controller
|
||||
{
|
||||
|
||||
protected $chapterRepo;
|
||||
protected $exportFormatter;
|
||||
|
||||
@@ -22,6 +23,7 @@ class ChapterExportController extends Controller
|
||||
|
||||
/**
|
||||
* Exports a chapter to pdf.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -29,11 +31,13 @@ class ChapterExportController extends Controller
|
||||
{
|
||||
$chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
|
||||
$pdfContent = $this->exportFormatter->chapterToPdf($chapter);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $chapterSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a chapter to a self-contained HTML file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -41,22 +45,26 @@ class ChapterExportController extends Controller
|
||||
{
|
||||
$chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
|
||||
$containedHtml = $this->exportFormatter->chapterToContainedHtml($chapter);
|
||||
|
||||
return $this->downloadResponse($containedHtml, $chapterSlug . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a chapter to a simple plaintext .txt file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function plainText(string $bookSlug, string $chapterSlug)
|
||||
{
|
||||
$chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
|
||||
$chapterText = $this->exportFormatter->chapterToPlainText($chapter);
|
||||
|
||||
return $this->downloadResponse($chapterText, $chapterSlug . '.txt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a chapter to a simple markdown file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function markdown(string $bookSlug, string $chapterSlug)
|
||||
@@ -64,6 +72,7 @@ class ChapterExportController extends Controller
|
||||
// TODO: This should probably export to a zip file.
|
||||
$chapter = $this->chapterRepo->getBySlug($bookSlug, $chapterSlug);
|
||||
$chapterText = $this->exportFormatter->chapterToMarkdown($chapter);
|
||||
|
||||
return $this->downloadResponse($chapterText, $chapterSlug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use Activity;
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Actions\CommentRepo;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -17,13 +17,14 @@ class CommentController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a new comment for a Page
|
||||
* Save a new comment for a Page.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function savePageComment(Request $request, int $pageId)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'text' => 'required|string',
|
||||
'text' => 'required|string',
|
||||
'parent_id' => 'nullable|integer',
|
||||
]);
|
||||
|
||||
@@ -40,11 +41,13 @@ class CommentController extends Controller
|
||||
// Create a new comment.
|
||||
$this->checkPermission('comment-create-all');
|
||||
$comment = $this->commentRepo->create($page, $request->get('text'), $request->get('parent_id'));
|
||||
|
||||
return view('comments.comment', ['comment' => $comment]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing comment.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, int $commentId)
|
||||
@@ -58,6 +61,7 @@ class CommentController extends Controller
|
||||
$this->checkOwnablePermission('comment-update', $comment);
|
||||
|
||||
$comment = $this->commentRepo->update($comment, $request->get('text'));
|
||||
|
||||
return view('comments.comment', ['comment' => $comment]);
|
||||
}
|
||||
|
||||
@@ -70,6 +74,7 @@ class CommentController extends Controller
|
||||
$this->checkOwnablePermission('comment-delete', $comment);
|
||||
|
||||
$this->commentRepo->delete($comment);
|
||||
|
||||
return response()->json(['message' => trans('entities.comment_deleted')]);
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Facades\Activity;
|
||||
use BookStack\Interfaces\Loggable;
|
||||
use BookStack\HasCreatorAndUpdater;
|
||||
use BookStack\Model;
|
||||
use finfo;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
@@ -16,7 +15,8 @@ use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
use DispatchesJobs, ValidatesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
/**
|
||||
* Check if the current user is signed in.
|
||||
@@ -106,7 +106,7 @@ abstract class Controller extends BaseController
|
||||
/**
|
||||
* Send back a json error message.
|
||||
*/
|
||||
protected function jsonError(string $messageText = "", int $statusCode = 500): JsonResponse
|
||||
protected function jsonError(string $messageText = '', int $statusCode = 500): JsonResponse
|
||||
{
|
||||
return response()->json(['message' => $messageText, 'status' => 'error'], $statusCode);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ abstract class Controller extends BaseController
|
||||
{
|
||||
return response()->make($content, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $fileName . '"'
|
||||
'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -130,9 +130,10 @@ abstract class Controller extends BaseController
|
||||
{
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->buffer($content) ?: 'application/octet-stream';
|
||||
|
||||
return response()->make($content, 200, [
|
||||
'Content-Type' => $mime,
|
||||
'Content-Disposition' => 'inline; filename="' . $fileName . '"'
|
||||
'Content-Disposition' => 'inline; filename="' . $fileName . '"',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -162,6 +163,7 @@ abstract class Controller extends BaseController
|
||||
|
||||
/**
|
||||
* Log an activity in the system.
|
||||
*
|
||||
* @param string|Loggable
|
||||
*/
|
||||
protected function logActivity(string $type, $detail = ''): void
|
||||
|
@@ -17,13 +17,13 @@ class FavouriteController extends Controller
|
||||
{
|
||||
$viewCount = 20;
|
||||
$page = intval($request->get('page', 1));
|
||||
$favourites = (new TopFavourites)->run($viewCount + 1, (($page - 1) * $viewCount));
|
||||
$favourites = (new TopFavourites())->run($viewCount + 1, (($page - 1) * $viewCount));
|
||||
|
||||
$hasMoreLink = ($favourites->count() > $viewCount) ? url("/favourites?page=" . ($page+1)) : null;
|
||||
$hasMoreLink = ($favourites->count() > $viewCount) ? url('/favourites?page=' . ($page + 1)) : null;
|
||||
|
||||
return view('common.detailed-listing-with-more', [
|
||||
'title' => trans('entities.my_favourites'),
|
||||
'entities' => $favourites->slice(0, $viewCount),
|
||||
'title' => trans('entities.my_favourites'),
|
||||
'entities' => $favourites->slice(0, $viewCount),
|
||||
'hasMoreLink' => $hasMoreLink,
|
||||
]);
|
||||
}
|
||||
@@ -41,6 +41,7 @@ class FavouriteController extends Controller
|
||||
$this->showSuccessNotification(trans('activities.favourite_add_notification', [
|
||||
'name' => $favouritable->name,
|
||||
]));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@@ -57,6 +58,7 @@ class FavouriteController extends Controller
|
||||
$this->showSuccessNotification(trans('activities.favourite_remove_notification', [
|
||||
'name' => $favouritable->name,
|
||||
]));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@@ -68,7 +70,7 @@ class FavouriteController extends Controller
|
||||
{
|
||||
$modelInfo = $this->validate($request, [
|
||||
'type' => 'required|string',
|
||||
'id' => 'required|integer',
|
||||
'id' => 'required|integer',
|
||||
]);
|
||||
|
||||
if (!class_exists($modelInfo['type'])) {
|
||||
@@ -76,8 +78,8 @@ class FavouriteController extends Controller
|
||||
}
|
||||
|
||||
/** @var Model $model */
|
||||
$model = new $modelInfo['type'];
|
||||
if (! $model instanceof Favouritable) {
|
||||
$model = new $modelInfo['type']();
|
||||
if (!$model instanceof Favouritable) {
|
||||
throw new \Exception('Model not favouritable');
|
||||
}
|
||||
|
||||
|
@@ -1,18 +1,19 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use Activity;
|
||||
use BookStack\Entities\Models\Book;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Queries\RecentlyViewed;
|
||||
use BookStack\Entities\Queries\TopFavourites;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Repos\BookRepo;
|
||||
use BookStack\Entities\Repos\BookshelfRepo;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use Views;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Display the homepage.
|
||||
*/
|
||||
@@ -33,9 +34,9 @@ class HomeController extends Controller
|
||||
|
||||
$recentFactor = count($draftPages) > 0 ? 0.5 : 1;
|
||||
$recents = $this->isSignedIn() ?
|
||||
(new RecentlyViewed)->run(12*$recentFactor, 1)
|
||||
(new RecentlyViewed())->run(12 * $recentFactor, 1)
|
||||
: Book::visible()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get();
|
||||
$favourites = (new TopFavourites)->run(6);
|
||||
$favourites = (new TopFavourites())->run(6);
|
||||
$recentlyUpdatedPages = Page::visible()->with('book')
|
||||
->where('draft', false)
|
||||
->orderBy('updated_at', 'desc')
|
||||
@@ -49,11 +50,11 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
$commonData = [
|
||||
'activity' => $activity,
|
||||
'recents' => $recents,
|
||||
'activity' => $activity,
|
||||
'recents' => $recents,
|
||||
'recentlyUpdatedPages' => $recentlyUpdatedPages,
|
||||
'draftPages' => $draftPages,
|
||||
'favourites' => $favourites,
|
||||
'draftPages' => $draftPages,
|
||||
'favourites' => $favourites,
|
||||
];
|
||||
|
||||
// Add required list ordering & sorting for books & shelves views.
|
||||
@@ -64,15 +65,15 @@ class HomeController extends Controller
|
||||
$order = setting()->getForCurrentUser($key . '_sort_order', 'asc');
|
||||
|
||||
$sortOptions = [
|
||||
'name' => trans('common.sort_name'),
|
||||
'name' => trans('common.sort_name'),
|
||||
'created_at' => trans('common.sort_created_at'),
|
||||
'updated_at' => trans('common.sort_updated_at'),
|
||||
];
|
||||
|
||||
$commonData = array_merge($commonData, [
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
'view' => $view,
|
||||
'sort' => $sort,
|
||||
'order' => $order,
|
||||
'sortOptions' => $sortOptions,
|
||||
]);
|
||||
}
|
||||
@@ -80,6 +81,7 @@ class HomeController extends Controller
|
||||
if ($homepageOption === 'bookshelves') {
|
||||
$shelves = app(BookshelfRepo::class)->getAllPaginated(18, $commonData['sort'], $commonData['order']);
|
||||
$data = array_merge($commonData, ['shelves' => $shelves]);
|
||||
|
||||
return view('common.home-shelves', $data);
|
||||
}
|
||||
|
||||
@@ -87,6 +89,7 @@ class HomeController extends Controller
|
||||
$bookRepo = app(BookRepo::class);
|
||||
$books = $bookRepo->getAllPaginated(18, $commonData['sort'], $commonData['order']);
|
||||
$data = array_merge($commonData, ['books' => $books]);
|
||||
|
||||
return view('common.home-book', $data);
|
||||
}
|
||||
|
||||
@@ -96,6 +99,7 @@ class HomeController extends Controller
|
||||
$customHomepage = Page::query()->where('draft', '=', false)->findOrFail($id);
|
||||
$pageContent = new PageContent($customHomepage);
|
||||
$customHomepage->html = $pageContent->render(true);
|
||||
|
||||
return view('common.home-custom', array_merge($commonData, ['customHomepage' => $customHomepage]));
|
||||
}
|
||||
|
||||
@@ -104,6 +108,7 @@ class HomeController extends Controller
|
||||
|
||||
/**
|
||||
* Get custom head HTML, Used in ajax calls to show in editor.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function customHeadContent()
|
||||
@@ -112,7 +117,7 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view for /robots.txt
|
||||
* Show the view for /robots.txt.
|
||||
*/
|
||||
public function getRobots()
|
||||
{
|
||||
|
@@ -3,10 +3,10 @@
|
||||
namespace BookStack\Http\Controllers\Images;
|
||||
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Uploads\ImageRepo;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
|
||||
class DrawioImageController extends Controller
|
||||
{
|
||||
@@ -29,21 +29,23 @@ class DrawioImageController extends Controller
|
||||
$parentTypeFilter = $request->get('filter_type', null);
|
||||
|
||||
$imgData = $this->imageRepo->getEntityFiltered('drawio', $parentTypeFilter, $page, 24, $uploadedToFilter, $searchTerm);
|
||||
|
||||
return view('components.image-manager-list', [
|
||||
'images' => $imgData['images'],
|
||||
'images' => $imgData['images'],
|
||||
'hasMore' => $imgData['has_more'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new gallery image in the system.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'image' => 'required|string',
|
||||
'uploaded_to' => 'required|integer'
|
||||
'image' => 'required|string',
|
||||
'uploaded_to' => 'required|integer',
|
||||
]);
|
||||
|
||||
$this->checkPermission('image-create-all');
|
||||
@@ -67,16 +69,16 @@ class DrawioImageController extends Controller
|
||||
$image = $this->imageRepo->getById($id);
|
||||
$page = $image->getPage();
|
||||
if ($image === null || $image->type !== 'drawio' || !userCan('page-view', $page)) {
|
||||
return $this->jsonError("Image data could not be found");
|
||||
return $this->jsonError('Image data could not be found');
|
||||
}
|
||||
|
||||
$imageData = $this->imageRepo->getImageData($image);
|
||||
if ($imageData === null) {
|
||||
return $this->jsonError("Image data could not be found");
|
||||
return $this->jsonError('Image data could not be found');
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'content' => base64_encode($imageData)
|
||||
'content' => base64_encode($imageData),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,9 @@
|
||||
namespace BookStack\Http\Controllers\Images;
|
||||
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Uploads\ImageRepo;
|
||||
use Illuminate\Http\Request;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class GalleryImageController extends Controller
|
||||
@@ -32,21 +32,23 @@ class GalleryImageController extends Controller
|
||||
$parentTypeFilter = $request->get('filter_type', null);
|
||||
|
||||
$imgData = $this->imageRepo->getEntityFiltered('gallery', $parentTypeFilter, $page, 24, $uploadedToFilter, $searchTerm);
|
||||
|
||||
return view('components.image-manager-list', [
|
||||
'images' => $imgData['images'],
|
||||
'images' => $imgData['images'],
|
||||
'hasMore' => $imgData['has_more'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new gallery image in the system.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->checkPermission('image-create-all');
|
||||
$this->validate($request, [
|
||||
'file' => $this->getImageValidationRules()
|
||||
'file' => $this->getImageValidationRules(),
|
||||
]);
|
||||
|
||||
try {
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers\Images;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Images;
|
||||
|
||||
use BookStack\Exceptions\ImageUploadException;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
@@ -28,6 +30,7 @@ class ImageController extends Controller
|
||||
|
||||
/**
|
||||
* Provide an image file from storage.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showImage(string $path)
|
||||
@@ -42,16 +45,16 @@ class ImageController extends Controller
|
||||
return response()->file($path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update image details
|
||||
* Update image details.
|
||||
*
|
||||
* @throws ImageUploadException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|min:2|string'
|
||||
'name' => 'required|min:2|string',
|
||||
]);
|
||||
|
||||
$image = $this->imageRepo->getById($id);
|
||||
@@ -61,14 +64,16 @@ class ImageController extends Controller
|
||||
$image = $this->imageRepo->updateImageDetails($image, $request->all());
|
||||
|
||||
$this->imageRepo->loadThumbs($image);
|
||||
|
||||
return view('components.image-manager-form', [
|
||||
'image' => $image,
|
||||
'image' => $image,
|
||||
'dependantPages' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form for editing the given image.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function edit(Request $request, string $id)
|
||||
@@ -81,14 +86,16 @@ class ImageController extends Controller
|
||||
}
|
||||
|
||||
$this->imageRepo->loadThumbs($image);
|
||||
|
||||
return view('components.image-manager-form', [
|
||||
'image' => $image,
|
||||
'image' => $image,
|
||||
'dependantPages' => $dependantPages ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an image and all thumbnail/image files
|
||||
* Deletes an image and all thumbnail/image files.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
@@ -98,6 +105,7 @@ class ImageController extends Controller
|
||||
$this->checkImagePermission($image);
|
||||
|
||||
$this->imageRepo->destroyImage($image);
|
||||
|
||||
return response('');
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@ class MaintenanceController extends Controller
|
||||
$recycleStats = (new TrashCan())->getTrashedCounts();
|
||||
|
||||
return view('settings.maintenance', [
|
||||
'version' => $version,
|
||||
'version' => $version,
|
||||
'recycleStats' => $recycleStats,
|
||||
]);
|
||||
}
|
||||
@@ -45,6 +45,7 @@ class MaintenanceController extends Controller
|
||||
$deleteCount = count($imagesToDelete);
|
||||
if ($deleteCount === 0) {
|
||||
$this->showWarningNotification(trans('settings.maint_image_cleanup_nothing_found'));
|
||||
|
||||
return redirect('/settings/maintenance')->withInput();
|
||||
}
|
||||
|
||||
|
@@ -1,12 +1,14 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\View;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\BookContents;
|
||||
use BookStack\Entities\Tools\NextPreviousContentLocator;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Entities\Tools\PageEditActivity;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\PermissionsUpdater;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Exceptions\PermissionsException;
|
||||
@@ -17,7 +19,6 @@ use Throwable;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
|
||||
protected $pageRepo;
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,7 @@ class PageController extends Controller
|
||||
|
||||
/**
|
||||
* Show the form for creating a new page.
|
||||
*
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function create(string $bookSlug, string $chapterSlug = null)
|
||||
@@ -40,22 +42,25 @@ class PageController extends Controller
|
||||
// Redirect to draft edit screen if signed in
|
||||
if ($this->isSignedIn()) {
|
||||
$draft = $this->pageRepo->getNewDraftPage($parent);
|
||||
|
||||
return redirect($draft->getUrl());
|
||||
}
|
||||
|
||||
// Otherwise show the edit view if they're a guest
|
||||
$this->setPageTitle(trans('entities.pages_new'));
|
||||
|
||||
return view('pages.guest-create', ['parent' => $parent]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new page as a guest user.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function createAsGuest(Request $request, string $bookSlug, string $chapterSlug = null)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255'
|
||||
'name' => 'required|string|max:255',
|
||||
]);
|
||||
|
||||
$parent = $this->pageRepo->getParentFromSlugs($bookSlug, $chapterSlug);
|
||||
@@ -64,7 +69,7 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getNewDraftPage($parent);
|
||||
$this->pageRepo->publishDraft($page, [
|
||||
'name' => $request->get('name'),
|
||||
'html' => ''
|
||||
'html' => '',
|
||||
]);
|
||||
|
||||
return redirect($page->getUrl('/edit'));
|
||||
@@ -72,6 +77,7 @@ class PageController extends Controller
|
||||
|
||||
/**
|
||||
* Show form to continue editing a draft page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function editDraft(string $bookSlug, int $pageId)
|
||||
@@ -84,23 +90,24 @@ class PageController extends Controller
|
||||
$templates = $this->pageRepo->getTemplates(10);
|
||||
|
||||
return view('pages.edit', [
|
||||
'page' => $draft,
|
||||
'book' => $draft->book,
|
||||
'isDraft' => true,
|
||||
'page' => $draft,
|
||||
'book' => $draft->book,
|
||||
'isDraft' => true,
|
||||
'draftsEnabled' => $draftsEnabled,
|
||||
'templates' => $templates,
|
||||
'templates' => $templates,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new page by changing a draft into a page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request, string $bookSlug, int $pageId)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255'
|
||||
'name' => 'required|string|max:255',
|
||||
]);
|
||||
$draftPage = $this->pageRepo->getById($pageId);
|
||||
$this->checkOwnablePermission('page-create', $draftPage->getParent());
|
||||
@@ -113,6 +120,7 @@ class PageController extends Controller
|
||||
/**
|
||||
* Display the specified page.
|
||||
* If the page is not found via the slug the revisions are searched for a match.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function show(string $bookSlug, string $pageSlug)
|
||||
@@ -146,20 +154,22 @@ class PageController extends Controller
|
||||
|
||||
View::incrementFor($page);
|
||||
$this->setPageTitle($page->getShortName());
|
||||
|
||||
return view('pages.show', [
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'current' => $page,
|
||||
'sidebarTree' => $sidebarTree,
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'current' => $page,
|
||||
'sidebarTree' => $sidebarTree,
|
||||
'commentsEnabled' => $commentsEnabled,
|
||||
'pageNav' => $pageNav,
|
||||
'next' => $nextPreviousLocator->getNext(),
|
||||
'previous' => $nextPreviousLocator->getPrevious(),
|
||||
'pageNav' => $pageNav,
|
||||
'next' => $nextPreviousLocator->getNext(),
|
||||
'previous' => $nextPreviousLocator->getPrevious(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page from an ajax request.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function getPageAjax(int $pageId)
|
||||
@@ -167,11 +177,13 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getById($pageId);
|
||||
$page->setHidden(array_diff($page->getHidden(), ['html', 'markdown']));
|
||||
$page->addHidden(['book']);
|
||||
|
||||
return response()->json($page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function edit(string $bookSlug, string $pageSlug)
|
||||
@@ -203,24 +215,26 @@ class PageController extends Controller
|
||||
$templates = $this->pageRepo->getTemplates(10);
|
||||
$draftsEnabled = $this->isSignedIn();
|
||||
$this->setPageTitle(trans('entities.pages_editing_named', ['pageName' => $page->getShortName()]));
|
||||
|
||||
return view('pages.edit', [
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'current' => $page,
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'current' => $page,
|
||||
'draftsEnabled' => $draftsEnabled,
|
||||
'templates' => $templates,
|
||||
'templates' => $templates,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified page in storage.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function update(Request $request, string $bookSlug, string $pageSlug)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255'
|
||||
'name' => 'required|string|max:255',
|
||||
]);
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->checkOwnablePermission('page-update', $page);
|
||||
@@ -232,6 +246,7 @@ class PageController extends Controller
|
||||
|
||||
/**
|
||||
* Save a draft update as a revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function saveDraft(Request $request, int $pageId)
|
||||
@@ -246,25 +261,29 @@ class PageController extends Controller
|
||||
$draft = $this->pageRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown']));
|
||||
|
||||
$updateTime = $draft->updated_at->timestamp;
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => trans('entities.pages_edit_draft_save_at'),
|
||||
'timestamp' => $updateTime
|
||||
'status' => 'success',
|
||||
'message' => trans('entities.pages_edit_draft_save_at'),
|
||||
'timestamp' => $updateTime,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect from a special link url which uses the page id rather than the name.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function redirectFromLink(int $pageId)
|
||||
{
|
||||
$page = $this->pageRepo->getById($pageId);
|
||||
|
||||
return redirect($page->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the deletion page for the specified page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showDelete(string $bookSlug, string $pageSlug)
|
||||
@@ -272,15 +291,17 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->checkOwnablePermission('page-delete', $page);
|
||||
$this->setPageTitle(trans('entities.pages_delete_named', ['pageName' => $page->getShortName()]));
|
||||
|
||||
return view('pages.delete', [
|
||||
'book' => $page->book,
|
||||
'page' => $page,
|
||||
'current' => $page
|
||||
'book' => $page->book,
|
||||
'page' => $page,
|
||||
'current' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the deletion page for the specified page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showDeleteDraft(string $bookSlug, int $pageId)
|
||||
@@ -288,15 +309,17 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getById($pageId);
|
||||
$this->checkOwnablePermission('page-update', $page);
|
||||
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName' => $page->getShortName()]));
|
||||
|
||||
return view('pages.delete', [
|
||||
'book' => $page->book,
|
||||
'page' => $page,
|
||||
'current' => $page
|
||||
'book' => $page->book,
|
||||
'page' => $page,
|
||||
'current' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified page from storage.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -313,6 +336,7 @@ class PageController extends Controller
|
||||
|
||||
/**
|
||||
* Remove the specified draft page from storage.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -330,6 +354,7 @@ class PageController extends Controller
|
||||
if ($chapter && userCan('view', $chapter)) {
|
||||
return redirect($chapter->getUrl());
|
||||
}
|
||||
|
||||
return redirect($book->getUrl());
|
||||
}
|
||||
|
||||
@@ -343,13 +368,14 @@ class PageController extends Controller
|
||||
->setPath(url('/pages/recently-updated'));
|
||||
|
||||
return view('common.detailed-listing-paginated', [
|
||||
'title' => trans('entities.recently_updated_pages'),
|
||||
'entities' => $pages
|
||||
'title' => trans('entities.recently_updated_pages'),
|
||||
'entities' => $pages,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view to choose a new parent to move a page into.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showMove(string $bookSlug, string $pageSlug)
|
||||
@@ -357,14 +383,16 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->checkOwnablePermission('page-update', $page);
|
||||
$this->checkOwnablePermission('page-delete', $page);
|
||||
|
||||
return view('pages.move', [
|
||||
'book' => $page->book,
|
||||
'page' => $page
|
||||
'page' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the action of moving the location of a page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -387,15 +415,18 @@ class PageController extends Controller
|
||||
}
|
||||
|
||||
$this->showErrorNotification(trans('errors.selected_book_chapter_not_found'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('entities.pages_move_success', ['parentName' => $parent->name]));
|
||||
|
||||
return redirect($page->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view to copy a page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showCopy(string $bookSlug, string $pageSlug)
|
||||
@@ -403,15 +434,16 @@ class PageController extends Controller
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->checkOwnablePermission('page-view', $page);
|
||||
session()->flashInput(['name' => $page->name]);
|
||||
|
||||
return view('pages.copy', [
|
||||
'book' => $page->book,
|
||||
'page' => $page
|
||||
'page' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a copy of a page within the requested target destination.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -431,21 +463,25 @@ class PageController extends Controller
|
||||
}
|
||||
|
||||
$this->showErrorNotification(trans('errors.selected_book_chapter_not_found'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('entities.pages_copy_success'));
|
||||
|
||||
return redirect($pageCopy->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Permissions view.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function showPermissions(string $bookSlug, string $pageSlug)
|
||||
{
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->checkOwnablePermission('restrictions-manage', $page);
|
||||
|
||||
return view('pages.permissions', [
|
||||
'page' => $page,
|
||||
]);
|
||||
@@ -453,6 +489,7 @@ class PageController extends Controller
|
||||
|
||||
/**
|
||||
* Set the permissions for this page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -464,6 +501,7 @@ class PageController extends Controller
|
||||
$permissionsUpdater->updateFromPermissionsForm($page, $request);
|
||||
|
||||
$this->showSuccessNotification(trans('entities.pages_permissions_success'));
|
||||
|
||||
return redirect($page->getUrl());
|
||||
}
|
||||
}
|
||||
|
@@ -2,15 +2,14 @@
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\ExportFormatter;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use Throwable;
|
||||
|
||||
class PageExportController extends Controller
|
||||
{
|
||||
|
||||
protected $pageRepo;
|
||||
protected $exportFormatter;
|
||||
|
||||
@@ -25,7 +24,8 @@ class PageExportController extends Controller
|
||||
|
||||
/**
|
||||
* Exports a page to a PDF.
|
||||
* https://github.com/barryvdh/laravel-dompdf
|
||||
* https://github.com/barryvdh/laravel-dompdf.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -34,11 +34,13 @@ class PageExportController extends Controller
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$page->html = (new PageContent($page))->render();
|
||||
$pdfContent = $this->exportFormatter->pageToPdf($page);
|
||||
|
||||
return $this->downloadResponse($pdfContent, $pageSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a page to a self-contained HTML file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws Throwable
|
||||
*/
|
||||
@@ -47,28 +49,33 @@ class PageExportController extends Controller
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$page->html = (new PageContent($page))->render();
|
||||
$containedHtml = $this->exportFormatter->pageToContainedHtml($page);
|
||||
|
||||
return $this->downloadResponse($containedHtml, $pageSlug . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a page to a simple plaintext .txt file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function plainText(string $bookSlug, string $pageSlug)
|
||||
{
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$pageText = $this->exportFormatter->pageToPlainText($page);
|
||||
|
||||
return $this->downloadResponse($pageText, $pageSlug . '.txt');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export a page to a simple markdown .md file.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function markdown(string $bookSlug, string $pageSlug)
|
||||
{
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$pageText = $this->exportFormatter->pageToMarkdown($page);
|
||||
|
||||
return $this->downloadResponse($pageText, $pageSlug . '.md');
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use Ssddanbrown\HtmlDiff\Diff;
|
||||
|
||||
class PageRevisionController extends Controller
|
||||
{
|
||||
|
||||
protected $pageRepo;
|
||||
|
||||
/**
|
||||
@@ -20,20 +21,23 @@ class PageRevisionController extends Controller
|
||||
|
||||
/**
|
||||
* Shows the last revisions for this page.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function index(string $bookSlug, string $pageSlug)
|
||||
{
|
||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||
$this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
|
||||
|
||||
return view('pages.revisions', [
|
||||
'page' => $page,
|
||||
'current' => $page
|
||||
'page' => $page,
|
||||
'current' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a preview of a single revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function show(string $bookSlug, string $pageSlug, int $revisionId)
|
||||
@@ -50,16 +54,18 @@ class PageRevisionController extends Controller
|
||||
$page->html = (new PageContent($page))->render();
|
||||
|
||||
$this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
|
||||
|
||||
return view('pages.revision', [
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'diff' => null,
|
||||
'revision' => $revision
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'diff' => null,
|
||||
'revision' => $revision,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the changes of a single revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function changes(string $bookSlug, string $pageSlug, int $revisionId)
|
||||
@@ -81,15 +87,16 @@ class PageRevisionController extends Controller
|
||||
$this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
|
||||
|
||||
return view('pages.revision', [
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'diff' => $diff,
|
||||
'revision' => $revision
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'diff' => $diff,
|
||||
'revision' => $revision,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores a page using the content of the specified revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function restore(string $bookSlug, string $pageSlug, int $revisionId)
|
||||
@@ -104,6 +111,7 @@ class PageRevisionController extends Controller
|
||||
|
||||
/**
|
||||
* Deletes a revision using the id of the specified revision.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function destroy(string $bookSlug, string $pageSlug, int $revId)
|
||||
@@ -122,11 +130,13 @@ class PageRevisionController extends Controller
|
||||
// Check if its the latest revision, cannot delete latest revision.
|
||||
if (intval($currentRevision->id) === intval($revId)) {
|
||||
$this->showErrorNotification(trans('entities.revision_cannot_delete_latest'));
|
||||
|
||||
return redirect($page->getUrl('/revisions'));
|
||||
}
|
||||
|
||||
$revision->delete();
|
||||
$this->showSuccessNotification(trans('entities.revision_delete_success'));
|
||||
|
||||
return redirect($page->getUrl('/revisions'));
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ class PageTemplateController extends Controller
|
||||
protected $pageRepo;
|
||||
|
||||
/**
|
||||
* PageTemplateController constructor
|
||||
* PageTemplateController constructor.
|
||||
*/
|
||||
public function __construct(PageRepo $pageRepo)
|
||||
{
|
||||
@@ -32,12 +32,13 @@ class PageTemplateController extends Controller
|
||||
}
|
||||
|
||||
return view('pages.template-manager-list', [
|
||||
'templates' => $templates
|
||||
'templates' => $templates,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of a template.
|
||||
*
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function get(int $templateId)
|
||||
@@ -49,7 +50,7 @@ class PageTemplateController extends Controller
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'html' => $page->html,
|
||||
'html' => $page->html,
|
||||
'markdown' => $page->markdown,
|
||||
]);
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Entities\Models\Deletion;
|
||||
@@ -7,7 +9,6 @@ use BookStack\Entities\Tools\TrashCan;
|
||||
|
||||
class RecycleBinController extends Controller
|
||||
{
|
||||
|
||||
protected $recycleBinBaseUrl = '/settings/recycle-bin';
|
||||
|
||||
/**
|
||||
@@ -19,11 +20,11 @@ class RecycleBinController extends Controller
|
||||
$this->middleware(function ($request, $next) {
|
||||
$this->checkPermission('settings-manage');
|
||||
$this->checkPermission('restrictions-manage-all');
|
||||
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the top-level listing for the recycle bin.
|
||||
*/
|
||||
@@ -32,6 +33,7 @@ class RecycleBinController extends Controller
|
||||
$deletions = Deletion::query()->with(['deletable', 'deleter'])->paginate(10);
|
||||
|
||||
$this->setPageTitle(trans('settings.recycle_bin'));
|
||||
|
||||
return view('settings.recycle-bin.index', [
|
||||
'deletions' => $deletions,
|
||||
]);
|
||||
@@ -60,13 +62,14 @@ class RecycleBinController extends Controller
|
||||
$parentDeletion = ($currentDeletable === $deletion->deletable) ? null : $currentDeletable->deletions()->first();
|
||||
|
||||
return view('settings.recycle-bin.restore', [
|
||||
'deletion' => $deletion,
|
||||
'deletion' => $deletion,
|
||||
'parentDeletion' => $parentDeletion,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the element attached to the given deletion.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function restore(string $id)
|
||||
@@ -77,6 +80,7 @@ class RecycleBinController extends Controller
|
||||
$restoreCount = (new TrashCan())->restoreFromDeletion($deletion);
|
||||
|
||||
$this->showSuccessNotification(trans('settings.recycle_bin_restore_notification', ['count' => $restoreCount]));
|
||||
|
||||
return redirect($this->recycleBinBaseUrl);
|
||||
}
|
||||
|
||||
@@ -95,6 +99,7 @@ class RecycleBinController extends Controller
|
||||
|
||||
/**
|
||||
* Permanently delete the content associated with the given deletion.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
@@ -105,11 +110,13 @@ class RecycleBinController extends Controller
|
||||
$deleteCount = (new TrashCan())->destroyFromDeletion($deletion);
|
||||
|
||||
$this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
|
||||
|
||||
return redirect($this->recycleBinBaseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty out the recycle bin.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function empty()
|
||||
@@ -118,6 +125,7 @@ class RecycleBinController extends Controller
|
||||
|
||||
$this->logActivity(ActivityType::RECYCLE_BIN_EMPTY);
|
||||
$this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
|
||||
|
||||
return redirect($this->recycleBinBaseUrl);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Auth\Permissions\PermissionsRepo;
|
||||
use BookStack\Exceptions\PermissionsException;
|
||||
@@ -8,7 +10,6 @@ use Illuminate\Validation\ValidationException;
|
||||
|
||||
class RoleController extends Controller
|
||||
{
|
||||
|
||||
protected $permissionsRepo;
|
||||
|
||||
/**
|
||||
@@ -26,15 +27,17 @@ class RoleController extends Controller
|
||||
{
|
||||
$this->checkPermission('user-roles-manage');
|
||||
$roles = $this->permissionsRepo->getAllRoles();
|
||||
|
||||
return view('settings.roles.index', ['roles' => $roles]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form to create a new role
|
||||
* Show the form to create a new role.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->checkPermission('user-roles-manage');
|
||||
|
||||
return view('settings.roles.create');
|
||||
}
|
||||
|
||||
@@ -46,16 +49,18 @@ class RoleController extends Controller
|
||||
$this->checkPermission('user-roles-manage');
|
||||
$this->validate($request, [
|
||||
'display_name' => 'required|min:3|max:180',
|
||||
'description' => 'max:180'
|
||||
'description' => 'max:180',
|
||||
]);
|
||||
|
||||
$this->permissionsRepo->saveNewRole($request->all());
|
||||
$this->showSuccessNotification(trans('settings.role_create_success'));
|
||||
|
||||
return redirect('/settings/roles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing a user role.
|
||||
*
|
||||
* @throws PermissionsException
|
||||
*/
|
||||
public function edit(string $id)
|
||||
@@ -65,11 +70,13 @@ class RoleController extends Controller
|
||||
if ($role->hidden) {
|
||||
throw new PermissionsException(trans('errors.role_cannot_be_edited'));
|
||||
}
|
||||
|
||||
return view('settings.roles.edit', ['role' => $role]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user role.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
@@ -77,11 +84,12 @@ class RoleController extends Controller
|
||||
$this->checkPermission('user-roles-manage');
|
||||
$this->validate($request, [
|
||||
'display_name' => 'required|min:3|max:180',
|
||||
'description' => 'max:180'
|
||||
'description' => 'max:180',
|
||||
]);
|
||||
|
||||
$this->permissionsRepo->updateRole($id, $request->all());
|
||||
$this->showSuccessNotification(trans('settings.role_update_success'));
|
||||
|
||||
return redirect('/settings/roles');
|
||||
}
|
||||
|
||||
@@ -96,12 +104,14 @@ class RoleController extends Controller
|
||||
$roles = $this->permissionsRepo->getAllRolesExcept($role);
|
||||
$blankRole = $role->newInstance(['display_name' => trans('settings.role_delete_no_migration')]);
|
||||
$roles->prepend($blankRole);
|
||||
|
||||
return view('settings.roles.delete', ['role' => $role, 'roles' => $roles]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a role from the system,
|
||||
* Migrate from a previous role if set.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(Request $request, string $id)
|
||||
@@ -112,10 +122,12 @@ class RoleController extends Controller
|
||||
$this->permissionsRepo->deleteRole($id, $request->get('migrate_role_id'));
|
||||
} catch (PermissionsException $e) {
|
||||
$this->showErrorNotification($e->getMessage());
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->showSuccessNotification(trans('settings.role_delete_success'));
|
||||
|
||||
return redirect('/settings/roles');
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Entities\Queries\Popular;
|
||||
use BookStack\Entities\Tools\SearchOptions;
|
||||
use BookStack\Entities\Tools\SearchRunner;
|
||||
use BookStack\Entities\Tools\ShelfContext;
|
||||
use BookStack\Entities\Tools\SearchOptions;
|
||||
use BookStack\Entities\Tools\SiblingFetcher;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -30,17 +32,17 @@ class SearchController extends Controller
|
||||
$this->setPageTitle(trans('entities.search_for_term', ['term' => $fullSearchString]));
|
||||
|
||||
$page = intval($request->get('page', '0')) ?: 1;
|
||||
$nextPageLink = url('/search?term=' . urlencode($fullSearchString) . '&page=' . ($page+1));
|
||||
$nextPageLink = url('/search?term=' . urlencode($fullSearchString) . '&page=' . ($page + 1));
|
||||
|
||||
$results = $this->searchRunner->searchEntities($searchOpts, 'all', $page, 20);
|
||||
|
||||
return view('search.all', [
|
||||
'entities' => $results['results'],
|
||||
'entities' => $results['results'],
|
||||
'totalResults' => $results['total'],
|
||||
'searchTerm' => $fullSearchString,
|
||||
'hasNextPage' => $results['has_more'],
|
||||
'searchTerm' => $fullSearchString,
|
||||
'hasNextPage' => $results['has_more'],
|
||||
'nextPageLink' => $nextPageLink,
|
||||
'options' => $searchOpts,
|
||||
'options' => $searchOpts,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -51,6 +53,7 @@ class SearchController extends Controller
|
||||
{
|
||||
$term = $request->get('term', '');
|
||||
$results = $this->searchRunner->searchBook($bookId, $term);
|
||||
|
||||
return view('partials.entity-list', ['entities' => $results]);
|
||||
}
|
||||
|
||||
@@ -61,6 +64,7 @@ class SearchController extends Controller
|
||||
{
|
||||
$term = $request->get('term', '');
|
||||
$results = $this->searchRunner->searchChapter($chapterId, $term);
|
||||
|
||||
return view('partials.entity-list', ['entities' => $results]);
|
||||
}
|
||||
|
||||
@@ -71,15 +75,15 @@ class SearchController extends Controller
|
||||
public function searchEntitiesAjax(Request $request)
|
||||
{
|
||||
$entityTypes = $request->filled('types') ? explode(',', $request->get('types')) : ['page', 'chapter', 'book'];
|
||||
$searchTerm = $request->get('term', false);
|
||||
$searchTerm = $request->get('term', false);
|
||||
$permission = $request->get('permission', 'view');
|
||||
|
||||
// Search for entities otherwise show most popular
|
||||
if ($searchTerm !== false) {
|
||||
$searchTerm .= ' {type:'. implode('|', $entityTypes) .'}';
|
||||
$searchTerm .= ' {type:' . implode('|', $entityTypes) . '}';
|
||||
$entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20, $permission)['results'];
|
||||
} else {
|
||||
$entities = (new Popular)->run(20, 0, $entityTypes, $permission);
|
||||
$entities = (new Popular())->run(20, 0, $entityTypes, $permission);
|
||||
}
|
||||
|
||||
return view('search.entity-ajax-list', ['entities' => $entities]);
|
||||
@@ -93,7 +97,8 @@ class SearchController extends Controller
|
||||
$type = $request->get('entity_type', null);
|
||||
$id = $request->get('entity_id', null);
|
||||
|
||||
$entities = (new SiblingFetcher)->fetch($type, $id);
|
||||
$entities = (new SiblingFetcher())->fetch($type, $id);
|
||||
|
||||
return view('partials.entity-list-basic', ['entities' => $entities, 'style' => 'compact']);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\User;
|
||||
@@ -29,8 +31,8 @@ class SettingController extends Controller
|
||||
$version = trim(file_get_contents(base_path('version')));
|
||||
|
||||
return view('settings.index', [
|
||||
'version' => $version,
|
||||
'guestUser' => User::getDefault()
|
||||
'version' => $version,
|
||||
'guestUser' => User::getDefault(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -72,6 +74,7 @@ class SettingController extends Controller
|
||||
$this->logActivity(ActivityType::SETTINGS_UPDATE, $section);
|
||||
$this->showSuccessNotification(trans('settings.settings_save_success'));
|
||||
$redirectLocation = '/settings#' . $section;
|
||||
|
||||
return redirect(rtrim($redirectLocation, '#'));
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -7,7 +9,6 @@ use Illuminate\Support\Str;
|
||||
|
||||
class StatusController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Show the system status as a simple json page.
|
||||
*/
|
||||
@@ -20,16 +21,19 @@ class StatusController extends Controller
|
||||
'cache' => $this->trueWithoutError(function () {
|
||||
$rand = Str::random();
|
||||
Cache::set('status_test', $rand);
|
||||
|
||||
return Cache::get('status_test') === $rand;
|
||||
}),
|
||||
'session' => $this->trueWithoutError(function () {
|
||||
$rand = Str::random();
|
||||
Session::put('status_test', $rand);
|
||||
|
||||
return Session::get('status_test') === $rand;
|
||||
}),
|
||||
];
|
||||
|
||||
$hasError = in_array(false, $statuses);
|
||||
|
||||
return response()->json($statuses, $hasError ? 500 : 200);
|
||||
}
|
||||
|
||||
|
@@ -1,11 +1,12 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\TagRepo;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
|
||||
protected $tagRepo;
|
||||
|
||||
/**
|
||||
@@ -23,6 +24,7 @@ class TagController extends Controller
|
||||
{
|
||||
$searchTerm = $request->get('search', null);
|
||||
$suggestions = $this->tagRepo->getNameSuggestions($searchTerm);
|
||||
|
||||
return response()->json($suggestions);
|
||||
}
|
||||
|
||||
@@ -34,6 +36,7 @@ class TagController extends Controller
|
||||
$searchTerm = $request->get('search', null);
|
||||
$tagName = $request->get('name', null);
|
||||
$suggestions = $this->tagRepo->getValueSuggestions($searchTerm, $tagName);
|
||||
|
||||
return response()->json($suggestions);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Api\ApiToken;
|
||||
@@ -9,7 +11,6 @@ use Illuminate\Support\Str;
|
||||
|
||||
class UserApiTokenController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Show the form to create a new API token.
|
||||
*/
|
||||
@@ -20,6 +21,7 @@ class UserApiTokenController extends Controller
|
||||
$this->checkPermissionOrCurrentUser('users-manage', $userId);
|
||||
|
||||
$user = User::query()->findOrFail($userId);
|
||||
|
||||
return view('users.api-tokens.create', [
|
||||
'user' => $user,
|
||||
]);
|
||||
@@ -34,7 +36,7 @@ class UserApiTokenController extends Controller
|
||||
$this->checkPermissionOrCurrentUser('users-manage', $userId);
|
||||
|
||||
$this->validate($request, [
|
||||
'name' => 'required|max:250',
|
||||
'name' => 'required|max:250',
|
||||
'expires_at' => 'date_format:Y-m-d',
|
||||
]);
|
||||
|
||||
@@ -42,10 +44,10 @@ class UserApiTokenController extends Controller
|
||||
$secret = Str::random(32);
|
||||
|
||||
$token = (new ApiToken())->forceFill([
|
||||
'name' => $request->get('name'),
|
||||
'token_id' => Str::random(32),
|
||||
'secret' => Hash::make($secret),
|
||||
'user_id' => $user->id,
|
||||
'name' => $request->get('name'),
|
||||
'token_id' => Str::random(32),
|
||||
'secret' => Hash::make($secret),
|
||||
'user_id' => $user->id,
|
||||
'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(),
|
||||
]);
|
||||
|
||||
@@ -71,9 +73,9 @@ class UserApiTokenController extends Controller
|
||||
$secret = session()->pull('api-token-secret:' . $token->id, null);
|
||||
|
||||
return view('users.api-tokens.edit', [
|
||||
'user' => $user,
|
||||
'token' => $token,
|
||||
'model' => $token,
|
||||
'user' => $user,
|
||||
'token' => $token,
|
||||
'model' => $token,
|
||||
'secret' => $secret,
|
||||
]);
|
||||
}
|
||||
@@ -84,18 +86,19 @@ class UserApiTokenController extends Controller
|
||||
public function update(Request $request, int $userId, int $tokenId)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'name' => 'required|max:250',
|
||||
'name' => 'required|max:250',
|
||||
'expires_at' => 'date_format:Y-m-d',
|
||||
]);
|
||||
|
||||
[$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
|
||||
$token->fill([
|
||||
'name' => $request->get('name'),
|
||||
'name' => $request->get('name'),
|
||||
'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(),
|
||||
])->save();
|
||||
|
||||
$this->showSuccessNotification(trans('settings.user_api_token_update_success'));
|
||||
$this->logActivity(ActivityType::API_TOKEN_UPDATE, $token);
|
||||
|
||||
return redirect($user->getEditUrl('/api-tokens/' . $token->id));
|
||||
}
|
||||
|
||||
@@ -105,8 +108,9 @@ class UserApiTokenController extends Controller
|
||||
public function delete(int $userId, int $tokenId)
|
||||
{
|
||||
[$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
|
||||
|
||||
return view('users.api-tokens.delete', [
|
||||
'user' => $user,
|
||||
'user' => $user,
|
||||
'token' => $token,
|
||||
]);
|
||||
}
|
||||
@@ -138,6 +142,7 @@ class UserApiTokenController extends Controller
|
||||
|
||||
$user = User::query()->findOrFail($userId);
|
||||
$token = ApiToken::query()->where('user_id', '=', $user->id)->where('id', '=', $tokenId)->firstOrFail();
|
||||
|
||||
return [$user, $token];
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\Access\SocialAuthService;
|
||||
@@ -15,7 +17,6 @@ use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
||||
protected $user;
|
||||
protected $userRepo;
|
||||
protected $inviteService;
|
||||
@@ -39,14 +40,15 @@ class UserController extends Controller
|
||||
{
|
||||
$this->checkPermission('users-manage');
|
||||
$listDetails = [
|
||||
'order' => $request->get('order', 'asc'),
|
||||
'order' => $request->get('order', 'asc'),
|
||||
'search' => $request->get('search', ''),
|
||||
'sort' => $request->get('sort', 'name'),
|
||||
'sort' => $request->get('sort', 'name'),
|
||||
];
|
||||
$users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails);
|
||||
|
||||
$this->setPageTitle(trans('settings.users'));
|
||||
$users->appends($listDetails);
|
||||
|
||||
return view('users.index', ['users' => $users, 'listDetails' => $listDetails]);
|
||||
}
|
||||
|
||||
@@ -58,11 +60,13 @@ class UserController extends Controller
|
||||
$this->checkPermission('users-manage');
|
||||
$authMethod = config('auth.method');
|
||||
$roles = $this->userRepo->getAllRoles();
|
||||
|
||||
return view('users.create', ['authMethod' => $authMethod, 'roles' => $roles]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created user in storage.
|
||||
*
|
||||
* @throws UserUpdateException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
@@ -71,7 +75,7 @@ class UserController extends Controller
|
||||
$this->checkPermission('users-manage');
|
||||
$validationRules = [
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:users,email'
|
||||
'email' => 'required|email|unique:users,email',
|
||||
];
|
||||
|
||||
$authMethod = config('auth.method');
|
||||
@@ -108,6 +112,7 @@ class UserController extends Controller
|
||||
$this->userRepo->downloadAndAssignUserAvatar($user);
|
||||
|
||||
$this->logActivity(ActivityType::USER_CREATE, $user);
|
||||
|
||||
return redirect('/settings/users');
|
||||
}
|
||||
|
||||
@@ -125,16 +130,18 @@ class UserController extends Controller
|
||||
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
|
||||
$this->setPageTitle(trans('settings.user_profile'));
|
||||
$roles = $this->userRepo->getAllRoles();
|
||||
|
||||
return view('users.edit', [
|
||||
'user' => $user,
|
||||
'user' => $user,
|
||||
'activeSocialDrivers' => $activeSocialDrivers,
|
||||
'authMethod' => $authMethod,
|
||||
'roles' => $roles
|
||||
'authMethod' => $authMethod,
|
||||
'roles' => $roles,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified user in storage.
|
||||
*
|
||||
* @throws UserUpdateException
|
||||
* @throws ImageUploadException
|
||||
* @throws ValidationException
|
||||
@@ -208,6 +215,7 @@ class UserController extends Controller
|
||||
$this->logActivity(ActivityType::USER_UPDATE, $user);
|
||||
|
||||
$redirectUrl = userCan('users-manage') ? '/settings/users' : ('/settings/users/' . $user->id);
|
||||
|
||||
return redirect($redirectUrl);
|
||||
}
|
||||
|
||||
@@ -220,11 +228,13 @@ class UserController extends Controller
|
||||
|
||||
$user = $this->userRepo->getById($id);
|
||||
$this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
|
||||
|
||||
return view('users.delete', ['user' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified user from storage.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function destroy(Request $request, int $id)
|
||||
@@ -237,11 +247,13 @@ class UserController extends Controller
|
||||
|
||||
if ($this->userRepo->isOnlyAdmin($user)) {
|
||||
$this->showErrorNotification(trans('errors.users_cannot_delete_only_admin'));
|
||||
|
||||
return redirect($user->getEditUrl());
|
||||
}
|
||||
|
||||
if ($user->system_name === 'public') {
|
||||
$this->showErrorNotification(trans('errors.users_cannot_delete_guest'));
|
||||
|
||||
return redirect($user->getEditUrl());
|
||||
}
|
||||
|
||||
@@ -304,6 +316,7 @@ class UserController extends Controller
|
||||
if (!in_array($type, $validSortTypes)) {
|
||||
return redirect()->back(500);
|
||||
}
|
||||
|
||||
return $this->changeListSort($id, $request, $type);
|
||||
}
|
||||
|
||||
@@ -314,6 +327,7 @@ class UserController extends Controller
|
||||
{
|
||||
$enabled = setting()->getForCurrentUser('dark-mode-enabled', false);
|
||||
setting()->putUser(user(), 'dark-mode-enabled', $enabled ? 'false' : 'true');
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@@ -325,14 +339,15 @@ class UserController extends Controller
|
||||
$this->checkPermissionOrCurrentUser('users-manage', $id);
|
||||
$keyWhitelist = ['home-details'];
|
||||
if (!in_array($key, $keyWhitelist)) {
|
||||
return response("Invalid key", 500);
|
||||
return response('Invalid key', 500);
|
||||
}
|
||||
|
||||
$newState = $request->get('expand', 'false');
|
||||
|
||||
$user = $this->user->findOrFail($id);
|
||||
setting()->putUser($user, 'section_expansion#' . $key, $newState);
|
||||
return response("", 204);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,11 +1,13 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Auth\UserRepo;
|
||||
|
||||
class UserProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the user profile page
|
||||
* Show the user profile page.
|
||||
*/
|
||||
public function show(UserRepo $repo, string $slug)
|
||||
{
|
||||
@@ -16,10 +18,10 @@ class UserProfileController extends Controller
|
||||
$assetCounts = $repo->getAssetCounts($user);
|
||||
|
||||
return view('users.profile', [
|
||||
'user' => $user,
|
||||
'activity' => $userActivity,
|
||||
'user' => $user,
|
||||
'activity' => $userActivity,
|
||||
'recentlyCreated' => $recentlyCreated,
|
||||
'assetCounts' => $assetCounts
|
||||
'assetCounts' => $assetCounts,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ class UserSearchController extends Controller
|
||||
}
|
||||
|
||||
$users = $query->get();
|
||||
|
||||
return view('components.user-select-list', compact('users'));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user