1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Merge branch 'master' into 129-page-templates

This commit is contained in:
Dan Brown
2019-08-04 16:26:38 +01:00
107 changed files with 1465 additions and 500 deletions

View File

@ -168,14 +168,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getAvatar($size = 50)
{
$default = baseUrl('/user_avatar.png');
$default = url('/user_avatar.png');
$imageId = $this->image_id;
if ($imageId === 0 || $imageId === '0' || $imageId === null) {
return $default;
}
try {
$avatar = $this->avatar ? baseUrl($this->avatar->getThumb($size, $size, false)) : $default;
$avatar = $this->avatar ? url($this->avatar->getThumb($size, $size, false)) : $default;
} catch (\Exception $err) {
$avatar = $default;
}
@ -197,7 +197,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getEditUrl()
{
return baseUrl('/settings/users/' . $this->id);
return url('/settings/users/' . $this->id);
}
/**
@ -206,7 +206,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getProfileUrl()
{
return baseUrl('/user/' . $this->id);
return url('/user/' . $this->id);
}
/**

View File

@ -52,7 +52,7 @@ return [
'locale' => env('APP_LANG', 'en'),
// Locales available
'locales' => ['en', 'ar', 'de', 'de_informal', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'cs', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'uk', 'zh_CN', 'zh_TW'],
'locales' => ['en', 'ar', 'de', 'de_informal', 'es', 'es_AR', 'fr', 'hu', 'nl', 'pt_BR', 'sk', 'cs', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'uk', 'zh_CN', 'zh_TW'],
// Application Fallback Locale
'fallback_locale' => 'en',

View File

@ -25,9 +25,9 @@ class Book extends Entity
public function getUrl($path = false)
{
if ($path !== false) {
return baseUrl('/books/' . urlencode($this->slug) . '/' . trim($path, '/'));
return url('/books/' . urlencode($this->slug) . '/' . trim($path, '/'));
}
return baseUrl('/books/' . urlencode($this->slug));
return url('/books/' . urlencode($this->slug));
}
/**
@ -44,7 +44,7 @@ class Book extends Entity
}
try {
$cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
$cover = $this->cover ? url($this->cover->getThumb($width, $height, false)) : $default;
} catch (\Exception $err) {
$cover = $default;
}

View File

@ -39,9 +39,9 @@ class Bookshelf extends Entity
public function getUrl($path = false)
{
if ($path !== false) {
return baseUrl('/shelves/' . urlencode($this->slug) . '/' . trim($path, '/'));
return url('/shelves/' . urlencode($this->slug) . '/' . trim($path, '/'));
}
return baseUrl('/shelves/' . urlencode($this->slug));
return url('/shelves/' . urlencode($this->slug));
}
/**
@ -59,7 +59,7 @@ class Bookshelf extends Entity
}
try {
$cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
$cover = $this->cover ? url($this->cover->getThumb($width, $height, false)) : $default;
} catch (\Exception $err) {
$cover = $default;
}

View File

@ -42,10 +42,13 @@ class Chapter extends Entity
public function getUrl($path = false)
{
$bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
$fullPath = '/books/' . urlencode($bookSlug) . '/chapter/' . urlencode($this->slug);
if ($path !== false) {
return baseUrl('/books/' . urlencode($bookSlug) . '/chapter/' . urlencode($this->slug) . '/' . trim($path, '/'));
$fullPath .= '/' . trim($path, '/');
}
return baseUrl('/books/' . urlencode($bookSlug) . '/chapter/' . urlencode($this->slug));
return url($fullPath);
}
/**

View File

@ -96,10 +96,10 @@ class Page extends Entity
$idComponent = $this->draft ? $this->id : urlencode($this->slug);
if ($path !== false) {
return baseUrl('/books/' . urlencode($bookSlug) . $midText . $idComponent . '/' . trim($path, '/'));
return url('/books/' . urlencode($bookSlug) . $midText . $idComponent . '/' . trim($path, '/'));
}
return baseUrl('/books/' . urlencode($bookSlug) . $midText . $idComponent);
return url('/books/' . urlencode($bookSlug) . $midText . $idComponent);
}
/**

View File

@ -760,13 +760,13 @@ class EntityRepo
$xPath = new DOMXPath($doc);
// Remove standard script tags
$scriptElems = $xPath->query('//body//*//script');
$scriptElems = $xPath->query('//script');
foreach ($scriptElems as $scriptElem) {
$scriptElem->parentNode->removeChild($scriptElem);
}
// Remove 'on*' attributes
$onAttributes = $xPath->query('//body//*/@*[starts-with(name(), \'on\')]');
$onAttributes = $xPath->query('//@*[starts-with(name(), \'on\')]');
foreach ($onAttributes as $attr) {
/** @var \DOMAttr $attr*/
$attrName = $attr->nodeName;

View File

@ -53,8 +53,8 @@ class LoginController extends Controller
$this->socialAuthService = $socialAuthService;
$this->ldapService = $ldapService;
$this->userRepo = $userRepo;
$this->redirectPath = baseUrl('/');
$this->redirectAfterLogout = baseUrl('/login');
$this->redirectPath = url('/');
$this->redirectAfterLogout = url('/login');
parent::__construct();
}
@ -106,9 +106,7 @@ class LoginController extends Controller
$this->ldapService->syncGroups($user, $request->get($this->username()));
}
$path = session()->pull('url.intended', '/');
$path = baseUrl($path, true);
return redirect($path);
return redirect()->intended('/');
}
/**

View File

@ -2,17 +2,23 @@
namespace BookStack\Http\Controllers\Auth;
use BookStack\Auth\Access\EmailConfirmationService;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Auth\SocialAccount;
use BookStack\Auth\User;
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\SocialDriverNotConfigured;
use BookStack\Exceptions\SocialSignInAccountNotUsed;
use BookStack\Exceptions\SocialSignInException;
use BookStack\Exceptions\UserRegistrationException;
use BookStack\Http\Controllers\Controller;
use Exception;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;
use Laravel\Socialite\Contracts\User as SocialUser;
use Validator;
@ -46,18 +52,18 @@ class RegisterController extends Controller
/**
* Create a new controller instance.
*
* @param \BookStack\Auth\Access\SocialAuthService $socialAuthService
* @param SocialAuthService $socialAuthService
* @param \BookStack\Auth\EmailConfirmationService $emailConfirmationService
* @param \BookStack\Auth\UserRepo $userRepo
* @param UserRepo $userRepo
*/
public function __construct(\BookStack\Auth\Access\SocialAuthService $socialAuthService, \BookStack\Auth\Access\EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
{
$this->middleware('guest')->only(['getRegister', 'postRegister', 'socialRegister']);
$this->socialAuthService = $socialAuthService;
$this->emailConfirmationService = $emailConfirmationService;
$this->userRepo = $userRepo;
$this->redirectTo = baseUrl('/');
$this->redirectPath = baseUrl('/');
$this->redirectTo = url('/');
$this->redirectPath = url('/');
parent::__construct();
}
@ -101,8 +107,8 @@ class RegisterController extends Controller
/**
* Handle a registration request for the application.
* @param Request|\Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @param Request|Request $request
* @return RedirectResponse|Redirector
* @throws UserRegistrationException
*/
public function postRegister(Request $request)
@ -117,7 +123,7 @@ class RegisterController extends Controller
/**
* Create a new user instance after a valid registration.
* @param array $data
* @return \BookStack\Auth\User
* @return User
*/
protected function create(array $data)
{
@ -133,7 +139,7 @@ class RegisterController extends Controller
* @param array $userData
* @param bool|false|SocialAccount $socialAccount
* @param bool $emailVerified
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @return RedirectResponse|Redirector
* @throws UserRegistrationException
*/
protected function registerUser(array $userData, $socialAccount = false, $emailVerified = false)
@ -182,7 +188,7 @@ class RegisterController extends Controller
/**
* Confirms an email via a token and logs the user into the system.
* @param $token
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @return RedirectResponse|Redirector
* @throws UserRegistrationException
*/
public function confirmEmail($token)
@ -200,7 +206,7 @@ class RegisterController extends Controller
/**
* Shows a notice that a user's email address has not been confirmed,
* Also has the option to re-send the confirmation email.
* @return \Illuminate\View\View
* @return View
*/
public function showAwaitingConfirmation()
{
@ -210,7 +216,7 @@ class RegisterController extends Controller
/**
* Resend the confirmation email
* @param Request $request
* @return \Illuminate\View\View
* @return View
*/
public function resendConfirmation(Request $request)
{
@ -235,7 +241,7 @@ class RegisterController extends Controller
* @param $socialDriver
* @return mixed
* @throws UserRegistrationException
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
* @throws SocialDriverNotConfigured
*/
public function socialRegister($socialDriver)
{
@ -248,10 +254,10 @@ class RegisterController extends Controller
* The callback for social login services.
* @param $socialDriver
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @return RedirectResponse|Redirector
* @throws SocialSignInException
* @throws UserRegistrationException
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
* @throws SocialDriverNotConfigured
*/
public function socialCallback($socialDriver, Request $request)
{
@ -292,7 +298,7 @@ class RegisterController extends Controller
/**
* Detach a social account from a user.
* @param $socialDriver
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @return RedirectResponse|Redirector
*/
public function detachSocialAccount($socialDriver)
{
@ -303,7 +309,7 @@ class RegisterController extends Controller
* Register a new user after a registration callback.
* @param string $socialDriver
* @param SocialUser $socialUser
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @return RedirectResponse|Redirector
* @throws UserRegistrationException
*/
protected function socialRegisterCallback(string $socialDriver, SocialUser $socialUser)

View File

@ -541,7 +541,7 @@ class PageController extends Controller
public function showRecentlyUpdated()
{
// TODO - Still exist?
$pages = $this->pageRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated'));
$pages = $this->pageRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(url('/pages/recently-updated'));
return view('pages.detailed-listing', [
'title' => trans('entities.recently_updated_pages'),
'pages' => $pages

View File

@ -48,7 +48,7 @@ class SearchController extends Controller
$this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
$page = intval($request->get('page', '0')) ?: 1;
$nextPageLink = baseUrl('/search?term=' . urlencode($searchTerm) . '&page=' . ($page+1));
$nextPageLink = url('/search?term=' . urlencode($searchTerm) . '&page=' . ($page+1));
$results = $this->searchService->searchEntities($searchTerm, 'all', $page, 20);

View File

@ -41,7 +41,7 @@ class Authenticate
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest(baseUrl('/login'));
return redirect()->guest(url('/login'));
}
}

26
app/Http/Request.php Normal file
View File

@ -0,0 +1,26 @@
<?php namespace BookStack\Http;
use Illuminate\Http\Request as LaravelRequest;
class Request extends LaravelRequest
{
/**
* Override the default request methods to get the scheme and host
* to set the custom APP_URL, if set.
* @return \Illuminate\Config\Repository|mixed|string
*/
public function getSchemeAndHttpHost()
{
$base = config('app.url', null);
if ($base) {
$base = trim($base, '/');
} else {
$base = $this->getScheme().'://'.$this->getHttpHost();
}
return $base;
}
}

View File

@ -26,6 +26,6 @@ class ConfirmEmail extends MailNotification
->subject(trans('auth.email_confirm_subject', $appName))
->greeting(trans('auth.email_confirm_greeting', $appName))
->line(trans('auth.email_confirm_text'))
->action(trans('auth.email_confirm_action'), baseUrl('/register/confirm/' . $this->token));
->action(trans('auth.email_confirm_action'), url('/register/confirm/' . $this->token));
}
}

View File

@ -29,7 +29,7 @@ class ResetPassword extends MailNotification
return $this->newMailMessage()
->subject(trans('auth.email_reset_subject', ['appName' => setting('app-name')]))
->line(trans('auth.email_reset_text'))
->action(trans('auth.reset_password'), baseUrl('password/reset/' . $this->token))
->action(trans('auth.reset_password'), url('password/reset/' . $this->token))
->line(trans('auth.email_reset_not_requested'));
}
}

View File

@ -12,6 +12,7 @@ use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Schema;
use URL;
use Validator;
class AppServiceProvider extends ServiceProvider
@ -23,6 +24,9 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
// Set root URL
URL::forceRootUrl(config('app.url'));
// Custom validation methods
Validator::extend('image_extension', function ($attribute, $value, $parameters, $validator) {
$validImageExtensions = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff', 'webp'];

View File

@ -18,7 +18,7 @@ class PaginationServiceProvider extends IlluminatePaginationServiceProvider
});
Paginator::currentPathResolver(function () {
return baseUrl($this->app['request']->path());
return url($this->app['request']->path());
});
Paginator::currentPageResolver(function ($pageName = 'page') {

View File

@ -37,6 +37,6 @@ class Attachment extends Ownable
if ($this->external && strpos($this->path, 'http') !== 0) {
return $this->path;
}
return baseUrl('/attachments/' . $this->id);
return url('/attachments/' . $this->id);
}
}

View File

@ -417,7 +417,7 @@ class ImageService extends UploadService
$isLocal = strpos(trim($uri), 'http') !== 0;
// Attempt to find local files even if url not absolute
$base = baseUrl('/');
$base = url('/');
if (!$isLocal && strpos($uri, $base) === 0) {
$isLocal = true;
$uri = str_replace($base, '', $uri);
@ -442,7 +442,12 @@ class ImageService extends UploadService
return null;
}
return 'data:image/' . pathinfo($uri, PATHINFO_EXTENSION) . ';base64,' . base64_encode($imageData);
$extension = pathinfo($uri, PATHINFO_EXTENSION);
if ($extension === 'svg') {
$extension = 'svg+xml';
}
return 'data:image/' . $extension . ';base64,' . base64_encode($imageData);
}
/**
@ -469,7 +474,7 @@ class ImageService extends UploadService
$this->storageUrl = $storageUrl;
}
$basePath = ($this->storageUrl == false) ? baseUrl('/') : $this->storageUrl;
$basePath = ($this->storageUrl == false) ? url('/') : $this->storageUrl;
return rtrim($basePath, '/') . $filePath;
}
}

View File

@ -1,8 +1,9 @@
<?php
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Entity;
use BookStack\Auth\User;
use BookStack\Ownable;
use BookStack\Settings\SettingService;
/**
* Get the path to a versioned file.
@ -11,7 +12,7 @@ use BookStack\Ownable;
* @return string
* @throws Exception
*/
function versioned_asset($file = '')
function versioned_asset($file = '') : string
{
static $version = null;
@ -26,17 +27,17 @@ function versioned_asset($file = '')
}
$path = $file . '?version=' . urlencode($version) . $additional;
return baseUrl($path);
return url($path);
}
/**
* Helper method to get the current User.
* Defaults to public 'Guest' user if not logged in.
* @return \BookStack\Auth\User
* @return User
*/
function user()
function user() : User
{
return auth()->user() ?: \BookStack\Auth\User::getDefault();
return auth()->user() ?: User::getDefault();
}
/**
@ -63,9 +64,9 @@ function hasAppAccess() : bool
* that particular item.
* @param string $permission
* @param Ownable $ownable
* @return mixed
* @return bool
*/
function userCan(string $permission, Ownable $ownable = null)
function userCan(string $permission, Ownable $ownable = null) : bool
{
if ($ownable === null) {
return user() && user()->can($permission);
@ -83,7 +84,7 @@ function userCan(string $permission, Ownable $ownable = null)
* @param string|null $entityClass
* @return bool
*/
function userCanOnAny(string $permission, string $entityClass = null)
function userCanOnAny(string $permission, string $entityClass = null) : bool
{
$permissionService = app(PermissionService::class);
return $permissionService->checkUserHasPermissionOnAnything($permission, $entityClass);
@ -93,83 +94,27 @@ function userCanOnAny(string $permission, string $entityClass = null)
* Helper to access system settings.
* @param $key
* @param bool $default
* @return bool|string|\BookStack\Settings\SettingService
* @return bool|string|SettingService
*/
function setting($key = null, $default = false)
{
$settingService = resolve(\BookStack\Settings\SettingService::class);
$settingService = resolve(SettingService::class);
if (is_null($key)) {
return $settingService;
}
return $settingService->get($key, $default);
}
/**
* Helper to create url's relative to the applications root path.
* @param string $path
* @param bool $forceAppDomain
* @return string
*/
function baseUrl($path, $forceAppDomain = false)
{
$isFullUrl = strpos($path, 'http') === 0;
if ($isFullUrl && !$forceAppDomain) {
return $path;
}
$path = trim($path, '/');
$base = rtrim(config('app.url'), '/');
// Remove non-specified domain if forced and we have a domain
if ($isFullUrl && $forceAppDomain) {
if (!empty($base) && strpos($path, $base) === 0) {
$path = mb_substr($path, mb_strlen($base));
} else {
$explodedPath = explode('/', $path);
$path = implode('/', array_splice($explodedPath, 3));
}
}
// Return normal url path if not specified in config
if (config('app.url') === '') {
return url($path);
}
return $base . '/' . ltrim($path, '/');
}
/**
* Get an instance of the redirector.
* Overrides the default laravel redirect helper.
* Ensures it redirects even when the app is in a subdirectory.
*
* @param string|null $to
* @param int $status
* @param array $headers
* @param bool $secure
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
*/
function redirect($to = null, $status = 302, $headers = [], $secure = null)
{
if (is_null($to)) {
return app('redirect');
}
$to = baseUrl($to);
return app('redirect')->to($to, $status, $headers, $secure);
}
/**
* Get a path to a theme resource.
* @param string $path
* @return string|boolean
* @return string
*/
function theme_path($path = '')
function theme_path($path = '') : string
{
$theme = config('view.theme');
if (!$theme) {
return false;
return '';
}
return base_path('themes/' . $theme .($path ? DIRECTORY_SEPARATOR.$path : $path));
@ -241,5 +186,5 @@ function sortUrl($path, $data, $overrideData = [])
return $path;
}
return baseUrl($path . '?' . implode('&', $queryStringSections));
return url($path . '?' . implode('&', $queryStringSections));
}