Merge branch 'master' into release
This commit is contained in:
commit
d7adcf6c69
|
@ -48,6 +48,7 @@ GITHUB_APP_ID=false
|
||||||
GITHUB_APP_SECRET=false
|
GITHUB_APP_SECRET=false
|
||||||
GOOGLE_APP_ID=false
|
GOOGLE_APP_ID=false
|
||||||
GOOGLE_APP_SECRET=false
|
GOOGLE_APP_SECRET=false
|
||||||
|
GOOGLE_SELECT_ACCOUNT=false
|
||||||
OKTA_BASE_URL=false
|
OKTA_BASE_URL=false
|
||||||
OKTA_APP_ID=false
|
OKTA_APP_ID=false
|
||||||
OKTA_APP_SECRET=false
|
OKTA_APP_SECRET=false
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace BookStack;
|
namespace BookStack\Actions;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property string key
|
* @property string key
|
|
@ -1,7 +1,7 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
use BookStack\Activity;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Entity;
|
use BookStack\Entities\Entity;
|
||||||
use Session;
|
use Session;
|
||||||
|
|
||||||
class ActivityService
|
class ActivityService
|
||||||
|
@ -12,7 +12,7 @@ class ActivityService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityService constructor.
|
* ActivityService constructor.
|
||||||
* @param Activity $activity
|
* @param \BookStack\Actions\Activity $activity
|
||||||
* @param PermissionService $permissionService
|
* @param PermissionService $permissionService
|
||||||
*/
|
*/
|
||||||
public function __construct(Activity $activity, PermissionService $permissionService)
|
public function __construct(Activity $activity, PermissionService $permissionService)
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
|
use BookStack\Ownable;
|
||||||
|
|
||||||
class Comment extends Ownable
|
class Comment extends Ownable
|
||||||
{
|
{
|
|
@ -1,7 +1,6 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
use BookStack\Comment;
|
use BookStack\Entities\Entity;
|
||||||
use BookStack\Entity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CommentRepo
|
* Class CommentRepo
|
||||||
|
@ -11,13 +10,13 @@ class CommentRepo
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Comment $comment
|
* @var \BookStack\Actions\Comment $comment
|
||||||
*/
|
*/
|
||||||
protected $comment;
|
protected $comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommentRepo constructor.
|
* CommentRepo constructor.
|
||||||
* @param Comment $comment
|
* @param \BookStack\Actions\Comment $comment
|
||||||
*/
|
*/
|
||||||
public function __construct(Comment $comment)
|
public function __construct(Comment $comment)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +26,7 @@ class CommentRepo
|
||||||
/**
|
/**
|
||||||
* Get a comment by ID.
|
* Get a comment by ID.
|
||||||
* @param $id
|
* @param $id
|
||||||
* @return Comment|\Illuminate\Database\Eloquent\Model
|
* @return \BookStack\Actions\Comment|\Illuminate\Database\Eloquent\Model
|
||||||
*/
|
*/
|
||||||
public function getById($id)
|
public function getById($id)
|
||||||
{
|
{
|
||||||
|
@ -36,9 +35,9 @@ class CommentRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new comment on an entity.
|
* Create a new comment on an entity.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return Comment
|
* @return \BookStack\Actions\Comment
|
||||||
*/
|
*/
|
||||||
public function create(Entity $entity, $data = [])
|
public function create(Entity $entity, $data = [])
|
||||||
{
|
{
|
||||||
|
@ -53,7 +52,7 @@ class CommentRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an existing comment.
|
* Update an existing comment.
|
||||||
* @param Comment $comment
|
* @param \BookStack\Actions\Comment $comment
|
||||||
* @param array $input
|
* @param array $input
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +65,7 @@ class CommentRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a comment from the system.
|
* Delete a comment from the system.
|
||||||
* @param Comment $comment
|
* @param \BookStack\Actions\Comment $comment
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function delete($comment)
|
public function delete($comment)
|
||||||
|
@ -76,7 +75,7 @@ class CommentRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next local ID relative to the linked entity.
|
* Get the next local ID relative to the linked entity.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function getNextLocalId(Entity $entity)
|
protected function getNextLocalId(Entity $entity)
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Attribute
|
* Class Attribute
|
|
@ -1,8 +1,7 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
use BookStack\Tag;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Entity;
|
use BookStack\Entities\Entity;
|
||||||
use BookStack\Services\PermissionService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TagRepo
|
* Class TagRepo
|
||||||
|
@ -17,9 +16,9 @@ class TagRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TagRepo constructor.
|
* TagRepo constructor.
|
||||||
* @param Tag $attr
|
* @param \BookStack\Actions\Tag $attr
|
||||||
* @param Entity $ent
|
* @param \BookStack\Entities\Entity $ent
|
||||||
* @param PermissionService $ps
|
* @param \BookStack\Auth\Permissions\PermissionService $ps
|
||||||
*/
|
*/
|
||||||
public function __construct(Tag $attr, Entity $ent, PermissionService $ps)
|
public function __construct(Tag $attr, Entity $ent, PermissionService $ps)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +106,7 @@ class TagRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save an array of tags to an entity
|
* Save an array of tags to an entity
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @param array $tags
|
* @param array $tags
|
||||||
* @return array|\Illuminate\Database\Eloquent\Collection
|
* @return array|\Illuminate\Database\Eloquent\Collection
|
||||||
*/
|
*/
|
||||||
|
@ -128,7 +127,7 @@ class TagRepo
|
||||||
/**
|
/**
|
||||||
* Create a new Tag instance from user input.
|
* Create a new Tag instance from user input.
|
||||||
* @param $input
|
* @param $input
|
||||||
* @return Tag
|
* @return \BookStack\Actions\Tag
|
||||||
*/
|
*/
|
||||||
protected function newInstanceFromInput($input)
|
protected function newInstanceFromInput($input)
|
||||||
{
|
{
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class View extends Model
|
class View extends Model
|
||||||
{
|
{
|
|
@ -1,7 +1,7 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Actions;
|
||||||
|
|
||||||
use BookStack\Entity;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\View;
|
use BookStack\Entities\Entity;
|
||||||
|
|
||||||
class ViewService
|
class ViewService
|
||||||
{
|
{
|
||||||
|
@ -10,8 +10,8 @@ class ViewService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ViewService constructor.
|
* ViewService constructor.
|
||||||
* @param View $view
|
* @param \BookStack\Actions\View $view
|
||||||
* @param PermissionService $permissionService
|
* @param \BookStack\Auth\Permissions\PermissionService $permissionService
|
||||||
*/
|
*/
|
||||||
public function __construct(View $view, PermissionService $permissionService)
|
public function __construct(View $view, PermissionService $permissionService)
|
||||||
{
|
{
|
||||||
|
@ -50,12 +50,13 @@ class ViewService
|
||||||
* Get the entities with the most views.
|
* Get the entities with the most views.
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @param int $page
|
* @param int $page
|
||||||
* @param bool|false|array $filterModel
|
* @param Entity|false|array $filterModel
|
||||||
* @param string $action - used for permission checking
|
* @param string $action - used for permission checking
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public function getPopular($count = 10, $page = 0, $filterModel = false, $action = 'view')
|
public function getPopular($count = 10, $page = 0, $filterModel = false, $action = 'view')
|
||||||
{
|
{
|
||||||
|
// TODO - Standardise input filter
|
||||||
$skipCount = $count * $page;
|
$skipCount = $count * $page;
|
||||||
$query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
|
$query = $this->permissionService->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type', $action)
|
||||||
->select('*', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
|
->select('*', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
|
||||||
|
@ -65,7 +66,7 @@ class ViewService
|
||||||
if ($filterModel && is_array($filterModel)) {
|
if ($filterModel && is_array($filterModel)) {
|
||||||
$query->whereIn('viewable_type', $filterModel);
|
$query->whereIn('viewable_type', $filterModel);
|
||||||
} else if ($filterModel) {
|
} else if ($filterModel) {
|
||||||
$query->where('viewable_type', '=', get_class($filterModel));
|
$query->where('viewable_type', '=', $filterModel->getMorphClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
|
return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
|
||||||
|
@ -89,7 +90,7 @@ class ViewService
|
||||||
->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
|
->filterRestrictedEntityRelations($this->view, 'views', 'viewable_id', 'viewable_type');
|
||||||
|
|
||||||
if ($filterModel) {
|
if ($filterModel) {
|
||||||
$query = $query->where('viewable_type', '=', get_class($filterModel));
|
$query = $query->where('viewable_type', '=', $filterModel->getMorphClass());
|
||||||
}
|
}
|
||||||
$query = $query->where('user_id', '=', $user->id);
|
$query = $query->where('user_id', '=', $user->id);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Auth\Access;
|
||||||
|
|
||||||
use BookStack\Notifications\ConfirmEmail;
|
use BookStack\Auth\User;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Auth\UserRepo;
|
||||||
use Carbon\Carbon;
|
|
||||||
use BookStack\Exceptions\ConfirmationEmailException;
|
use BookStack\Exceptions\ConfirmationEmailException;
|
||||||
use BookStack\Exceptions\UserRegistrationException;
|
use BookStack\Exceptions\UserRegistrationException;
|
||||||
use BookStack\User;
|
use BookStack\Notifications\ConfirmEmail;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Connection as Database;
|
use Illuminate\Database\Connection as Database;
|
||||||
|
|
||||||
class EmailConfirmationService
|
class EmailConfirmationService
|
||||||
|
@ -16,7 +16,7 @@ class EmailConfirmationService
|
||||||
/**
|
/**
|
||||||
* EmailConfirmationService constructor.
|
* EmailConfirmationService constructor.
|
||||||
* @param Database $db
|
* @param Database $db
|
||||||
* @param UserRepo $users
|
* @param \BookStack\Auth\UserRepo $users
|
||||||
*/
|
*/
|
||||||
public function __construct(Database $db, UserRepo $users)
|
public function __construct(Database $db, UserRepo $users)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ class EmailConfirmationService
|
||||||
/**
|
/**
|
||||||
* Create new confirmation for a user,
|
* Create new confirmation for a user,
|
||||||
* Also removes any existing old ones.
|
* Also removes any existing old ones.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @throws ConfirmationEmailException
|
* @throws ConfirmationEmailException
|
||||||
*/
|
*/
|
||||||
public function sendConfirmation(User $user)
|
public function sendConfirmation(User $user)
|
||||||
|
@ -88,7 +88,7 @@ class EmailConfirmationService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all email confirmations that belong to a user.
|
* Delete all email confirmations that belong to a user.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function deleteConfirmationsByUser(User $user)
|
public function deleteConfirmationsByUser(User $user)
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Auth\Access;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Ldap
|
* Class Ldap
|
|
@ -1,9 +1,10 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Auth\Access;
|
||||||
|
|
||||||
|
use BookStack\Auth\Access;
|
||||||
|
use BookStack\Auth\Role;
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Exceptions\LdapException;
|
use BookStack\Exceptions\LdapException;
|
||||||
use BookStack\Repos\UserRepo;
|
|
||||||
use BookStack\Role;
|
|
||||||
use BookStack\User;
|
|
||||||
use Illuminate\Contracts\Auth\Authenticatable;
|
use Illuminate\Contracts\Auth\Authenticatable;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
@ -24,9 +25,9 @@ class LdapService
|
||||||
/**
|
/**
|
||||||
* LdapService constructor.
|
* LdapService constructor.
|
||||||
* @param Ldap $ldap
|
* @param Ldap $ldap
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(Ldap $ldap, UserRepo $userRepo)
|
public function __construct(Access\Ldap $ldap, UserRepo $userRepo)
|
||||||
{
|
{
|
||||||
$this->ldap = $ldap;
|
$this->ldap = $ldap;
|
||||||
$this->config = config('services.ldap');
|
$this->config = config('services.ldap');
|
||||||
|
@ -298,7 +299,7 @@ class LdapService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync the LDAP groups to the user roles for the current user
|
* Sync the LDAP groups to the user roles for the current user
|
||||||
* @param \BookStack\User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param string $username
|
* @param string $username
|
||||||
* @throws LdapException
|
* @throws LdapException
|
||||||
*/
|
*/
|
||||||
|
@ -347,7 +348,7 @@ class LdapService
|
||||||
/**
|
/**
|
||||||
* Check a role against an array of group names to see if it matches.
|
* Check a role against an array of group names to see if it matches.
|
||||||
* Checked against role 'external_auth_id' if set otherwise the name of the role.
|
* Checked against role 'external_auth_id' if set otherwise the name of the role.
|
||||||
* @param Role $role
|
* @param \BookStack\Auth\Role $role
|
||||||
* @param array $groupNames
|
* @param array $groupNames
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
|
@ -1,11 +1,11 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Auth\Access;
|
||||||
|
|
||||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
use BookStack\Auth\SocialAccount;
|
||||||
use Laravel\Socialite\Contracts\Factory as Socialite;
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Exceptions\SocialDriverNotConfigured;
|
use BookStack\Exceptions\SocialDriverNotConfigured;
|
||||||
|
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
||||||
use BookStack\Exceptions\UserRegistrationException;
|
use BookStack\Exceptions\UserRegistrationException;
|
||||||
use BookStack\Repos\UserRepo;
|
use Laravel\Socialite\Contracts\Factory as Socialite;
|
||||||
use BookStack\SocialAccount;
|
|
||||||
use Laravel\Socialite\Contracts\User as SocialUser;
|
use Laravel\Socialite\Contracts\User as SocialUser;
|
||||||
|
|
||||||
class SocialAuthService
|
class SocialAuthService
|
||||||
|
@ -19,7 +19,7 @@ class SocialAuthService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SocialAuthService constructor.
|
* SocialAuthService constructor.
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
* @param Socialite $socialite
|
* @param Socialite $socialite
|
||||||
* @param SocialAccount $socialAccount
|
* @param SocialAccount $socialAccount
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +40,7 @@ class SocialAuthService
|
||||||
public function startLogIn($socialDriver)
|
public function startLogIn($socialDriver)
|
||||||
{
|
{
|
||||||
$driver = $this->validateDriver($socialDriver);
|
$driver = $this->validateDriver($socialDriver);
|
||||||
return $this->socialite->driver($driver)->redirect();
|
return $this->getSocialDriver($driver)->redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +52,7 @@ class SocialAuthService
|
||||||
public function startRegister($socialDriver)
|
public function startRegister($socialDriver)
|
||||||
{
|
{
|
||||||
$driver = $this->validateDriver($socialDriver);
|
$driver = $this->validateDriver($socialDriver);
|
||||||
return $this->socialite->driver($driver)->redirect();
|
return $this->getSocialDriver($driver)->redirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -247,4 +247,20 @@ 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide redirect options per service for the Laravel Socialite driver
|
||||||
|
* @param $driverName
|
||||||
|
* @return \Laravel\Socialite\Contracts\Provider
|
||||||
|
*/
|
||||||
|
public function getSocialDriver(string $driverName)
|
||||||
|
{
|
||||||
|
$driver = $this->socialite->driver($driverName);
|
||||||
|
|
||||||
|
if ($driverName === 'google' && config('services.google.select_account')) {
|
||||||
|
$driver->with(['prompt' => 'select_account']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $driver;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth\Permissions;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class EntityPermission extends Model
|
class EntityPermission extends Model
|
||||||
{
|
{
|
|
@ -1,4 +1,8 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth\Permissions;
|
||||||
|
|
||||||
|
use BookStack\Auth\Role;
|
||||||
|
use BookStack\Entities\Entity;
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class JointPermission extends Model
|
class JointPermission extends Model
|
||||||
{
|
{
|
|
@ -1,15 +1,14 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Auth\Permissions;
|
||||||
|
|
||||||
use BookStack\Book;
|
use BookStack\Auth\Permissions;
|
||||||
use BookStack\Bookshelf;
|
use BookStack\Auth\Role;
|
||||||
use BookStack\Chapter;
|
use BookStack\Entities\Book;
|
||||||
use BookStack\Entity;
|
use BookStack\Entities\Bookshelf;
|
||||||
use BookStack\EntityPermission;
|
use BookStack\Entities\Chapter;
|
||||||
use BookStack\JointPermission;
|
use BookStack\Entities\Entity;
|
||||||
|
use BookStack\Entities\EntityProvider;
|
||||||
|
use BookStack\Entities\Page;
|
||||||
use BookStack\Ownable;
|
use BookStack\Ownable;
|
||||||
use BookStack\Page;
|
|
||||||
use BookStack\Role;
|
|
||||||
use BookStack\User;
|
|
||||||
use Illuminate\Database\Connection;
|
use Illuminate\Database\Connection;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||||
|
@ -23,17 +22,31 @@ class PermissionService
|
||||||
protected $userRoles = false;
|
protected $userRoles = false;
|
||||||
protected $currentUserModel = false;
|
protected $currentUserModel = false;
|
||||||
|
|
||||||
public $book;
|
/**
|
||||||
public $chapter;
|
* @var Connection
|
||||||
public $page;
|
*/
|
||||||
public $bookshelf;
|
|
||||||
|
|
||||||
protected $db;
|
protected $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JointPermission
|
||||||
|
*/
|
||||||
protected $jointPermission;
|
protected $jointPermission;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Role
|
||||||
|
*/
|
||||||
protected $role;
|
protected $role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EntityPermission
|
||||||
|
*/
|
||||||
protected $entityPermission;
|
protected $entityPermission;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EntityProvider
|
||||||
|
*/
|
||||||
|
protected $entityProvider;
|
||||||
|
|
||||||
protected $entityCache;
|
protected $entityCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,29 +55,20 @@ class PermissionService
|
||||||
* @param EntityPermission $entityPermission
|
* @param EntityPermission $entityPermission
|
||||||
* @param Role $role
|
* @param Role $role
|
||||||
* @param Connection $db
|
* @param Connection $db
|
||||||
* @param Bookshelf $bookshelf
|
* @param EntityProvider $entityProvider
|
||||||
* @param Book $book
|
|
||||||
* @param Chapter $chapter
|
|
||||||
* @param Page $page
|
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
JointPermission $jointPermission,
|
JointPermission $jointPermission,
|
||||||
EntityPermission $entityPermission,
|
Permissions\EntityPermission $entityPermission,
|
||||||
Role $role,
|
Role $role,
|
||||||
Connection $db,
|
Connection $db,
|
||||||
Bookshelf $bookshelf,
|
EntityProvider $entityProvider
|
||||||
Book $book,
|
|
||||||
Chapter $chapter,
|
|
||||||
Page $page
|
|
||||||
) {
|
) {
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->jointPermission = $jointPermission;
|
$this->jointPermission = $jointPermission;
|
||||||
$this->entityPermission = $entityPermission;
|
$this->entityPermission = $entityPermission;
|
||||||
$this->role = $role;
|
$this->role = $role;
|
||||||
$this->bookshelf = $bookshelf;
|
$this->entityProvider = $entityProvider;
|
||||||
$this->book = $book;
|
|
||||||
$this->chapter = $chapter;
|
|
||||||
$this->page = $page;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,7 +82,7 @@ class PermissionService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the local entity cache and ensure it's empty
|
* Prepare the local entity cache and ensure it's empty
|
||||||
* @param Entity[] $entities
|
* @param \BookStack\Entities\Entity[] $entities
|
||||||
*/
|
*/
|
||||||
protected function readyEntityCache($entities = [])
|
protected function readyEntityCache($entities = [])
|
||||||
{
|
{
|
||||||
|
@ -104,7 +108,7 @@ class PermissionService
|
||||||
return $this->entityCache['book']->get($bookId);
|
return $this->entityCache['book']->get($bookId);
|
||||||
}
|
}
|
||||||
|
|
||||||
$book = $this->book->find($bookId);
|
$book = $this->entityProvider->book->find($bookId);
|
||||||
if ($book === null) {
|
if ($book === null) {
|
||||||
$book = false;
|
$book = false;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +119,7 @@ class PermissionService
|
||||||
/**
|
/**
|
||||||
* Get a chapter via ID, Checks local cache
|
* Get a chapter via ID, Checks local cache
|
||||||
* @param $chapterId
|
* @param $chapterId
|
||||||
* @return Book
|
* @return \BookStack\Entities\Book
|
||||||
*/
|
*/
|
||||||
protected function getChapter($chapterId)
|
protected function getChapter($chapterId)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +127,7 @@ class PermissionService
|
||||||
return $this->entityCache['chapter']->get($chapterId);
|
return $this->entityCache['chapter']->get($chapterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
$chapter = $this->chapter->find($chapterId);
|
$chapter = $this->entityProvider->chapter->find($chapterId);
|
||||||
if ($chapter === null) {
|
if ($chapter === null) {
|
||||||
$chapter = false;
|
$chapter = false;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +176,7 @@ class PermissionService
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all bookshelves
|
// Chunk through all bookshelves
|
||||||
$this->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
$this->entityProvider->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
||||||
->chunk(50, function ($shelves) use ($roles) {
|
->chunk(50, function ($shelves) use ($roles) {
|
||||||
$this->buildJointPermissionsForShelves($shelves, $roles);
|
$this->buildJointPermissionsForShelves($shelves, $roles);
|
||||||
});
|
});
|
||||||
|
@ -184,7 +188,8 @@ class PermissionService
|
||||||
*/
|
*/
|
||||||
protected function bookFetchQuery()
|
protected function bookFetchQuery()
|
||||||
{
|
{
|
||||||
return $this->book->newQuery()->select(['id', 'restricted', 'created_by'])->with(['chapters' => function ($query) {
|
return $this->entityProvider->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']);
|
||||||
|
@ -234,7 +239,7 @@ class PermissionService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild the entity jointPermissions for a particular entity.
|
* Rebuild the entity jointPermissions for a particular entity.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function buildJointPermissionsForEntity(Entity $entity)
|
public function buildJointPermissionsForEntity(Entity $entity)
|
||||||
|
@ -290,7 +295,7 @@ class PermissionService
|
||||||
});
|
});
|
||||||
|
|
||||||
// Chunk through all bookshelves
|
// Chunk through all bookshelves
|
||||||
$this->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
$this->entityProvider->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
||||||
->chunk(50, function ($shelves) use ($roles) {
|
->chunk(50, function ($shelves) use ($roles) {
|
||||||
$this->buildJointPermissionsForShelves($shelves, $roles);
|
$this->buildJointPermissionsForShelves($shelves, $roles);
|
||||||
});
|
});
|
||||||
|
@ -329,7 +334,7 @@ class PermissionService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all of the entity jointPermissions for a list of entities.
|
* Delete all of the entity jointPermissions for a list of entities.
|
||||||
* @param Entity[] $entities
|
* @param \BookStack\Entities\Entity[] $entities
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function deleteManyJointPermissionsForEntities($entities)
|
protected function deleteManyJointPermissionsForEntities($entities)
|
||||||
|
@ -410,7 +415,7 @@ class PermissionService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the actions related to an entity.
|
* Get the actions related to an entity.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getActions(Entity $entity)
|
protected function getActions(Entity $entity)
|
||||||
|
@ -496,7 +501,7 @@ class PermissionService
|
||||||
/**
|
/**
|
||||||
* Create an array of data with the information of an entity jointPermissions.
|
* Create an array of data with the information of an entity jointPermissions.
|
||||||
* Used to build data for bulk insertion.
|
* Used to build data for bulk insertion.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @param Role $role
|
* @param Role $role
|
||||||
* @param $action
|
* @param $action
|
||||||
* @param $permissionAll
|
* @param $permissionAll
|
||||||
|
@ -554,7 +559,7 @@ class PermissionService
|
||||||
/**
|
/**
|
||||||
* Check if an entity has restrictions set on itself or its
|
* Check if an entity has restrictions set on itself or its
|
||||||
* parent tree.
|
* parent tree.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @param $action
|
* @param $action
|
||||||
* @return bool|mixed
|
* @return bool|mixed
|
||||||
*/
|
*/
|
||||||
|
@ -604,7 +609,9 @@ class PermissionService
|
||||||
*/
|
*/
|
||||||
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) {
|
$entities = $this->entityProvider;
|
||||||
|
$pageSelect = $this->db->table('pages')->selectRaw($entities->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) {
|
||||||
|
@ -612,7 +619,7 @@ class PermissionService
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$chapterSelect = $this->db->table('chapters')->selectRaw($this->chapter->entityRawQuery())->where('book_id', '=', $book_id);
|
$chapterSelect = $this->db->table('chapters')->selectRaw($entities->chapter->entityRawQuery())->where('book_id', '=', $book_id);
|
||||||
$query = $this->db->query()->select('*')->from($this->db->raw("({$pageSelect->toSql()} UNION {$chapterSelect->toSql()}) AS U"))
|
$query = $this->db->query()->select('*')->from($this->db->raw("({$pageSelect->toSql()} UNION {$chapterSelect->toSql()}) AS U"))
|
||||||
->mergeBindings($pageSelect)->mergeBindings($chapterSelect);
|
->mergeBindings($pageSelect)->mergeBindings($chapterSelect);
|
||||||
|
|
||||||
|
@ -635,7 +642,7 @@ class PermissionService
|
||||||
/**
|
/**
|
||||||
* Add restrictions for a generic entity
|
* Add restrictions for a generic entity
|
||||||
* @param string $entityType
|
* @param string $entityType
|
||||||
* @param Builder|Entity $query
|
* @param Builder|\BookStack\Entities\Entity $query
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @return Builder
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
|
@ -703,12 +710,13 @@ class PermissionService
|
||||||
$this->currentAction = 'view';
|
$this->currentAction = 'view';
|
||||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
|
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
|
||||||
|
|
||||||
$q = $query->where(function ($query) use ($tableDetails) {
|
$pageMorphClass = $this->entityProvider->page->getMorphClass();
|
||||||
$query->where(function ($query) use (&$tableDetails) {
|
$q = $query->where(function ($query) use ($tableDetails, $pageMorphClass) {
|
||||||
$query->whereExists(function ($permissionQuery) use (&$tableDetails) {
|
$query->where(function ($query) use (&$tableDetails, $pageMorphClass) {
|
||||||
|
$query->whereExists(function ($permissionQuery) use (&$tableDetails, $pageMorphClass) {
|
||||||
$permissionQuery->select('id')->from('joint_permissions')
|
$permissionQuery->select('id')->from('joint_permissions')
|
||||||
->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
->whereRaw('joint_permissions.entity_id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
|
||||||
->where('entity_type', '=', 'Bookstack\\Page')
|
->where('entity_type', '=', $pageMorphClass)
|
||||||
->where('action', '=', $this->currentAction)
|
->where('action', '=', $this->currentAction)
|
||||||
->whereIn('role_id', $this->getRoles())
|
->whereIn('role_id', $this->getRoles())
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
|
@ -726,7 +734,7 @@ class PermissionService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current user
|
* Get the current user
|
||||||
* @return User
|
* @return \BookStack\Auth\User
|
||||||
*/
|
*/
|
||||||
private function currentUser()
|
private function currentUser()
|
||||||
{
|
{
|
|
@ -1,10 +1,8 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Auth\Permissions;
|
||||||
|
|
||||||
|
use BookStack\Auth\Permissions;
|
||||||
|
use BookStack\Auth\Role;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\RolePermission;
|
|
||||||
use BookStack\Role;
|
|
||||||
use BookStack\Services\PermissionService;
|
|
||||||
use Setting;
|
|
||||||
|
|
||||||
class PermissionsRepo
|
class PermissionsRepo
|
||||||
{
|
{
|
||||||
|
@ -19,9 +17,9 @@ class PermissionsRepo
|
||||||
* PermissionsRepo constructor.
|
* PermissionsRepo constructor.
|
||||||
* @param RolePermission $permission
|
* @param RolePermission $permission
|
||||||
* @param Role $role
|
* @param Role $role
|
||||||
* @param PermissionService $permissionService
|
* @param \BookStack\Auth\Permissions\PermissionService $permissionService
|
||||||
*/
|
*/
|
||||||
public function __construct(RolePermission $permission, Role $role, PermissionService $permissionService)
|
public function __construct(RolePermission $permission, Role $role, Permissions\PermissionService $permissionService)
|
||||||
{
|
{
|
||||||
$this->permission = $permission;
|
$this->permission = $permission;
|
||||||
$this->role = $role;
|
$this->role = $role;
|
|
@ -1,4 +1,7 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth\Permissions;
|
||||||
|
|
||||||
|
use BookStack\Auth\Role;
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class RolePermission extends Model
|
class RolePermission extends Model
|
||||||
{
|
{
|
|
@ -1,4 +1,7 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth;
|
||||||
|
|
||||||
|
use BookStack\Auth\Permissions\JointPermission;
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class Role extends Model
|
class Role extends Model
|
||||||
{
|
{
|
||||||
|
@ -27,7 +30,7 @@ class Role extends Model
|
||||||
*/
|
*/
|
||||||
public function permissions()
|
public function permissions()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(RolePermission::class, 'permission_role', 'role_id', 'permission_id');
|
return $this->belongsToMany(Permissions\RolePermission::class, 'permission_role', 'role_id', 'permission_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,18 +51,18 @@ class Role extends Model
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a permission to this role.
|
* Add a permission to this role.
|
||||||
* @param RolePermission $permission
|
* @param \BookStack\Auth\Permissions\RolePermission $permission
|
||||||
*/
|
*/
|
||||||
public function attachPermission(RolePermission $permission)
|
public function attachPermission(Permissions\RolePermission $permission)
|
||||||
{
|
{
|
||||||
$this->permissions()->attach($permission->id);
|
$this->permissions()->attach($permission->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detach a single permission from this role.
|
* Detach a single permission from this role.
|
||||||
* @param RolePermission $permission
|
* @param \BookStack\Auth\Permissions\RolePermission $permission
|
||||||
*/
|
*/
|
||||||
public function detachPermission(RolePermission $permission)
|
public function detachPermission(Permissions\RolePermission $permission)
|
||||||
{
|
{
|
||||||
$this->permissions()->detach($permission->id);
|
$this->permissions()->detach($permission->id);
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class SocialAccount extends Model
|
class SocialAccount extends Model
|
||||||
{
|
{
|
|
@ -1,6 +1,8 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Auth;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
use BookStack\Notifications\ResetPassword;
|
use BookStack\Notifications\ResetPassword;
|
||||||
|
use BookStack\Uploads\Image;
|
||||||
use Illuminate\Auth\Authenticatable;
|
use Illuminate\Auth\Authenticatable;
|
||||||
use Illuminate\Auth\Passwords\CanResetPassword;
|
use Illuminate\Auth\Passwords\CanResetPassword;
|
||||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
|
@ -1,10 +1,9 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Auth;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Image;
|
use BookStack\Uploads\Image;
|
||||||
use BookStack\Role;
|
|
||||||
use BookStack\User;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Images;
|
use Images;
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ class UserRepo
|
||||||
* Creates a new user and attaches a role to them.
|
* Creates a new user and attaches a role to them.
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param boolean $verifyEmail
|
* @param boolean $verifyEmail
|
||||||
* @return User
|
* @return \BookStack\Auth\User
|
||||||
*/
|
*/
|
||||||
public function registerNew(array $data, $verifyEmail = false)
|
public function registerNew(array $data, $verifyEmail = false)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +121,7 @@ class UserRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the give user is the only admin.
|
* Checks if the give user is the only admin.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isOnlyAdmin(User $user)
|
public function isOnlyAdmin(User $user)
|
||||||
|
@ -142,7 +141,7 @@ class UserRepo
|
||||||
* Create a new basic instance of user.
|
* Create a new basic instance of user.
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param boolean $verifyEmail
|
* @param boolean $verifyEmail
|
||||||
* @return User
|
* @return \BookStack\Auth\User
|
||||||
*/
|
*/
|
||||||
public function create(array $data, $verifyEmail = false)
|
public function create(array $data, $verifyEmail = false)
|
||||||
{
|
{
|
||||||
|
@ -157,7 +156,7 @@ class UserRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given user from storage, Delete all related content.
|
* Remove the given user from storage, Delete all related content.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function destroy(User $user)
|
public function destroy(User $user)
|
||||||
|
@ -174,7 +173,7 @@ class UserRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the latest activity for a user.
|
* Get the latest activity for a user.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @param int $page
|
* @param int $page
|
||||||
* @return array
|
* @return array
|
||||||
|
@ -186,7 +185,7 @@ class UserRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the recently created content for this given user.
|
* Get the recently created content for this given user.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
@ -207,15 +206,15 @@ class UserRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get asset created counts for the give user.
|
* Get asset created counts for the give user.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getAssetCounts(User $user)
|
public function getAssetCounts(User $user)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'pages' => $this->entityRepo->page->where('created_by', '=', $user->id)->count(),
|
'pages' => $this->entityRepo->getUserTotalCreated('page', $user),
|
||||||
'chapters' => $this->entityRepo->chapter->where('created_by', '=', $user->id)->count(),
|
'chapters' => $this->entityRepo->getUserTotalCreated('chapter', $user),
|
||||||
'books' => $this->entityRepo->book->where('created_by', '=', $user->id)->count(),
|
'books' => $this->entityRepo->getUserTotalCreated('book', $user),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\Services\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class CleanupImages extends Command
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
* @param ImageService $imageService
|
* @param \BookStack\Uploads\ImageService $imageService
|
||||||
*/
|
*/
|
||||||
public function __construct(ImageService $imageService)
|
public function __construct(ImageService $imageService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\Activity;
|
use BookStack\Actions\Activity;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class ClearActivity extends Command
|
class ClearActivity extends Command
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\PageRevision;
|
use BookStack\Entities\PageRevision;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class ClearRevisions extends Command
|
class ClearRevisions extends Command
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Auth\UserRepo;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class CreateAdmin extends Command
|
class CreateAdmin extends Command
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\User;
|
use BookStack\Auth\User;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Auth\UserRepo;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class DeleteUsers extends Command
|
class DeleteUsers extends Command
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\Services\PermissionService;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class RegeneratePermissions extends Command
|
class RegeneratePermissions extends Command
|
||||||
|
@ -31,7 +31,7 @@ class RegeneratePermissions extends Command
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
*
|
*
|
||||||
* @param PermissionService $permissionService
|
* @param \BookStack\Auth\\BookStack\Auth\Permissions\PermissionService $permissionService
|
||||||
*/
|
*/
|
||||||
public function __construct(PermissionService $permissionService)
|
public function __construct(PermissionService $permissionService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Console\Commands;
|
namespace BookStack\Console\Commands;
|
||||||
|
|
||||||
use BookStack\Services\SearchService;
|
use BookStack\Entities\SearchService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
class RegenerateSearch extends Command
|
class RegenerateSearch extends Command
|
||||||
|
@ -26,7 +26,7 @@ class RegenerateSearch extends Command
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
*
|
*
|
||||||
* @param SearchService $searchService
|
* @param \BookStack\Entities\SearchService $searchService
|
||||||
*/
|
*/
|
||||||
public function __construct(SearchService $searchService)
|
public function __construct(SearchService $searchService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Uploads\Image;
|
||||||
|
|
||||||
class Book extends Entity
|
class Book extends Entity
|
||||||
{
|
{
|
||||||
|
@ -6,6 +8,15 @@ class Book extends Entity
|
||||||
|
|
||||||
protected $fillable = ['name', 'description', 'image_id'];
|
protected $fillable = ['name', 'description', 'image_id'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the morph class for this model.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMorphClass()
|
||||||
|
{
|
||||||
|
return 'BookStack\\Book';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the url for this book.
|
* Get the url for this book.
|
||||||
* @param string|bool $path
|
* @param string|bool $path
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Uploads\Image;
|
||||||
|
|
||||||
class Bookshelf extends Entity
|
class Bookshelf extends Entity
|
||||||
{
|
{
|
||||||
|
@ -8,6 +10,15 @@ class Bookshelf extends Entity
|
||||||
|
|
||||||
protected $fillable = ['name', 'description', 'image_id'];
|
protected $fillable = ['name', 'description', 'image_id'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the morph class for this model.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMorphClass()
|
||||||
|
{
|
||||||
|
return 'BookStack\\Bookshelf';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the books in this shelf.
|
* Get the books in this shelf.
|
||||||
* Should not be used directly since does not take into account permissions.
|
* Should not be used directly since does not take into account permissions.
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
class Chapter extends Entity
|
class Chapter extends Entity
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,15 @@ class Chapter extends Entity
|
||||||
|
|
||||||
protected $fillable = ['name', 'description', 'priority', 'book_id'];
|
protected $fillable = ['name', 'description', 'priority', 'book_id'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the morph class for this model.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMorphClass()
|
||||||
|
{
|
||||||
|
return 'BookStack\\Chapter';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the book this chapter is within.
|
* Get the book this chapter is within.
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
@ -1,7 +1,31 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Actions\Activity;
|
||||||
|
use BookStack\Actions\Comment;
|
||||||
|
use BookStack\Actions\Tag;
|
||||||
|
use BookStack\Actions\View;
|
||||||
|
use BookStack\Auth\Permissions\EntityPermission;
|
||||||
|
use BookStack\Auth\Permissions\JointPermission;
|
||||||
|
use BookStack\Ownable;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Entity
|
||||||
|
* The base class for book-like items such as pages, chapters & books.
|
||||||
|
* This is not a database model in itself but extended.
|
||||||
|
*
|
||||||
|
* @property integer $id
|
||||||
|
* @property string $name
|
||||||
|
* @property string $slug
|
||||||
|
* @property Carbon $created_at
|
||||||
|
* @property Carbon $updated_at
|
||||||
|
* @property int $created_by
|
||||||
|
* @property int $updated_by
|
||||||
|
* @property boolean $restricted
|
||||||
|
*
|
||||||
|
* @package BookStack\Entities
|
||||||
|
*/
|
||||||
class Entity extends Ownable
|
class Entity extends Ownable
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -15,6 +39,17 @@ class Entity extends Ownable
|
||||||
*/
|
*/
|
||||||
public $searchFactor = 1.0;
|
public $searchFactor = 1.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the morph class for this model.
|
||||||
|
* Set here since, due to folder changes, the namespace used
|
||||||
|
* in the database no longer matches the class namespace.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMorphClass()
|
||||||
|
{
|
||||||
|
return 'BookStack\\Entity';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this entity to another given entity.
|
* Compares this entity to another given entity.
|
||||||
* Matches by comparing class and id.
|
* Matches by comparing class and id.
|
||||||
|
@ -158,7 +193,7 @@ class Entity extends Ownable
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return app('BookStack\\' . $className);
|
return app('BookStack\\Entities\\' . $className);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EntityProvider
|
||||||
|
*
|
||||||
|
* Provides access to the core entity models.
|
||||||
|
* Wrapped up in this provider since they are often used together
|
||||||
|
* so this is a neater alternative to injecting all in individually.
|
||||||
|
*
|
||||||
|
* @package BookStack\Entities
|
||||||
|
*/
|
||||||
|
class EntityProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Bookshelf
|
||||||
|
*/
|
||||||
|
public $bookshelf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Book
|
||||||
|
*/
|
||||||
|
public $book;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Chapter
|
||||||
|
*/
|
||||||
|
public $chapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Page
|
||||||
|
*/
|
||||||
|
public $page;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PageRevision
|
||||||
|
*/
|
||||||
|
public $pageRevision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EntityProvider constructor.
|
||||||
|
* @param Bookshelf $bookshelf
|
||||||
|
* @param Book $book
|
||||||
|
* @param Chapter $chapter
|
||||||
|
* @param Page $page
|
||||||
|
* @param PageRevision $pageRevision
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
Bookshelf $bookshelf,
|
||||||
|
Book $book,
|
||||||
|
Chapter $chapter,
|
||||||
|
Page $page,
|
||||||
|
PageRevision $pageRevision
|
||||||
|
) {
|
||||||
|
$this->bookshelf = $bookshelf;
|
||||||
|
$this->book = $book;
|
||||||
|
$this->chapter = $chapter;
|
||||||
|
$this->page = $page;
|
||||||
|
$this->pageRevision = $pageRevision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch all core entity types as an associated array
|
||||||
|
* with their basic names as the keys.
|
||||||
|
* @return Entity[]
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'bookshelf' => $this->bookshelf,
|
||||||
|
'book' => $this->book,
|
||||||
|
'chapter' => $this->chapter,
|
||||||
|
'page' => $this->page,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an entity instance by it's basic name.
|
||||||
|
* @param string $type
|
||||||
|
* @return Entity
|
||||||
|
*/
|
||||||
|
public function get(string $type)
|
||||||
|
{
|
||||||
|
$type = strtolower($type);
|
||||||
|
return $this->all()[$type];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
use BookStack\Book;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Chapter;
|
use BookStack\Uploads\ImageService;
|
||||||
use BookStack\Page;
|
|
||||||
use BookStack\Repos\EntityRepo;
|
|
||||||
|
|
||||||
class ExportService
|
class ExportService
|
||||||
{
|
{
|
||||||
|
@ -13,7 +11,8 @@ class ExportService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExportService constructor.
|
* ExportService constructor.
|
||||||
* @param $entityRepo
|
* @param EntityRepo $entityRepo
|
||||||
|
* @param ImageService $imageService
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, ImageService $imageService)
|
public function __construct(EntityRepo $entityRepo, ImageService $imageService)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +23,7 @@ class ExportService
|
||||||
/**
|
/**
|
||||||
* Convert a page to a self-contained HTML file.
|
* Convert a page to a self-contained HTML file.
|
||||||
* Includes required CSS & image content. Images are base64 encoded into the HTML.
|
* Includes required CSS & image content. Images are base64 encoded into the HTML.
|
||||||
* @param Page $page
|
* @param \BookStack\Entities\Page $page
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
|
@ -39,7 +38,7 @@ class ExportService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a chapter to a self-contained HTML file.
|
* Convert a chapter to a self-contained HTML file.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
|
@ -89,7 +88,7 @@ class ExportService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a chapter to a PDF file.
|
* Convert a chapter to a PDF file.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
|
@ -108,7 +107,7 @@ class ExportService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a book to a PDF file
|
* Convert a book to a PDF file
|
||||||
* @param Book $book
|
* @param \BookStack\Entities\Book $book
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
|
@ -208,7 +207,7 @@ class ExportService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a chapter into a plain text string.
|
* Convert a chapter into a plain text string.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function chapterToPlainText(Chapter $chapter)
|
public function chapterToPlainText(Chapter $chapter)
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Uploads\Attachment;
|
||||||
|
|
||||||
class Page extends Entity
|
class Page extends Entity
|
||||||
{
|
{
|
||||||
|
@ -8,6 +10,15 @@ class Page extends Entity
|
||||||
|
|
||||||
public $textField = 'text';
|
public $textField = 'text';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the morph class for this model.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMorphClass()
|
||||||
|
{
|
||||||
|
return 'BookStack\\Page';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts this page into a simplified array.
|
* Converts this page into a simplified array.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
@ -115,7 +126,7 @@ class Page extends Entity
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current revision for the page if existing
|
* Get the current revision for the page if existing
|
||||||
* @return \BookStack\PageRevision|null
|
* @return \BookStack\Entities\PageRevision|null
|
||||||
*/
|
*/
|
||||||
public function getCurrentRevision()
|
public function getCurrentRevision()
|
||||||
{
|
{
|
|
@ -1,4 +1,7 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class PageRevision extends Model
|
class PageRevision extends Model
|
||||||
{
|
{
|
|
@ -1,54 +1,30 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Entities\Repos;
|
||||||
|
|
||||||
use BookStack\Book;
|
use BookStack\Actions\TagRepo;
|
||||||
use BookStack\Bookshelf;
|
use BookStack\Actions\ViewService;
|
||||||
use BookStack\Chapter;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Entity;
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Entities\Book;
|
||||||
|
use BookStack\Entities\Bookshelf;
|
||||||
|
use BookStack\Entities\Chapter;
|
||||||
|
use BookStack\Entities\Entity;
|
||||||
|
use BookStack\Entities\EntityProvider;
|
||||||
|
use BookStack\Entities\Page;
|
||||||
|
use BookStack\Entities\SearchService;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Exceptions\NotifyException;
|
use BookStack\Exceptions\NotifyException;
|
||||||
use BookStack\Page;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use BookStack\PageRevision;
|
|
||||||
use BookStack\Services\AttachmentService;
|
|
||||||
use BookStack\Services\PermissionService;
|
|
||||||
use BookStack\Services\SearchService;
|
|
||||||
use BookStack\Services\ViewService;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use DOMDocument;
|
use DOMDocument;
|
||||||
use DOMXPath;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class EntityRepo
|
class EntityRepo
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var Bookshelf
|
|
||||||
*/
|
|
||||||
public $bookshelf;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Book $book
|
* @var EntityProvider
|
||||||
*/
|
*/
|
||||||
public $book;
|
protected $entityProvider;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Chapter
|
|
||||||
*/
|
|
||||||
public $chapter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Page
|
|
||||||
*/
|
|
||||||
public $page;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var PageRevision
|
|
||||||
*/
|
|
||||||
protected $pageRevision;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base entity instances keyed by type
|
|
||||||
* @var []Entity
|
|
||||||
*/
|
|
||||||
protected $entities;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var PermissionService
|
* @var PermissionService
|
||||||
|
@ -72,63 +48,36 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EntityRepo constructor.
|
* EntityRepo constructor.
|
||||||
* @param Bookshelf $bookshelf
|
* @param EntityProvider $entityProvider
|
||||||
* @param Book $book
|
|
||||||
* @param Chapter $chapter
|
|
||||||
* @param Page $page
|
|
||||||
* @param PageRevision $pageRevision
|
|
||||||
* @param ViewService $viewService
|
* @param ViewService $viewService
|
||||||
* @param PermissionService $permissionService
|
* @param PermissionService $permissionService
|
||||||
* @param TagRepo $tagRepo
|
* @param TagRepo $tagRepo
|
||||||
* @param SearchService $searchService
|
* @param SearchService $searchService
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Bookshelf $bookshelf,
|
EntityProvider $entityProvider,
|
||||||
Book $book,
|
|
||||||
Chapter $chapter,
|
|
||||||
Page $page,
|
|
||||||
PageRevision $pageRevision,
|
|
||||||
ViewService $viewService,
|
ViewService $viewService,
|
||||||
PermissionService $permissionService,
|
PermissionService $permissionService,
|
||||||
TagRepo $tagRepo,
|
TagRepo $tagRepo,
|
||||||
SearchService $searchService
|
SearchService $searchService
|
||||||
) {
|
) {
|
||||||
$this->bookshelf = $bookshelf;
|
$this->entityProvider = $entityProvider;
|
||||||
$this->book = $book;
|
|
||||||
$this->chapter = $chapter;
|
|
||||||
$this->page = $page;
|
|
||||||
$this->pageRevision = $pageRevision;
|
|
||||||
$this->entities = [
|
|
||||||
'bookshelf' => $this->bookshelf,
|
|
||||||
'page' => $this->page,
|
|
||||||
'chapter' => $this->chapter,
|
|
||||||
'book' => $this->book
|
|
||||||
];
|
|
||||||
$this->viewService = $viewService;
|
$this->viewService = $viewService;
|
||||||
$this->permissionService = $permissionService;
|
$this->permissionService = $permissionService;
|
||||||
$this->tagRepo = $tagRepo;
|
$this->tagRepo = $tagRepo;
|
||||||
$this->searchService = $searchService;
|
$this->searchService = $searchService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an entity instance via type.
|
|
||||||
* @param $type
|
|
||||||
* @return Entity
|
|
||||||
*/
|
|
||||||
protected function getEntity($type)
|
|
||||||
{
|
|
||||||
return $this->entities[strtolower($type)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base query for searching entities via permission system
|
* Base query for searching entities via permission system
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param bool $allowDrafts
|
* @param bool $allowDrafts
|
||||||
|
* @param string $permission
|
||||||
* @return \Illuminate\Database\Query\Builder
|
* @return \Illuminate\Database\Query\Builder
|
||||||
*/
|
*/
|
||||||
protected function entityQuery($type, $allowDrafts = false, $permission = 'view')
|
protected function entityQuery($type, $allowDrafts = false, $permission = 'view')
|
||||||
{
|
{
|
||||||
$q = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type), $permission);
|
$q = $this->permissionService->enforceEntityRestrictions($type, $this->entityProvider->get($type), $permission);
|
||||||
if (strtolower($type) === 'page' && !$allowDrafts) {
|
if (strtolower($type) === 'page' && !$allowDrafts) {
|
||||||
$q = $q->where('draft', '=', false);
|
$q = $q->where('draft', '=', false);
|
||||||
}
|
}
|
||||||
|
@ -152,15 +101,35 @@ class EntityRepo
|
||||||
* @param integer $id
|
* @param integer $id
|
||||||
* @param bool $allowDrafts
|
* @param bool $allowDrafts
|
||||||
* @param bool $ignorePermissions
|
* @param bool $ignorePermissions
|
||||||
* @return Entity
|
* @return \BookStack\Entities\Entity
|
||||||
*/
|
*/
|
||||||
public function getById($type, $id, $allowDrafts = false, $ignorePermissions = false)
|
public function getById($type, $id, $allowDrafts = false, $ignorePermissions = false)
|
||||||
{
|
{
|
||||||
|
$query = $this->entityQuery($type, $allowDrafts);
|
||||||
|
|
||||||
if ($ignorePermissions) {
|
if ($ignorePermissions) {
|
||||||
$entity = $this->getEntity($type);
|
$query = $this->entityProvider->get($type)->newQuery();
|
||||||
return $entity->newQuery()->find($id);
|
|
||||||
}
|
}
|
||||||
return $this->entityQuery($type, $allowDrafts)->find($id);
|
|
||||||
|
return $query->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
* @param []int $ids
|
||||||
|
* @param bool $allowDrafts
|
||||||
|
* @param bool $ignorePermissions
|
||||||
|
* @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|Collection
|
||||||
|
*/
|
||||||
|
public function getManyById($type, $ids, $allowDrafts = false, $ignorePermissions = false)
|
||||||
|
{
|
||||||
|
$query = $this->entityQuery($type, $allowDrafts);
|
||||||
|
|
||||||
|
if ($ignorePermissions) {
|
||||||
|
$query = $this->entityProvider->get($type)->newQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->whereIn('id', $ids)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,7 +137,7 @@ class EntityRepo
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $slug
|
* @param string $slug
|
||||||
* @param string|bool $bookSlug
|
* @param string|bool $bookSlug
|
||||||
* @return Entity
|
* @return \BookStack\Entities\Entity
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function getBySlug($type, $slug, $bookSlug = false)
|
public function getBySlug($type, $slug, $bookSlug = false)
|
||||||
|
@ -178,7 +147,7 @@ class EntityRepo
|
||||||
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->entityProvider->book->getTable())
|
||||||
->where('slug', '=', $bookSlug)->limit(1);
|
->where('slug', '=', $bookSlug)->limit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -190,26 +159,6 @@ class EntityRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search through page revisions and retrieve the last page in the
|
|
||||||
* current book that has a slug equal to the one given.
|
|
||||||
* @param string $pageSlug
|
|
||||||
* @param string $bookSlug
|
|
||||||
* @return null|Page
|
|
||||||
*/
|
|
||||||
public function getPageByOldSlug($pageSlug, $bookSlug)
|
|
||||||
{
|
|
||||||
$revision = $this->pageRevision->where('slug', '=', $pageSlug)
|
|
||||||
->whereHas('page', function ($query) {
|
|
||||||
$this->permissionService->enforceEntityRestrictions('page', $query);
|
|
||||||
})
|
|
||||||
->where('type', '=', 'version')
|
|
||||||
->where('book_slug', '=', $bookSlug)
|
|
||||||
->orderBy('created_at', 'desc')
|
|
||||||
->with('page')->first();
|
|
||||||
return $revision !== null ? $revision->page : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all entities of a type with the given permission, limited by count unless count is false.
|
* Get all entities of a type with the given permission, limited by count unless count is false.
|
||||||
* @param string $type
|
* @param string $type
|
||||||
|
@ -247,7 +196,7 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
public function getRecentlyCreated($type, $count = 20, $page = 0, $additionalQuery = false)
|
public function getRecentlyCreated($type, $count = 20, $page = 0, $additionalQuery = false)
|
||||||
{
|
{
|
||||||
$query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type))
|
$query = $this->permissionService->enforceEntityRestrictions($type, $this->entityProvider->get($type))
|
||||||
->orderBy('created_at', 'desc');
|
->orderBy('created_at', 'desc');
|
||||||
if (strtolower($type) === 'page') {
|
if (strtolower($type) === 'page') {
|
||||||
$query = $query->where('draft', '=', false);
|
$query = $query->where('draft', '=', false);
|
||||||
|
@ -268,7 +217,7 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
public function getRecentlyUpdated($type, $count = 20, $page = 0, $additionalQuery = false)
|
public function getRecentlyUpdated($type, $count = 20, $page = 0, $additionalQuery = false)
|
||||||
{
|
{
|
||||||
$query = $this->permissionService->enforceEntityRestrictions($type, $this->getEntity($type))
|
$query = $this->permissionService->enforceEntityRestrictions($type, $this->entityProvider->get($type))
|
||||||
->orderBy('updated_at', 'desc');
|
->orderBy('updated_at', 'desc');
|
||||||
if (strtolower($type) === 'page') {
|
if (strtolower($type) === 'page') {
|
||||||
$query = $query->where('draft', '=', false);
|
$query = $query->where('draft', '=', false);
|
||||||
|
@ -288,7 +237,7 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
public function getRecentlyViewed($type, $count = 10, $page = 0)
|
public function getRecentlyViewed($type, $count = 10, $page = 0)
|
||||||
{
|
{
|
||||||
$filter = is_bool($type) ? false : $this->getEntity($type);
|
$filter = is_bool($type) ? false : $this->entityProvider->get($type);
|
||||||
return $this->viewService->getUserRecentlyViewed($count, $page, $filter);
|
return $this->viewService->getUserRecentlyViewed($count, $page, $filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +272,7 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
public function getPopular($type, $count = 10, $page = 0)
|
public function getPopular($type, $count = 10, $page = 0)
|
||||||
{
|
{
|
||||||
$filter = is_bool($type) ? false : $this->getEntity($type);
|
$filter = is_bool($type) ? false : $this->entityProvider->get($type);
|
||||||
return $this->viewService->getPopular($count, $page, $filter);
|
return $this->viewService->getPopular($count, $page, $filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,19 +280,32 @@ class EntityRepo
|
||||||
* Get draft pages owned by the current user.
|
* Get draft pages owned by the current user.
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @param int $page
|
* @param int $page
|
||||||
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function getUserDraftPages($count = 20, $page = 0)
|
public function getUserDraftPages($count = 20, $page = 0)
|
||||||
{
|
{
|
||||||
return $this->page->where('draft', '=', true)
|
return $this->entityProvider->page->where('draft', '=', true)
|
||||||
->where('created_by', '=', user()->id)
|
->where('created_by', '=', user()->id)
|
||||||
->orderBy('updated_at', 'desc')
|
->orderBy('updated_at', 'desc')
|
||||||
->skip($count * $page)->take($count)->get();
|
->skip($count * $page)->take($count)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of entities the given user has created.
|
||||||
|
* @param string $type
|
||||||
|
* @param User $user
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getUserTotalCreated(string $type, User $user)
|
||||||
|
{
|
||||||
|
return $this->entityProvider->get($type)
|
||||||
|
->where('created_by', '=', $user->id)->count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the child items for a chapter sorted by priority but
|
* Get the child items for a chapter sorted by priority but
|
||||||
* with draft items floated to the top.
|
* with draft items floated to the top.
|
||||||
* @param Bookshelf $bookshelf
|
* @param \BookStack\Entities\Bookshelf $bookshelf
|
||||||
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
||||||
*/
|
*/
|
||||||
public function getBookshelfChildren(Bookshelf $bookshelf)
|
public function getBookshelfChildren(Bookshelf $bookshelf)
|
||||||
|
@ -355,7 +317,7 @@ class EntityRepo
|
||||||
* Get all child objects of a book.
|
* Get all child objects of a book.
|
||||||
* Returns a sorted collection of Pages and Chapters.
|
* Returns a sorted collection of Pages and Chapters.
|
||||||
* Loads the book slug onto child elements to prevent access database access for getting the slug.
|
* Loads the book slug onto child elements to prevent access database access for getting the slug.
|
||||||
* @param Book $book
|
* @param \BookStack\Entities\Book $book
|
||||||
* @param bool $filterDrafts
|
* @param bool $filterDrafts
|
||||||
* @param bool $renderPages
|
* @param bool $renderPages
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
@ -368,14 +330,14 @@ class EntityRepo
|
||||||
$tree = [];
|
$tree = [];
|
||||||
|
|
||||||
foreach ($q as $index => $rawEntity) {
|
foreach ($q as $index => $rawEntity) {
|
||||||
if ($rawEntity->entity_type === 'BookStack\\Page') {
|
if ($rawEntity->entity_type === $this->entityProvider->page->getMorphClass()) {
|
||||||
$entities[$index] = $this->page->newFromBuilder($rawEntity);
|
$entities[$index] = $this->entityProvider->page->newFromBuilder($rawEntity);
|
||||||
if ($renderPages) {
|
if ($renderPages) {
|
||||||
$entities[$index]->html = $rawEntity->html;
|
$entities[$index]->html = $rawEntity->html;
|
||||||
$entities[$index]->html = $this->renderPage($entities[$index]);
|
$entities[$index]->html = $this->renderPage($entities[$index]);
|
||||||
};
|
};
|
||||||
} else if ($rawEntity->entity_type === 'BookStack\\Chapter') {
|
} else if ($rawEntity->entity_type === $this->entityProvider->chapter->getMorphClass()) {
|
||||||
$entities[$index] = $this->chapter->newFromBuilder($rawEntity);
|
$entities[$index] = $this->entityProvider->chapter->newFromBuilder($rawEntity);
|
||||||
$key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
|
$key = $entities[$index]->entity_type . ':' . $entities[$index]->id;
|
||||||
$parents[$key] = $entities[$index];
|
$parents[$key] = $entities[$index];
|
||||||
$parents[$key]->setAttribute('pages', collect());
|
$parents[$key]->setAttribute('pages', collect());
|
||||||
|
@ -390,7 +352,7 @@ class EntityRepo
|
||||||
if ($entity->chapter_id === 0 || $entity->chapter_id === '0') {
|
if ($entity->chapter_id === 0 || $entity->chapter_id === '0') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$parentKey = 'BookStack\\Chapter:' . $entity->chapter_id;
|
$parentKey = $this->entityProvider->chapter->getMorphClass() . ':' . $entity->chapter_id;
|
||||||
if (!isset($parents[$parentKey])) {
|
if (!isset($parents[$parentKey])) {
|
||||||
$tree[] = $entity;
|
$tree[] = $entity;
|
||||||
continue;
|
continue;
|
||||||
|
@ -405,7 +367,7 @@ class EntityRepo
|
||||||
/**
|
/**
|
||||||
* Get the child items for a chapter sorted by priority but
|
* Get the child items for a chapter sorted by priority but
|
||||||
* with draft items floated to the top.
|
* with draft items floated to the top.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
||||||
*/
|
*/
|
||||||
public function getChapterChildren(Chapter $chapter)
|
public function getChapterChildren(Chapter $chapter)
|
||||||
|
@ -417,7 +379,7 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next sequential priority for a new child element in the given book.
|
* Get the next sequential priority for a new child element in the given book.
|
||||||
* @param Book $book
|
* @param \BookStack\Entities\Book $book
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getNewBookPriority(Book $book)
|
public function getNewBookPriority(Book $book)
|
||||||
|
@ -428,7 +390,7 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a new priority for a new page to be added to the given chapter.
|
* Get a new priority for a new page to be added to the given chapter.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getNewChapterPriority(Chapter $chapter)
|
public function getNewChapterPriority(Chapter $chapter)
|
||||||
|
@ -464,7 +426,7 @@ class EntityRepo
|
||||||
*/
|
*/
|
||||||
protected function slugExists($type, $slug, $currentId = false, $bookId = false)
|
protected function slugExists($type, $slug, $currentId = false, $bookId = false)
|
||||||
{
|
{
|
||||||
$query = $this->getEntity($type)->where('slug', '=', $slug);
|
$query = $this->entityProvider->get($type)->where('slug', '=', $slug);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -476,10 +438,11 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates entity restrictions from a request
|
* Updates entity restrictions from a request
|
||||||
* @param $request
|
* @param Request $request
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function updateEntityPermissionsFromRequest($request, Entity $entity)
|
public function updateEntityPermissionsFromRequest(Request $request, Entity $entity)
|
||||||
{
|
{
|
||||||
$entity->restricted = $request->get('restricted', '') === 'true';
|
$entity->restricted = $request->get('restricted', '') === 'true';
|
||||||
$entity->permissions()->delete();
|
$entity->permissions()->delete();
|
||||||
|
@ -507,12 +470,12 @@ class EntityRepo
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param array $input
|
* @param array $input
|
||||||
* @param bool|Book $book
|
* @param bool|Book $book
|
||||||
* @return Entity
|
* @return \BookStack\Entities\Entity
|
||||||
*/
|
*/
|
||||||
public function createFromInput($type, $input = [], $book = false)
|
public function createFromInput($type, $input = [], $book = false)
|
||||||
{
|
{
|
||||||
$isChapter = strtolower($type) === 'chapter';
|
$isChapter = strtolower($type) === 'chapter';
|
||||||
$entityModel = $this->getEntity($type)->newInstance($input);
|
$entityModel = $this->entityProvider->get($type)->newInstance($input);
|
||||||
$entityModel->slug = $this->findSuitableSlug($type, $entityModel->name, false, $isChapter ? $book->id : false);
|
$entityModel->slug = $this->findSuitableSlug($type, $entityModel->name, false, $isChapter ? $book->id : false);
|
||||||
$entityModel->created_by = user()->id;
|
$entityModel->created_by = user()->id;
|
||||||
$entityModel->updated_by = user()->id;
|
$entityModel->updated_by = user()->id;
|
||||||
|
@ -531,9 +494,9 @@ class EntityRepo
|
||||||
* Update entity details from request input.
|
* Update entity details from request input.
|
||||||
* Used for books and chapters
|
* Used for books and chapters
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param Entity $entityModel
|
* @param \BookStack\Entities\Entity $entityModel
|
||||||
* @param array $input
|
* @param array $input
|
||||||
* @return Entity
|
* @return \BookStack\Entities\Entity
|
||||||
*/
|
*/
|
||||||
public function updateFromInput($type, Entity $entityModel, $input = [])
|
public function updateFromInput($type, Entity $entityModel, $input = [])
|
||||||
{
|
{
|
||||||
|
@ -556,7 +519,7 @@ class EntityRepo
|
||||||
/**
|
/**
|
||||||
* Sync the books assigned to a shelf from a comma-separated list
|
* Sync the books assigned to a shelf from a comma-separated list
|
||||||
* of book IDs.
|
* of book IDs.
|
||||||
* @param Bookshelf $shelf
|
* @param \BookStack\Entities\Bookshelf $shelf
|
||||||
* @param string $books
|
* @param string $books
|
||||||
*/
|
*/
|
||||||
public function updateShelfBooks(Bookshelf $shelf, string $books)
|
public function updateShelfBooks(Bookshelf $shelf, string $books)
|
||||||
|
@ -581,7 +544,7 @@ class EntityRepo
|
||||||
* @param integer $newBookId
|
* @param integer $newBookId
|
||||||
* @param Entity $entity
|
* @param Entity $entity
|
||||||
* @param bool $rebuildPermissions
|
* @param bool $rebuildPermissions
|
||||||
* @return Entity
|
* @return \BookStack\Entities\Entity
|
||||||
*/
|
*/
|
||||||
public function changeBook($type, $newBookId, Entity $entity, $rebuildPermissions = false)
|
public function changeBook($type, $newBookId, Entity $entity, $rebuildPermissions = false)
|
||||||
{
|
{
|
||||||
|
@ -635,191 +598,6 @@ class EntityRepo
|
||||||
return $slug;
|
return $slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a new draft page instance.
|
|
||||||
* @param Book $book
|
|
||||||
* @param Chapter|bool $chapter
|
|
||||||
* @return Page
|
|
||||||
*/
|
|
||||||
public function getDraftPage(Book $book, $chapter = false)
|
|
||||||
{
|
|
||||||
$page = $this->page->newInstance();
|
|
||||||
$page->name = trans('entities.pages_initial_name');
|
|
||||||
$page->created_by = user()->id;
|
|
||||||
$page->updated_by = user()->id;
|
|
||||||
$page->draft = true;
|
|
||||||
|
|
||||||
if ($chapter) {
|
|
||||||
$page->chapter_id = $chapter->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$book->pages()->save($page);
|
|
||||||
$page = $this->page->find($page->id);
|
|
||||||
$this->permissionService->buildJointPermissionsForEntity($page);
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Publish a draft page to make it a normal page.
|
|
||||||
* Sets the slug and updates the content.
|
|
||||||
* @param Page $draftPage
|
|
||||||
* @param array $input
|
|
||||||
* @return Page
|
|
||||||
*/
|
|
||||||
public function publishPageDraft(Page $draftPage, array $input)
|
|
||||||
{
|
|
||||||
$draftPage->fill($input);
|
|
||||||
|
|
||||||
// Save page tags if present
|
|
||||||
if (isset($input['tags'])) {
|
|
||||||
$this->tagRepo->saveTagsToEntity($draftPage, $input['tags']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
|
|
||||||
$draftPage->html = $this->formatHtml($input['html']);
|
|
||||||
$draftPage->text = $this->pageToPlainText($draftPage);
|
|
||||||
$draftPage->draft = false;
|
|
||||||
$draftPage->revision_count = 1;
|
|
||||||
|
|
||||||
$draftPage->save();
|
|
||||||
$this->savePageRevision($draftPage, trans('entities.pages_initial_revision'));
|
|
||||||
$this->searchService->indexEntity($draftPage);
|
|
||||||
return $draftPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a copy of a page in a new location with a new name.
|
|
||||||
* @param Page $page
|
|
||||||
* @param Entity $newParent
|
|
||||||
* @param string $newName
|
|
||||||
* @return Page
|
|
||||||
*/
|
|
||||||
public function copyPage(Page $page, Entity $newParent, $newName = '')
|
|
||||||
{
|
|
||||||
$newBook = $newParent->isA('book') ? $newParent : $newParent->book;
|
|
||||||
$newChapter = $newParent->isA('chapter') ? $newParent : null;
|
|
||||||
$copyPage = $this->getDraftPage($newBook, $newChapter);
|
|
||||||
$pageData = $page->getAttributes();
|
|
||||||
|
|
||||||
// Update name
|
|
||||||
if (!empty($newName)) {
|
|
||||||
$pageData['name'] = $newName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy tags from previous page if set
|
|
||||||
if ($page->tags) {
|
|
||||||
$pageData['tags'] = [];
|
|
||||||
foreach ($page->tags as $tag) {
|
|
||||||
$pageData['tags'][] = ['name' => $tag->name, 'value' => $tag->value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set priority
|
|
||||||
if ($newParent->isA('chapter')) {
|
|
||||||
$pageData['priority'] = $this->getNewChapterPriority($newParent);
|
|
||||||
} else {
|
|
||||||
$pageData['priority'] = $this->getNewBookPriority($newParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->publishPageDraft($copyPage, $pageData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a page revision into the system.
|
|
||||||
* @param Page $page
|
|
||||||
* @param null|string $summary
|
|
||||||
* @return PageRevision
|
|
||||||
*/
|
|
||||||
public function savePageRevision(Page $page, $summary = null)
|
|
||||||
{
|
|
||||||
$revision = $this->pageRevision->newInstance($page->toArray());
|
|
||||||
if (setting('app-editor') !== 'markdown') {
|
|
||||||
$revision->markdown = '';
|
|
||||||
}
|
|
||||||
$revision->page_id = $page->id;
|
|
||||||
$revision->slug = $page->slug;
|
|
||||||
$revision->book_slug = $page->book->slug;
|
|
||||||
$revision->created_by = user()->id;
|
|
||||||
$revision->created_at = $page->updated_at;
|
|
||||||
$revision->type = 'version';
|
|
||||||
$revision->summary = $summary;
|
|
||||||
$revision->revision_number = $page->revision_count;
|
|
||||||
$revision->save();
|
|
||||||
|
|
||||||
$revisionLimit = config('app.revision_limit');
|
|
||||||
if ($revisionLimit !== false) {
|
|
||||||
$revisionsToDelete = $this->pageRevision->where('page_id', '=', $page->id)
|
|
||||||
->orderBy('created_at', 'desc')->skip(intval($revisionLimit))->take(10)->get(['id']);
|
|
||||||
if ($revisionsToDelete->count() > 0) {
|
|
||||||
$this->pageRevision->whereIn('id', $revisionsToDelete->pluck('id'))->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats a page's html to be tagged correctly
|
|
||||||
* within the system.
|
|
||||||
* @param string $htmlText
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function formatHtml($htmlText)
|
|
||||||
{
|
|
||||||
if ($htmlText == '') {
|
|
||||||
return $htmlText;
|
|
||||||
}
|
|
||||||
libxml_use_internal_errors(true);
|
|
||||||
$doc = new DOMDocument();
|
|
||||||
$doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
|
|
||||||
|
|
||||||
$container = $doc->documentElement;
|
|
||||||
$body = $container->childNodes->item(0);
|
|
||||||
$childNodes = $body->childNodes;
|
|
||||||
|
|
||||||
// Ensure no duplicate ids are used
|
|
||||||
$idArray = [];
|
|
||||||
|
|
||||||
foreach ($childNodes as $index => $childNode) {
|
|
||||||
/** @var \DOMElement $childNode */
|
|
||||||
if (get_class($childNode) !== 'DOMElement') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overwrite id if not a BookStack custom id
|
|
||||||
if ($childNode->hasAttribute('id')) {
|
|
||||||
$id = $childNode->getAttribute('id');
|
|
||||||
if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
|
|
||||||
$idArray[] = $id;
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an unique id for the element
|
|
||||||
// Uses the content as a basis to ensure output is the same every time
|
|
||||||
// the same content is passed through.
|
|
||||||
$contentId = 'bkmrk-' . substr(strtolower(preg_replace('/\s+/', '-', trim($childNode->nodeValue))), 0, 20);
|
|
||||||
$newId = urlencode($contentId);
|
|
||||||
$loopIndex = 0;
|
|
||||||
while (in_array($newId, $idArray)) {
|
|
||||||
$newId = urlencode($contentId . '-' . $loopIndex);
|
|
||||||
$loopIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$childNode->setAttribute('id', $newId);
|
|
||||||
$idArray[] = $newId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate inner html as a string
|
|
||||||
$html = '';
|
|
||||||
foreach ($childNodes as $childNode) {
|
|
||||||
$html .= $doc->saveHTML($childNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the page for viewing, Parsing and performing features such as page transclusion.
|
* Render the page for viewing, Parsing and performing features such as page transclusion.
|
||||||
* @param Page $page
|
* @param Page $page
|
||||||
|
@ -900,17 +678,6 @@ class EntityRepo
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the plain text version of a page's content.
|
|
||||||
* @param Page $page
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function pageToPlainText(Page $page)
|
|
||||||
{
|
|
||||||
$html = $this->renderPage($page);
|
|
||||||
return strip_tags($html);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for image usage within page content.
|
* Search for image usage within page content.
|
||||||
* @param $imageString
|
* @param $imageString
|
||||||
|
@ -927,281 +694,9 @@ class EntityRepo
|
||||||
return count($pages) > 0 ? $pages : false;
|
return count($pages) > 0 ? $pages : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the headers on the page to get a navigation menu
|
|
||||||
* @param String $pageContent
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getPageNav($pageContent)
|
|
||||||
{
|
|
||||||
if ($pageContent == '') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
libxml_use_internal_errors(true);
|
|
||||||
$doc = new DOMDocument();
|
|
||||||
$doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8'));
|
|
||||||
$xPath = new DOMXPath($doc);
|
|
||||||
$headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
|
|
||||||
|
|
||||||
if (is_null($headers)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$tree = collect([]);
|
|
||||||
foreach ($headers as $header) {
|
|
||||||
$text = $header->nodeValue;
|
|
||||||
$tree->push([
|
|
||||||
'nodeName' => strtolower($header->nodeName),
|
|
||||||
'level' => intval(str_replace('h', '', $header->nodeName)),
|
|
||||||
'link' => '#' . $header->getAttribute('id'),
|
|
||||||
'text' => strlen($text) > 30 ? substr($text, 0, 27) . '...' : $text
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalise headers if only smaller headers have been used
|
|
||||||
if (count($tree) > 0) {
|
|
||||||
$minLevel = $tree->pluck('level')->min();
|
|
||||||
$tree = $tree->map(function ($header) use ($minLevel) {
|
|
||||||
$header['level'] -= ($minLevel - 2);
|
|
||||||
return $header;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return $tree->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a page with any fillable data and saves it into the database.
|
|
||||||
* @param Page $page
|
|
||||||
* @param int $book_id
|
|
||||||
* @param array $input
|
|
||||||
* @return Page
|
|
||||||
*/
|
|
||||||
public function updatePage(Page $page, $book_id, $input)
|
|
||||||
{
|
|
||||||
// Hold the old details to compare later
|
|
||||||
$oldHtml = $page->html;
|
|
||||||
$oldName = $page->name;
|
|
||||||
|
|
||||||
// Prevent slug being updated if no name change
|
|
||||||
if ($page->name !== $input['name']) {
|
|
||||||
$page->slug = $this->findSuitableSlug('page', $input['name'], $page->id, $book_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save page tags if present
|
|
||||||
if (isset($input['tags'])) {
|
|
||||||
$this->tagRepo->saveTagsToEntity($page, $input['tags']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update with new details
|
|
||||||
$userId = user()->id;
|
|
||||||
$page->fill($input);
|
|
||||||
$page->html = $this->formatHtml($input['html']);
|
|
||||||
$page->text = $this->pageToPlainText($page);
|
|
||||||
if (setting('app-editor') !== 'markdown') {
|
|
||||||
$page->markdown = '';
|
|
||||||
}
|
|
||||||
$page->updated_by = $userId;
|
|
||||||
$page->revision_count++;
|
|
||||||
$page->save();
|
|
||||||
|
|
||||||
// Remove all update drafts for this user & page.
|
|
||||||
$this->userUpdatePageDraftsQuery($page, $userId)->delete();
|
|
||||||
|
|
||||||
// Save a revision after updating
|
|
||||||
if ($oldHtml !== $input['html'] || $oldName !== $input['name'] || $input['summary'] !== null) {
|
|
||||||
$this->savePageRevision($page, $input['summary']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->searchService->indexEntity($page);
|
|
||||||
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base query for getting user update drafts.
|
|
||||||
* @param Page $page
|
|
||||||
* @param $userId
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
protected function userUpdatePageDraftsQuery(Page $page, $userId)
|
|
||||||
{
|
|
||||||
return $this->pageRevision->where('created_by', '=', $userId)
|
|
||||||
->where('type', 'update_draft')
|
|
||||||
->where('page_id', '=', $page->id)
|
|
||||||
->orderBy('created_at', 'desc');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether a user has a draft version of a particular page or not.
|
|
||||||
* @param Page $page
|
|
||||||
* @param $userId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasUserGotPageDraft(Page $page, $userId)
|
|
||||||
{
|
|
||||||
return $this->userUpdatePageDraftsQuery($page, $userId)->count() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the latest updated draft revision for a particular page and user.
|
|
||||||
* @param Page $page
|
|
||||||
* @param $userId
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getUserPageDraft(Page $page, $userId)
|
|
||||||
{
|
|
||||||
return $this->userUpdatePageDraftsQuery($page, $userId)->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the notification message that informs the user that they are editing a draft page.
|
|
||||||
* @param PageRevision $draft
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getUserPageDraftMessage(PageRevision $draft)
|
|
||||||
{
|
|
||||||
$message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
|
|
||||||
if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) {
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
return $message . "\n" . trans('entities.pages_draft_edited_notification');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a page is being actively editing.
|
|
||||||
* Checks for edits since last page updated.
|
|
||||||
* Passing in a minuted range will check for edits
|
|
||||||
* within the last x minutes.
|
|
||||||
* @param Page $page
|
|
||||||
* @param null $minRange
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isPageEditingActive(Page $page, $minRange = null)
|
|
||||||
{
|
|
||||||
$draftSearch = $this->activePageEditingQuery($page, $minRange);
|
|
||||||
return $draftSearch->count() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A query to check for active update drafts on a particular page.
|
|
||||||
* @param Page $page
|
|
||||||
* @param null $minRange
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
protected function activePageEditingQuery(Page $page, $minRange = null)
|
|
||||||
{
|
|
||||||
$query = $this->pageRevision->where('type', '=', 'update_draft')
|
|
||||||
->where('page_id', '=', $page->id)
|
|
||||||
->where('updated_at', '>', $page->updated_at)
|
|
||||||
->where('created_by', '!=', user()->id)
|
|
||||||
->with('createdBy');
|
|
||||||
|
|
||||||
if ($minRange !== null) {
|
|
||||||
$query = $query->where('updated_at', '>=', Carbon::now()->subMinutes($minRange));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restores a revision's content back into a page.
|
|
||||||
* @param Page $page
|
|
||||||
* @param Book $book
|
|
||||||
* @param int $revisionId
|
|
||||||
* @return Page
|
|
||||||
*/
|
|
||||||
public function restorePageRevision(Page $page, Book $book, $revisionId)
|
|
||||||
{
|
|
||||||
$page->revision_count++;
|
|
||||||
$this->savePageRevision($page);
|
|
||||||
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
|
||||||
$page->fill($revision->toArray());
|
|
||||||
$page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
|
|
||||||
$page->text = $this->pageToPlainText($page);
|
|
||||||
$page->updated_by = user()->id;
|
|
||||||
$page->save();
|
|
||||||
$this->searchService->indexEntity($page);
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save a page update draft.
|
|
||||||
* @param Page $page
|
|
||||||
* @param array $data
|
|
||||||
* @return PageRevision|Page
|
|
||||||
*/
|
|
||||||
public function updatePageDraft(Page $page, $data = [])
|
|
||||||
{
|
|
||||||
// If the page itself is a draft simply update that
|
|
||||||
if ($page->draft) {
|
|
||||||
$page->fill($data);
|
|
||||||
if (isset($data['html'])) {
|
|
||||||
$page->text = $this->pageToPlainText($page);
|
|
||||||
}
|
|
||||||
$page->save();
|
|
||||||
return $page;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise save the data to a revision
|
|
||||||
$userId = user()->id;
|
|
||||||
$drafts = $this->userUpdatePageDraftsQuery($page, $userId)->get();
|
|
||||||
|
|
||||||
if ($drafts->count() > 0) {
|
|
||||||
$draft = $drafts->first();
|
|
||||||
} else {
|
|
||||||
$draft = $this->pageRevision->newInstance();
|
|
||||||
$draft->page_id = $page->id;
|
|
||||||
$draft->slug = $page->slug;
|
|
||||||
$draft->book_slug = $page->book->slug;
|
|
||||||
$draft->created_by = $userId;
|
|
||||||
$draft->type = 'update_draft';
|
|
||||||
}
|
|
||||||
|
|
||||||
$draft->fill($data);
|
|
||||||
if (setting('app-editor') !== 'markdown') {
|
|
||||||
$draft->markdown = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$draft->save();
|
|
||||||
return $draft;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a notification message concerning the editing activity on a particular page.
|
|
||||||
* @param Page $page
|
|
||||||
* @param null $minRange
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPageEditingActiveMessage(Page $page, $minRange = null)
|
|
||||||
{
|
|
||||||
$pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get();
|
|
||||||
|
|
||||||
$userMessage = $pageDraftEdits->count() > 1 ? trans('entities.pages_draft_edit_active.start_a', ['count' => $pageDraftEdits->count()]): trans('entities.pages_draft_edit_active.start_b', ['userName' => $pageDraftEdits->first()->createdBy->name]);
|
|
||||||
$timeMessage = $minRange === null ? trans('entities.pages_draft_edit_active.time_a') : trans('entities.pages_draft_edit_active.time_b', ['minCount'=>$minRange]);
|
|
||||||
return trans('entities.pages_draft_edit_active.message', ['start' => $userMessage, 'time' => $timeMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the page's parent to the given entity.
|
|
||||||
* @param Page $page
|
|
||||||
* @param Entity $parent
|
|
||||||
*/
|
|
||||||
public function changePageParent(Page $page, Entity $parent)
|
|
||||||
{
|
|
||||||
$book = $parent->isA('book') ? $parent : $parent->book;
|
|
||||||
$page->chapter_id = $parent->isA('chapter') ? $parent->id : 0;
|
|
||||||
$page->save();
|
|
||||||
if ($page->book->id !== $book->id) {
|
|
||||||
$page = $this->changeBook('page', $book->id, $page);
|
|
||||||
}
|
|
||||||
$page->load('book');
|
|
||||||
$this->permissionService->buildJointPermissionsForEntity($book);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a bookshelf instance
|
* Destroy a bookshelf instance
|
||||||
* @param Bookshelf $shelf
|
* @param \BookStack\Entities\Bookshelf $shelf
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function destroyBookshelf(Bookshelf $shelf)
|
public function destroyBookshelf(Bookshelf $shelf)
|
||||||
|
@ -1212,7 +707,7 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the provided book and all its child entities.
|
* Destroy the provided book and all its child entities.
|
||||||
* @param Book $book
|
* @param \BookStack\Entities\Book $book
|
||||||
* @throws NotifyException
|
* @throws NotifyException
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
|
@ -1230,7 +725,7 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a chapter and its relations.
|
* Destroy a chapter and its relations.
|
||||||
* @param Chapter $chapter
|
* @param \BookStack\Entities\Chapter $chapter
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function destroyChapter(Chapter $chapter)
|
public function destroyChapter(Chapter $chapter)
|
||||||
|
@ -1272,7 +767,7 @@ class EntityRepo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy or handle the common relations connected to an entity.
|
* Destroy or handle the common relations connected to an entity.
|
||||||
* @param Entity $entity
|
* @param \BookStack\Entities\Entity $entity
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
protected function destroyEntityCommonRelations(Entity $entity)
|
protected function destroyEntityCommonRelations(Entity $entity)
|
||||||
|
@ -1289,7 +784,7 @@ class EntityRepo
|
||||||
/**
|
/**
|
||||||
* Copy the permissions of a bookshelf to all child books.
|
* Copy the permissions of a bookshelf to all child books.
|
||||||
* Returns the number of books that had permissions updated.
|
* Returns the number of books that had permissions updated.
|
||||||
* @param Bookshelf $bookshelf
|
* @param \BookStack\Entities\Bookshelf $bookshelf
|
||||||
* @return int
|
* @return int
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
|
@ -0,0 +1,508 @@
|
||||||
|
<?php namespace BookStack\Entities\Repos;
|
||||||
|
|
||||||
|
use BookStack\Entities\Book;
|
||||||
|
use BookStack\Entities\Chapter;
|
||||||
|
use BookStack\Entities\Entity;
|
||||||
|
use BookStack\Entities\Page;
|
||||||
|
use BookStack\Entities\PageRevision;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use DOMDocument;
|
||||||
|
use DOMXPath;
|
||||||
|
|
||||||
|
class PageRepo extends EntityRepo
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get page by slug.
|
||||||
|
* @param string $pageSlug
|
||||||
|
* @param string $bookSlug
|
||||||
|
* @return Page
|
||||||
|
* @throws \BookStack\Exceptions\NotFoundException
|
||||||
|
*/
|
||||||
|
public function getPageBySlug(string $pageSlug, string $bookSlug)
|
||||||
|
{
|
||||||
|
return $this->getBySlug('page', $pageSlug, $bookSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search through page revisions and retrieve the last page in the
|
||||||
|
* current book that has a slug equal to the one given.
|
||||||
|
* @param string $pageSlug
|
||||||
|
* @param string $bookSlug
|
||||||
|
* @return null|Page
|
||||||
|
*/
|
||||||
|
public function getPageByOldSlug(string $pageSlug, string $bookSlug)
|
||||||
|
{
|
||||||
|
$revision = $this->entityProvider->pageRevision->where('slug', '=', $pageSlug)
|
||||||
|
->whereHas('page', function ($query) {
|
||||||
|
$this->permissionService->enforceEntityRestrictions('page', $query);
|
||||||
|
})
|
||||||
|
->where('type', '=', 'version')
|
||||||
|
->where('book_slug', '=', $bookSlug)
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->with('page')->first();
|
||||||
|
return $revision !== null ? $revision->page : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a page with any fillable data and saves it into the database.
|
||||||
|
* @param Page $page
|
||||||
|
* @param int $book_id
|
||||||
|
* @param array $input
|
||||||
|
* @return Page
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function updatePage(Page $page, int $book_id, array $input)
|
||||||
|
{
|
||||||
|
// Hold the old details to compare later
|
||||||
|
$oldHtml = $page->html;
|
||||||
|
$oldName = $page->name;
|
||||||
|
|
||||||
|
// Prevent slug being updated if no name change
|
||||||
|
if ($page->name !== $input['name']) {
|
||||||
|
$page->slug = $this->findSuitableSlug('page', $input['name'], $page->id, $book_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save page tags if present
|
||||||
|
if (isset($input['tags'])) {
|
||||||
|
$this->tagRepo->saveTagsToEntity($page, $input['tags']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update with new details
|
||||||
|
$userId = user()->id;
|
||||||
|
$page->fill($input);
|
||||||
|
$page->html = $this->formatHtml($input['html']);
|
||||||
|
$page->text = $this->pageToPlainText($page);
|
||||||
|
if (setting('app-editor') !== 'markdown') {
|
||||||
|
$page->markdown = '';
|
||||||
|
}
|
||||||
|
$page->updated_by = $userId;
|
||||||
|
$page->revision_count++;
|
||||||
|
$page->save();
|
||||||
|
|
||||||
|
// Remove all update drafts for this user & page.
|
||||||
|
$this->userUpdatePageDraftsQuery($page, $userId)->delete();
|
||||||
|
|
||||||
|
// Save a revision after updating
|
||||||
|
if ($oldHtml !== $input['html'] || $oldName !== $input['name'] || $input['summary'] !== null) {
|
||||||
|
$this->savePageRevision($page, $input['summary']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->searchService->indexEntity($page);
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a page revision into the system.
|
||||||
|
* @param Page $page
|
||||||
|
* @param null|string $summary
|
||||||
|
* @return PageRevision
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function savePageRevision(Page $page, string $summary = null)
|
||||||
|
{
|
||||||
|
$revision = $this->entityProvider->pageRevision->newInstance($page->toArray());
|
||||||
|
if (setting('app-editor') !== 'markdown') {
|
||||||
|
$revision->markdown = '';
|
||||||
|
}
|
||||||
|
$revision->page_id = $page->id;
|
||||||
|
$revision->slug = $page->slug;
|
||||||
|
$revision->book_slug = $page->book->slug;
|
||||||
|
$revision->created_by = user()->id;
|
||||||
|
$revision->created_at = $page->updated_at;
|
||||||
|
$revision->type = 'version';
|
||||||
|
$revision->summary = $summary;
|
||||||
|
$revision->revision_number = $page->revision_count;
|
||||||
|
$revision->save();
|
||||||
|
|
||||||
|
$revisionLimit = config('app.revision_limit');
|
||||||
|
if ($revisionLimit !== false) {
|
||||||
|
$revisionsToDelete = $this->entityProvider->pageRevision->where('page_id', '=', $page->id)
|
||||||
|
->orderBy('created_at', 'desc')->skip(intval($revisionLimit))->take(10)->get(['id']);
|
||||||
|
if ($revisionsToDelete->count() > 0) {
|
||||||
|
$this->entityProvider->pageRevision->whereIn('id', $revisionsToDelete->pluck('id'))->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a page's html to be tagged correctly
|
||||||
|
* within the system.
|
||||||
|
* @param string $htmlText
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function formatHtml(string $htmlText)
|
||||||
|
{
|
||||||
|
if ($htmlText == '') {
|
||||||
|
return $htmlText;
|
||||||
|
}
|
||||||
|
libxml_use_internal_errors(true);
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
$doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
|
||||||
|
|
||||||
|
$container = $doc->documentElement;
|
||||||
|
$body = $container->childNodes->item(0);
|
||||||
|
$childNodes = $body->childNodes;
|
||||||
|
|
||||||
|
// Ensure no duplicate ids are used
|
||||||
|
$idArray = [];
|
||||||
|
|
||||||
|
foreach ($childNodes as $index => $childNode) {
|
||||||
|
/** @var \DOMElement $childNode */
|
||||||
|
if (get_class($childNode) !== 'DOMElement') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overwrite id if not a BookStack custom id
|
||||||
|
if ($childNode->hasAttribute('id')) {
|
||||||
|
$id = $childNode->getAttribute('id');
|
||||||
|
if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
|
||||||
|
$idArray[] = $id;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an unique id for the element
|
||||||
|
// Uses the content as a basis to ensure output is the same every time
|
||||||
|
// the same content is passed through.
|
||||||
|
$contentId = 'bkmrk-' . substr(strtolower(preg_replace('/\s+/', '-', trim($childNode->nodeValue))), 0, 20);
|
||||||
|
$newId = urlencode($contentId);
|
||||||
|
$loopIndex = 0;
|
||||||
|
while (in_array($newId, $idArray)) {
|
||||||
|
$newId = urlencode($contentId . '-' . $loopIndex);
|
||||||
|
$loopIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$childNode->setAttribute('id', $newId);
|
||||||
|
$idArray[] = $newId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate inner html as a string
|
||||||
|
$html = '';
|
||||||
|
foreach ($childNodes as $childNode) {
|
||||||
|
$html .= $doc->saveHTML($childNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plain text version of a page's content.
|
||||||
|
* @param \BookStack\Entities\Page $page
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function pageToPlainText(Page $page)
|
||||||
|
{
|
||||||
|
$html = $this->renderPage($page);
|
||||||
|
return strip_tags($html);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new draft page instance.
|
||||||
|
* @param Book $book
|
||||||
|
* @param Chapter|null $chapter
|
||||||
|
* @return \BookStack\Entities\Page
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function getDraftPage(Book $book, Chapter $chapter = null)
|
||||||
|
{
|
||||||
|
$page = $this->entityProvider->page->newInstance();
|
||||||
|
$page->name = trans('entities.pages_initial_name');
|
||||||
|
$page->created_by = user()->id;
|
||||||
|
$page->updated_by = user()->id;
|
||||||
|
$page->draft = true;
|
||||||
|
|
||||||
|
if ($chapter) {
|
||||||
|
$page->chapter_id = $chapter->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$book->pages()->save($page);
|
||||||
|
$page = $this->entityProvider->page->find($page->id);
|
||||||
|
$this->permissionService->buildJointPermissionsForEntity($page);
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a page update draft.
|
||||||
|
* @param Page $page
|
||||||
|
* @param array $data
|
||||||
|
* @return PageRevision|Page
|
||||||
|
*/
|
||||||
|
public function updatePageDraft(Page $page, array $data = [])
|
||||||
|
{
|
||||||
|
// If the page itself is a draft simply update that
|
||||||
|
if ($page->draft) {
|
||||||
|
$page->fill($data);
|
||||||
|
if (isset($data['html'])) {
|
||||||
|
$page->text = $this->pageToPlainText($page);
|
||||||
|
}
|
||||||
|
$page->save();
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise save the data to a revision
|
||||||
|
$userId = user()->id;
|
||||||
|
$drafts = $this->userUpdatePageDraftsQuery($page, $userId)->get();
|
||||||
|
|
||||||
|
if ($drafts->count() > 0) {
|
||||||
|
$draft = $drafts->first();
|
||||||
|
} else {
|
||||||
|
$draft = $this->entityProvider->pageRevision->newInstance();
|
||||||
|
$draft->page_id = $page->id;
|
||||||
|
$draft->slug = $page->slug;
|
||||||
|
$draft->book_slug = $page->book->slug;
|
||||||
|
$draft->created_by = $userId;
|
||||||
|
$draft->type = 'update_draft';
|
||||||
|
}
|
||||||
|
|
||||||
|
$draft->fill($data);
|
||||||
|
if (setting('app-editor') !== 'markdown') {
|
||||||
|
$draft->markdown = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$draft->save();
|
||||||
|
return $draft;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish a draft page to make it a normal page.
|
||||||
|
* Sets the slug and updates the content.
|
||||||
|
* @param Page $draftPage
|
||||||
|
* @param array $input
|
||||||
|
* @return Page
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function publishPageDraft(Page $draftPage, array $input)
|
||||||
|
{
|
||||||
|
$draftPage->fill($input);
|
||||||
|
|
||||||
|
// Save page tags if present
|
||||||
|
if (isset($input['tags'])) {
|
||||||
|
$this->tagRepo->saveTagsToEntity($draftPage, $input['tags']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$draftPage->slug = $this->findSuitableSlug('page', $draftPage->name, false, $draftPage->book->id);
|
||||||
|
$draftPage->html = $this->formatHtml($input['html']);
|
||||||
|
$draftPage->text = $this->pageToPlainText($draftPage);
|
||||||
|
$draftPage->draft = false;
|
||||||
|
$draftPage->revision_count = 1;
|
||||||
|
|
||||||
|
$draftPage->save();
|
||||||
|
$this->savePageRevision($draftPage, trans('entities.pages_initial_revision'));
|
||||||
|
$this->searchService->indexEntity($draftPage);
|
||||||
|
return $draftPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base query for getting user update drafts.
|
||||||
|
* @param Page $page
|
||||||
|
* @param $userId
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function userUpdatePageDraftsQuery(Page $page, int $userId)
|
||||||
|
{
|
||||||
|
return $this->entityProvider->pageRevision->where('created_by', '=', $userId)
|
||||||
|
->where('type', 'update_draft')
|
||||||
|
->where('page_id', '=', $page->id)
|
||||||
|
->orderBy('created_at', 'desc');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest updated draft revision for a particular page and user.
|
||||||
|
* @param Page $page
|
||||||
|
* @param $userId
|
||||||
|
* @return PageRevision|null
|
||||||
|
*/
|
||||||
|
public function getUserPageDraft(Page $page, int $userId)
|
||||||
|
{
|
||||||
|
return $this->userUpdatePageDraftsQuery($page, $userId)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the notification message that informs the user that they are editing a draft page.
|
||||||
|
* @param PageRevision $draft
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUserPageDraftMessage(PageRevision $draft)
|
||||||
|
{
|
||||||
|
$message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
|
||||||
|
if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) {
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
return $message . "\n" . trans('entities.pages_draft_edited_notification');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A query to check for active update drafts on a particular page.
|
||||||
|
* @param Page $page
|
||||||
|
* @param int $minRange
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function activePageEditingQuery(Page $page, int $minRange = null)
|
||||||
|
{
|
||||||
|
$query = $this->entityProvider->pageRevision->where('type', '=', 'update_draft')
|
||||||
|
->where('page_id', '=', $page->id)
|
||||||
|
->where('updated_at', '>', $page->updated_at)
|
||||||
|
->where('created_by', '!=', user()->id)
|
||||||
|
->with('createdBy');
|
||||||
|
|
||||||
|
if ($minRange !== null) {
|
||||||
|
$query = $query->where('updated_at', '>=', Carbon::now()->subMinutes($minRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a page is being actively editing.
|
||||||
|
* Checks for edits since last page updated.
|
||||||
|
* Passing in a minuted range will check for edits
|
||||||
|
* within the last x minutes.
|
||||||
|
* @param Page $page
|
||||||
|
* @param int $minRange
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isPageEditingActive(Page $page, int $minRange = null)
|
||||||
|
{
|
||||||
|
$draftSearch = $this->activePageEditingQuery($page, $minRange);
|
||||||
|
return $draftSearch->count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a notification message concerning the editing activity on a particular page.
|
||||||
|
* @param Page $page
|
||||||
|
* @param int $minRange
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPageEditingActiveMessage(Page $page, int $minRange = null)
|
||||||
|
{
|
||||||
|
$pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get();
|
||||||
|
|
||||||
|
$userMessage = $pageDraftEdits->count() > 1 ? trans('entities.pages_draft_edit_active.start_a', ['count' => $pageDraftEdits->count()]): trans('entities.pages_draft_edit_active.start_b', ['userName' => $pageDraftEdits->first()->createdBy->name]);
|
||||||
|
$timeMessage = $minRange === null ? trans('entities.pages_draft_edit_active.time_a') : trans('entities.pages_draft_edit_active.time_b', ['minCount'=>$minRange]);
|
||||||
|
return trans('entities.pages_draft_edit_active.message', ['start' => $userMessage, 'time' => $timeMessage]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the headers on the page to get a navigation menu
|
||||||
|
* @param string $pageContent
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getPageNav(string $pageContent)
|
||||||
|
{
|
||||||
|
if ($pageContent == '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
libxml_use_internal_errors(true);
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
$doc->loadHTML(mb_convert_encoding($pageContent, 'HTML-ENTITIES', 'UTF-8'));
|
||||||
|
$xPath = new DOMXPath($doc);
|
||||||
|
$headers = $xPath->query("//h1|//h2|//h3|//h4|//h5|//h6");
|
||||||
|
|
||||||
|
if (is_null($headers)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$tree = collect([]);
|
||||||
|
foreach ($headers as $header) {
|
||||||
|
$text = $header->nodeValue;
|
||||||
|
$tree->push([
|
||||||
|
'nodeName' => strtolower($header->nodeName),
|
||||||
|
'level' => intval(str_replace('h', '', $header->nodeName)),
|
||||||
|
'link' => '#' . $header->getAttribute('id'),
|
||||||
|
'text' => strlen($text) > 30 ? substr($text, 0, 27) . '...' : $text
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalise headers if only smaller headers have been used
|
||||||
|
if (count($tree) > 0) {
|
||||||
|
$minLevel = $tree->pluck('level')->min();
|
||||||
|
$tree = $tree->map(function ($header) use ($minLevel) {
|
||||||
|
$header['level'] -= ($minLevel - 2);
|
||||||
|
return $header;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return $tree->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores a revision's content back into a page.
|
||||||
|
* @param Page $page
|
||||||
|
* @param Book $book
|
||||||
|
* @param int $revisionId
|
||||||
|
* @return Page
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function restorePageRevision(Page $page, Book $book, int $revisionId)
|
||||||
|
{
|
||||||
|
$page->revision_count++;
|
||||||
|
$this->savePageRevision($page);
|
||||||
|
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
||||||
|
$page->fill($revision->toArray());
|
||||||
|
$page->slug = $this->findSuitableSlug('page', $page->name, $page->id, $book->id);
|
||||||
|
$page->text = $this->pageToPlainText($page);
|
||||||
|
$page->updated_by = user()->id;
|
||||||
|
$page->save();
|
||||||
|
$this->searchService->indexEntity($page);
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the page's parent to the given entity.
|
||||||
|
* @param Page $page
|
||||||
|
* @param Entity $parent
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function changePageParent(Page $page, Entity $parent)
|
||||||
|
{
|
||||||
|
$book = $parent->isA('book') ? $parent : $parent->book;
|
||||||
|
$page->chapter_id = $parent->isA('chapter') ? $parent->id : 0;
|
||||||
|
$page->save();
|
||||||
|
if ($page->book->id !== $book->id) {
|
||||||
|
$page = $this->changeBook('page', $book->id, $page);
|
||||||
|
}
|
||||||
|
$page->load('book');
|
||||||
|
$this->permissionService->buildJointPermissionsForEntity($book);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a copy of a page in a new location with a new name.
|
||||||
|
* @param \BookStack\Entities\Page $page
|
||||||
|
* @param \BookStack\Entities\Entity $newParent
|
||||||
|
* @param string $newName
|
||||||
|
* @return \BookStack\Entities\Page
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function copyPage(Page $page, Entity $newParent, string $newName = '')
|
||||||
|
{
|
||||||
|
$newBook = $newParent->isA('book') ? $newParent : $newParent->book;
|
||||||
|
$newChapter = $newParent->isA('chapter') ? $newParent : null;
|
||||||
|
$copyPage = $this->getDraftPage($newBook, $newChapter);
|
||||||
|
$pageData = $page->getAttributes();
|
||||||
|
|
||||||
|
// Update name
|
||||||
|
if (!empty($newName)) {
|
||||||
|
$pageData['name'] = $newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy tags from previous page if set
|
||||||
|
if ($page->tags) {
|
||||||
|
$pageData['tags'] = [];
|
||||||
|
foreach ($page->tags as $tag) {
|
||||||
|
$pageData['tags'][] = ['name' => $tag->name, 'value' => $tag->value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set priority
|
||||||
|
if ($newParent->isA('chapter')) {
|
||||||
|
$pageData['priority'] = $this->getNewChapterPriority($newParent);
|
||||||
|
} else {
|
||||||
|
$pageData['priority'] = $this->getNewBookPriority($newParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->publishPageDraft($copyPage, $pageData);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,34 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
use BookStack\Book;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Bookshelf;
|
|
||||||
use BookStack\Chapter;
|
|
||||||
use BookStack\Entity;
|
|
||||||
use BookStack\Page;
|
|
||||||
use BookStack\SearchTerm;
|
|
||||||
use Illuminate\Database\Connection;
|
use Illuminate\Database\Connection;
|
||||||
|
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class SearchService
|
class SearchService
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var SearchTerm
|
||||||
|
*/
|
||||||
protected $searchTerm;
|
protected $searchTerm;
|
||||||
protected $bookshelf;
|
|
||||||
protected $book;
|
|
||||||
protected $chapter;
|
|
||||||
protected $page;
|
|
||||||
protected $db;
|
|
||||||
protected $permissionService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Entity[]
|
* @var EntityProvider
|
||||||
*/
|
*/
|
||||||
protected $entities;
|
protected $entityProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Connection
|
||||||
|
*/
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PermissionService
|
||||||
|
*/
|
||||||
|
protected $permissionService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acceptable operators to be used in a query
|
* Acceptable operators to be used in a query
|
||||||
|
@ -35,27 +39,15 @@ class SearchService
|
||||||
/**
|
/**
|
||||||
* SearchService constructor.
|
* SearchService constructor.
|
||||||
* @param SearchTerm $searchTerm
|
* @param SearchTerm $searchTerm
|
||||||
* @param Bookshelf $bookshelf
|
* @param EntityProvider $entityProvider
|
||||||
* @param Book $book
|
|
||||||
* @param Chapter $chapter
|
|
||||||
* @param Page $page
|
|
||||||
* @param Connection $db
|
* @param Connection $db
|
||||||
* @param PermissionService $permissionService
|
* @param PermissionService $permissionService
|
||||||
*/
|
*/
|
||||||
public function __construct(SearchTerm $searchTerm, Bookshelf $bookshelf, Book $book, Chapter $chapter, Page $page, Connection $db, PermissionService $permissionService)
|
public function __construct(SearchTerm $searchTerm, EntityProvider $entityProvider, Connection $db, PermissionService $permissionService)
|
||||||
{
|
{
|
||||||
$this->searchTerm = $searchTerm;
|
$this->searchTerm = $searchTerm;
|
||||||
$this->bookshelf = $bookshelf;
|
$this->entityProvider = $entityProvider;
|
||||||
$this->book = $book;
|
|
||||||
$this->chapter = $chapter;
|
|
||||||
$this->page = $page;
|
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->entities = [
|
|
||||||
'bookshelf' => $this->bookshelf,
|
|
||||||
'page' => $this->page,
|
|
||||||
'chapter' => $this->chapter,
|
|
||||||
'book' => $this->book
|
|
||||||
];
|
|
||||||
$this->permissionService = $permissionService;
|
$this->permissionService = $permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +72,7 @@ class SearchService
|
||||||
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20, $action = 'view')
|
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20, $action = 'view')
|
||||||
{
|
{
|
||||||
$terms = $this->parseSearchString($searchString);
|
$terms = $this->parseSearchString($searchString);
|
||||||
$entityTypes = array_keys($this->entities);
|
$entityTypes = array_keys($this->entityProvider->all());
|
||||||
$entityTypesToSearch = $entityTypes;
|
$entityTypesToSearch = $entityTypes;
|
||||||
|
|
||||||
if ($entityType !== 'all') {
|
if ($entityType !== 'all') {
|
||||||
|
@ -177,17 +169,17 @@ class SearchService
|
||||||
* @param array $terms
|
* @param array $terms
|
||||||
* @param string $entityType
|
* @param string $entityType
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return EloquentBuilder
|
||||||
*/
|
*/
|
||||||
protected function buildEntitySearchQuery($terms, $entityType = 'page', $action = 'view')
|
protected function buildEntitySearchQuery($terms, $entityType = 'page', $action = 'view')
|
||||||
{
|
{
|
||||||
$entity = $this->getEntity($entityType);
|
$entity = $this->entityProvider->get($entityType);
|
||||||
$entitySelect = $entity->newQuery();
|
$entitySelect = $entity->newQuery();
|
||||||
|
|
||||||
// Handle normal search terms
|
// Handle normal search terms
|
||||||
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', '=', $entity->getMorphClass());
|
||||||
$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 .'%');
|
||||||
|
@ -201,9 +193,9 @@ 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 (EloquentBuilder $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 (EloquentBuilder $query) use ($inputTerm, $entity) {
|
||||||
$query->where('name', 'like', '%'.$inputTerm .'%')
|
$query->where('name', 'like', '%'.$inputTerm .'%')
|
||||||
->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
|
->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
|
||||||
});
|
});
|
||||||
|
@ -291,14 +283,14 @@ class SearchService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a tag search term onto a entity query.
|
* Apply a tag search term onto a entity query.
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
* @param EloquentBuilder $query
|
||||||
* @param string $tagTerm
|
* @param string $tagTerm
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function applyTagSearch(\Illuminate\Database\Eloquent\Builder $query, $tagTerm)
|
protected function applyTagSearch(EloquentBuilder $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 (EloquentBuilder $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] : '';
|
||||||
|
@ -323,16 +315,6 @@ class SearchService
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an entity instance via type.
|
|
||||||
* @param $type
|
|
||||||
* @return Entity
|
|
||||||
*/
|
|
||||||
protected function getEntity($type)
|
|
||||||
{
|
|
||||||
return $this->entities[strtolower($type)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index the given entity.
|
* Index the given entity.
|
||||||
* @param Entity $entity
|
* @param Entity $entity
|
||||||
|
@ -352,7 +334,7 @@ class SearchService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index multiple Entities at once
|
* Index multiple Entities at once
|
||||||
* @param Entity[] $entities
|
* @param \BookStack\Entities\Entity[] $entities
|
||||||
*/
|
*/
|
||||||
protected function indexEntities($entities)
|
protected function indexEntities($entities)
|
||||||
{
|
{
|
||||||
|
@ -380,7 +362,7 @@ class SearchService
|
||||||
{
|
{
|
||||||
$this->searchTerm->truncate();
|
$this->searchTerm->truncate();
|
||||||
|
|
||||||
foreach ($this->entities as $entityModel) {
|
foreach ($this->entityProvider->all() as $entityModel) {
|
||||||
$selectFields = ['id', 'name', $entityModel->textField];
|
$selectFields = ['id', 'name', $entityModel->textField];
|
||||||
$entityModel->newQuery()->select($selectFields)->chunk(1000, function ($entities) {
|
$entityModel->newQuery()->select($selectFields)->chunk(1000, function ($entities) {
|
||||||
$this->indexEntities($entities);
|
$this->indexEntities($entities);
|
||||||
|
@ -434,7 +416,7 @@ class SearchService
|
||||||
* Custom entity search filters
|
* Custom entity search filters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected function filterUpdatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterUpdatedAfter(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$date = date_create($input);
|
$date = date_create($input);
|
||||||
|
@ -444,7 +426,7 @@ class SearchService
|
||||||
$query->where('updated_at', '>=', $date);
|
$query->where('updated_at', '>=', $date);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterUpdatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterUpdatedBefore(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$date = date_create($input);
|
$date = date_create($input);
|
||||||
|
@ -454,7 +436,7 @@ class SearchService
|
||||||
$query->where('updated_at', '<', $date);
|
$query->where('updated_at', '<', $date);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterCreatedAfter(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterCreatedAfter(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$date = date_create($input);
|
$date = date_create($input);
|
||||||
|
@ -464,7 +446,7 @@ class SearchService
|
||||||
$query->where('created_at', '>=', $date);
|
$query->where('created_at', '>=', $date);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterCreatedBefore(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterCreatedBefore(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$date = date_create($input);
|
$date = date_create($input);
|
||||||
|
@ -474,7 +456,7 @@ class SearchService
|
||||||
$query->where('created_at', '<', $date);
|
$query->where('created_at', '<', $date);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterCreatedBy(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
if (!is_numeric($input) && $input !== 'me') {
|
if (!is_numeric($input) && $input !== 'me') {
|
||||||
return;
|
return;
|
||||||
|
@ -485,7 +467,7 @@ class SearchService
|
||||||
$query->where('created_by', '=', $input);
|
$query->where('created_by', '=', $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterUpdatedBy(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
if (!is_numeric($input) && $input !== 'me') {
|
if (!is_numeric($input) && $input !== 'me') {
|
||||||
return;
|
return;
|
||||||
|
@ -496,41 +478,41 @@ class SearchService
|
||||||
$query->where('updated_by', '=', $input);
|
$query->where('updated_by', '=', $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterInName(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterInName(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
$query->where('name', 'like', '%' .$input. '%');
|
$query->where('name', 'like', '%' .$input. '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterInTitle(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterInTitle(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
$this->filterInName($query, $model, $input);
|
$this->filterInName($query, $model, $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterInBody(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterInBody(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
$query->where($model->textField, 'like', '%' .$input. '%');
|
$query->where($model->textField, 'like', '%' .$input. '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterIsRestricted(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterIsRestricted(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
$query->where('restricted', '=', true);
|
$query->where('restricted', '=', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterViewedByMe(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterViewedByMe(EloquentBuilder $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(EloquentBuilder $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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterSortBy(EloquentBuilder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
$functionName = camel_case('sort_by_' . $input);
|
$functionName = camel_case('sort_by_' . $input);
|
||||||
if (method_exists($this, $functionName)) {
|
if (method_exists($this, $functionName)) {
|
||||||
|
@ -543,7 +525,7 @@ class SearchService
|
||||||
* Sorting filter options
|
* Sorting filter options
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected function sortByLastCommented(\Illuminate\Database\Eloquent\Builder $query, Entity $model)
|
protected function sortByLastCommented(EloquentBuilder $query, Entity $model)
|
||||||
{
|
{
|
||||||
$commentsTable = $this->db->getTablePrefix() . 'comments';
|
$commentsTable = $this->db->getTablePrefix() . 'comments';
|
||||||
$morphClass = str_replace('\\', '\\\\', $model->getMorphClass());
|
$morphClass = str_replace('\\', '\\\\', $model->getMorphClass());
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Entities;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class SearchTerm extends Model
|
class SearchTerm extends Model
|
||||||
{
|
{
|
|
@ -3,12 +3,12 @@
|
||||||
namespace BookStack\Exceptions;
|
namespace BookStack\Exceptions;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Auth\AuthenticationException;
|
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
|
||||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
|
||||||
use Illuminate\Auth\Access\AuthorizationException;
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
|
use Illuminate\Auth\AuthenticationException;
|
||||||
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
class Handler extends ExceptionHandler
|
class Handler extends ExceptionHandler
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack\Services\Facades;
|
<?php namespace BookStack\Facades;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack\Services\Facades;
|
<?php namespace BookStack\Facades;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack\Services\Facades;
|
<?php namespace BookStack\Facades;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?php namespace BookStack\Services\Facades;
|
<?php namespace BookStack\Facades;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Exceptions\FileUploadException;
|
use BookStack\Exceptions\FileUploadException;
|
||||||
use BookStack\Attachment;
|
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Uploads\Attachment;
|
||||||
use BookStack\Services\AttachmentService;
|
use BookStack\Uploads\AttachmentService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class AttachmentController extends Controller
|
class AttachmentController extends Controller
|
||||||
|
@ -15,7 +15,7 @@ class AttachmentController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AttachmentController constructor.
|
* AttachmentController constructor.
|
||||||
* @param AttachmentService $attachmentService
|
* @param \BookStack\Uploads\AttachmentService $attachmentService
|
||||||
* @param Attachment $attachment
|
* @param Attachment $attachment
|
||||||
* @param EntityRepo $entityRepo
|
* @param EntityRepo $entityRepo
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
namespace BookStack\Http\Controllers\Auth;
|
namespace BookStack\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use BookStack\Auth\Access\LdapService;
|
||||||
|
use BookStack\Auth\Access\SocialAuthService;
|
||||||
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Exceptions\AuthException;
|
use BookStack\Exceptions\AuthException;
|
||||||
use BookStack\Http\Controllers\Controller;
|
use BookStack\Http\Controllers\Controller;
|
||||||
use BookStack\Repos\UserRepo;
|
|
||||||
use BookStack\Services\LdapService;
|
|
||||||
use BookStack\Services\SocialAuthService;
|
|
||||||
use Illuminate\Contracts\Auth\Authenticatable;
|
use Illuminate\Contracts\Auth\Authenticatable;
|
||||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -43,9 +43,9 @@ class LoginController extends Controller
|
||||||
/**
|
/**
|
||||||
* Create a new controller instance.
|
* Create a new controller instance.
|
||||||
*
|
*
|
||||||
* @param SocialAuthService $socialAuthService
|
* @param \BookStack\Auth\\BookStack\Auth\Access\SocialAuthService $socialAuthService
|
||||||
* @param LdapService $ldapService
|
* @param LdapService $ldapService
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(SocialAuthService $socialAuthService, LdapService $ldapService, UserRepo $userRepo)
|
public function __construct(SocialAuthService $socialAuthService, LdapService $ldapService, UserRepo $userRepo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,21 +2,19 @@
|
||||||
|
|
||||||
namespace BookStack\Http\Controllers\Auth;
|
namespace BookStack\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use BookStack\Auth\SocialAccount;
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
||||||
use BookStack\Exceptions\SocialSignInException;
|
use BookStack\Exceptions\SocialSignInException;
|
||||||
use BookStack\Exceptions\UserRegistrationException;
|
use BookStack\Exceptions\UserRegistrationException;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Http\Controllers\Controller;
|
||||||
use BookStack\Services\EmailConfirmationService;
|
|
||||||
use BookStack\Services\SocialAuthService;
|
|
||||||
use BookStack\SocialAccount;
|
|
||||||
use BookStack\User;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Validator;
|
|
||||||
use BookStack\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
|
||||||
use Laravel\Socialite\Contracts\User as SocialUser;
|
use Laravel\Socialite\Contracts\User as SocialUser;
|
||||||
|
use Validator;
|
||||||
|
|
||||||
class RegisterController extends Controller
|
class RegisterController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -48,11 +46,11 @@ class RegisterController extends Controller
|
||||||
/**
|
/**
|
||||||
* Create a new controller instance.
|
* Create a new controller instance.
|
||||||
*
|
*
|
||||||
* @param SocialAuthService $socialAuthService
|
* @param \BookStack\Auth\Access\SocialAuthService $socialAuthService
|
||||||
* @param EmailConfirmationService $emailConfirmationService
|
* @param \BookStack\Auth\EmailConfirmationService $emailConfirmationService
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
|
public function __construct(\BookStack\Auth\Access\SocialAuthService $socialAuthService, \BookStack\Auth\Access\EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
|
||||||
{
|
{
|
||||||
$this->middleware('guest')->only(['getRegister', 'postRegister', 'socialRegister']);
|
$this->middleware('guest')->only(['getRegister', 'postRegister', 'socialRegister']);
|
||||||
$this->socialAuthService = $socialAuthService;
|
$this->socialAuthService = $socialAuthService;
|
||||||
|
@ -119,7 +117,7 @@ class RegisterController extends Controller
|
||||||
/**
|
/**
|
||||||
* Create a new user instance after a valid registration.
|
* Create a new user instance after a valid registration.
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return User
|
* @return \BookStack\Auth\User
|
||||||
*/
|
*/
|
||||||
protected function create(array $data)
|
protected function create(array $data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
use BookStack\Book;
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Entities\Book;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Services\ExportService;
|
use BookStack\Entities\ExportService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Views;
|
use Views;
|
||||||
|
@ -19,8 +19,8 @@ class BookController extends Controller
|
||||||
/**
|
/**
|
||||||
* BookController constructor.
|
* BookController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param EntityRepo $entityRepo
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
* @param ExportService $exportService
|
* @param \BookStack\Entities\ExportService $exportService
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
||||||
{
|
{
|
||||||
|
@ -204,7 +204,7 @@ class BookController extends Controller
|
||||||
|
|
||||||
// Get the books involved in the sort
|
// Get the books involved in the sort
|
||||||
$bookIdsInvolved = $bookIdsInvolved->unique()->toArray();
|
$bookIdsInvolved = $bookIdsInvolved->unique()->toArray();
|
||||||
$booksInvolved = $this->entityRepo->book->newQuery()->whereIn('id', $bookIdsInvolved)->get();
|
$booksInvolved = $this->entityRepo->getManyById('book', $bookIdsInvolved, false, true);
|
||||||
// Throw permission error if invalid ids or inaccessible books given.
|
// Throw permission error if invalid ids or inaccessible books given.
|
||||||
if (count($bookIdsInvolved) !== count($booksInvolved)) {
|
if (count($bookIdsInvolved) !== count($booksInvolved)) {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
use BookStack\Book;
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Bookshelf;
|
use BookStack\Entities\Bookshelf;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Entities\ExportService;
|
||||||
use BookStack\Services\ExportService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Views;
|
use Views;
|
||||||
|
@ -19,9 +18,9 @@ class BookshelfController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BookController constructor.
|
* BookController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param \BookStack\Entities\Repos\EntityRepo $entityRepo
|
||||||
* @param UserRepo $userRepo
|
* @param UserRepo $userRepo
|
||||||
* @param ExportService $exportService
|
* @param \BookStack\Entities\ExportService $exportService
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Auth\UserRepo;
|
||||||
use BookStack\Repos\UserRepo;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Services\ExportService;
|
use BookStack\Entities\ExportService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Views;
|
use Views;
|
||||||
|
@ -19,7 +19,7 @@ class ChapterController extends Controller
|
||||||
* ChapterController constructor.
|
* ChapterController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param EntityRepo $entityRepo
|
||||||
* @param UserRepo $userRepo
|
* @param UserRepo $userRepo
|
||||||
* @param ExportService $exportService
|
* @param \BookStack\Entities\ExportService $exportService
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
use BookStack\Repos\CommentRepo;
|
use BookStack\Actions\CommentRepo;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ class CommentController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommentController constructor.
|
* CommentController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param \BookStack\Entities\Repos\EntityRepo $entityRepo
|
||||||
* @param CommentRepo $commentRepo
|
* @param \BookStack\Actions\CommentRepo $commentRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, CommentRepo $commentRepo)
|
public function __construct(EntityRepo $entityRepo, CommentRepo $commentRepo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
namespace BookStack\Http\Controllers;
|
namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
use BookStack\Ownable;
|
use BookStack\Ownable;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
|
||||||
use BookStack\User;
|
|
||||||
|
|
||||||
abstract class Controller extends BaseController
|
abstract class Controller extends BaseController
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Views;
|
use Views;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Repos\PageRepo;
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Uploads\Image;
|
||||||
use BookStack\Repos\ImageRepo;
|
use BookStack\Uploads\ImageRepo;
|
||||||
use Illuminate\Filesystem\Filesystem as File;
|
use Illuminate\Filesystem\Filesystem as File;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use BookStack\Image;
|
|
||||||
use BookStack\Repos\PageRepo;
|
|
||||||
|
|
||||||
class ImageController extends Controller
|
class ImageController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -220,7 +219,7 @@ class ImageController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the usage of an image on pages.
|
* Show the usage of an image on pages.
|
||||||
* @param EntityRepo $entityRepo
|
* @param \BookStack\Entities\Repos\EntityRepo $entityRepo
|
||||||
* @param $id
|
* @param $id
|
||||||
* @return \Illuminate\Http\JsonResponse
|
* @return \Illuminate\Http\JsonResponse
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,31 +1,32 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Activity;
|
use Activity;
|
||||||
|
use BookStack\Auth\UserRepo;
|
||||||
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
|
use BookStack\Entities\ExportService;
|
||||||
|
use BookStack\Entities\Repos\PageRepo;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Repos\EntityRepo;
|
use GatherContent\Htmldiff\Htmldiff;
|
||||||
use BookStack\Repos\UserRepo;
|
|
||||||
use BookStack\Services\ExportService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Views;
|
use Views;
|
||||||
use GatherContent\Htmldiff\Htmldiff;
|
|
||||||
|
|
||||||
class PageController extends Controller
|
class PageController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $entityRepo;
|
protected $pageRepo;
|
||||||
protected $exportService;
|
protected $exportService;
|
||||||
protected $userRepo;
|
protected $userRepo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PageController constructor.
|
* PageController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param \BookStack\Entities\Repos\PageRepo $pageRepo
|
||||||
* @param ExportService $exportService
|
* @param \BookStack\Entities\ExportService $exportService
|
||||||
* @param UserRepo $userRepo
|
* @param UserRepo $userRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(EntityRepo $entityRepo, ExportService $exportService, UserRepo $userRepo)
|
public function __construct(PageRepo $pageRepo, ExportService $exportService, UserRepo $userRepo)
|
||||||
{
|
{
|
||||||
$this->entityRepo = $entityRepo;
|
$this->pageRepo = $pageRepo;
|
||||||
$this->exportService = $exportService;
|
$this->exportService = $exportService;
|
||||||
$this->userRepo = $userRepo;
|
$this->userRepo = $userRepo;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
@ -42,11 +43,11 @@ class PageController extends Controller
|
||||||
public function create($bookSlug, $chapterSlug = null)
|
public function create($bookSlug, $chapterSlug = null)
|
||||||
{
|
{
|
||||||
if ($chapterSlug !== null) {
|
if ($chapterSlug !== null) {
|
||||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
$chapter = $this->pageRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||||
$book = $chapter->book;
|
$book = $chapter->book;
|
||||||
} else {
|
} else {
|
||||||
$chapter = null;
|
$chapter = null;
|
||||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
$book = $this->pageRepo->getBySlug('book', $bookSlug);
|
||||||
}
|
}
|
||||||
|
|
||||||
$parent = $chapter ? $chapter : $book;
|
$parent = $chapter ? $chapter : $book;
|
||||||
|
@ -54,7 +55,7 @@ class PageController extends Controller
|
||||||
|
|
||||||
// Redirect to draft edit screen if signed in
|
// Redirect to draft edit screen if signed in
|
||||||
if ($this->signedIn) {
|
if ($this->signedIn) {
|
||||||
$draft = $this->entityRepo->getDraftPage($book, $chapter);
|
$draft = $this->pageRepo->getDraftPage($book, $chapter);
|
||||||
return redirect($draft->getUrl());
|
return redirect($draft->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,18 +79,18 @@ class PageController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($chapterSlug !== null) {
|
if ($chapterSlug !== null) {
|
||||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
$chapter = $this->pageRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||||
$book = $chapter->book;
|
$book = $chapter->book;
|
||||||
} else {
|
} else {
|
||||||
$chapter = null;
|
$chapter = null;
|
||||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
$book = $this->pageRepo->getBySlug('book', $bookSlug);
|
||||||
}
|
}
|
||||||
|
|
||||||
$parent = $chapter ? $chapter : $book;
|
$parent = $chapter ? $chapter : $book;
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission('page-create', $parent);
|
||||||
|
|
||||||
$page = $this->entityRepo->getDraftPage($book, $chapter);
|
$page = $this->pageRepo->getDraftPage($book, $chapter);
|
||||||
$this->entityRepo->publishPageDraft($page, [
|
$this->pageRepo->publishPageDraft($page, [
|
||||||
'name' => $request->get('name'),
|
'name' => $request->get('name'),
|
||||||
'html' => ''
|
'html' => ''
|
||||||
]);
|
]);
|
||||||
|
@ -104,7 +105,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function editDraft($bookSlug, $pageId)
|
public function editDraft($bookSlug, $pageId)
|
||||||
{
|
{
|
||||||
$draft = $this->entityRepo->getById('page', $pageId, true);
|
$draft = $this->pageRepo->getById('page', $pageId, true);
|
||||||
$this->checkOwnablePermission('page-create', $draft->parent);
|
$this->checkOwnablePermission('page-create', $draft->parent);
|
||||||
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
||||||
|
|
||||||
|
@ -131,19 +132,19 @@ class PageController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$input = $request->all();
|
$input = $request->all();
|
||||||
$draftPage = $this->entityRepo->getById('page', $pageId, true);
|
$draftPage = $this->pageRepo->getById('page', $pageId, true);
|
||||||
$book = $draftPage->book;
|
$book = $draftPage->book;
|
||||||
|
|
||||||
$parent = $draftPage->parent;
|
$parent = $draftPage->parent;
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission('page-create', $parent);
|
||||||
|
|
||||||
if ($parent->isA('chapter')) {
|
if ($parent->isA('chapter')) {
|
||||||
$input['priority'] = $this->entityRepo->getNewChapterPriority($parent);
|
$input['priority'] = $this->pageRepo->getNewChapterPriority($parent);
|
||||||
} else {
|
} else {
|
||||||
$input['priority'] = $this->entityRepo->getNewBookPriority($parent);
|
$input['priority'] = $this->pageRepo->getNewBookPriority($parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $this->entityRepo->publishPageDraft($draftPage, $input);
|
$page = $this->pageRepo->publishPageDraft($draftPage, $input);
|
||||||
|
|
||||||
Activity::add($page, 'page_create', $book->id);
|
Activity::add($page, 'page_create', $book->id);
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
|
@ -160,9 +161,9 @@ class PageController extends Controller
|
||||||
public function show($bookSlug, $pageSlug)
|
public function show($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
} catch (NotFoundException $e) {
|
} catch (NotFoundException $e) {
|
||||||
$page = $this->entityRepo->getPageByOldSlug($pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageByOldSlug($pageSlug, $bookSlug);
|
||||||
if ($page === null) {
|
if ($page === null) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -171,9 +172,9 @@ class PageController extends Controller
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-view', $page);
|
$this->checkOwnablePermission('page-view', $page);
|
||||||
|
|
||||||
$page->html = $this->entityRepo->renderPage($page);
|
$page->html = $this->pageRepo->renderPage($page);
|
||||||
$sidebarTree = $this->entityRepo->getBookChildren($page->book);
|
$sidebarTree = $this->pageRepo->getBookChildren($page->book);
|
||||||
$pageNav = $this->entityRepo->getPageNav($page->html);
|
$pageNav = $this->pageRepo->getPageNav($page->html);
|
||||||
|
|
||||||
// check if the comment's are enabled
|
// check if the comment's are enabled
|
||||||
$commentsEnabled = !setting('app-disable-comments');
|
$commentsEnabled = !setting('app-disable-comments');
|
||||||
|
@ -199,7 +200,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function getPageAjax($pageId)
|
public function getPageAjax($pageId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getById('page', $pageId);
|
$page = $this->pageRepo->getById('page', $pageId);
|
||||||
return response()->json($page);
|
return response()->json($page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,28 +209,29 @@ class PageController extends Controller
|
||||||
* @param string $bookSlug
|
* @param string $bookSlug
|
||||||
* @param string $pageSlug
|
* @param string $pageSlug
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function edit($bookSlug, $pageSlug)
|
public function edit($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
$this->setPageTitle(trans('entities.pages_editing_named', ['pageName'=>$page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_editing_named', ['pageName'=>$page->getShortName()]));
|
||||||
$page->isDraft = false;
|
$page->isDraft = false;
|
||||||
|
|
||||||
// Check for active editing
|
// Check for active editing
|
||||||
$warnings = [];
|
$warnings = [];
|
||||||
if ($this->entityRepo->isPageEditingActive($page, 60)) {
|
if ($this->pageRepo->isPageEditingActive($page, 60)) {
|
||||||
$warnings[] = $this->entityRepo->getPageEditingActiveMessage($page, 60);
|
$warnings[] = $this->pageRepo->getPageEditingActiveMessage($page, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a current draft version for this user
|
// Check for a current draft version for this user
|
||||||
if ($this->entityRepo->hasUserGotPageDraft($page, $this->currentUser->id)) {
|
$userPageDraft = $this->pageRepo->getUserPageDraft($page, $this->currentUser->id);
|
||||||
$draft = $this->entityRepo->getUserPageDraft($page, $this->currentUser->id);
|
if ($userPageDraft !== null) {
|
||||||
$page->name = $draft->name;
|
$page->name = $userPageDraft->name;
|
||||||
$page->html = $draft->html;
|
$page->html = $userPageDraft->html;
|
||||||
$page->markdown = $draft->markdown;
|
$page->markdown = $userPageDraft->markdown;
|
||||||
$page->isDraft = true;
|
$page->isDraft = true;
|
||||||
$warnings [] = $this->entityRepo->getUserPageDraftMessage($draft);
|
$warnings [] = $this->pageRepo->getUserPageDraftMessage($userPageDraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($warnings) > 0) {
|
if (count($warnings) > 0) {
|
||||||
|
@ -257,9 +259,9 @@ class PageController extends Controller
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'name' => 'required|string|max:255'
|
'name' => 'required|string|max:255'
|
||||||
]);
|
]);
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
$this->entityRepo->updatePage($page, $page->book->id, $request->all());
|
$this->pageRepo->updatePage($page, $page->book->id, $request->all());
|
||||||
Activity::add($page, 'page_update', $page->book->id);
|
Activity::add($page, 'page_update', $page->book->id);
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
@ -272,7 +274,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function saveDraft(Request $request, $pageId)
|
public function saveDraft(Request $request, $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getById('page', $pageId, true);
|
$page = $this->pageRepo->getById('page', $pageId, true);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
|
|
||||||
if (!$this->signedIn) {
|
if (!$this->signedIn) {
|
||||||
|
@ -282,7 +284,7 @@ class PageController extends Controller
|
||||||
], 500);
|
], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$draft = $this->entityRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown']));
|
$draft = $this->pageRepo->updatePageDraft($page, $request->only(['name', 'html', 'markdown']));
|
||||||
|
|
||||||
$updateTime = $draft->updated_at->timestamp;
|
$updateTime = $draft->updated_at->timestamp;
|
||||||
return response()->json([
|
return response()->json([
|
||||||
|
@ -300,7 +302,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function redirectFromLink($pageId)
|
public function redirectFromLink($pageId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getById('page', $pageId);
|
$page = $this->pageRepo->getById('page', $pageId);
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +314,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showDelete($bookSlug, $pageSlug)
|
public function showDelete($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission('page-delete', $page);
|
||||||
$this->setPageTitle(trans('entities.pages_delete_named', ['pageName'=>$page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_delete_named', ['pageName'=>$page->getShortName()]));
|
||||||
return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
|
return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
|
||||||
|
@ -328,7 +330,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showDeleteDraft($bookSlug, $pageId)
|
public function showDeleteDraft($bookSlug, $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getById('page', $pageId, true);
|
$page = $this->pageRepo->getById('page', $pageId, true);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName'=>$page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName'=>$page->getShortName()]));
|
||||||
return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
|
return view('pages/delete', ['book' => $page->book, 'page' => $page, 'current' => $page]);
|
||||||
|
@ -343,10 +345,10 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroy($bookSlug, $pageSlug)
|
public function destroy($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$book = $page->book;
|
$book = $page->book;
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission('page-delete', $page);
|
||||||
$this->entityRepo->destroyPage($page);
|
$this->pageRepo->destroyPage($page);
|
||||||
|
|
||||||
Activity::addMessage('page_delete', $book->id, $page->name);
|
Activity::addMessage('page_delete', $book->id, $page->name);
|
||||||
session()->flash('success', trans('entities.pages_delete_success'));
|
session()->flash('success', trans('entities.pages_delete_success'));
|
||||||
|
@ -362,11 +364,11 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroyDraft($bookSlug, $pageId)
|
public function destroyDraft($bookSlug, $pageId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getById('page', $pageId, true);
|
$page = $this->pageRepo->getById('page', $pageId, true);
|
||||||
$book = $page->book;
|
$book = $page->book;
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
session()->flash('success', trans('entities.pages_delete_draft_success'));
|
session()->flash('success', trans('entities.pages_delete_draft_success'));
|
||||||
$this->entityRepo->destroyPage($page);
|
$this->pageRepo->destroyPage($page);
|
||||||
return redirect($book->getUrl());
|
return redirect($book->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +380,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRevisions($bookSlug, $pageSlug)
|
public function showRevisions($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
|
$this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
|
||||||
return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
|
return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
|
||||||
}
|
}
|
||||||
|
@ -392,7 +394,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRevision($bookSlug, $pageSlug, $revisionId)
|
public function showRevision($bookSlug, $pageSlug, $revisionId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
||||||
if ($revision === null) {
|
if ($revision === null) {
|
||||||
abort(404);
|
abort(404);
|
||||||
|
@ -417,7 +419,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRevisionChanges($bookSlug, $pageSlug, $revisionId)
|
public function showRevisionChanges($bookSlug, $pageSlug, $revisionId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
$revision = $page->revisions()->where('id', '=', $revisionId)->first();
|
||||||
if ($revision === null) {
|
if ($revision === null) {
|
||||||
abort(404);
|
abort(404);
|
||||||
|
@ -447,9 +449,9 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function restoreRevision($bookSlug, $pageSlug, $revisionId)
|
public function restoreRevision($bookSlug, $pageSlug, $revisionId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
$page = $this->entityRepo->restorePageRevision($page, $page->book, $revisionId);
|
$page = $this->pageRepo->restorePageRevision($page, $page->book, $revisionId);
|
||||||
Activity::add($page, 'page_restore', $page->book->id);
|
Activity::add($page, 'page_restore', $page->book->id);
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
@ -466,7 +468,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroyRevision($bookSlug, $pageSlug, $revId)
|
public function destroyRevision($bookSlug, $pageSlug, $revId)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-delete', $page);
|
$this->checkOwnablePermission('page-delete', $page);
|
||||||
|
|
||||||
$revision = $page->revisions()->where('id', '=', $revId)->first();
|
$revision = $page->revisions()->where('id', '=', $revId)->first();
|
||||||
|
@ -497,8 +499,8 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function exportPdf($bookSlug, $pageSlug)
|
public function exportPdf($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$page->html = $this->entityRepo->renderPage($page);
|
$page->html = $this->pageRepo->renderPage($page);
|
||||||
$pdfContent = $this->exportService->pageToPdf($page);
|
$pdfContent = $this->exportService->pageToPdf($page);
|
||||||
return $this->downloadResponse($pdfContent, $pageSlug . '.pdf');
|
return $this->downloadResponse($pdfContent, $pageSlug . '.pdf');
|
||||||
}
|
}
|
||||||
|
@ -511,8 +513,8 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function exportHtml($bookSlug, $pageSlug)
|
public function exportHtml($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$page->html = $this->entityRepo->renderPage($page);
|
$page->html = $this->pageRepo->renderPage($page);
|
||||||
$containedHtml = $this->exportService->pageToContainedHtml($page);
|
$containedHtml = $this->exportService->pageToContainedHtml($page);
|
||||||
return $this->downloadResponse($containedHtml, $pageSlug . '.html');
|
return $this->downloadResponse($containedHtml, $pageSlug . '.html');
|
||||||
}
|
}
|
||||||
|
@ -525,7 +527,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function exportPlainText($bookSlug, $pageSlug)
|
public function exportPlainText($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$pageText = $this->exportService->pageToPlainText($page);
|
$pageText = $this->exportService->pageToPlainText($page);
|
||||||
return $this->downloadResponse($pageText, $pageSlug . '.txt');
|
return $this->downloadResponse($pageText, $pageSlug . '.txt');
|
||||||
}
|
}
|
||||||
|
@ -536,7 +538,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRecentlyCreated()
|
public function showRecentlyCreated()
|
||||||
{
|
{
|
||||||
$pages = $this->entityRepo->getRecentlyCreatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-created'));
|
$pages = $this->pageRepo->getRecentlyCreatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-created'));
|
||||||
return view('pages/detailed-listing', [
|
return view('pages/detailed-listing', [
|
||||||
'title' => trans('entities.recently_created_pages'),
|
'title' => trans('entities.recently_created_pages'),
|
||||||
'pages' => $pages
|
'pages' => $pages
|
||||||
|
@ -549,7 +551,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRecentlyUpdated()
|
public function showRecentlyUpdated()
|
||||||
{
|
{
|
||||||
$pages = $this->entityRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated'));
|
$pages = $this->pageRepo->getRecentlyUpdatedPaginated('page', 20)->setPath(baseUrl('/pages/recently-updated'));
|
||||||
return view('pages/detailed-listing', [
|
return view('pages/detailed-listing', [
|
||||||
'title' => trans('entities.recently_updated_pages'),
|
'title' => trans('entities.recently_updated_pages'),
|
||||||
'pages' => $pages
|
'pages' => $pages
|
||||||
|
@ -564,7 +566,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showRestrict($bookSlug, $pageSlug)
|
public function showRestrict($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $page);
|
$this->checkOwnablePermission('restrictions-manage', $page);
|
||||||
$roles = $this->userRepo->getRestrictableRoles();
|
$roles = $this->userRepo->getRestrictableRoles();
|
||||||
return view('pages/restrictions', [
|
return view('pages/restrictions', [
|
||||||
|
@ -582,7 +584,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showMove($bookSlug, $pageSlug)
|
public function showMove($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
return view('pages/move', [
|
return view('pages/move', [
|
||||||
'book' => $page->book,
|
'book' => $page->book,
|
||||||
|
@ -600,7 +602,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function move($bookSlug, $pageSlug, Request $request)
|
public function move($bookSlug, $pageSlug, Request $request)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection', null);
|
$entitySelection = $request->get('entity_selection', null);
|
||||||
|
@ -614,7 +616,7 @@ class PageController extends Controller
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$parent = $this->entityRepo->getById($entityType, $entityId);
|
$parent = $this->pageRepo->getById($entityType, $entityId);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
session()->flash(trans('entities.selected_book_chapter_not_found'));
|
session()->flash(trans('entities.selected_book_chapter_not_found'));
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
@ -622,7 +624,7 @@ class PageController extends Controller
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission('page-create', $parent);
|
||||||
|
|
||||||
$this->entityRepo->changePageParent($page, $parent);
|
$this->pageRepo->changePageParent($page, $parent);
|
||||||
Activity::add($page, 'page_move', $page->book->id);
|
Activity::add($page, 'page_move', $page->book->id);
|
||||||
session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name]));
|
session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name]));
|
||||||
|
|
||||||
|
@ -638,7 +640,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function showCopy($bookSlug, $pageSlug)
|
public function showCopy($bookSlug, $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
session()->flashInput(['name' => $page->name]);
|
session()->flashInput(['name' => $page->name]);
|
||||||
return view('pages/copy', [
|
return view('pages/copy', [
|
||||||
|
@ -657,7 +659,7 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function copy($bookSlug, $pageSlug, Request $request)
|
public function copy($bookSlug, $pageSlug, Request $request)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('page-update', $page);
|
$this->checkOwnablePermission('page-update', $page);
|
||||||
|
|
||||||
$entitySelection = $request->get('entity_selection', null);
|
$entitySelection = $request->get('entity_selection', null);
|
||||||
|
@ -669,7 +671,7 @@ class PageController extends Controller
|
||||||
$entityId = intval($stringExploded[1]);
|
$entityId = intval($stringExploded[1]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$parent = $this->entityRepo->getById($entityType, $entityId);
|
$parent = $this->pageRepo->getById($entityType, $entityId);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
session()->flash(trans('entities.selected_book_chapter_not_found'));
|
session()->flash(trans('entities.selected_book_chapter_not_found'));
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
@ -678,7 +680,7 @@ class PageController extends Controller
|
||||||
|
|
||||||
$this->checkOwnablePermission('page-create', $parent);
|
$this->checkOwnablePermission('page-create', $parent);
|
||||||
|
|
||||||
$pageCopy = $this->entityRepo->copyPage($page, $parent, $request->get('name', ''));
|
$pageCopy = $this->pageRepo->copyPage($page, $parent, $request->get('name', ''));
|
||||||
|
|
||||||
Activity::add($pageCopy, 'page_create', $pageCopy->book->id);
|
Activity::add($pageCopy, 'page_create', $pageCopy->book->id);
|
||||||
session()->flash('success', trans('entities.pages_copy_success'));
|
session()->flash('success', trans('entities.pages_copy_success'));
|
||||||
|
@ -696,9 +698,9 @@ class PageController extends Controller
|
||||||
*/
|
*/
|
||||||
public function restrict($bookSlug, $pageSlug, Request $request)
|
public function restrict($bookSlug, $pageSlug, Request $request)
|
||||||
{
|
{
|
||||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
|
||||||
$this->checkOwnablePermission('restrictions-manage', $page);
|
$this->checkOwnablePermission('restrictions-manage', $page);
|
||||||
$this->entityRepo->updateEntityPermissionsFromRequest($request, $page);
|
$this->pageRepo->updateEntityPermissionsFromRequest($request, $page);
|
||||||
session()->flash('success', trans('entities.pages_permissions_success'));
|
session()->flash('success', trans('entities.pages_permissions_success'));
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Auth\Permissions\PermissionsRepo;
|
||||||
use BookStack\Exceptions\PermissionsException;
|
use BookStack\Exceptions\PermissionsException;
|
||||||
use BookStack\Repos\PermissionsRepo;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class PermissionController extends Controller
|
class PermissionController extends Controller
|
||||||
|
@ -11,7 +11,7 @@ class PermissionController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PermissionController constructor.
|
* PermissionController constructor.
|
||||||
* @param PermissionsRepo $permissionsRepo
|
* @param \BookStack\Auth\Permissions\PermissionsRepo $permissionsRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(PermissionsRepo $permissionsRepo)
|
public function __construct(PermissionsRepo $permissionsRepo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use BookStack\Repos\EntityRepo;
|
use BookStack\Actions\ViewService;
|
||||||
use BookStack\Services\SearchService;
|
use BookStack\Entities\Repos\EntityRepo;
|
||||||
use BookStack\Services\ViewService;
|
use BookStack\Entities\SearchService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class SearchController extends Controller
|
class SearchController extends Controller
|
||||||
|
@ -13,7 +13,7 @@ class SearchController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SearchController constructor.
|
* SearchController constructor.
|
||||||
* @param EntityRepo $entityRepo
|
* @param \BookStack\Entities\Repos\EntityRepo $entityRepo
|
||||||
* @param ViewService $viewService
|
* @param ViewService $viewService
|
||||||
* @param SearchService $searchService
|
* @param SearchService $searchService
|
||||||
*/
|
*/
|
||||||
|
@ -97,7 +97,7 @@ class SearchController extends Controller
|
||||||
$entities = $this->searchService->searchEntities($searchTerm, 'all', 1, 20, $permission)['results'];
|
$entities = $this->searchService->searchEntities($searchTerm, 'all', 1, 20, $permission)['results'];
|
||||||
} else {
|
} else {
|
||||||
$entityNames = $entityTypes->map(function ($type) {
|
$entityNames = $entityTypes->map(function ($type) {
|
||||||
return 'BookStack\\' . ucfirst($type);
|
return 'BookStack\\' . ucfirst($type); // TODO - Extract this elsewhere, too specific and stringy
|
||||||
})->toArray();
|
})->toArray();
|
||||||
$entities = $this->viewService->getPopular(20, 0, $entityNames, $permission);
|
$entities = $this->viewService->getPopular(20, 0, $entityNames, $permission);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use BookStack\Services\ImageService;
|
use BookStack\Uploads\ImageService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Setting;
|
use Setting;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use BookStack\Repos\TagRepo;
|
use BookStack\Actions\TagRepo;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class TagController extends Controller
|
class TagController extends Controller
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
<?php namespace BookStack\Http\Controllers;
|
<?php namespace BookStack\Http\Controllers;
|
||||||
|
|
||||||
use Exception;
|
use BookStack\Auth\Access\SocialAuthService;
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use BookStack\Auth\UserRepo;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use BookStack\Repos\UserRepo;
|
|
||||||
use BookStack\Services\SocialAuthService;
|
|
||||||
use BookStack\User;
|
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -16,7 +15,7 @@ class UserController extends Controller
|
||||||
/**
|
/**
|
||||||
* UserController constructor.
|
* UserController constructor.
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param UserRepo $userRepo
|
* @param \BookStack\Auth\UserRepo $userRepo
|
||||||
*/
|
*/
|
||||||
public function __construct(User $user, UserRepo $userRepo)
|
public function __construct(User $user, UserRepo $userRepo)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +100,7 @@ class UserController extends Controller
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified user.
|
* Show the form for editing the specified user.
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @param SocialAuthService $socialAuthService
|
* @param \BookStack\Auth\Access\SocialAuthService $socialAuthService
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public function edit($id, SocialAuthService $socialAuthService)
|
public function edit($id, SocialAuthService $socialAuthService)
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
namespace BookStack\Http\Middleware;
|
namespace BookStack\Http\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class TrustProxies extends Middleware
|
class TrustProxies extends Middleware
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
namespace BookStack\Notifications;
|
namespace BookStack\Notifications;
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Notifications\Notification;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
class ConfirmEmail extends Notification implements ShouldQueue
|
class ConfirmEmail extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
namespace BookStack\Notifications;
|
namespace BookStack\Notifications;
|
||||||
|
|
||||||
use Illuminate\Notifications\Notification;
|
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
class ResetPassword extends Notification
|
class ResetPassword extends Notification
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
|
||||||
abstract class Ownable extends Model
|
abstract class Ownable extends Model
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
<?php namespace BookStack\Providers;
|
<?php namespace BookStack\Providers;
|
||||||
|
|
||||||
use BookStack\Services\SettingService;
|
use Blade;
|
||||||
use BookStack\Setting;
|
use BookStack\Entities\Book;
|
||||||
|
use BookStack\Entities\Bookshelf;
|
||||||
|
use BookStack\Entities\Chapter;
|
||||||
|
use BookStack\Entities\Page;
|
||||||
|
use BookStack\Settings\Setting;
|
||||||
|
use BookStack\Settings\SettingService;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Schema;
|
||||||
use Validator;
|
use Validator;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
|
@ -20,12 +27,21 @@ class AppServiceProvider extends ServiceProvider
|
||||||
return in_array($value->getMimeType(), $imageMimes);
|
return in_array($value->getMimeType(), $imageMimes);
|
||||||
});
|
});
|
||||||
|
|
||||||
\Blade::directive('icon', function ($expression) {
|
// Custom blade view directives
|
||||||
|
Blade::directive('icon', function ($expression) {
|
||||||
return "<?php echo icon($expression); ?>";
|
return "<?php echo icon($expression); ?>";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow longer string lengths after upgrade to utf8mb4
|
// Allow longer string lengths after upgrade to utf8mb4
|
||||||
\Schema::defaultStringLength(191);
|
Schema::defaultStringLength(191);
|
||||||
|
|
||||||
|
// Set morph-map due to namespace changes
|
||||||
|
Relation::morphMap([
|
||||||
|
'BookStack\\Bookshelf' => Bookshelf::class,
|
||||||
|
'BookStack\\Book' => Book::class,
|
||||||
|
'BookStack\\Chapter' => Chapter::class,
|
||||||
|
'BookStack\\Page' => Page::class,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
use BookStack\Services\LdapService;
|
use BookStack\Auth\Access\LdapService;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AuthServiceProvider extends ServiceProvider
|
class AuthServiceProvider extends ServiceProvider
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Broadcast;
|
|
||||||
|
|
||||||
class BroadcastServiceProvider extends ServiceProvider
|
class BroadcastServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,18 +2,18 @@
|
||||||
|
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use BookStack\Activity;
|
use BookStack\Actions\Activity;
|
||||||
use BookStack\Image;
|
use BookStack\Actions\ActivityService;
|
||||||
use BookStack\Services\ImageService;
|
use BookStack\Actions\View;
|
||||||
use BookStack\Services\PermissionService;
|
use BookStack\Actions\ViewService;
|
||||||
use BookStack\Services\ViewService;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Setting;
|
use BookStack\Settings\Setting;
|
||||||
use BookStack\View;
|
use BookStack\Settings\SettingService;
|
||||||
|
use BookStack\Uploads\Image;
|
||||||
|
use BookStack\Uploads\ImageService;
|
||||||
use Illuminate\Contracts\Cache\Repository;
|
use Illuminate\Contracts\Cache\Repository;
|
||||||
use Illuminate\Contracts\Filesystem\Factory;
|
use Illuminate\Contracts\Filesystem\Factory;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use BookStack\Services\ActivityService;
|
|
||||||
use BookStack\Services\SettingService;
|
|
||||||
use Intervention\Image\ImageManager;
|
use Intervention\Image\ImageManager;
|
||||||
|
|
||||||
class CustomFacadeProvider extends ServiceProvider
|
class CustomFacadeProvider extends ServiceProvider
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
|
||||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
use SocialiteProviders\Manager\SocialiteWasCalled;
|
use SocialiteProviders\Manager\SocialiteWasCalled;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use BookStack\Role;
|
use BookStack\Auth\Access\LdapService;
|
||||||
use BookStack\Services\LdapService;
|
|
||||||
use BookStack\User;
|
|
||||||
use Illuminate\Contracts\Auth\Authenticatable;
|
use Illuminate\Contracts\Auth\Authenticatable;
|
||||||
use Illuminate\Contracts\Auth\UserProvider;
|
use Illuminate\Contracts\Auth\UserProvider;
|
||||||
|
|
||||||
|
@ -19,7 +17,7 @@ class LdapUserProvider implements UserProvider
|
||||||
protected $model;
|
protected $model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var LdapService
|
* @var \BookStack\Auth\LdapService
|
||||||
*/
|
*/
|
||||||
protected $ldapService;
|
protected $ldapService;
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ class LdapUserProvider implements UserProvider
|
||||||
/**
|
/**
|
||||||
* LdapUserProvider constructor.
|
* LdapUserProvider constructor.
|
||||||
* @param $model
|
* @param $model
|
||||||
* @param LdapService $ldapService
|
* @param \BookStack\Auth\LdapService $ldapService
|
||||||
*/
|
*/
|
||||||
public function __construct($model, LdapService $ldapService)
|
public function __construct($model, LdapService $ldapService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace BookStack\Providers;
|
namespace BookStack\Providers;
|
||||||
|
|
||||||
use Illuminate\Routing\Router;
|
|
||||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||||
use Route;
|
use Route;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Settings;
|
||||||
|
|
||||||
|
use BookStack\Model;
|
||||||
|
|
||||||
class Setting extends Model
|
class Setting extends Model
|
||||||
{
|
{
|
|
@ -1,7 +1,5 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Settings;
|
||||||
|
|
||||||
use BookStack\Setting;
|
|
||||||
use BookStack\User;
|
|
||||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +53,7 @@ class SettingService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a user-specific setting from the database or cache.
|
* Get a user-specific setting from the database or cache.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param $key
|
* @param $key
|
||||||
* @param bool $default
|
* @param bool $default
|
||||||
* @return bool|string
|
* @return bool|string
|
||||||
|
@ -174,7 +172,7 @@ class SettingService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put a user-specific setting into the database.
|
* Put a user-specific setting into the database.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param $key
|
* @param $key
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return bool
|
* @return bool
|
|
@ -1,4 +1,7 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
|
use BookStack\Entities\Page;
|
||||||
|
use BookStack\Ownable;
|
||||||
|
|
||||||
class Attachment extends Ownable
|
class Attachment extends Ownable
|
||||||
{
|
{
|
||||||
|
@ -18,7 +21,7 @@ class Attachment extends Ownable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the page this file was uploaded to.
|
* Get the page this file was uploaded to.
|
||||||
* @return Page
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
*/
|
*/
|
||||||
public function page()
|
public function page()
|
||||||
{
|
{
|
|
@ -1,7 +1,6 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
use BookStack\Exceptions\FileUploadException;
|
use BookStack\Exceptions\FileUploadException;
|
||||||
use BookStack\Attachment;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php namespace BookStack;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
|
use BookStack\Ownable;
|
||||||
use Images;
|
use Images;
|
||||||
|
|
||||||
class Image extends Ownable
|
class Image extends Ownable
|
|
@ -1,9 +1,7 @@
|
||||||
<?php namespace BookStack\Repos;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
use BookStack\Image;
|
use BookStack\Auth\Permissions\PermissionService;
|
||||||
use BookStack\Page;
|
use BookStack\Entities\Page;
|
||||||
use BookStack\Services\ImageService;
|
|
||||||
use BookStack\Services\PermissionService;
|
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
||||||
class ImageRepo
|
class ImageRepo
|
||||||
|
@ -18,8 +16,8 @@ class ImageRepo
|
||||||
* ImageRepo constructor.
|
* ImageRepo constructor.
|
||||||
* @param Image $image
|
* @param Image $image
|
||||||
* @param ImageService $imageService
|
* @param ImageService $imageService
|
||||||
* @param PermissionService $permissionService
|
* @param \BookStack\Auth\Permissions\PermissionService $permissionService
|
||||||
* @param Page $page
|
* @param \BookStack\Entities\Page $page
|
||||||
*/
|
*/
|
||||||
public function __construct(Image $image, ImageService $imageService, PermissionService $permissionService, Page $page)
|
public function __construct(Image $image, ImageService $imageService, PermissionService $permissionService, Page $page)
|
||||||
{
|
{
|
|
@ -1,14 +1,13 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Image;
|
|
||||||
use BookStack\User;
|
|
||||||
use DB;
|
use DB;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Contracts\Cache\Repository as Cache;
|
||||||
|
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
|
||||||
use Intervention\Image\Exception\NotSupportedException;
|
use Intervention\Image\Exception\NotSupportedException;
|
||||||
use Intervention\Image\ImageManager;
|
use Intervention\Image\ImageManager;
|
||||||
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
|
|
||||||
use Illuminate\Contracts\Cache\Repository as Cache;
|
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
||||||
class ImageService extends UploadService
|
class ImageService extends UploadService
|
||||||
|
@ -281,7 +280,7 @@ class ImageService extends UploadService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a gravatar image and set a the profile image for a user.
|
* Save a gravatar image and set a the profile image for a user.
|
||||||
* @param User $user
|
* @param \BookStack\Auth\User $user
|
||||||
* @param int $size
|
* @param int $size
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws Exception
|
* @throws Exception
|
|
@ -1,9 +1,9 @@
|
||||||
<?php namespace BookStack\Services;
|
<?php namespace BookStack\Uploads;
|
||||||
|
|
||||||
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
|
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
|
||||||
use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
|
use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
|
||||||
|
|
||||||
class UploadService
|
abstract class UploadService
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -30,11 +30,11 @@ function versioned_asset($file = '')
|
||||||
/**
|
/**
|
||||||
* Helper method to get the current User.
|
* Helper method to get the current User.
|
||||||
* Defaults to public 'Guest' user if not logged in.
|
* Defaults to public 'Guest' user if not logged in.
|
||||||
* @return \BookStack\User
|
* @return \BookStack\Auth\User
|
||||||
*/
|
*/
|
||||||
function user()
|
function user()
|
||||||
{
|
{
|
||||||
return auth()->user() ?: \BookStack\User::getDefault();
|
return auth()->user() ?: \BookStack\Auth\User::getDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,7 @@ function userCan($permission, Ownable $ownable = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check permission on ownable item
|
// Check permission on ownable item
|
||||||
$permissionService = app(\BookStack\Services\PermissionService::class);
|
$permissionService = app(\BookStack\Auth\Permissions\PermissionService::class);
|
||||||
return $permissionService->checkOwnableUserAccess($ownable, $permission);
|
return $permissionService->checkOwnableUserAccess($ownable, $permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ function userCan($permission, Ownable $ownable = null)
|
||||||
* Helper to access system settings.
|
* Helper to access system settings.
|
||||||
* @param $key
|
* @param $key
|
||||||
* @param bool $default
|
* @param bool $default
|
||||||
* @return bool|string|\BookStack\Services\SettingService
|
* @return bool|string|\BookStack\Settings\SettingService
|
||||||
*/
|
*/
|
||||||
function setting($key = null, $default = false)
|
function setting($key = null, $default = false)
|
||||||
{
|
{
|
||||||
$settingService = resolve(\BookStack\Services\SettingService::class);
|
$settingService = resolve(\BookStack\Settings\SettingService::class);
|
||||||
if (is_null($key)) {
|
if (is_null($key)) {
|
||||||
return $settingService;
|
return $settingService;
|
||||||
}
|
}
|
||||||
|
@ -92,10 +92,15 @@ function baseUrl($path, $forceAppDomain = false)
|
||||||
if ($isFullUrl && !$forceAppDomain) {
|
if ($isFullUrl && !$forceAppDomain) {
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = trim($path, '/');
|
$path = trim($path, '/');
|
||||||
|
$base = rtrim(config('app.url'), '/');
|
||||||
|
|
||||||
// Remove non-specified domain if forced and we have a domain
|
// Remove non-specified domain if forced and we have a domain
|
||||||
if ($isFullUrl && $forceAppDomain) {
|
if ($isFullUrl && $forceAppDomain) {
|
||||||
|
if (!empty($base) && strpos($path, $base) === 0) {
|
||||||
|
$path = trim(substr($path, strlen($base) - 1));
|
||||||
|
}
|
||||||
$explodedPath = explode('/', $path);
|
$explodedPath = explode('/', $path);
|
||||||
$path = implode('/', array_splice($explodedPath, 3));
|
$path = implode('/', array_splice($explodedPath, 3));
|
||||||
}
|
}
|
||||||
|
@ -105,7 +110,7 @@ function baseUrl($path, $forceAppDomain = false)
|
||||||
return url($path);
|
return url($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtrim(config('app.url'), '/') . '/' . $path;
|
return $base . '/' . $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"php": ">=7.0.0",
|
"php": ">=7.0.0",
|
||||||
"ext-tidy": "*",
|
"ext-tidy": "*",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
"laravel/framework": "~5.5.42",
|
"laravel/framework": "~5.5.44",
|
||||||
"fideloper/proxy": "~3.3",
|
"fideloper/proxy": "~3.3",
|
||||||
"intervention/image": "^2.4",
|
"intervention/image": "^2.4",
|
||||||
"laravel/socialite": "^3.0",
|
"laravel/socialite": "^3.0",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -84,7 +84,7 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'locale' => env('APP_LANG', 'en'),
|
'locale' => env('APP_LANG', 'en'),
|
||||||
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -274,10 +274,10 @@ return [
|
||||||
* Custom
|
* Custom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'Activity' => BookStack\Services\Facades\Activity::class,
|
'Activity' => BookStack\Facades\Activity::class,
|
||||||
'Setting' => BookStack\Services\Facades\Setting::class,
|
'Setting' => BookStack\Facades\Setting::class,
|
||||||
'Views' => BookStack\Services\Facades\Views::class,
|
'Views' => BookStack\Facades\Views::class,
|
||||||
'Images' => BookStack\Services\Facades\Images::class,
|
'Images' => BookStack\Facades\Images::class,
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ return [
|
||||||
'providers' => [
|
'providers' => [
|
||||||
'users' => [
|
'users' => [
|
||||||
'driver' => env('AUTH_METHOD', 'standard') === 'standard' ? 'eloquent' : env('AUTH_METHOD'),
|
'driver' => env('AUTH_METHOD', 'standard') === 'standard' ? 'eloquent' : env('AUTH_METHOD'),
|
||||||
'model' => BookStack\User::class,
|
'model' => \BookStack\Auth\User::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
// 'users' => [
|
// 'users' => [
|
||||||
|
|
|
@ -38,7 +38,7 @@ return [
|
||||||
],
|
],
|
||||||
|
|
||||||
'stripe' => [
|
'stripe' => [
|
||||||
'model' => BookStack\User::class,
|
'model' => \BookStack\Auth\User::class,
|
||||||
'key' => '',
|
'key' => '',
|
||||||
'secret' => '',
|
'secret' => '',
|
||||||
],
|
],
|
||||||
|
@ -59,6 +59,7 @@ return [
|
||||||
'name' => 'Google',
|
'name' => 'Google',
|
||||||
'auto_register' => env('GOOGLE_AUTO_REGISTER', false),
|
'auto_register' => env('GOOGLE_AUTO_REGISTER', false),
|
||||||
'auto_confirm' => env('GOOGLE_AUTO_CONFIRM_EMAIL', false),
|
'auto_confirm' => env('GOOGLE_AUTO_CONFIRM_EMAIL', false),
|
||||||
|
'select_account' => env('GOOGLE_SELECT_ACCOUNT', false),
|
||||||
],
|
],
|
||||||
|
|
||||||
'slack' => [
|
'slack' => [
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$factory->define(BookStack\User::class, function ($faker) {
|
$factory->define(\BookStack\Auth\User::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->name,
|
'name' => $faker->name,
|
||||||
'email' => $faker->email,
|
'email' => $faker->email,
|
||||||
|
@ -21,7 +21,7 @@ $factory->define(BookStack\User::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Bookshelf::class, function ($faker) {
|
$factory->define(\BookStack\Entities\Bookshelf::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->sentence,
|
'name' => $faker->sentence,
|
||||||
'slug' => str_random(10),
|
'slug' => str_random(10),
|
||||||
|
@ -29,7 +29,7 @@ $factory->define(BookStack\Bookshelf::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Book::class, function ($faker) {
|
$factory->define(\BookStack\Entities\Book::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->sentence,
|
'name' => $faker->sentence,
|
||||||
'slug' => str_random(10),
|
'slug' => str_random(10),
|
||||||
|
@ -37,7 +37,7 @@ $factory->define(BookStack\Book::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Chapter::class, function ($faker) {
|
$factory->define(\BookStack\Entities\Chapter::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->sentence,
|
'name' => $faker->sentence,
|
||||||
'slug' => str_random(10),
|
'slug' => str_random(10),
|
||||||
|
@ -45,7 +45,7 @@ $factory->define(BookStack\Chapter::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Page::class, function ($faker) {
|
$factory->define(\BookStack\Entities\Page::class, function ($faker) {
|
||||||
$html = '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>';
|
$html = '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>';
|
||||||
return [
|
return [
|
||||||
'name' => $faker->sentence,
|
'name' => $faker->sentence,
|
||||||
|
@ -56,21 +56,21 @@ $factory->define(BookStack\Page::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Role::class, function ($faker) {
|
$factory->define(\BookStack\Auth\Role::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'display_name' => $faker->sentence(3),
|
'display_name' => $faker->sentence(3),
|
||||||
'description' => $faker->sentence(10)
|
'description' => $faker->sentence(10)
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Tag::class, function ($faker) {
|
$factory->define(\BookStack\Actions\Tag::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->city,
|
'name' => $faker->city,
|
||||||
'value' => $faker->sentence(3)
|
'value' => $faker->sentence(3)
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Image::class, function ($faker) {
|
$factory->define(\BookStack\Uploads\Image::class, function ($faker) {
|
||||||
return [
|
return [
|
||||||
'name' => $faker->slug . '.jpg',
|
'name' => $faker->slug . '.jpg',
|
||||||
'url' => $faker->url,
|
'url' => $faker->url,
|
||||||
|
@ -80,7 +80,7 @@ $factory->define(BookStack\Image::class, function ($faker) {
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
$factory->define(BookStack\Comment::class, function($faker) {
|
$factory->define(\BookStack\Actions\Comment::class, function($faker) {
|
||||||
$text = $faker->paragraph(1);
|
$text = $faker->paragraph(1);
|
||||||
$html = '<p>' . $text. '</p>';
|
$html = '<p>' . $text. '</p>';
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use BookStack\Image;
|
use BookStack\Uploads\Image;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
|
|
@ -119,11 +119,11 @@ class CreateBookshelvesTable extends Migration
|
||||||
Schema::dropIfExists('bookshelves');
|
Schema::dropIfExists('bookshelves');
|
||||||
|
|
||||||
// Drop related polymorphic items
|
// Drop related polymorphic items
|
||||||
DB::table('activities')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('activities')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
DB::table('views')->where('viewable_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('views')->where('viewable_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
DB::table('entity_permissions')->where('restrictable_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('entity_permissions')->where('restrictable_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
DB::table('tags')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('tags')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
DB::table('search_terms')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('search_terms')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
DB::table('comments')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
DB::table('comments')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,39 +12,39 @@ class DummyContentSeeder extends Seeder
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
// Create an editor user
|
// Create an editor user
|
||||||
$editorUser = factory(\BookStack\User::class)->create();
|
$editorUser = factory(\BookStack\Auth\User::class)->create();
|
||||||
$editorRole = \BookStack\Role::getRole('editor');
|
$editorRole = \BookStack\Auth\Role::getRole('editor');
|
||||||
$editorUser->attachRole($editorRole);
|
$editorUser->attachRole($editorRole);
|
||||||
|
|
||||||
// Create a viewer user
|
// Create a viewer user
|
||||||
$viewerUser = factory(\BookStack\User::class)->create();
|
$viewerUser = factory(\BookStack\Auth\User::class)->create();
|
||||||
$role = \BookStack\Role::getRole('viewer');
|
$role = \BookStack\Auth\Role::getRole('viewer');
|
||||||
$viewerUser->attachRole($role);
|
$viewerUser->attachRole($role);
|
||||||
|
|
||||||
$byData = ['created_by' => $editorUser->id, 'updated_by' => $editorUser->id];
|
$byData = ['created_by' => $editorUser->id, 'updated_by' => $editorUser->id];
|
||||||
|
|
||||||
factory(\BookStack\Book::class, 5)->create($byData)
|
factory(\BookStack\Entities\Book::class, 5)->create($byData)
|
||||||
->each(function($book) use ($editorUser, $byData) {
|
->each(function($book) use ($editorUser, $byData) {
|
||||||
$chapters = factory(\BookStack\Chapter::class, 3)->create($byData)
|
$chapters = factory(\BookStack\Entities\Chapter::class, 3)->create($byData)
|
||||||
->each(function($chapter) use ($editorUser, $book, $byData){
|
->each(function($chapter) use ($editorUser, $book, $byData){
|
||||||
$pages = factory(\BookStack\Page::class, 3)->make(array_merge($byData, ['book_id' => $book->id]));
|
$pages = factory(\BookStack\Entities\Page::class, 3)->make(array_merge($byData, ['book_id' => $book->id]));
|
||||||
$chapter->pages()->saveMany($pages);
|
$chapter->pages()->saveMany($pages);
|
||||||
});
|
});
|
||||||
$pages = factory(\BookStack\Page::class, 3)->make($byData);
|
$pages = factory(\BookStack\Entities\Page::class, 3)->make($byData);
|
||||||
$book->chapters()->saveMany($chapters);
|
$book->chapters()->saveMany($chapters);
|
||||||
$book->pages()->saveMany($pages);
|
$book->pages()->saveMany($pages);
|
||||||
});
|
});
|
||||||
|
|
||||||
$largeBook = factory(\BookStack\Book::class)->create(array_merge($byData, ['name' => 'Large book' . str_random(10)]));
|
$largeBook = factory(\BookStack\Entities\Book::class)->create(array_merge($byData, ['name' => 'Large book' . str_random(10)]));
|
||||||
$pages = factory(\BookStack\Page::class, 200)->make($byData);
|
$pages = factory(\BookStack\Entities\Page::class, 200)->make($byData);
|
||||||
$chapters = factory(\BookStack\Chapter::class, 50)->make($byData);
|
$chapters = factory(\BookStack\Entities\Chapter::class, 50)->make($byData);
|
||||||
$largeBook->pages()->saveMany($pages);
|
$largeBook->pages()->saveMany($pages);
|
||||||
$largeBook->chapters()->saveMany($chapters);
|
$largeBook->chapters()->saveMany($chapters);
|
||||||
|
|
||||||
$shelves = factory(\BookStack\Bookshelf::class, 10)->create($byData);
|
$shelves = factory(\BookStack\Entities\Bookshelf::class, 10)->create($byData);
|
||||||
$largeBook->shelves()->attach($shelves->pluck('id'));
|
$largeBook->shelves()->attach($shelves->pluck('id'));
|
||||||
|
|
||||||
app(\BookStack\Services\PermissionService::class)->buildJointPermissions();
|
app(\BookStack\Auth\Permissions\PermissionService::class)->buildJointPermissions();
|
||||||
app(\BookStack\Services\SearchService::class)->indexAllEntities();
|
app(\BookStack\Entities\SearchService::class)->indexAllEntities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,16 @@ class LargeContentSeeder extends Seeder
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
// Create an editor user
|
// Create an editor user
|
||||||
$editorUser = factory(\BookStack\User::class)->create();
|
$editorUser = factory(\BookStack\Auth\User::class)->create();
|
||||||
$editorRole = \BookStack\Role::getRole('editor');
|
$editorRole = \BookStack\Auth\Role::getRole('editor');
|
||||||
$editorUser->attachRole($editorRole);
|
$editorUser->attachRole($editorRole);
|
||||||
|
|
||||||
$largeBook = factory(\BookStack\Book::class)->create(['name' => 'Large book' . str_random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
$largeBook = factory(\BookStack\Entities\Book::class)->create(['name' => 'Large book' . str_random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||||
$pages = factory(\BookStack\Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
$pages = factory(\BookStack\Entities\Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||||
$chapters = factory(\BookStack\Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
$chapters = factory(\BookStack\Entities\Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||||
$largeBook->pages()->saveMany($pages);
|
$largeBook->pages()->saveMany($pages);
|
||||||
$largeBook->chapters()->saveMany($chapters);
|
$largeBook->chapters()->saveMany($chapters);
|
||||||
app(\BookStack\Services\PermissionService::class)->buildJointPermissions();
|
app(\BookStack\Auth\Permissions\PermissionService::class)->buildJointPermissions();
|
||||||
app(\BookStack\Services\SearchService::class)->indexAllEntities();
|
app(\BookStack\Entities\SearchService::class)->indexAllEntities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
|
@ -10,34 +10,34 @@
|
||||||
"permissions": "chown -R $USER:$USER bootstrap/cache storage public/uploads"
|
"permissions": "chown -R $USER:$USER bootstrap/cache storage public/uploads"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.0.0-beta.40",
|
"@babel/core": "^7.1.5",
|
||||||
"@babel/polyfill": "^7.0.0-beta.40",
|
"@babel/polyfill": "^7.0.0",
|
||||||
"@babel/preset-env": "^7.0.0-beta.40",
|
"@babel/preset-env": "^7.1.5",
|
||||||
"autoprefixer": "^8.1.0",
|
"autoprefixer": "^8.6.5",
|
||||||
"babel-loader": "^8.0.0-beta.0",
|
"babel-loader": "^8.0.4",
|
||||||
"css-loader": "^0.28.10",
|
"css-loader": "^0.28.11",
|
||||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
"livereload": "^0.7.0",
|
"livereload": "^0.7.0",
|
||||||
"node-sass": "^4.9.2",
|
"node-sass": "^4.10.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.3",
|
||||||
"postcss-loader": "^2.1.1",
|
"postcss-loader": "^2.1.6",
|
||||||
"sass-loader": "^7.0.1",
|
"sass-loader": "^7.1.0",
|
||||||
"style-loader": "^0.21.0",
|
"style-loader": "^0.21.0",
|
||||||
"uglifyjs-webpack-plugin": "^1.2.3",
|
"uglifyjs-webpack-plugin": "^1.3.0",
|
||||||
"webpack": "^4.16.3",
|
"webpack": "^4.25.1",
|
||||||
"webpack-cli": "^2.0.11"
|
"webpack-cli": "^3.1.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"clipboard": "^2.0.0",
|
"clipboard": "^2.0.1",
|
||||||
"codemirror": "^5.26.0",
|
"codemirror": "^5.41.0",
|
||||||
"dropzone": "^5.4.0",
|
"dropzone": "^5.5.1",
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.3.1",
|
||||||
"jquery-sortable": "^0.9.13",
|
"jquery-sortable": "^0.9.13",
|
||||||
"markdown-it": "^8.3.1",
|
"markdown-it": "^8.4.2",
|
||||||
"markdown-it-task-lists": "^2.0.0",
|
"markdown-it-task-lists": "^2.1.1",
|
||||||
"vue": "^2.2.6",
|
"vue": "^2.5.17",
|
||||||
"vuedraggable": "^2.14.1"
|
"vuedraggable": "^2.16.0"
|
||||||
},
|
},
|
||||||
"browser": {
|
"browser": {
|
||||||
"vue": "vue/dist/vue.common.js"
|
"vue": "vue/dist/vue.common.js"
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
<env name="GOOGLE_APP_SECRET" value="aaaaaaaaaaaaaa"/>
|
<env name="GOOGLE_APP_SECRET" value="aaaaaaaaaaaaaa"/>
|
||||||
<env name="GOOGLE_AUTO_REGISTER" value=""/>
|
<env name="GOOGLE_AUTO_REGISTER" value=""/>
|
||||||
<env name="GOOGLE_AUTO_CONFIRM_EMAIL" value=""/>
|
<env name="GOOGLE_AUTO_CONFIRM_EMAIL" value=""/>
|
||||||
|
<env name="GOOGLE_SELECT_ACCOUNT" value=""/>
|
||||||
<env name="APP_URL" value="http://bookstack.dev"/>
|
<env name="APP_URL" value="http://bookstack.dev"/>
|
||||||
|
<env name="DEBUGBAR_ENABLED" value="false"/>
|
||||||
</php>
|
</php>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
@ -56,4 +56,4 @@ class BackToTop {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = BackToTop;
|
export default BackToTop;
|
|
@ -69,4 +69,4 @@ class ChapterToggle {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ChapterToggle;
|
export default ChapterToggle;
|
||||||
|
|
|
@ -34,4 +34,4 @@ class Collapsible {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Collapsible;
|
export default Collapsible;
|
|
@ -45,4 +45,4 @@ class DropDown {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DropDown;
|
export default DropDown;
|
|
@ -44,4 +44,4 @@ class EditorToolbox {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = EditorToolbox;
|
export default EditorToolbox;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue