0
0
Fork 0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-05-07 01:30:06 +00:00

Set /app PHP code to PSR-2 standard

Also adde draw.io to attribution list.

Closes 
This commit is contained in:
Dan Brown 2018-01-28 16:58:52 +00:00
parent 30b4f81fc6
commit 62342433f4
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9
80 changed files with 593 additions and 335 deletions

View file

@ -16,7 +16,9 @@ class Activity extends Model
*/ */
public function entity() public function entity()
{ {
if ($this->entity_type === '') $this->entity_type = null; if ($this->entity_type === '') {
$this->entity_type = null;
}
return $this->morphTo('entity'); return $this->morphTo('entity');
} }
@ -43,8 +45,8 @@ class Activity extends Model
* @param $activityB * @param $activityB
* @return bool * @return bool
*/ */
public function isSimilarTo($activityB) { public function isSimilarTo($activityB)
{
return [$this->key, $this->entity_type, $this->entity_id] === [$activityB->key, $activityB->entity_type, $activityB->entity_id]; return [$this->key, $this->entity_type, $this->entity_id] === [$activityB->key, $activityB->entity_type, $activityB->entity_id];
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class Attachment extends Ownable class Attachment extends Ownable
{ {
protected $fillable = ['name', 'order']; protected $fillable = ['name', 'order'];
@ -11,7 +10,9 @@ class Attachment extends Ownable
*/ */
public function getFileName() public function getFileName()
{ {
if (str_contains($this->name, '.')) return $this->name; if (str_contains($this->name, '.')) {
return $this->name;
}
return $this->name . '.' . $this->extension; return $this->name . '.' . $this->extension;
} }
@ -32,5 +33,4 @@ class Attachment extends Ownable
{ {
return baseUrl('/attachments/' . $this->id); return baseUrl('/attachments/' . $this->id);
} }
} }

View file

@ -27,7 +27,9 @@ class Book extends Entity
public function getBookCover($width = 440, $height = 250) public function getBookCover($width = 440, $height = 250)
{ {
$default = baseUrl('/book_default_cover.png'); $default = baseUrl('/book_default_cover.png');
if (!$this->image_id) return $default; if (!$this->image_id) {
return $default;
}
try { try {
$cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default; $cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
@ -91,5 +93,4 @@ class Book extends Entity
{ {
return "'BookStack\\\\Book' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at"; return "'BookStack\\\\Book' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class Chapter extends Entity class Chapter extends Entity
{ {
protected $fillable = ['name', 'description', 'priority', 'book_id']; protected $fillable = ['name', 'description', 'priority', 'book_id'];
@ -59,5 +58,4 @@ class Chapter extends Entity
{ {
return "'BookStack\\\\Chapter' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, '' as html, book_id, priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at"; return "'BookStack\\\\Chapter' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, '' as html, book_id, priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
} }
} }

View file

@ -6,7 +6,8 @@ use BookStack\User;
use BookStack\Repos\UserRepo; use BookStack\Repos\UserRepo;
use Illuminate\Console\Command; use Illuminate\Console\Command;
class DeleteUsers extends Command{ class DeleteUsers extends Command
{
/** /**
* The name and signature of the console command. * The name and signature of the console command.
@ -37,14 +38,11 @@ class DeleteUsers extends Command{
{ {
$confirm = $this->ask('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)'); $confirm = $this->ask('This will delete all users from the system that are not "admin" or system users. Are you sure you want to continue? (Type "yes" to continue)');
$numDeleted = 0; $numDeleted = 0;
if (strtolower(trim($confirm)) === 'yes') if (strtolower(trim($confirm)) === 'yes') {
{
$totalUsers = $this->user->count(); $totalUsers = $this->user->count();
$users = $this->user->where('system_name', '=', null)->with('roles')->get(); $users = $this->user->where('system_name', '=', null)->with('roles')->get();
foreach ($users as $user) foreach ($users as $user) {
{ if ($user->hasSystemRole('admin')) {
if ($user->hasSystemRole('admin'))
{
// don't delete users with "admin" role // don't delete users with "admin" role
continue; continue;
} }
@ -52,11 +50,8 @@ class DeleteUsers extends Command{
++$numDeleted; ++$numDeleted;
} }
$this->info("Deleted $numDeleted of $totalUsers total users."); $this->info("Deleted $numDeleted of $totalUsers total users.");
} } else {
else
{
$this->info('Exiting...'); $this->info('Exiting...');
} }
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphMany;
class Entity extends Ownable class Entity extends Ownable
@ -28,7 +27,9 @@ class Entity extends Ownable
{ {
$matches = [get_class($this), $this->id] === [get_class($entity), $entity->id]; $matches = [get_class($this), $this->id] === [get_class($entity), $entity->id];
if ($matches) return true; if ($matches) {
return true;
}
if (($entity->isA('chapter') || $entity->isA('page')) && $this->isA('book')) { if (($entity->isA('chapter') || $entity->isA('page')) && $this->isA('book')) {
return $entity->book_id === $this->id; return $entity->book_id === $this->id;
@ -159,7 +160,9 @@ class Entity extends Ownable
*/ */
public function getShortName($length = 25) public function getShortName($length = 25)
{ {
if (strlen($this->name) <= $length) return $this->name; if (strlen($this->name) <= $length) {
return $this->name;
}
return substr($this->name, 0, $length - 3) . '...'; return substr($this->name, 0, $length - 3) . '...';
} }
@ -176,13 +179,18 @@ class Entity extends Ownable
* Return a generalised, common raw query that can be 'unioned' across entities. * Return a generalised, common raw query that can be 'unioned' across entities.
* @return string * @return string
*/ */
public function entityRawQuery(){return '';} public function entityRawQuery()
{
return '';
}
/** /**
* Get the url of this entity * Get the url of this entity
* @param $path * @param $path
* @return string * @return string
*/ */
public function getUrl($path){return '/';} public function getUrl($path)
{
return '/';
}
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class EntityPermission extends Model class EntityPermission extends Model
{ {

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class AuthException extends PrettyException
{
class AuthException extends PrettyException {} }

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class ConfirmationEmailException extends NotifyException
{
class ConfirmationEmailException extends NotifyException {} }

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class FileUploadException extends PrettyException
{
class FileUploadException extends PrettyException {} }

View file

@ -95,9 +95,12 @@ class Handler extends ExceptionHandler
* @param $type * @param $type
* @return bool * @return bool
*/ */
protected function isExceptionType(Exception $e, $type) { protected function isExceptionType(Exception $e, $type)
{
do { do {
if (is_a($e, $type)) return true; if (is_a($e, $type)) {
return true;
}
} while ($e = $e->getPrevious()); } while ($e = $e->getPrevious());
return false; return false;
} }
@ -107,7 +110,8 @@ class Handler extends ExceptionHandler
* @param Exception $e * @param Exception $e
* @return string * @return string
*/ */
protected function getOriginalMessage(Exception $e) { protected function getOriginalMessage(Exception $e)
{
do { do {
$message = $e->getMessage(); $message = $e->getMessage();
} while ($e = $e->getPrevious()); } while ($e = $e->getPrevious());

View file

@ -1,3 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class ImageUploadException extends PrettyException {} class ImageUploadException extends PrettyException
{
}

View file

@ -1,3 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class LdapException extends PrettyException {} class LdapException extends PrettyException
{
}

View file

@ -1,7 +1,7 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class NotFoundException extends PrettyException
class NotFoundException extends PrettyException { {
/** /**
* NotFoundException constructor. * NotFoundException constructor.
@ -11,4 +11,4 @@ class NotFoundException extends PrettyException {
{ {
parent::__construct($message, 404); parent::__construct($message, 404);
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class NotifyException extends \Exception class NotifyException extends \Exception
{ {
@ -18,4 +17,4 @@ class NotifyException extends \Exception
$this->redirectLocation = $redirectLocation; $this->redirectLocation = $redirectLocation;
parent::__construct(); parent::__construct();
} }
} }

View file

@ -1,6 +1,8 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
use Exception; use Exception;
class PermissionsException extends Exception {} class PermissionsException extends Exception
{
}

View file

@ -1,3 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class PrettyException extends \Exception {} class PrettyException extends \Exception
{
}

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class SocialDriverNotConfigured extends PrettyException
{
class SocialDriverNotConfigured extends PrettyException {} }

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class SocialSignInException extends NotifyException
{
class SocialSignInException extends NotifyException {} }

View file

@ -1,4 +1,6 @@
<?php namespace BookStack\Exceptions; <?php namespace BookStack\Exceptions;
class UserRegistrationException extends NotifyException
{
class UserRegistrationException extends NotifyException {} }

View file

@ -64,5 +64,4 @@ class ForgotPasswordController extends Controller
['email' => trans($response)] ['email' => trans($response)]
); );
} }
}
}

View file

@ -70,7 +70,9 @@ class LoginController extends Controller
protected function authenticated(Request $request, Authenticatable $user) protected function authenticated(Request $request, Authenticatable $user)
{ {
// Explicitly log them out for now if they do no exist. // Explicitly log them out for now if they do no exist.
if (!$user->exists) auth()->logout($user); if (!$user->exists) {
auth()->logout($user);
}
if (!$user->exists && $user->email === null && !$request->filled('email')) { if (!$user->exists && $user->email === null && !$request->filled('email')) {
$request->flash(); $request->flash();
@ -83,7 +85,6 @@ class LoginController extends Controller
} }
if (!$user->exists) { if (!$user->exists) {
// Check for users with same email already // Check for users with same email already
$alreadyUser = $user->newQuery()->where('email', '=', $user->email)->count() > 0; $alreadyUser = $user->newQuery()->where('email', '=', $user->email)->count() > 0;
if ($alreadyUser) { if ($alreadyUser) {
@ -130,4 +131,4 @@ class LoginController extends Controller
session()->put('social-callback', 'login'); session()->put('social-callback', 'login');
return $this->socialAuthService->startLogIn($socialDriver); return $this->socialAuthService->startLogIn($socialDriver);
} }
} }

View file

@ -113,7 +113,8 @@ class RegisterController extends Controller
if ($validator->fails()) { if ($validator->fails()) {
$this->throwValidationException( $this->throwValidationException(
$request, $validator $request,
$validator
); );
} }
@ -272,8 +273,12 @@ class RegisterController extends Controller
} }
$action = session()->pull('social-callback'); $action = session()->pull('social-callback');
if ($action == 'login') return $this->socialAuthService->handleLoginCallback($socialDriver); if ($action == 'login') {
if ($action == 'register') return $this->socialRegisterCallback($socialDriver); return $this->socialAuthService->handleLoginCallback($socialDriver);
}
if ($action == 'register') {
return $this->socialRegisterCallback($socialDriver);
}
return redirect()->back(); return redirect()->back();
} }
@ -308,5 +313,4 @@ class RegisterController extends Controller
]; ];
return $this->registerUser($userData, $socialAccount); return $this->registerUser($userData, $socialAccount);
} }
}
}

View file

@ -46,4 +46,4 @@ class ResetPasswordController extends Controller
return redirect($this->redirectPath()) return redirect($this->redirectPath())
->with('status', trans($response)); ->with('status', trans($response));
} }
} }

View file

@ -109,7 +109,7 @@ class BookController extends Controller
{ {
$book = $this->entityRepo->getBySlug('book', $slug); $book = $this->entityRepo->getBySlug('book', $slug);
$this->checkOwnablePermission('book-update', $book); $this->checkOwnablePermission('book-update', $book);
$this->setPageTitle(trans('entities.books_edit_named',['bookName'=>$book->getShortName()])); $this->setPageTitle(trans('entities.books_edit_named', ['bookName'=>$book->getShortName()]));
return view('books/edit', ['book' => $book, 'current' => $book]); return view('books/edit', ['book' => $book, 'current' => $book]);
} }
@ -194,7 +194,7 @@ class BookController extends Controller
$bookIdsInvolved = collect([$book->id]); $bookIdsInvolved = collect([$book->id]);
// Load models into map // Load models into map
$sortMap->each(function($mapItem) use ($bookIdsInvolved) { $sortMap->each(function ($mapItem) use ($bookIdsInvolved) {
$mapItem->type = ($mapItem->type === 'page' ? 'page' : 'chapter'); $mapItem->type = ($mapItem->type === 'page' ? 'page' : 'chapter');
$mapItem->model = $this->entityRepo->getById($mapItem->type, $mapItem->id); $mapItem->model = $this->entityRepo->getById($mapItem->type, $mapItem->id);
// Store source and target books // Store source and target books
@ -210,12 +210,12 @@ class BookController extends Controller
$this->showPermissionError(); $this->showPermissionError();
} }
// Check permissions of involved books // Check permissions of involved books
$booksInvolved->each(function(Book $book) { $booksInvolved->each(function (Book $book) {
$this->checkOwnablePermission('book-update', $book); $this->checkOwnablePermission('book-update', $book);
}); });
// Perform the sort // Perform the sort
$sortMap->each(function($mapItem) { $sortMap->each(function ($mapItem) {
$model = $mapItem->model; $model = $mapItem->model;
$priorityChanged = intval($model->priority) !== intval($mapItem->sort); $priorityChanged = intval($model->priority) !== intval($mapItem->sort);
@ -236,7 +236,7 @@ class BookController extends Controller
}); });
// Rebuild permissions and add activity for involved books. // Rebuild permissions and add activity for involved books.
$booksInvolved->each(function(Book $book) { $booksInvolved->each(function (Book $book) {
$this->entityRepo->buildJointPermissionsForBook($book); $this->entityRepo->buildJointPermissionsForBook($book);
Activity::add($book, 'book_sort', $book->id); Activity::add($book, 'book_sort', $book->id);
}); });

View file

@ -159,7 +159,8 @@ class ChapterController extends Controller
* @return mixed * @return mixed
* @throws \BookStack\Exceptions\NotFoundException * @throws \BookStack\Exceptions\NotFoundException
*/ */
public function showMove($bookSlug, $chapterSlug) { public function showMove($bookSlug, $chapterSlug)
{
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
$this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()])); $this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
$this->checkOwnablePermission('chapter-update', $chapter); $this->checkOwnablePermission('chapter-update', $chapter);
@ -177,7 +178,8 @@ class ChapterController extends Controller
* @return mixed * @return mixed
* @throws \BookStack\Exceptions\NotFoundException * @throws \BookStack\Exceptions\NotFoundException
*/ */
public function move($bookSlug, $chapterSlug, Request $request) { public function move($bookSlug, $chapterSlug, Request $request)
{
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
$this->checkOwnablePermission('chapter-update', $chapter); $this->checkOwnablePermission('chapter-update', $chapter);

View file

@ -51,7 +51,9 @@ abstract class Controller extends BaseController
*/ */
protected function preventAccessForDemoUsers() protected function preventAccessForDemoUsers()
{ {
if (config('app.env') === 'demo') $this->showPermissionError(); if (config('app.env') === 'demo') {
$this->showPermissionError();
}
} }
/** /**
@ -100,7 +102,9 @@ abstract class Controller extends BaseController
*/ */
protected function checkOwnablePermission($permission, Ownable $ownable) protected function checkOwnablePermission($permission, Ownable $ownable)
{ {
if (userCan($permission, $ownable)) return true; if (userCan($permission, $ownable)) {
return true;
}
return $this->showPermissionError(); return $this->showPermissionError();
} }
@ -113,7 +117,9 @@ abstract class Controller extends BaseController
protected function checkPermissionOr($permissionName, $callback) protected function checkPermissionOr($permissionName, $callback)
{ {
$callbackResult = $callback(); $callbackResult = $callback();
if ($callbackResult === false) $this->checkPermission($permissionName); if ($callbackResult === false) {
$this->checkPermission($permissionName);
}
return true; return true;
} }
@ -145,5 +151,4 @@ abstract class Controller extends BaseController
->withInput($request->input()) ->withInput($request->input())
->withErrors($errors, $this->errorBag()); ->withErrors($errors, $this->errorBag());
} }
} }

View file

@ -56,7 +56,8 @@ class HomeController extends Controller
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
* @throws \Exception * @throws \Exception
*/ */
public function getTranslations() { public function getTranslations()
{
$locale = app()->getLocale(); $locale = app()->getLocale();
$cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale; $cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale;
if (cache()->has($cacheKey) && config('app.env') !== 'development') { if (cache()->has($cacheKey) && config('app.env') !== 'development') {
@ -95,5 +96,4 @@ class HomeController extends Controller
{ {
return view('partials/custom-head-content'); return view('partials/custom-head-content');
} }
} }

View file

@ -63,14 +63,14 @@ class ImageController extends Controller
* @param Request $request * @param Request $request
* @return mixed * @return mixed
*/ */
public function searchByType($type, $page = 0, Request $request) public function searchByType(Request $request, $type, $page = 0)
{ {
$this->validate($request, [ $this->validate($request, [
'term' => 'required|string' 'term' => 'required|string'
]); ]);
$searchTerm = $request->get('term'); $searchTerm = $request->get('term');
$imgData = $this->imageRepo->searchPaginatedByType($type, $page, 24, $searchTerm); $imgData = $this->imageRepo->searchPaginatedByType($type, $searchTerm, $page, 24);
return response()->json($imgData); return response()->json($imgData);
} }
@ -92,17 +92,19 @@ class ImageController extends Controller
* @param Request $request * @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
*/ */
public function getGalleryFiltered($filter, $page = 0, Request $request) public function getGalleryFiltered(Request $request, $filter, $page = 0)
{ {
$this->validate($request, [ $this->validate($request, [
'page_id' => 'required|integer' 'page_id' => 'required|integer'
]); ]);
$validFilters = collect(['page', 'book']); $validFilters = collect(['page', 'book']);
if (!$validFilters->contains($filter)) return response('Invalid filter', 500); if (!$validFilters->contains($filter)) {
return response('Invalid filter', 500);
}
$pageId = $request->get('page_id'); $pageId = $request->get('page_id');
$imgData = $this->imageRepo->getGalleryFiltered($page, 24, strtolower($filter), $pageId); $imgData = $this->imageRepo->getGalleryFiltered(strtolower($filter), $pageId, $page, 24);
return response()->json($imgData); return response()->json($imgData);
} }
@ -265,6 +267,4 @@ class ImageController extends Controller
$this->imageRepo->destroyImage($image); $this->imageRepo->destroyImage($image);
return response()->json(trans('components.images_deleted')); return response()->json(trans('components.images_deleted'));
} }
} }

View file

@ -153,7 +153,9 @@ class PageController extends Controller
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug); $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
} catch (NotFoundException $e) { } catch (NotFoundException $e) {
$page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug); $page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug);
if ($page === null) throw $e; if ($page === null) {
throw $e;
}
return redirect($page->getUrl()); return redirect($page->getUrl());
} }
@ -220,7 +222,9 @@ class PageController extends Controller
$warnings [] = $this->entityRepo->getUserPageDraftMessage($draft); $warnings [] = $this->entityRepo->getUserPageDraftMessage($draft);
} }
if (count($warnings) > 0) session()->flash('warning', implode("\n", $warnings)); if (count($warnings) > 0) {
session()->flash('warning', implode("\n", $warnings));
}
$draftsEnabled = $this->signedIn; $draftsEnabled = $this->signedIn;
return view('pages/edit', [ return view('pages/edit', [
@ -604,5 +608,4 @@ class PageController extends Controller
session()->flash('success', trans('entities.pages_permissions_success')); session()->flash('success', trans('entities.pages_permissions_success'));
return redirect($page->getUrl()); return redirect($page->getUrl());
} }
} }

View file

@ -67,7 +67,9 @@ class PermissionController extends Controller
{ {
$this->checkPermission('user-roles-manage'); $this->checkPermission('user-roles-manage');
$role = $this->permissionsRepo->getRoleById($id); $role = $this->permissionsRepo->getRoleById($id);
if ($role->hidden) throw new PermissionsException(trans('errors.role_cannot_be_edited')); if ($role->hidden) {
throw new PermissionsException(trans('errors.role_cannot_be_edited'));
}
return view('settings/roles/edit', ['role' => $role]); return view('settings/roles/edit', ['role' => $role]);
} }

View file

@ -104,7 +104,4 @@ class SearchController extends Controller
return view('search/entity-ajax-list', ['entities' => $entities]); return view('search/entity-ajax-list', ['entities' => $entities]);
} }
} }

View file

@ -33,7 +33,9 @@ class SettingController extends Controller
// Cycles through posted settings and update them // Cycles through posted settings and update them
foreach ($request->all() as $name => $value) { foreach ($request->all() as $name => $value) {
if (strpos($name, 'setting-') !== 0) continue; if (strpos($name, 'setting-') !== 0) {
continue;
}
$key = str_replace('setting-', '', trim($name)); $key = str_replace('setting-', '', trim($name));
Setting::put($key, $value); Setting::put($key, $value);
} }
@ -41,5 +43,4 @@ class SettingController extends Controller
session()->flash('success', trans('settings.settings_save_success')); session()->flash('success', trans('settings.settings_save_success'));
return redirect('/settings'); return redirect('/settings');
} }
} }

View file

@ -54,5 +54,4 @@ class TagController extends Controller
$suggestions = $this->tagRepo->getValueSuggestions($searchTerm, $tagName); $suggestions = $this->tagRepo->getValueSuggestions($searchTerm, $tagName);
return response()->json($suggestions); return response()->json($suggestions);
} }
} }

View file

@ -102,7 +102,6 @@ class UserController extends Controller
} catch (Exception $e) { } catch (Exception $e) {
\Log::error('Failed to save user gravatar image'); \Log::error('Failed to save user gravatar image');
} }
} }
return redirect('/settings/users'); return redirect('/settings/users');
@ -256,7 +255,8 @@ class UserController extends Controller
* @param Request $request * @param Request $request
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*/ */
public function switchBookView($id, Request $request) { public function switchBookView($id, Request $request)
{
$this->checkPermissionOr('users-manage', function () use ($id) { $this->checkPermissionOr('users-manage', function () use ($id) {
return $this->currentUser->id == $id; return $this->currentUser->id == $id;
}); });
@ -271,5 +271,4 @@ class UserController extends Controller
return redirect()->back(302, [], "/settings/users/$id"); return redirect()->back(302, [], "/settings/users/$id");
} }
} }

View file

@ -19,7 +19,9 @@ class Localization
$locale = $defaultLang; $locale = $defaultLang;
$availableLocales = config('app.locales'); $availableLocales = config('app.locales');
foreach ($request->getLanguages() as $lang) { foreach ($request->getLanguages() as $lang) {
if (!in_array($lang, $availableLocales)) continue; if (!in_array($lang, $availableLocales)) {
continue;
}
$locale = $lang; $locale = $lang;
break; break;
} }

View file

@ -15,5 +15,4 @@ class Model extends EloquentModel
{ {
return parent::getAttributeFromArray($key); return parent::getAttributeFromArray($key);
} }
}
}

View file

@ -49,5 +49,4 @@ class ConfirmEmail extends Notification implements ShouldQueue
->line(trans('auth.email_confirm_text')) ->line(trans('auth.email_confirm_text'))
->action(trans('auth.email_confirm_action'), baseUrl('/register/confirm/' . $this->token)); ->action(trans('auth.email_confirm_action'), baseUrl('/register/confirm/' . $this->token));
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
abstract class Ownable extends Model abstract class Ownable extends Model
{ {
/** /**
@ -29,5 +28,4 @@ abstract class Ownable extends Model
{ {
return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]); return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]);
} }
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class Page extends Entity class Page extends Entity
{ {
protected $fillable = ['name', 'html', 'priority', 'markdown']; protected $fillable = ['name', 'html', 'priority', 'markdown'];
@ -101,8 +100,8 @@ class Page extends Entity
* @return string * @return string
*/ */
public function entityRawQuery($withContent = false) public function entityRawQuery($withContent = false)
{ $htmlQuery = $withContent ? 'html' : "'' as html"; {
$htmlQuery = $withContent ? 'html' : "'' as html";
return "'BookStack\\\\Page' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, {$htmlQuery}, book_id, priority, chapter_id, draft, created_by, updated_by, updated_at, created_at"; return "'BookStack\\\\Page' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, {$htmlQuery}, book_id, priority, chapter_id, draft, created_by, updated_by, updated_at, created_at";
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class PageRevision extends Model class PageRevision extends Model
{ {
protected $fillable = ['name', 'html', 'text', 'markdown', 'summary']; protected $fillable = ['name', 'html', 'text', 'markdown', 'summary'];
@ -31,7 +30,9 @@ class PageRevision extends Model
public function getUrl($path = null) public function getUrl($path = null)
{ {
$url = $this->page->getUrl() . '/revisions/' . $this->id; $url = $this->page->getUrl() . '/revisions/' . $this->id;
if ($path) return $url . '/' . trim($path, '/'); if ($path) {
return $url . '/' . trim($path, '/');
}
return $url; return $url;
} }
@ -58,5 +59,4 @@ class PageRevision extends Model
{ {
return $type === 'revision'; return $type === 'revision';
} }
} }

View file

@ -15,12 +15,12 @@ class AppServiceProvider extends ServiceProvider
public function boot() public function boot()
{ {
// Custom validation methods // Custom validation methods
Validator::extend('is_image', function($attribute, $value, $parameters, $validator) { Validator::extend('is_image', function ($attribute, $value, $parameters, $validator) {
$imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/tiff', 'image/webp']; $imageMimes = ['image/png', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/tiff', 'image/webp'];
return in_array($value->getMimeType(), $imageMimes); return in_array($value->getMimeType(), $imageMimes);
}); });
\Blade::directive('icon', function($expression) { \Blade::directive('icon', function ($expression) {
return "<?php echo icon($expression); ?>"; return "<?php echo icon($expression); ?>";
}); });
@ -35,7 +35,7 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function register() public function register()
{ {
$this->app->singleton(SettingService::class, function($app) { $this->app->singleton(SettingService::class, function ($app) {
return new SettingService($app->make(Setting::class), $app->make('Illuminate\Contracts\Cache\Repository')); return new SettingService($app->make(Setting::class), $app->make('Illuminate\Contracts\Cache\Repository'));
}); });
} }

View file

@ -25,7 +25,7 @@ class AuthServiceProvider extends ServiceProvider
*/ */
public function register() public function register()
{ {
Auth::provider('ldap', function($app, array $config) { Auth::provider('ldap', function ($app, array $config) {
return new LdapUserProvider($config['model'], $app[LdapService::class]); return new LdapUserProvider($config['model'], $app[LdapService::class]);
}); });
} }

View file

@ -34,28 +34,28 @@ class CustomFacadeProvider extends ServiceProvider
*/ */
public function register() public function register()
{ {
$this->app->bind('activity', function() { $this->app->bind('activity', function () {
return new ActivityService( return new ActivityService(
$this->app->make(Activity::class), $this->app->make(Activity::class),
$this->app->make(PermissionService::class) $this->app->make(PermissionService::class)
); );
}); });
$this->app->bind('views', function() { $this->app->bind('views', function () {
return new ViewService( return new ViewService(
$this->app->make(View::class), $this->app->make(View::class),
$this->app->make(PermissionService::class) $this->app->make(PermissionService::class)
); );
}); });
$this->app->bind('setting', function() { $this->app->bind('setting', function () {
return new SettingService( return new SettingService(
$this->app->make(Setting::class), $this->app->make(Setting::class),
$this->app->make(Repository::class) $this->app->make(Repository::class)
); );
}); });
$this->app->bind('images', function() { $this->app->bind('images', function () {
return new ImageService( return new ImageService(
$this->app->make(ImageManager::class), $this->app->make(ImageManager::class),
$this->app->make(Factory::class), $this->app->make(Factory::class),

View file

@ -2,7 +2,6 @@
namespace BookStack\Providers; namespace BookStack\Providers;
use BookStack\Role; use BookStack\Role;
use BookStack\Services\LdapService; use BookStack\Services\LdapService;
use BookStack\User; use BookStack\User;
@ -102,7 +101,9 @@ class LdapUserProvider implements UserProvider
{ {
// Get user via LDAP // Get user via LDAP
$userDetails = $this->ldapService->getUserDetails($credentials['username']); $userDetails = $this->ldapService->getUserDetails($credentials['username']);
if ($userDetails === null) return null; if ($userDetails === null) {
return null;
}
// Search current user base by looking up a uid // Search current user base by looking up a uid
$model = $this->createModel(); $model = $this->createModel();
@ -110,7 +111,9 @@ class LdapUserProvider implements UserProvider
->where('external_auth_id', $userDetails['uid']) ->where('external_auth_id', $userDetails['uid'])
->first(); ->first();
if ($currentUser !== null) return $currentUser; if ($currentUser !== null) {
return $currentUser;
}
$model->name = $userDetails['name']; $model->name = $userDetails['name'];
$model->external_auth_id = $userDetails['uid']; $model->external_auth_id = $userDetails['uid'];

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Providers; <?php namespace BookStack\Providers;
use Illuminate\Pagination\PaginationServiceProvider as IlluminatePaginationServiceProvider; use Illuminate\Pagination\PaginationServiceProvider as IlluminatePaginationServiceProvider;
use Illuminate\Pagination\Paginator; use Illuminate\Pagination\Paginator;
@ -32,4 +31,4 @@ class PaginationServiceProvider extends IlluminatePaginationServiceProvider
return 1; return 1;
}); });
} }
} }

View file

@ -7,7 +7,8 @@ use BookStack\Entity;
* Class CommentRepo * Class CommentRepo
* @package BookStack\Repos * @package BookStack\Repos
*/ */
class CommentRepo { class CommentRepo
{
/** /**
* @var Comment $comment * @var Comment $comment
@ -39,7 +40,7 @@ class CommentRepo {
* @param array $data * @param array $data
* @return Comment * @return Comment
*/ */
public function create (Entity $entity, $data = []) public function create(Entity $entity, $data = [])
{ {
$userId = user()->id; $userId = user()->id;
$comment = $this->comment->newInstance($data); $comment = $this->comment->newInstance($data);
@ -81,7 +82,9 @@ class CommentRepo {
protected function getNextLocalId(Entity $entity) protected function getNextLocalId(Entity $entity)
{ {
$comments = $entity->comments(false)->orderBy('local_id', 'desc')->first(); $comments = $entity->comments(false)->orderBy('local_id', 'desc')->first();
if ($comments === null) return 1; if ($comments === null) {
return 1;
}
return $comments->local_id + 1; return $comments->local_id + 1;
} }
} }

View file

@ -77,11 +77,15 @@ class EntityRepo
* @param SearchService $searchService * @param SearchService $searchService
*/ */
public function __construct( public function __construct(
Book $book, Chapter $chapter, Page $page, PageRevision $pageRevision, Book $book,
ViewService $viewService, PermissionService $permissionService, Chapter $chapter,
TagRepo $tagRepo, SearchService $searchService Page $page,
) PageRevision $pageRevision,
{ ViewService $viewService,
PermissionService $permissionService,
TagRepo $tagRepo,
SearchService $searchService
) {
$this->book = $book; $this->book = $book;
$this->chapter = $chapter; $this->chapter = $chapter;
$this->page = $page; $this->page = $page;
@ -163,14 +167,16 @@ class EntityRepo
$q = $this->entityQuery($type)->where('slug', '=', $slug); $q = $this->entityQuery($type)->where('slug', '=', $slug);
if (strtolower($type) === 'chapter' || strtolower($type) === 'page') { if (strtolower($type) === 'chapter' || strtolower($type) === 'page') {
$q = $q->where('book_id', '=', function($query) use ($bookSlug) { $q = $q->where('book_id', '=', function ($query) use ($bookSlug) {
$query->select('id') $query->select('id')
->from($this->book->getTable()) ->from($this->book->getTable())
->where('slug', '=', $bookSlug)->limit(1); ->where('slug', '=', $bookSlug)->limit(1);
}); });
} }
$entity = $q->first(); $entity = $q->first();
if ($entity === null) throw new NotFoundException(trans('errors.' . strtolower($type) . '_not_found')); if ($entity === null) {
throw new NotFoundException(trans('errors.' . strtolower($type) . '_not_found'));
}
return $entity; return $entity;
} }
@ -205,7 +211,9 @@ class EntityRepo
public function getAll($type, $count = 20, $permission = 'view') public function getAll($type, $count = 20, $permission = 'view')
{ {
$q = $this->entityQuery($type, false, $permission)->orderBy('name', 'asc'); $q = $this->entityQuery($type, false, $permission)->orderBy('name', 'asc');
if ($count !== false) $q = $q->take($count); if ($count !== false) {
$q = $q->take($count);
}
return $q->get(); return $q->get();
} }
@ -232,7 +240,9 @@ class EntityRepo
{ {
$query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type)) $query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type))
->orderBy('created_at', 'desc'); ->orderBy('created_at', 'desc');
if (strtolower($type) === 'page') $query = $query->where('draft', '=', false); if (strtolower($type) === 'page') {
$query = $query->where('draft', '=', false);
}
if ($additionalQuery !== false && is_callable($additionalQuery)) { if ($additionalQuery !== false && is_callable($additionalQuery)) {
$additionalQuery($query); $additionalQuery($query);
} }
@ -251,7 +261,9 @@ class EntityRepo
{ {
$query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type)) $query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type))
->orderBy('updated_at', 'desc'); ->orderBy('updated_at', 'desc');
if (strtolower($type) === 'page') $query = $query->where('draft', '=', false); if (strtolower($type) === 'page') {
$query = $query->where('draft', '=', false);
}
if ($additionalQuery !== false && is_callable($additionalQuery)) { if ($additionalQuery !== false && is_callable($additionalQuery)) {
$additionalQuery($query); $additionalQuery($query);
} }
@ -348,12 +360,16 @@ class EntityRepo
$parents[$key] = $entities[$index]; $parents[$key] = $entities[$index];
$parents[$key]->setAttribute('pages', collect()); $parents[$key]->setAttribute('pages', collect());
} }
if ($entities[$index]->chapter_id === 0 || $entities[$index]->chapter_id === '0') $tree[] = $entities[$index]; if ($entities[$index]->chapter_id === 0 || $entities[$index]->chapter_id === '0') {
$tree[] = $entities[$index];
}
$entities[$index]->book = $book; $entities[$index]->book = $book;
} }
foreach ($entities as $entity) { foreach ($entities as $entity) {
if ($entity->chapter_id === 0 || $entity->chapter_id === '0') continue; if ($entity->chapter_id === 0 || $entity->chapter_id === '0') {
continue;
}
$parentKey = 'BookStack\\Chapter:' . $entity->chapter_id; $parentKey = 'BookStack\\Chapter:' . $entity->chapter_id;
if (!isset($parents[$parentKey])) { if (!isset($parents[$parentKey])) {
$tree[] = $entity; $tree[] = $entity;
@ -432,7 +448,9 @@ class EntityRepo
if (strtolower($type) === 'page' || strtolower($type) === 'chapter') { if (strtolower($type) === 'page' || strtolower($type) === 'chapter') {
$query = $query->where('book_id', '=', $bookId); $query = $query->where('book_id', '=', $bookId);
} }
if ($currentId) $query = $query->where('id', '!=', $currentId); if ($currentId) {
$query = $query->where('id', '!=', $currentId);
}
return $query->count() > 0; return $query->count() > 0;
} }
@ -559,7 +577,9 @@ class EntityRepo
$slug = preg_replace('/[\+\/\\\?\@\}\{\.\,\=\[\]\#\&\!\*\'\;\:\$\%]/', '', mb_strtolower($name)); $slug = preg_replace('/[\+\/\\\?\@\}\{\.\,\=\[\]\#\&\!\*\'\;\:\$\%]/', '', mb_strtolower($name));
$slug = preg_replace('/\s{2,}/', ' ', $slug); $slug = preg_replace('/\s{2,}/', ' ', $slug);
$slug = str_replace(' ', '-', $slug); $slug = str_replace(' ', '-', $slug);
if ($slug === "") $slug = substr(md5(rand(1, 500)), 0, 5); if ($slug === "") {
$slug = substr(md5(rand(1, 500)), 0, 5);
}
return $slug; return $slug;
} }
@ -600,7 +620,9 @@ class EntityRepo
public function savePageRevision(Page $page, $summary = null) public function savePageRevision(Page $page, $summary = null)
{ {
$revision = $this->pageRevision->newInstance($page->toArray()); $revision = $this->pageRevision->newInstance($page->toArray());
if (setting('app-editor') !== 'markdown') $revision->markdown = ''; if (setting('app-editor') !== 'markdown') {
$revision->markdown = '';
}
$revision->page_id = $page->id; $revision->page_id = $page->id;
$revision->slug = $page->slug; $revision->slug = $page->slug;
$revision->book_slug = $page->book->slug; $revision->book_slug = $page->book->slug;
@ -628,7 +650,9 @@ class EntityRepo
*/ */
protected function formatHtml($htmlText) protected function formatHtml($htmlText)
{ {
if ($htmlText == '') return $htmlText; if ($htmlText == '') {
return $htmlText;
}
libxml_use_internal_errors(true); libxml_use_internal_errors(true);
$doc = new DOMDocument(); $doc = new DOMDocument();
$doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8')); $doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
@ -642,7 +666,9 @@ class EntityRepo
foreach ($childNodes as $index => $childNode) { foreach ($childNodes as $index => $childNode) {
/** @var \DOMElement $childNode */ /** @var \DOMElement $childNode */
if (get_class($childNode) !== 'DOMElement') continue; if (get_class($childNode) !== 'DOMElement') {
continue;
}
// Overwrite id if not a BookStack custom id // Overwrite id if not a BookStack custom id
if ($childNode->hasAttribute('id')) { if ($childNode->hasAttribute('id')) {
@ -689,13 +715,17 @@ class EntityRepo
$content = $page->html; $content = $page->html;
$matches = []; $matches = [];
preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches); preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches);
if (count($matches[0]) === 0) return $content; if (count($matches[0]) === 0) {
return $content;
}
$topLevelTags = ['table', 'ul', 'ol']; $topLevelTags = ['table', 'ul', 'ol'];
foreach ($matches[1] as $index => $includeId) { foreach ($matches[1] as $index => $includeId) {
$splitInclude = explode('#', $includeId, 2); $splitInclude = explode('#', $includeId, 2);
$pageId = intval($splitInclude[0]); $pageId = intval($splitInclude[0]);
if (is_nan($pageId)) continue; if (is_nan($pageId)) {
continue;
}
$matchedPage = $this->getById('page', $pageId, false, $ignorePermissions); $matchedPage = $this->getById('page', $pageId, false, $ignorePermissions);
if ($matchedPage === null) { if ($matchedPage === null) {
@ -755,7 +785,9 @@ class EntityRepo
$page->updated_by = user()->id; $page->updated_by = user()->id;
$page->draft = true; $page->draft = true;
if ($chapter) $page->chapter_id = $chapter->id; if ($chapter) {
$page->chapter_id = $chapter->id;
}
$book->pages()->save($page); $book->pages()->save($page);
$page = $this->page->find($page->id); $page = $this->page->find($page->id);
@ -786,14 +818,18 @@ class EntityRepo
*/ */
public function getPageNav($pageContent) public function getPageNav($pageContent)
{ {
if ($pageContent == '') return []; if ($pageContent == '') {
return [];
}
libxml_use_internal_errors(true); libxml_use_internal_errors(true);
$doc = new DOMDocument(); $doc = new DOMDocument();
$doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8')); $doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8'));
$xPath = new DOMXPath($doc); $xPath = new DOMXPath($doc);
$headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6"); $headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
if (is_null($headers)) return []; if (is_null($headers)) {
return [];
}
$tree = collect([]); $tree = collect([]);
foreach ($headers as $header) { foreach ($headers as $header) {
@ -809,7 +845,7 @@ class EntityRepo
// Normalise headers if only smaller headers have been used // Normalise headers if only smaller headers have been used
if (count($tree) > 0) { if (count($tree) > 0) {
$minLevel = $tree->pluck('level')->min(); $minLevel = $tree->pluck('level')->min();
$tree = $tree->map(function($header) use ($minLevel) { $tree = $tree->map(function ($header) use ($minLevel) {
$header['level'] -= ($minLevel - 2); $header['level'] -= ($minLevel - 2);
return $header; return $header;
}); });
@ -845,7 +881,9 @@ class EntityRepo
$page->fill($input); $page->fill($input);
$page->html = $this->formatHtml($input['html']); $page->html = $this->formatHtml($input['html']);
$page->text = $this->pageToPlainText($page); $page->text = $this->pageToPlainText($page);
if (setting('app-editor') !== 'markdown') $page->markdown = ''; if (setting('app-editor') !== 'markdown') {
$page->markdown = '';
}
$page->updated_by = $userId; $page->updated_by = $userId;
$page->revision_count++; $page->revision_count++;
$page->save(); $page->save();
@ -907,7 +945,9 @@ class EntityRepo
public function getUserPageDraftMessage(PageRevision $draft) public function getUserPageDraftMessage(PageRevision $draft)
{ {
$message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]); $message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) return $message; if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) {
return $message;
}
return $message . "\n" . trans('entities.pages_draft_edited_notification'); return $message . "\n" . trans('entities.pages_draft_edited_notification');
} }
@ -1003,7 +1043,9 @@ class EntityRepo
} }
$draft->fill($data); $draft->fill($data);
if (setting('app-editor') !== 'markdown') $draft->markdown = ''; if (setting('app-editor') !== 'markdown') {
$draft->markdown = '';
}
$draft->save(); $draft->save();
return $draft; return $draft;
@ -1110,17 +1152,4 @@ class EntityRepo
$page->delete(); $page->delete();
} }
} }

View file

@ -92,7 +92,7 @@ class ImageRepo
* @param string $searchTerm * @param string $searchTerm
* @return array * @return array
*/ */
public function searchPaginatedByType($type, $page = 0, $pageSize = 24, $searchTerm) public function searchPaginatedByType($type, $searchTerm, $page = 0, $pageSize = 24)
{ {
$images = $this->image->where('type', '=', strtolower($type))->where('name', 'LIKE', '%' . $searchTerm . '%'); $images = $this->image->where('type', '=', strtolower($type))->where('name', 'LIKE', '%' . $searchTerm . '%');
return $this->returnPaginated($images, $page, $pageSize); return $this->returnPaginated($images, $page, $pageSize);
@ -101,13 +101,13 @@ class ImageRepo
/** /**
* Get gallery images with a particular filter criteria such as * Get gallery images with a particular filter criteria such as
* being within the current book or page. * being within the current book or page.
* @param int $pagination
* @param int $pageSize
* @param $filter * @param $filter
* @param $pageId * @param $pageId
* @param int $pageNum
* @param int $pageSize
* @return array * @return array
*/ */
public function getGalleryFiltered($pagination = 0, $pageSize = 24, $filter, $pageId) public function getGalleryFiltered($filter, $pageId, $pageNum = 0, $pageSize = 24)
{ {
$images = $this->image->where('type', '=', 'gallery'); $images = $this->image->where('type', '=', 'gallery');
@ -120,7 +120,7 @@ class ImageRepo
$images = $images->whereIn('uploaded_to', $validPageIds); $images = $images->whereIn('uploaded_to', $validPageIds);
} }
return $this->returnPaginated($images, $pagination, $pageSize); return $this->returnPaginated($images, $pageNum, $pageSize);
} }
/** /**
@ -254,5 +254,4 @@ class ImageRepo
$validTypes = ['drawing', 'gallery', 'cover', 'system', 'user']; $validTypes = ['drawing', 'gallery', 'cover', 'system', 'user'];
return in_array($type, $validTypes); return in_array($type, $validTypes);
} }
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Repos; <?php namespace BookStack\Repos;
use BookStack\Exceptions\PermissionsException; use BookStack\Exceptions\PermissionsException;
use BookStack\RolePermission; use BookStack\RolePermission;
use BookStack\Role; use BookStack\Role;
@ -149,5 +148,4 @@ class PermissionsRepo
$this->permissionService->deleteJointPermissionsForRole($role); $this->permissionService->deleteJointPermissionsForRole($role);
$role->delete(); $role->delete();
} }
}
}

View file

@ -52,7 +52,9 @@ class TagRepo
public function getForEntity($entityType, $entityId) public function getForEntity($entityType, $entityId)
{ {
$entity = $this->getEntity($entityType, $entityId); $entity = $this->getEntity($entityType, $entityId);
if ($entity === null) return collect(); if ($entity === null) {
return collect();
}
return $entity->tags; return $entity->tags;
} }
@ -95,7 +97,9 @@ class TagRepo
$query = $query->orderBy('count', 'desc')->take(50); $query = $query->orderBy('count', 'desc')->take(50);
} }
if ($tagName !== false) $query = $query->where('name', '=', $tagName); if ($tagName !== false) {
$query = $query->where('name', '=', $tagName);
}
$query = $this->permissionService->filterRestrictedEntityRelations($query, 'tags', 'entity_id', 'entity_type'); $query = $this->permissionService->filterRestrictedEntityRelations($query, 'tags', 'entity_id', 'entity_type');
return $query->get(['value'])->pluck('value'); return $query->get(['value'])->pluck('value');
@ -112,7 +116,9 @@ class TagRepo
$entity->tags()->delete(); $entity->tags()->delete();
$newTags = []; $newTags = [];
foreach ($tags as $tag) { foreach ($tags as $tag) {
if (trim($tag['name']) === '') continue; if (trim($tag['name']) === '') {
continue;
}
$newTags[] = $this->newInstanceFromInput($tag); $newTags[] = $this->newInstanceFromInput($tag);
} }
@ -132,5 +138,4 @@ class TagRepo
$values = ['name' => $name, 'value' => $value]; $values = ['name' => $name, 'value' => $value];
return $this->tag->newInstance($values); return $this->tag->newInstance($values);
} }
}
}

View file

@ -60,13 +60,13 @@ class UserRepo
* @param $sortData * @param $sortData
* @return \Illuminate\Database\Eloquent\Builder|static * @return \Illuminate\Database\Eloquent\Builder|static
*/ */
public function getAllUsersPaginatedAndSorted($count = 20, $sortData) public function getAllUsersPaginatedAndSorted($count, $sortData)
{ {
$query = $this->user->with('roles', 'avatar')->orderBy($sortData['sort'], $sortData['order']); $query = $this->user->with('roles', 'avatar')->orderBy($sortData['sort'], $sortData['order']);
if ($sortData['search']) { if ($sortData['search']) {
$term = '%' . $sortData['search'] . '%'; $term = '%' . $sortData['search'] . '%';
$query->where(function($query) use ($term) { $query->where(function ($query) use ($term) {
$query->where('name', 'like', $term) $query->where('name', 'like', $term)
->orWhere('email', 'like', $term); ->orWhere('email', 'like', $term);
}); });
@ -107,7 +107,9 @@ class UserRepo
public function attachDefaultRole($user) public function attachDefaultRole($user)
{ {
$roleId = setting('registration-role'); $roleId = setting('registration-role');
if ($roleId === false) $roleId = $this->role->first()->id; if ($roleId === false) {
$roleId = $this->role->first()->id;
}
$user->attachRoleId($roleId); $user->attachRoleId($roleId);
} }
@ -118,10 +120,14 @@ class UserRepo
*/ */
public function isOnlyAdmin(User $user) public function isOnlyAdmin(User $user)
{ {
if (!$user->hasSystemRole('admin')) return false; if (!$user->hasSystemRole('admin')) {
return false;
}
$adminRole = $this->role->getSystemRole('admin'); $adminRole = $this->role->getSystemRole('admin');
if ($adminRole->users->count() > 1) return false; if ($adminRole->users->count() > 1) {
return false;
}
return true; return true;
} }
@ -222,5 +228,4 @@ class UserRepo
{ {
return $this->role->where('system_name', '!=', 'admin')->get(); return $this->role->where('system_name', '!=', 'admin')->get();
} }
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class Role extends Model class Role extends Model
{ {
@ -40,7 +39,9 @@ class Role extends Model
{ {
$permissions = $this->getRelationValue('permissions'); $permissions = $this->getRelationValue('permissions');
foreach ($permissions as $permission) { foreach ($permissions as $permission) {
if ($permission->getRawAttribute('name') === $permissionName) return true; if ($permission->getRawAttribute('name') === $permissionName) {
return true;
}
} }
return false; return false;
} }
@ -91,5 +92,4 @@ class Role extends Model
{ {
return static::where('hidden', '=', false)->orderBy('name')->get(); return static::where('hidden', '=', false)->orderBy('name')->get();
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class RolePermission extends Model class RolePermission extends Model
{ {
/** /**
@ -8,7 +7,7 @@ class RolePermission extends Model
*/ */
public function roles() public function roles()
{ {
return $this->belongsToMany(Role::class, 'permission_role','permission_id', 'role_id'); return $this->belongsToMany(Role::class, 'permission_role', 'permission_id', 'role_id');
} }
/** /**

View file

@ -14,5 +14,4 @@ class SearchTerm extends Model
{ {
return $this->morphTo('entity'); return $this->morphTo('entity');
} }
} }

View file

@ -170,5 +170,4 @@ class ActivityService
Session::flash('success', $message); Session::flash('success', $message);
} }
} }
}
}

View file

@ -14,7 +14,9 @@ class AttachmentService extends UploadService
*/ */
protected function getStorage() protected function getStorage()
{ {
if ($this->storageInstance !== null) return $this->storageInstance; if ($this->storageInstance !== null) {
return $this->storageInstance;
}
$storageType = config('filesystems.default'); $storageType = config('filesystems.default');
@ -205,5 +207,4 @@ class AttachmentService extends UploadService
return $attachmentPath; return $attachmentPath;
} }
}
}

View file

@ -108,6 +108,4 @@ class EmailConfirmationService
} }
return $token; return $token;
} }
}
}

View file

@ -42,7 +42,7 @@ class ExportService
public function chapterToContainedHtml(Chapter $chapter) public function chapterToContainedHtml(Chapter $chapter)
{ {
$pages = $this->entityRepo->getChapterChildren($chapter); $pages = $this->entityRepo->getChapterChildren($chapter);
$pages->each(function($page) { $pages->each(function ($page) {
$page->html = $this->entityRepo->renderPage($page); $page->html = $this->entityRepo->renderPage($page);
}); });
$html = view('chapters/export', [ $html = view('chapters/export', [
@ -89,7 +89,7 @@ class ExportService
public function chapterToPdf(Chapter $chapter) public function chapterToPdf(Chapter $chapter)
{ {
$pages = $this->entityRepo->getChapterChildren($chapter); $pages = $this->entityRepo->getChapterChildren($chapter);
$pages->each(function($page) { $pages->each(function ($page) {
$page->html = $this->entityRepo->renderPage($page); $page->html = $this->entityRepo->renderPage($page);
}); });
$html = view('chapters/export', [ $html = view('chapters/export', [
@ -163,7 +163,9 @@ class ExportService
$pathString = public_path(trim($relString, '/')); $pathString = public_path(trim($relString, '/'));
} }
if ($isLocal && !file_exists($pathString)) continue; if ($isLocal && !file_exists($pathString)) {
continue;
}
try { try {
if ($isLocal) { if ($isLocal) {
$imageContent = file_get_contents($pathString); $imageContent = file_get_contents($pathString);
@ -173,7 +175,9 @@ class ExportService
$imageContent = curl_exec($ch); $imageContent = curl_exec($ch);
$err = curl_error($ch); $err = curl_error($ch);
curl_close($ch); curl_close($ch);
if ($err) throw new \Exception("Image fetch failed, Received error: " . $err); if ($err) {
throw new \Exception("Image fetch failed, Received error: " . $err);
}
} }
$imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent); $imageEncoded = 'data:image/' . pathinfo($pathString, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageContent);
$newImageString = str_replace($srcString, $imageEncoded, $oldImgString); $newImageString = str_replace($srcString, $imageEncoded, $oldImgString);
@ -257,17 +261,4 @@ class ExportService
} }
return $text; return $text;
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Services\Facades; <?php namespace BookStack\Services\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class Activity extends Facade class Activity extends Facade
@ -10,5 +9,8 @@ class Activity extends Facade
* *
* @return string * @return string
*/ */
protected static function getFacadeAccessor() { return 'activity'; } protected static function getFacadeAccessor()
} {
return 'activity';
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Services\Facades; <?php namespace BookStack\Services\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class Images extends Facade class Images extends Facade
@ -10,5 +9,8 @@ class Images extends Facade
* *
* @return string * @return string
*/ */
protected static function getFacadeAccessor() { return 'images'; } protected static function getFacadeAccessor()
} {
return 'images';
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Services\Facades; <?php namespace BookStack\Services\Facades;
use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\Facade;
class Setting extends Facade class Setting extends Facade
@ -10,5 +9,8 @@ class Setting extends Facade
* *
* @return string * @return string
*/ */
protected static function getFacadeAccessor() { return 'setting'; } protected static function getFacadeAccessor()
} {
return 'setting';
}
}

View file

@ -9,5 +9,8 @@ class Views extends Facade
* *
* @return string * @return string
*/ */
protected static function getFacadeAccessor() { return 'views'; } protected static function getFacadeAccessor()
} {
return 'views';
}
}

View file

@ -102,7 +102,9 @@ class ImageService extends UploadService
{ {
$imageName = $imageName ? $imageName : basename($url); $imageName = $imageName ? $imageName : basename($url);
$imageData = file_get_contents($url); $imageData = file_get_contents($url);
if($imageData === false) throw new \Exception(trans('errors.cannot_get_image_from_url', ['url' => $url])); if ($imageData === false) {
throw new \Exception(trans('errors.cannot_get_image_from_url', ['url' => $url]));
}
return $this->saveNew($imageName, $imageData, $type); return $this->saveNew($imageName, $imageData, $type);
} }
@ -121,7 +123,9 @@ class ImageService extends UploadService
$secureUploads = setting('app-secure-images'); $secureUploads = setting('app-secure-images');
$imageName = str_replace(' ', '-', $imageName); $imageName = str_replace(' ', '-', $imageName);
if ($secureUploads) $imageName = str_random(16) . '-' . $imageName; if ($secureUploads) {
$imageName = str_random(16) . '-' . $imageName;
}
$imagePath = '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/'; $imagePath = '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/';
@ -255,9 +259,13 @@ class ImageService extends UploadService
// Cleanup of empty folders // Cleanup of empty folders
foreach ($storage->directories($imageFolder) as $directory) { foreach ($storage->directories($imageFolder) as $directory) {
if ($this->isFolderEmpty($directory)) $storage->deleteDirectory($directory); if ($this->isFolderEmpty($directory)) {
$storage->deleteDirectory($directory);
}
}
if ($this->isFolderEmpty($imageFolder)) {
$storage->deleteDirectory($imageFolder);
} }
if ($this->isFolderEmpty($imageFolder)) $storage->deleteDirectory($imageFolder);
$image->delete(); $image->delete();
return true; return true;
@ -308,6 +316,4 @@ class ImageService extends UploadService
$basePath = ($this->storageUrl == false) ? baseUrl('/') : $this->storageUrl; $basePath = ($this->storageUrl == false) ? baseUrl('/') : $this->storageUrl;
return rtrim($basePath, '/') . $filePath; return rtrim($basePath, '/') . $filePath;
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Services; <?php namespace BookStack\Services;
/** /**
* Class Ldap * Class Ldap
* An object-orientated thin abstraction wrapper for common PHP LDAP functions. * An object-orientated thin abstraction wrapper for common PHP LDAP functions.
@ -93,5 +92,4 @@ class Ldap
{ {
return ldap_bind($ldapConnection, $bindRdn, $bindPassword); return ldap_bind($ldapConnection, $bindRdn, $bindPassword);
} }
} }

View file

@ -1,6 +1,5 @@
<?php namespace BookStack\Services; <?php namespace BookStack\Services;
use BookStack\Exceptions\LdapException; use BookStack\Exceptions\LdapException;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
@ -45,7 +44,9 @@ class LdapService
$followReferrals = $this->config['follow_referrals'] ? 1 : 0; $followReferrals = $this->config['follow_referrals'] ? 1 : 0;
$this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals); $this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals);
$users = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn', $emailAttr]); $users = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn', $emailAttr]);
if ($users['count'] === 0) return null; if ($users['count'] === 0) {
return null;
}
$user = $users[0]; $user = $users[0];
return [ return [
@ -66,8 +67,12 @@ class LdapService
public function validateUserCredentials(Authenticatable $user, $username, $password) public function validateUserCredentials(Authenticatable $user, $username, $password)
{ {
$ldapUser = $this->getUserDetails($username); $ldapUser = $this->getUserDetails($username);
if ($ldapUser === null) return false; if ($ldapUser === null) {
if ($ldapUser['uid'] !== $user->external_auth_id) return false; return false;
}
if ($ldapUser['uid'] !== $user->external_auth_id) {
return false;
}
$ldapConnection = $this->getConnection(); $ldapConnection = $this->getConnection();
try { try {
@ -97,7 +102,9 @@ class LdapService
$ldapBind = $this->ldap->bind($connection, $ldapDn, $ldapPass); $ldapBind = $this->ldap->bind($connection, $ldapDn, $ldapPass);
} }
if (!$ldapBind) throw new LdapException(($isAnonymous ? trans('errors.ldap_fail_anonymous') : trans('errors.ldap_fail_authed'))); if (!$ldapBind) {
throw new LdapException(($isAnonymous ? trans('errors.ldap_fail_anonymous') : trans('errors.ldap_fail_authed')));
}
} }
/** /**
@ -108,7 +115,9 @@ class LdapService
*/ */
protected function getConnection() protected function getConnection()
{ {
if ($this->ldapConnection !== null) return $this->ldapConnection; if ($this->ldapConnection !== null) {
return $this->ldapConnection;
}
// Check LDAP extension in installed // Check LDAP extension in installed
if (!function_exists('ldap_connect') && config('app.env') !== 'testing') { if (!function_exists('ldap_connect') && config('app.env') !== 'testing') {
@ -118,7 +127,9 @@ class LdapService
// Get port from server string and protocol if specified. // Get port from server string and protocol if specified.
$ldapServer = explode(':', $this->config['server']); $ldapServer = explode(':', $this->config['server']);
$hasProtocol = preg_match('/^ldaps{0,1}\:\/\//', $this->config['server']) === 1; $hasProtocol = preg_match('/^ldaps{0,1}\:\/\//', $this->config['server']) === 1;
if (!$hasProtocol) array_unshift($ldapServer, ''); if (!$hasProtocol) {
array_unshift($ldapServer, '');
}
$hostName = $ldapServer[0] . ($hasProtocol?':':'') . $ldapServer[1]; $hostName = $ldapServer[0] . ($hasProtocol?':':'') . $ldapServer[1];
$defaultPort = $ldapServer[0] === 'ldaps' ? 636 : 389; $defaultPort = $ldapServer[0] === 'ldaps' ? 636 : 389;
$ldapConnection = $this->ldap->connect($hostName, count($ldapServer) > 2 ? intval($ldapServer[2]) : $defaultPort); $ldapConnection = $this->ldap->connect($hostName, count($ldapServer) > 2 ? intval($ldapServer[2]) : $defaultPort);
@ -151,5 +162,4 @@ class LdapService
} }
return strtr($filterString, $newAttrs); return strtr($filterString, $newAttrs);
} }
}
}

View file

@ -88,7 +88,9 @@ class PermissionService
} }
$book = $this->book->find($bookId); $book = $this->book->find($bookId);
if ($book === null) $book = false; if ($book === null) {
$book = false;
}
if (isset($this->entityCache['books'])) { if (isset($this->entityCache['books'])) {
$this->entityCache['books']->put($bookId, $book); $this->entityCache['books']->put($bookId, $book);
} }
@ -108,7 +110,9 @@ class PermissionService
} }
$chapter = $this->chapter->find($chapterId); $chapter = $this->chapter->find($chapterId);
if ($chapter === null) $chapter = false; if ($chapter === null) {
$chapter = false;
}
if (isset($this->entityCache['chapters'])) { if (isset($this->entityCache['chapters'])) {
$this->entityCache['chapters']->put($chapterId, $chapter); $this->entityCache['chapters']->put($chapterId, $chapter);
} }
@ -122,7 +126,9 @@ class PermissionService
*/ */
protected function getRoles() protected function getRoles()
{ {
if ($this->userRoles !== false) return $this->userRoles; if ($this->userRoles !== false) {
return $this->userRoles;
}
$roles = []; $roles = [];
@ -161,9 +167,9 @@ class PermissionService
*/ */
protected function bookFetchQuery() protected function bookFetchQuery()
{ {
return $this->book->newQuery()->select(['id', 'restricted', 'created_by'])->with(['chapters' => function($query) { return $this->book->newQuery()->select(['id', 'restricted', 'created_by'])->with(['chapters' => function ($query) {
$query->select(['id', 'restricted', 'created_by', 'book_id']); $query->select(['id', 'restricted', 'created_by', 'book_id']);
}, 'pages' => function($query) { }, 'pages' => function ($query) {
$query->select(['id', 'restricted', 'created_by', 'book_id', 'chapter_id']); $query->select(['id', 'restricted', 'created_by', 'book_id', 'chapter_id']);
}]); }]);
} }
@ -174,7 +180,8 @@ class PermissionService
* @param array $roles * @param array $roles
* @param bool $deleteOld * @param bool $deleteOld
*/ */
protected function buildJointPermissionsForBooks($books, $roles, $deleteOld = false) { protected function buildJointPermissionsForBooks($books, $roles, $deleteOld = false)
{
$entities = clone $books; $entities = clone $books;
/** @var Book $book */ /** @var Book $book */
@ -187,7 +194,9 @@ class PermissionService
} }
} }
if ($deleteOld) $this->deleteManyJointPermissionsForEntities($entities->all()); if ($deleteOld) {
$this->deleteManyJointPermissionsForEntities($entities->all());
}
$this->createManyJointPermissions($entities, $roles); $this->createManyJointPermissions($entities, $roles);
} }
@ -261,7 +270,7 @@ class PermissionService
*/ */
protected function deleteManyJointPermissionsForRoles($roles) protected function deleteManyJointPermissionsForRoles($roles)
{ {
$roleIds = array_map(function($role) { $roleIds = array_map(function ($role) {
return $role->id; return $role->id;
}, $roles); }, $roles);
$this->jointPermission->newQuery()->whereIn('role_id', $roleIds)->delete(); $this->jointPermission->newQuery()->whereIn('role_id', $roleIds)->delete();
@ -282,21 +291,22 @@ class PermissionService
*/ */
protected function deleteManyJointPermissionsForEntities($entities) protected function deleteManyJointPermissionsForEntities($entities)
{ {
if (count($entities) === 0) return; if (count($entities) === 0) {
return;
}
$this->db->transaction(function() use ($entities) { $this->db->transaction(function () use ($entities) {
foreach (array_chunk($entities, 1000) as $entityChunk) { foreach (array_chunk($entities, 1000) as $entityChunk) {
$query = $this->db->table('joint_permissions'); $query = $this->db->table('joint_permissions');
foreach ($entityChunk as $entity) { foreach ($entityChunk as $entity) {
$query->orWhere(function(QueryBuilder $query) use ($entity) { $query->orWhere(function (QueryBuilder $query) use ($entity) {
$query->where('entity_id', '=', $entity->id) $query->where('entity_id', '=', $entity->id)
->where('entity_type', '=', $entity->getMorphClass()); ->where('entity_type', '=', $entity->getMorphClass());
}); });
} }
$query->delete(); $query->delete();
} }
}); });
} }
@ -315,7 +325,7 @@ class PermissionService
$permissionFetch = $this->entityPermission->newQuery(); $permissionFetch = $this->entityPermission->newQuery();
foreach ($entities as $entity) { foreach ($entities as $entity) {
$entityRestrictedMap[$entity->getMorphClass() . ':' . $entity->id] = boolval($entity->getRawAttribute('restricted')); $entityRestrictedMap[$entity->getMorphClass() . ':' . $entity->id] = boolval($entity->getRawAttribute('restricted'));
$permissionFetch->orWhere(function($query) use ($entity) { $permissionFetch->orWhere(function ($query) use ($entity) {
$query->where('restrictable_id', '=', $entity->id)->where('restrictable_type', '=', $entity->getMorphClass()); $query->where('restrictable_id', '=', $entity->id)->where('restrictable_type', '=', $entity->getMorphClass());
}); });
} }
@ -346,7 +356,7 @@ class PermissionService
} }
} }
$this->db->transaction(function() use ($jointPermissions) { $this->db->transaction(function () use ($jointPermissions) {
foreach (array_chunk($jointPermissions, 1000) as $jointPermissionChunk) { foreach (array_chunk($jointPermissions, 1000) as $jointPermissionChunk) {
$this->db->table('joint_permissions')->insert($jointPermissionChunk); $this->db->table('joint_permissions')->insert($jointPermissionChunk);
} }
@ -362,8 +372,12 @@ class PermissionService
protected function getActions(Entity $entity) protected function getActions(Entity $entity)
{ {
$baseActions = ['view', 'update', 'delete']; $baseActions = ['view', 'update', 'delete'];
if ($entity->isA('chapter') || $entity->isA('book')) $baseActions[] = 'page-create'; if ($entity->isA('chapter') || $entity->isA('book')) {
if ($entity->isA('book')) $baseActions[] = 'chapter-create'; $baseActions[] = 'page-create';
}
if ($entity->isA('book')) {
$baseActions[] = 'chapter-create';
}
return $baseActions; return $baseActions;
} }
@ -412,7 +426,10 @@ class PermissionService
} }
} }
return $this->createJointPermissionDataArray($entity, $role, $action, return $this->createJointPermissionDataArray(
$entity,
$role,
$action,
($hasExplicitAccessToParents || ($roleHasPermission && $hasPermissiveAccessToParents)), ($hasExplicitAccessToParents || ($roleHasPermission && $hasPermissiveAccessToParents)),
($hasExplicitAccessToParents || ($roleHasPermissionOwn && $hasPermissiveAccessToParents)) ($hasExplicitAccessToParents || ($roleHasPermissionOwn && $hasPermissiveAccessToParents))
); );
@ -426,7 +443,8 @@ class PermissionService
* @param $action * @param $action
* @return bool * @return bool
*/ */
protected function mapHasActiveRestriction($entityMap, Entity $entity, Role $role, $action) { protected function mapHasActiveRestriction($entityMap, Entity $entity, Role $role, $action)
{
$key = $entity->getMorphClass() . ':' . $entity->getRawAttribute('id') . ':' . $role->getRawAttribute('id') . ':' . $action; $key = $entity->getMorphClass() . ':' . $entity->getRawAttribute('id') . ':' . $role->getRawAttribute('id') . ':' . $action;
return isset($entityMap[$key]) ? $entityMap[$key] : false; return isset($entityMap[$key]) ? $entityMap[$key] : false;
} }
@ -545,11 +563,12 @@ class PermissionService
* @param bool $fetchPageContent * @param bool $fetchPageContent
* @return QueryBuilder * @return QueryBuilder
*/ */
public function bookChildrenQuery($book_id, $filterDrafts = false, $fetchPageContent = false) { public function bookChildrenQuery($book_id, $filterDrafts = false, $fetchPageContent = false)
$pageSelect = $this->db->table('pages')->selectRaw($this->page->entityRawQuery($fetchPageContent))->where('book_id', '=', $book_id)->where(function($query) use ($filterDrafts) { {
$pageSelect = $this->db->table('pages')->selectRaw($this->page->entityRawQuery($fetchPageContent))->where('book_id', '=', $book_id)->where(function ($query) use ($filterDrafts) {
$query->where('draft', '=', 0); $query->where('draft', '=', 0);
if (!$filterDrafts) { if (!$filterDrafts) {
$query->orWhere(function($query) { $query->orWhere(function ($query) {
$query->where('draft', '=', 1)->where('created_by', '=', $this->currentUser()->id); $query->where('draft', '=', 1)->where('created_by', '=', $this->currentUser()->id);
}); });
} }
@ -562,8 +581,8 @@ class PermissionService
$whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)') $whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)')
->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type') ->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type')
->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles()) ->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles())
->where(function($query) { ->where(function ($query) {
$query->where('jp.has_permission', '=', 1)->orWhere(function($query) { $query->where('jp.has_permission', '=', 1)->orWhere(function ($query) {
$query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id); $query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id);
}); });
}); });
@ -715,5 +734,4 @@ class PermissionService
$this->userRoles = false; $this->userRoles = false;
$this->isAdminUser = null; $this->isAdminUser = null;
} }
}
}

View file

@ -83,7 +83,9 @@ class SearchService
$total = 0; $total = 0;
foreach ($entityTypesToSearch as $entityType) { foreach ($entityTypesToSearch as $entityType) {
if (!in_array($entityType, $entityTypes)) continue; if (!in_array($entityType, $entityTypes)) {
continue;
}
$search = $this->searchEntityTable($terms, $entityType, $page, $count); $search = $this->searchEntityTable($terms, $entityType, $page, $count);
$total += $this->searchEntityTable($terms, $entityType, $page, $count, true); $total += $this->searchEntityTable($terms, $entityType, $page, $count, true);
$results = $results->merge($search); $results = $results->merge($search);
@ -111,7 +113,9 @@ class SearchService
$results = collect(); $results = collect();
foreach ($entityTypesToSearch as $entityType) { foreach ($entityTypesToSearch as $entityType) {
if (!in_array($entityType, $entityTypes)) continue; if (!in_array($entityType, $entityTypes)) {
continue;
}
$search = $this->buildEntitySearchQuery($terms, $entityType)->where('book_id', '=', $bookId)->take(20)->get(); $search = $this->buildEntitySearchQuery($terms, $entityType)->where('book_id', '=', $bookId)->take(20)->get();
$results = $results->merge($search); $results = $results->merge($search);
} }
@ -143,7 +147,9 @@ class SearchService
public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $getCount = false) public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $getCount = false)
{ {
$query = $this->buildEntitySearchQuery($terms, $entityType); $query = $this->buildEntitySearchQuery($terms, $entityType);
if ($getCount) return $query->count(); if ($getCount) {
return $query->count();
}
$query = $query->skip(($page-1) * $count)->take($count); $query = $query->skip(($page-1) * $count)->take($count);
return $query->get(); return $query->get();
@ -164,12 +170,12 @@ class SearchService
if (count($terms['search']) > 0) { if (count($terms['search']) > 0) {
$subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score')); $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score'));
$subQuery->where('entity_type', '=', 'BookStack\\' . ucfirst($entityType)); $subQuery->where('entity_type', '=', 'BookStack\\' . ucfirst($entityType));
$subQuery->where(function(Builder $query) use ($terms) { $subQuery->where(function (Builder $query) use ($terms) {
foreach ($terms['search'] as $inputTerm) { foreach ($terms['search'] as $inputTerm) {
$query->orWhere('term', 'like', $inputTerm .'%'); $query->orWhere('term', 'like', $inputTerm .'%');
} }
})->groupBy('entity_type', 'entity_id'); })->groupBy('entity_type', 'entity_id');
$entitySelect->join(\DB::raw('(' . $subQuery->toSql() . ') as s'), function(JoinClause $join) { $entitySelect->join(\DB::raw('(' . $subQuery->toSql() . ') as s'), function (JoinClause $join) {
$join->on('id', '=', 'entity_id'); $join->on('id', '=', 'entity_id');
})->selectRaw($entity->getTable().'.*, s.score')->orderBy('score', 'desc'); })->selectRaw($entity->getTable().'.*, s.score')->orderBy('score', 'desc');
$entitySelect->mergeBindings($subQuery); $entitySelect->mergeBindings($subQuery);
@ -177,7 +183,7 @@ class SearchService
// Handle exact term matching // Handle exact term matching
if (count($terms['exact']) > 0) { if (count($terms['exact']) > 0) {
$entitySelect->where(function(\Illuminate\Database\Eloquent\Builder $query) use ($terms, $entity) { $entitySelect->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($terms, $entity) {
foreach ($terms['exact'] as $inputTerm) { foreach ($terms['exact'] as $inputTerm) {
$query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) { $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) {
$query->where('name', 'like', '%'.$inputTerm .'%') $query->where('name', 'like', '%'.$inputTerm .'%')
@ -195,7 +201,9 @@ class SearchService
// Handle filters // Handle filters
foreach ($terms['filters'] as $filterTerm => $filterValue) { foreach ($terms['filters'] as $filterTerm => $filterValue) {
$functionName = camel_case('filter_' . $filterTerm); $functionName = camel_case('filter_' . $filterTerm);
if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue); if (method_exists($this, $functionName)) {
$this->$functionName($entitySelect, $entity, $filterValue);
}
} }
return $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view'); return $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
@ -234,7 +242,9 @@ class SearchService
// Parse standard terms // Parse standard terms
foreach (explode(' ', trim($searchString)) as $searchTerm) { foreach (explode(' ', trim($searchString)) as $searchTerm) {
if ($searchTerm !== '') $terms['search'][] = $searchTerm; if ($searchTerm !== '') {
$terms['search'][] = $searchTerm;
}
} }
// Split filter values out // Split filter values out
@ -267,15 +277,18 @@ class SearchService
* @param string $tagTerm * @param string $tagTerm
* @return mixed * @return mixed
*/ */
protected function applyTagSearch(\Illuminate\Database\Eloquent\Builder $query, $tagTerm) { protected function applyTagSearch(\Illuminate\Database\Eloquent\Builder $query, $tagTerm)
{
preg_match("/^(.*?)((".$this->getRegexEscapedOperators().")(.*?))?$/", $tagTerm, $tagSplit); preg_match("/^(.*?)((".$this->getRegexEscapedOperators().")(.*?))?$/", $tagTerm, $tagSplit);
$query->whereHas('tags', function(\Illuminate\Database\Eloquent\Builder $query) use ($tagSplit) { $query->whereHas('tags', function (\Illuminate\Database\Eloquent\Builder $query) use ($tagSplit) {
$tagName = $tagSplit[1]; $tagName = $tagSplit[1];
$tagOperator = count($tagSplit) > 2 ? $tagSplit[3] : ''; $tagOperator = count($tagSplit) > 2 ? $tagSplit[3] : '';
$tagValue = count($tagSplit) > 3 ? $tagSplit[4] : ''; $tagValue = count($tagSplit) > 3 ? $tagSplit[4] : '';
$validOperator = in_array($tagOperator, $this->queryOperators); $validOperator = in_array($tagOperator, $this->queryOperators);
if (!empty($tagOperator) && !empty($tagValue) && $validOperator) { if (!empty($tagOperator) && !empty($tagValue) && $validOperator) {
if (!empty($tagName)) $query->where('name', '=', $tagName); if (!empty($tagName)) {
$query->where('name', '=', $tagName);
}
if (is_numeric($tagValue) && $tagOperator !== 'like') { if (is_numeric($tagValue) && $tagOperator !== 'like') {
// We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will // We have to do a raw sql query for this since otherwise PDO will quote the value and MySQL will
// search the value as a string which prevents being able to do number-based operations // search the value as a string which prevents being able to do number-based operations
@ -323,7 +336,8 @@ class SearchService
* Index multiple Entities at once * Index multiple Entities at once
* @param Entity[] $entities * @param Entity[] $entities
*/ */
protected function indexEntities($entities) { protected function indexEntities($entities)
{
$terms = []; $terms = [];
foreach ($entities as $entity) { foreach ($entities as $entity) {
$nameTerms = $this->generateTermArrayFromText($entity->name, 5); $nameTerms = $this->generateTermArrayFromText($entity->name, 5);
@ -386,7 +400,9 @@ class SearchService
$token = strtok($text, $splitChars); $token = strtok($text, $splitChars);
while ($token !== false) { while ($token !== false) {
if (!isset($tokenMap[$token])) $tokenMap[$token] = 0; if (!isset($tokenMap[$token])) {
$tokenMap[$token] = 0;
}
$tokenMap[$token]++; $tokenMap[$token]++;
$token = strtok($splitChars); $token = strtok($splitChars);
} }
@ -410,43 +426,63 @@ class SearchService
protected function filterUpdatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterUpdatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
try { $date = date_create($input); try {
} catch (\Exception $e) {return;} $date = date_create($input);
} catch (\Exception $e) {
return;
}
$query->where('updated_at', '>=', $date); $query->where('updated_at', '>=', $date);
} }
protected function filterUpdatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterUpdatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
try { $date = date_create($input); try {
} catch (\Exception $e) {return;} $date = date_create($input);
} catch (\Exception $e) {
return;
}
$query->where('updated_at', '<', $date); $query->where('updated_at', '<', $date);
} }
protected function filterCreatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterCreatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
try { $date = date_create($input); try {
} catch (\Exception $e) {return;} $date = date_create($input);
} catch (\Exception $e) {
return;
}
$query->where('created_at', '>=', $date); $query->where('created_at', '>=', $date);
} }
protected function filterCreatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterCreatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
try { $date = date_create($input); try {
} catch (\Exception $e) {return;} $date = date_create($input);
} catch (\Exception $e) {
return;
}
$query->where('created_at', '<', $date); $query->where('created_at', '<', $date);
} }
protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
if (!is_numeric($input) && $input !== 'me') return; if (!is_numeric($input) && $input !== 'me') {
if ($input === 'me') $input = user()->id; return;
}
if ($input === 'me') {
$input = user()->id;
}
$query->where('created_by', '=', $input); $query->where('created_by', '=', $input);
} }
protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
if (!is_numeric($input) && $input !== 'me') return; if (!is_numeric($input) && $input !== 'me') {
if ($input === 'me') $input = user()->id; return;
}
if ($input === 'me') {
$input = user()->id;
}
$query->where('updated_by', '=', $input); $query->where('updated_by', '=', $input);
} }
@ -455,7 +491,10 @@ class SearchService
$query->where('name', 'like', '%' .$input. '%'); $query->where('name', 'like', '%' .$input. '%');
} }
protected function filterInTitle(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) {$this->filterInName($query, $model, $input);} protected function filterInTitle(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{
$this->filterInName($query, $model, $input);
}
protected function filterInBody(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterInBody(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
@ -469,14 +508,14 @@ class SearchService
protected function filterViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
$query->whereHas('views', function($query) { $query->whereHas('views', function ($query) {
$query->where('user_id', '=', user()->id); $query->where('user_id', '=', user()->id);
}); });
} }
protected function filterNotViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterNotViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
$query->whereDoesntHave('views', function($query) { $query->whereDoesntHave('views', function ($query) {
$query->where('user_id', '=', user()->id); $query->where('user_id', '=', user()->id);
}); });
} }
@ -484,7 +523,9 @@ class SearchService
protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input) protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
{ {
$functionName = camel_case('sort_by_' . $input); $functionName = camel_case('sort_by_' . $input);
if (method_exists($this, $functionName)) $this->$functionName($query, $model); if (method_exists($this, $functionName)) {
$this->$functionName($query, $model);
}
} }
@ -500,4 +541,4 @@ class SearchService
$query->join($commentQuery, $model->getTable() . '.id', '=', 'comments.entity_id')->orderBy('last_commented', 'desc'); $query->join($commentQuery, $model->getTable() . '.id', '=', 'comments.entity_id')->orderBy('last_commented', 'desc');
} }
} }

View file

@ -40,8 +40,12 @@ class SettingService
*/ */
public function get($key, $default = false) public function get($key, $default = false)
{ {
if ($default === false) $default = config('setting-defaults.' . $key, false); if ($default === false) {
if (isset($this->localCache[$key])) return $this->localCache[$key]; $default = config('setting-defaults.' . $key, false);
}
if (isset($this->localCache[$key])) {
return $this->localCache[$key];
}
$value = $this->getValueFromStore($key, $default); $value = $this->getValueFromStore($key, $default);
$formatted = $this->formatValue($value, $default); $formatted = $this->formatValue($value, $default);
@ -72,12 +76,16 @@ class SettingService
{ {
// Check for an overriding value // Check for an overriding value
$overrideValue = $this->getOverrideValue($key); $overrideValue = $this->getOverrideValue($key);
if ($overrideValue !== null) return $overrideValue; if ($overrideValue !== null) {
return $overrideValue;
}
// Check the cache // Check the cache
$cacheKey = $this->cachePrefix . $key; $cacheKey = $this->cachePrefix . $key;
$cacheVal = $this->cache->get($cacheKey, null); $cacheVal = $this->cache->get($cacheKey, null);
if ($cacheVal !== null) return $cacheVal; if ($cacheVal !== null) {
return $cacheVal;
}
// Check the database // Check the database
$settingObject = $this->getSettingObjectByKey($key); $settingObject = $this->getSettingObjectByKey($key);
@ -112,11 +120,17 @@ class SettingService
protected function formatValue($value, $default) protected function formatValue($value, $default)
{ {
// Change string booleans to actual booleans // Change string booleans to actual booleans
if ($value === 'true') $value = true; if ($value === 'true') {
if ($value === 'false') $value = false; $value = true;
}
if ($value === 'false') {
$value = false;
}
// Set to default if empty // Set to default if empty
if ($value === '') $value = $default; if ($value === '') {
$value = $default;
}
return $value; return $value;
} }
@ -225,8 +239,9 @@ class SettingService
*/ */
protected function getOverrideValue($key) protected function getOverrideValue($key)
{ {
if ($key === 'registration-enabled' && config('auth.method') === 'ldap') return false; if ($key === 'registration-enabled' && config('auth.method') === 'ldap') {
return false;
}
return null; return null;
} }
}
}

View file

@ -150,8 +150,12 @@ class SocialAuthService
{ {
$driver = trim(strtolower($socialDriver)); $driver = trim(strtolower($socialDriver));
if (!in_array($driver, $this->validSocialDrivers)) abort(404, trans('errors.social_driver_not_found')); if (!in_array($driver, $this->validSocialDrivers)) {
if (!$this->checkDriverConfigured($driver)) throw new SocialDriverNotConfigured(trans('errors.social_driver_not_configured', ['socialAccount' => title_case($socialDriver)])); abort(404, trans('errors.social_driver_not_found'));
}
if (!$this->checkDriverConfigured($driver)) {
throw new SocialDriverNotConfigured(trans('errors.social_driver_not_configured', ['socialAccount' => title_case($socialDriver)]));
}
return $driver; return $driver;
} }
@ -220,5 +224,4 @@ class SocialAuthService
session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => title_case($socialDriver)])); session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => title_case($socialDriver)]));
return redirect(user()->getEditUrl()); return redirect(user()->getEditUrl());
} }
}
}

View file

@ -32,7 +32,9 @@ class UploadService
*/ */
protected function getStorage() protected function getStorage()
{ {
if ($this->storageInstance !== null) return $this->storageInstance; if ($this->storageInstance !== null) {
return $this->storageInstance;
}
$storageType = config('filesystems.default'); $storageType = config('filesystems.default');
$this->storageInstance = $this->fileSystem->disk($storageType); $this->storageInstance = $this->fileSystem->disk($storageType);
@ -60,4 +62,4 @@ class UploadService
{ {
return strtolower(config('filesystems.default')) === 'local'; return strtolower(config('filesystems.default')) === 'local';
} }
} }

View file

@ -27,7 +27,9 @@ class ViewService
public function add(Entity $entity) public function add(Entity $entity)
{ {
$user = user(); $user = user();
if ($user === null || $user->isDefault()) return 0; if ($user === null || $user->isDefault()) {
return 0;
}
$view = $entity->views()->where('user_id', '=', $user->id)->first(); $view = $entity->views()->where('user_id', '=', $user->id)->first();
// Add view if model exists // Add view if model exists
if ($view) { if ($view) {
@ -77,12 +79,16 @@ class ViewService
public function getUserRecentlyViewed($count = 10, $page = 0, $filterModel = false) public function getUserRecentlyViewed($count = 10, $page = 0, $filterModel = false)
{ {
$user = user(); $user = user();
if ($user === null || $user->isDefault()) return collect(); if ($user === null || $user->isDefault()) {
return collect();
}
$query = $this->permissionService $query = $this->permissionService
->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type'); ->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
if ($filterModel) $query = $query->where('viewable_type', '=', get_class($filterModel)); if ($filterModel) {
$query = $query->where('viewable_type', '=', get_class($filterModel));
}
$query = $query->where('user_id', '=', $user->id); $query = $query->where('user_id', '=', $user->id);
$viewables = $query->with('viewable')->orderBy('updated_at', 'desc') $viewables = $query->with('viewable')->orderBy('updated_at', 'desc')
@ -97,5 +103,4 @@ class ViewService
{ {
$this->view->truncate(); $this->view->truncate();
} }
}
}

View file

@ -1,6 +1,5 @@
<?php namespace BookStack; <?php namespace BookStack;
class SocialAccount extends Model class SocialAccount extends Model
{ {

View file

@ -16,4 +16,4 @@ class Tag extends Model
{ {
return $this->morphTo('entity'); return $this->morphTo('entity');
} }
} }

View file

@ -60,7 +60,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/ */
public function roles() public function roles()
{ {
if ($this->id === 0) return ; if ($this->id === 0) {
return ;
}
return $this->belongsToMany(Role::class); return $this->belongsToMany(Role::class);
} }
@ -91,9 +93,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/ */
public function permissions($cache = true) public function permissions($cache = true)
{ {
if(isset($this->permissions) && $cache) return $this->permissions; if (isset($this->permissions) && $cache) {
return $this->permissions;
}
$this->load('roles.permissions'); $this->load('roles.permissions');
$permissions = $this->roles->map(function($role) { $permissions = $this->roles->map(function ($role) {
return $role->permissions; return $role->permissions;
})->flatten()->unique(); })->flatten()->unique();
$this->permissions = $permissions; $this->permissions = $permissions;
@ -107,7 +111,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/ */
public function can($permissionName) public function can($permissionName)
{ {
if ($this->email === 'guest') return false; if ($this->email === 'guest') {
return false;
}
return $this->permissions()->pluck('name')->contains($permissionName); return $this->permissions()->pluck('name')->contains($permissionName);
} }
@ -162,7 +168,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
{ {
$default = baseUrl('/user_avatar.png'); $default = baseUrl('/user_avatar.png');
$imageId = $this->image_id; $imageId = $this->image_id;
if ($imageId === 0 || $imageId === '0' || $imageId === null) return $default; if ($imageId === 0 || $imageId === '0' || $imageId === null) {
return $default;
}
try { try {
$avatar = $this->avatar ? baseUrl($this->avatar->getThumb($size, $size, false)) : $default; $avatar = $this->avatar ? baseUrl($this->avatar->getThumb($size, $size, false)) : $default;
@ -206,10 +214,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/ */
public function getShortName($chars = 8) public function getShortName($chars = 8)
{ {
if (strlen($this->name) <= $chars) return $this->name; if (strlen($this->name) <= $chars) {
return $this->name;
}
$splitName = explode(' ', $this->name); $splitName = explode(' ', $this->name);
if (strlen($splitName[0]) <= $chars) return $splitName[0]; if (strlen($splitName[0]) <= $chars) {
return $splitName[0];
}
return ''; return '';
} }

View file

@ -74,7 +74,9 @@ function userCan($permission, Ownable $ownable = null)
function setting($key = null, $default = false) function setting($key = null, $default = false)
{ {
$settingService = resolve(\BookStack\Services\SettingService::class); $settingService = resolve(\BookStack\Services\SettingService::class);
if (is_null($key)) return $settingService; if (is_null($key)) {
return $settingService;
}
return $settingService->get($key, $default); return $settingService->get($key, $default);
} }
@ -87,7 +89,9 @@ function setting($key = null, $default = false)
function baseUrl($path, $forceAppDomain = false) function baseUrl($path, $forceAppDomain = false)
{ {
$isFullUrl = strpos($path, 'http') === 0; $isFullUrl = strpos($path, 'http') === 0;
if ($isFullUrl && !$forceAppDomain) return $path; if ($isFullUrl && !$forceAppDomain) {
return $path;
}
$path = trim($path, '/'); $path = trim($path, '/');
// Remove non-specified domain if forced and we have a domain // Remove non-specified domain if forced and we have a domain
@ -126,7 +130,8 @@ function redirect($to = null, $status = 302, $headers = [], $secure = null)
return app('redirect')->to($to, $status, $headers, $secure); return app('redirect')->to($to, $status, $headers, $secure);
} }
function icon($name, $attrs = []) { function icon($name, $attrs = [])
{
$iconPath = resource_path('assets/icons/' . $name . '.svg'); $iconPath = resource_path('assets/icons/' . $name . '.svg');
$attrString = ' '; $attrString = ' ';
foreach ($attrs as $attrName => $attr) { foreach ($attrs as $attrName => $attr) {
@ -159,11 +164,15 @@ function sortUrl($path, $data, $overrideData = [])
foreach ($queryData as $name => $value) { foreach ($queryData as $name => $value) {
$trimmedVal = trim($value); $trimmedVal = trim($value);
if ($trimmedVal === '') continue; if ($trimmedVal === '') {
continue;
}
$queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal); $queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal);
} }
if (count($queryStringSections) === 0) return $path; if (count($queryStringSections) === 0) {
return $path;
}
return baseUrl($path . '?' . implode('&', $queryStringSections)); return baseUrl($path . '?' . implode('&', $queryStringSections));
} }

View file

@ -29,7 +29,8 @@
"symfony/dom-crawler": "3.1.*", "symfony/dom-crawler": "3.1.*",
"laravel/browser-kit-testing": "^2.0", "laravel/browser-kit-testing": "^2.0",
"barryvdh/laravel-ide-helper": "^2.4.1", "barryvdh/laravel-ide-helper": "^2.4.1",
"barryvdh/laravel-debugbar": "^3.1.0" "barryvdh/laravel-debugbar": "^3.1.0",
"squizlabs/php_codesniffer": "^3.2"
}, },
"autoload": { "autoload": {
"classmap": [ "classmap": [

53
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "7d60f09393b99551e9ffdb6622ed7ade", "content-hash": "8ad5cb7acc1115a77404d1be899984ac",
"packages": [ "packages": [
{ {
"name": "aws/aws-sdk-php", "name": "aws/aws-sdk-php",
@ -5027,6 +5027,57 @@
"homepage": "https://github.com/sebastianbergmann/version", "homepage": "https://github.com/sebastianbergmann/version",
"time": "2016-10-03T07:35:21+00:00" "time": "2016-10-03T07:35:21+00:00"
}, },
{
"name": "squizlabs/php_codesniffer",
"version": "3.2.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
"reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0"
},
"bin": [
"bin/phpcs",
"bin/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Greg Sherwood",
"role": "lead"
}
],
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "http://www.squizlabs.com/php-codesniffer",
"keywords": [
"phpcs",
"standards"
],
"time": "2017-12-19T21:44:46+00:00"
},
{ {
"name": "symfony/class-loader", "name": "symfony/class-loader",
"version": "v3.3.6", "version": "v3.3.6",

8
phpcs.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<ruleset name="PHP_CodeSniffer">
<description>The coding standard for BookStack.</description>
<file>app</file>
<exclude-pattern>*/migrations/*</exclude-pattern>
<arg value="np"/>
<rule ref="PSR2"/>
</ruleset>

View file

@ -72,7 +72,11 @@ Some strings have colon-prefixed variables in such as `:userName`. Leave these v
Feel free to create issues to request new features or to report bugs and problems. Just please follow the template given when creating the issue. Feel free to create issues to request new features or to report bugs and problems. Just please follow the template given when creating the issue.
### Pull Request ### Standards
PHP code within BookStack is generally to [PSR-2](http://www.php-fig.org/psr/psr-2/) standards. From the BookStack root folder you can run `./vendor/bin/phpcs` to check code is formatted correctly and `./vendor/bin/phpcbf` to auto-fix non-PSR-2 code.
### Pull Requests
Pull requests are very welcome. If the scope of your pull request is large it may be best to open the pull request early or create an issue for it to discuss how it will fit in to the project and plan out the merge. Pull requests are very welcome. If the scope of your pull request is large it may be best to open the pull request early or create an issue for it to discuss how it will fit in to the project and plan out the merge.
@ -111,3 +115,4 @@ These are the great open-source projects used to help build BookStack:
* [Snappy (WKHTML2PDF)](https://github.com/barryvdh/laravel-snappy) * [Snappy (WKHTML2PDF)](https://github.com/barryvdh/laravel-snappy)
* [Laravel IDE helper](https://github.com/barryvdh/laravel-ide-helper) * [Laravel IDE helper](https://github.com/barryvdh/laravel-ide-helper)
* [WKHTMLtoPDF](http://wkhtmltopdf.org/index.html) * [WKHTMLtoPDF](http://wkhtmltopdf.org/index.html)
* [Draw.io](https://github.com/jgraph/drawio)