Fixed some mis-refactoring and split search service

Search service broken into index and runner tools.
This commit is contained in:
Dan Brown 2020-11-22 00:17:45 +00:00
parent c7a2d568bf
commit ef1b98019a
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
108 changed files with 399 additions and 379 deletions

View File

@ -3,7 +3,7 @@
namespace BookStack\Actions;
use BookStack\Auth\User;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Entity;
use BookStack\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;

View File

@ -2,9 +2,9 @@
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Auth\User;
use BookStack\Entities\Chapter;
use BookStack\Entities\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Interfaces\Loggable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation;

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Actions;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Entity;
use League\CommonMark\CommonMarkConverter;
use BookStack\Facades\Activity as ActivityService;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Actions;
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Entity;
use DB;
use Illuminate\Support\Collection;

View File

@ -1,8 +1,8 @@
<?php namespace BookStack\Actions;
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Book;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\EntityProvider;
use DB;
use Illuminate\Support\Collection;
@ -28,7 +28,7 @@ class ViewService
/**
* Add a view to the given entity.
* @param \BookStack\Entities\Entity $entity
* @param \BookStack\Entities\Models\Entity $entity
* @return int
*/
public function add(Entity $entity)

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Auth\Permissions;
use BookStack\Auth\Role;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Entity;
use BookStack\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphOne;

View File

@ -2,8 +2,8 @@
use BookStack\Auth\Permissions;
use BookStack\Auth\Role;
use BookStack\Entities\Book;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\EntityProvider;
use BookStack\Ownable;
use Illuminate\Database\Connection;
@ -74,7 +74,7 @@ class PermissionService
/**
* Prepare the local entity cache and ensure it's empty
* @param \BookStack\Entities\Entity[] $entities
* @param \BookStack\Entities\Models\Entity[] $entities
*/
protected function readyEntityCache($entities = [])
{
@ -111,7 +111,7 @@ class PermissionService
/**
* Get a chapter via ID, Checks local cache
* @param $chapterId
* @return \BookStack\Entities\Book
* @return \BookStack\Entities\Models\Book
*/
protected function getChapter($chapterId)
{
@ -230,7 +230,7 @@ class PermissionService
/**
* Rebuild the entity jointPermissions for a particular entity.
* @param \BookStack\Entities\Entity $entity
* @param \BookStack\Entities\Models\Entity $entity
* @throws \Throwable
*/
public function buildJointPermissionsForEntity(Entity $entity)
@ -325,7 +325,7 @@ class PermissionService
/**
* Delete all of the entity jointPermissions for a list of entities.
* @param \BookStack\Entities\Entity[] $entities
* @param \BookStack\Entities\Models\Entity[] $entities
* @throws \Throwable
*/
protected function deleteManyJointPermissionsForEntities($entities)
@ -406,7 +406,7 @@ class PermissionService
/**
* Get the actions related to an entity.
* @param \BookStack\Entities\Entity $entity
* @param \BookStack\Entities\Models\Entity $entity
* @return array
*/
protected function getActions(Entity $entity)
@ -492,7 +492,7 @@ class PermissionService
/**
* Create an array of data with the information of an entity jointPermissions.
* Used to build data for bulk insertion.
* @param \BookStack\Entities\Entity $entity
* @param \BookStack\Entities\Models\Entity $entity
* @param Role $role
* @param $action
* @param $permissionAll
@ -583,7 +583,7 @@ class PermissionService
/**
* Check if an entity has restrictions set on itself or its
* parent tree.
* @param \BookStack\Entities\Entity $entity
* @param \BookStack\Entities\Models\Entity $entity
* @param $action
* @return bool|mixed
*/
@ -664,7 +664,7 @@ class PermissionService
/**
* Add restrictions for a generic entity
* @param string $entityType
* @param Builder|\BookStack\Entities\Entity $query
* @param Builder|\BookStack\Entities\Models\Entity $query
* @param string $action
* @return Builder
*/

View File

@ -1,10 +1,10 @@
<?php namespace BookStack\Auth;
use Activity;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\UserUpdateException;
use BookStack\Uploads\Image;

View File

@ -2,7 +2,7 @@
namespace BookStack\Console\Commands;
use BookStack\Entities\PageRevision;
use BookStack\Entities\Models\PageRevision;
use Illuminate\Console\Command;
class ClearRevisions extends Command

View File

@ -2,7 +2,7 @@
namespace BookStack\Console\Commands;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Repos\BookshelfRepo;
use Illuminate\Console\Command;

View File

@ -2,7 +2,7 @@
namespace BookStack\Console\Commands;
use BookStack\Entities\SearchService;
use BookStack\Entities\Tools\SearchIndex;
use DB;
use Illuminate\Console\Command;
@ -22,17 +22,15 @@ class RegenerateSearch extends Command
*/
protected $description = 'Re-index all content for searching';
protected $searchService;
protected $searchIndex;
/**
* Create a new command instance.
*
* @param SearchService $searchService
*/
public function __construct(SearchService $searchService)
public function __construct(SearchIndex $searchIndex)
{
parent::__construct();
$this->searchService = $searchService;
$this->searchIndex = $searchIndex;
}
/**
@ -45,10 +43,9 @@ class RegenerateSearch extends Command
$connection = DB::getDefaultConnection();
if ($this->option('database') !== null) {
DB::setDefaultConnection($this->option('database'));
$this->searchService->setConnection(DB::connection($this->option('database')));
}
$this->searchService->indexAllEntities();
$this->searchIndex->indexAllEntities();
DB::setDefaultConnection($connection);
$this->comment('Search index regenerated');
}

View File

@ -1,5 +1,6 @@
<?php namespace BookStack\Entities;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\ShelfContext;
use Illuminate\View\View;

View File

@ -1,5 +1,12 @@
<?php namespace BookStack\Entities;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Models\PageRevision;
/**
* Class EntityProvider
*

View File

@ -1,5 +1,10 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\HasCoverImage;
use BookStack\Entities\Models\Page;
use BookStack\Uploads\Image;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

View File

@ -1,5 +1,8 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Book;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

View File

@ -1,5 +1,8 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\HasCoverImage;
use BookStack\Entities\Models\Book;
use BookStack\Uploads\Image;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

View File

@ -1,5 +1,7 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Entities\Models\BookChild;
use BookStack\Entities\Models\Page;
use Illuminate\Support\Collection;
/**

View File

@ -1,6 +1,7 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Auth\User;
use BookStack\Entities\Models\Entity;
use BookStack\Interfaces\Loggable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

View File

@ -1,4 +1,4 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Actions\Activity;
use BookStack\Actions\Comment;
@ -6,6 +6,8 @@ use BookStack\Actions\Tag;
use BookStack\Actions\View;
use BookStack\Auth\Permissions\EntityPermission;
use BookStack\Auth\Permissions\JointPermission;
use BookStack\Entities\Tools\SearchIndex;
use BookStack\Entities\Tools\SlugGenerator;
use BookStack\Facades\Permissions;
use BookStack\Ownable;
use Carbon\Carbon;
@ -227,10 +229,9 @@ class Entity extends Ownable
/**
* Get an instance of an entity of the given type.
* @param $type
* @return Entity
* TODO - Refactor out
*/
public static function getEntityInstance($type)
public static function getEntityInstance(string $type): ?Entity
{
$types = ['Page', 'Book', 'Chapter', 'Bookshelf'];
$className = str_replace([' ', '-', '_'], '', ucwords($type));
@ -238,7 +239,7 @@ class Entity extends Ownable
return null;
}
return app('BookStack\\Entities\\' . $className);
return app('BookStack\\Entities\\Models\\' . $className);
}
/**
@ -315,8 +316,7 @@ class Entity extends Ownable
*/
public function indexForSearch()
{
$searchService = app()->make(SearchService::class);
$searchService->indexEntity(clone $this);
app(SearchIndex::class)->indexEntity(clone $this);
}
/**

View File

@ -1,7 +1,7 @@
<?php
namespace BookStack\Entities;
namespace BookStack\Entities\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

View File

@ -1,5 +1,8 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Entities\Models\BookChild;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\PageRevision;
use BookStack\Uploads\Attachment;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;

View File

@ -1,6 +1,7 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Auth\User;
use BookStack\Entities\Models\Page;
use BookStack\Model;
use Carbon\Carbon;

View File

@ -1,4 +1,4 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Models;
use BookStack\Model;

View File

@ -4,8 +4,8 @@ namespace BookStack\Entities\Repos;
use BookStack\Actions\ActivityType;
use BookStack\Actions\TagRepo;
use BookStack\Entities\Entity;
use BookStack\Entities\HasCoverImage;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\HasCoverImage;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Facades\Activity;
use BookStack\Uploads\ImageRepo;

View File

@ -2,7 +2,7 @@
use BookStack\Actions\ActivityType;
use BookStack\Actions\TagRepo;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\NotFoundException;

View File

@ -1,8 +1,8 @@
<?php namespace BookStack\Entities\Repos;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Exceptions\NotFoundException;

View File

@ -1,8 +1,8 @@
<?php namespace BookStack\Entities\Repos;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Exceptions\MoveOperationException;

View File

@ -1,14 +1,14 @@
<?php namespace BookStack\Entities\Repos;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Entities\Page;
use BookStack\Entities\PageRevision;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Models\PageRevision;
use BookStack\Exceptions\MoveOperationException;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\PermissionsException;

View File

@ -1,10 +1,10 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Book;
use BookStack\Entities\BookChild;
use BookStack\Entities\Chapter;
use BookStack\Entities\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\BookChild;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Exceptions\SortOperationException;
use Illuminate\Support\Collection;

View File

@ -1,14 +1,15 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Uploads\ImageService;
use DomPDF;
use Exception;
use SnappyPDF;
use Throwable;
class ExportService
class ExportFormatter
{
protected $imageService;

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use DOMDocument;
use DOMNodeList;
use DOMXPath;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Page;
use BookStack\Entities\PageRevision;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Models\PageRevision;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;

View File

@ -0,0 +1,119 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\EntityProvider;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\SearchTerm;
class SearchIndex
{
/**
* @var SearchTerm
*/
protected $searchTerm;
/**
* @var EntityProvider
*/
protected $entityProvider;
public function __construct(SearchTerm $searchTerm, EntityProvider $entityProvider)
{
$this->searchTerm = $searchTerm;
$this->entityProvider = $entityProvider;
}
/**
* Index the given entity.
*/
public function indexEntity(Entity $entity)
{
$this->deleteEntityTerms($entity);
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText() ?? '', 1 * $entity->searchFactor);
$terms = array_merge($nameTerms, $bodyTerms);
foreach ($terms as $index => $term) {
$terms[$index]['entity_type'] = $entity->getMorphClass();
$terms[$index]['entity_id'] = $entity->id;
}
$this->searchTerm->newQuery()->insert($terms);
}
/**
* Index multiple Entities at once
* @param Entity[] $entities
*/
protected function indexEntities(array $entities)
{
$terms = [];
foreach ($entities as $entity) {
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1 * $entity->searchFactor);
foreach (array_merge($nameTerms, $bodyTerms) as $term) {
$term['entity_id'] = $entity->id;
$term['entity_type'] = $entity->getMorphClass();
$terms[] = $term;
}
}
$chunkedTerms = array_chunk($terms, 500);
foreach ($chunkedTerms as $termChunk) {
$this->searchTerm->newQuery()->insert($termChunk);
}
}
/**
* Delete and re-index the terms for all entities in the system.
*/
public function indexAllEntities()
{
$this->searchTerm->newQuery()->truncate();
foreach ($this->entityProvider->all() as $entityModel) {
$selectFields = ['id', 'name', $entityModel->textField];
$entityModel->newQuery()
->withTrashed()
->select($selectFields)
->chunk(1000, function ($entities) {
$this->indexEntities($entities);
});
}
}
/**
* Delete related Entity search terms.
*/
public function deleteEntityTerms(Entity $entity)
{
$entity->searchTerms()->delete();
}
/**
* Create a scored term array from the given text.
*/
protected function generateTermArrayFromText(string $text, int $scoreAdjustment = 1): array
{
$tokenMap = []; // {TextToken => OccurrenceCount}
$splitChars = " \n\t.,!?:;()[]{}<>`'\"";
$token = strtok($text, $splitChars);
while ($token !== false) {
if (!isset($tokenMap[$token])) {
$tokenMap[$token] = 0;
}
$tokenMap[$token]++;
$token = strtok($splitChars);
}
$terms = [];
foreach ($tokenMap as $token => $count) {
$terms[] = [
'term' => $token,
'score' => $count * $scoreAdjustment
];
}
return $terms;
}
}

View File

@ -1,4 +1,4 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Tools;
use Illuminate\Http\Request;

View File

@ -1,6 +1,8 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Tools;
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\EntityProvider;
use BookStack\Entities\Models\Entity;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
@ -8,12 +10,8 @@ use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
class SearchService
class SearchRunner
{
/**
* @var SearchTerm
*/
protected $searchTerm;
/**
* @var EntityProvider
@ -37,25 +35,14 @@ class SearchService
*/
protected $queryOperators = ['<=', '>=', '=', '<', '>', 'like', '!='];
/**
* SearchService constructor.
*/
public function __construct(SearchTerm $searchTerm, EntityProvider $entityProvider, Connection $db, PermissionService $permissionService)
public function __construct(EntityProvider $entityProvider, Connection $db, PermissionService $permissionService)
{
$this->searchTerm = $searchTerm;
$this->entityProvider = $entityProvider;
$this->db = $db;
$this->permissionService = $permissionService;
}
/**
* Set the database connection
*/
public function setConnection(Connection $connection)
{
$this->db = $connection;
}
/**
* Search all entities in the system.
* The provided count is for each entity to search,
@ -115,11 +102,12 @@ class SearchService
$search = $this->buildEntitySearchQuery($opts, $entityType)->where('book_id', '=', $bookId)->take(20)->get();
$results = $results->merge($search);
}
return $results->sortByDesc('score')->take(20);
}
/**
* Search a book for entities
* Search a chapter for entities
*/
public function searchChapter(int $chapterId, string $searchString): Collection
{
@ -134,7 +122,7 @@ class SearchService
* matching instead of the items themselves.
* @return \Illuminate\Database\Eloquent\Collection|int|static[]
*/
public function searchEntityTable(SearchOptions $searchOpts, string $entityType = 'page', int $page = 1, int $count = 20, string $action = 'view', bool $getCount = false)
protected function searchEntityTable(SearchOptions $searchOpts, string $entityType = 'page', int $page = 1, int $count = 20, string $action = 'view', bool $getCount = false)
{
$query = $this->buildEntitySearchQuery($searchOpts, $entityType, $action);
if ($getCount) {
@ -155,28 +143,25 @@ class SearchService
// Handle normal search terms
if (count($searchOpts->searches) > 0) {
$subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score'));
$rawScoreSum = $this->db->raw('SUM(score) as score');
$subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', $rawScoreSum);
$subQuery->where('entity_type', '=', $entity->getMorphClass());
$subQuery->where(function (Builder $query) use ($searchOpts) {
foreach ($searchOpts->searches as $inputTerm) {
$query->orWhere('term', 'like', $inputTerm .'%');
}
})->groupBy('entity_type', 'entity_id');
$entitySelect->join(\DB::raw('(' . $subQuery->toSql() . ') as s'), function (JoinClause $join) {
$entitySelect->join($this->db->raw('(' . $subQuery->toSql() . ') as s'), function (JoinClause $join) {
$join->on('id', '=', 'entity_id');
})->selectRaw($entity->getTable().'.*, s.score')->orderBy('score', 'desc');
$entitySelect->mergeBindings($subQuery);
}
// Handle exact term matching
if (count($searchOpts->exacts) > 0) {
$entitySelect->where(function (EloquentBuilder $query) use ($searchOpts, $entity) {
foreach ($searchOpts->exacts as $inputTerm) {
$query->where(function (EloquentBuilder $query) use ($inputTerm, $entity) {
$query->where('name', 'like', '%'.$inputTerm .'%')
->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
});
}
foreach ($searchOpts->exacts as $inputTerm) {
$entitySelect->where(function (EloquentBuilder $query) use ($inputTerm, $entity) {
$query->where('name', 'like', '%'.$inputTerm .'%')
->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
});
}
@ -239,105 +224,6 @@ class SearchService
return $query;
}
/**
* Index the given entity.
*/
public function indexEntity(Entity $entity)
{
$this->deleteEntityTerms($entity);
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1 * $entity->searchFactor);
$terms = array_merge($nameTerms, $bodyTerms);
foreach ($terms as $index => $term) {
$terms[$index]['entity_type'] = $entity->getMorphClass();
$terms[$index]['entity_id'] = $entity->id;
}
$this->searchTerm->newQuery()->insert($terms);
}
/**
* Index multiple Entities at once
* @param \BookStack\Entities\Entity[] $entities
*/
protected function indexEntities($entities)
{
$terms = [];
foreach ($entities as $entity) {
$nameTerms = $this->generateTermArrayFromText($entity->name, 5 * $entity->searchFactor);
$bodyTerms = $this->generateTermArrayFromText($entity->getText(), 1 * $entity->searchFactor);
foreach (array_merge($nameTerms, $bodyTerms) as $term) {
$term['entity_id'] = $entity->id;
$term['entity_type'] = $entity->getMorphClass();
$terms[] = $term;
}
}
$chunkedTerms = array_chunk($terms, 500);
foreach ($chunkedTerms as $termChunk) {
$this->searchTerm->newQuery()->insert($termChunk);
}
}
/**
* Delete and re-index the terms for all entities in the system.
*/
public function indexAllEntities()
{
$this->searchTerm->truncate();
foreach ($this->entityProvider->all() as $entityModel) {
$selectFields = ['id', 'name', $entityModel->textField];
$entityModel->newQuery()
->withTrashed()
->select($selectFields)
->chunk(1000, function ($entities) {
$this->indexEntities($entities);
});
}
}
/**
* Delete related Entity search terms.
* @param Entity $entity
*/
public function deleteEntityTerms(Entity $entity)
{
$entity->searchTerms()->delete();
}
/**
* Create a scored term array from the given text.
* @param $text
* @param float|int $scoreAdjustment
* @return array
*/
protected function generateTermArrayFromText($text, $scoreAdjustment = 1)
{
$tokenMap = []; // {TextToken => OccurrenceCount}
$splitChars = " \n\t.,!?:;()[]{}<>`'\"";
$token = strtok($text, $splitChars);
while ($token !== false) {
if (!isset($tokenMap[$token])) {
$tokenMap[$token] = 0;
}
$tokenMap[$token]++;
$token = strtok($splitChars);
}
$terms = [];
foreach ($tokenMap as $token => $count) {
$terms[] = [
'term' => $token,
'score' => $count * $scoreAdjustment
];
}
return $terms;
}
/**
* Custom entity search filters
*/

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
class ShelfContext
{

View File

@ -1,5 +1,6 @@
<?php namespace BookStack\Entities;
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Models\Entity;
use Illuminate\Support\Str;
class SlugGenerator

View File

@ -1,13 +1,13 @@
<?php namespace BookStack\Entities\Tools;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Deletion;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Deletion;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\EntityProvider;
use BookStack\Entities\HasCoverImage;
use BookStack\Entities\Page;
use BookStack\Entities\Models\HasCoverImage;
use BookStack\Entities\Models\Page;
use BookStack\Exceptions\NotifyException;
use BookStack\Facades\Activity;
use BookStack\Uploads\AttachmentService;

View File

@ -1,10 +1,8 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Repos\BookRepo;
use BookStack\Exceptions\NotifyException;
use BookStack\Facades\Activity;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
@ -27,9 +25,6 @@ class BookApiController extends ApiController
],
];
/**
* BooksApiController constructor.
*/
public function __construct(BookRepo $bookRepo)
{
$this->bookRepo = $bookRepo;
@ -85,8 +80,7 @@ class BookApiController extends ApiController
/**
* Delete a single book from the system.
* @throws NotifyException
* @throws BindingResolutionException
* @throws \Exception
*/
public function delete(string $id)
{

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\Book;
use BookStack\Entities\ExportService;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Repos\BookRepo;
use Throwable;
@ -13,7 +13,7 @@ class BookExportApiController extends ApiController
/**
* BookExportController constructor.
*/
public function __construct(BookRepo $bookRepo, ExportService $exportService)
public function __construct(BookRepo $bookRepo, ExportFormatter $exportService)
{
$this->bookRepo = $bookRepo;
$this->exportService = $exportService;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Bookshelf;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Http\Request;

View File

@ -1,8 +1,8 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Repos\ChapterRepo;
use BookStack\Facades\Activity;
use Illuminate\Database\Eloquent\Relations\HasMany;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Http\Controllers\Api;
use BookStack\Entities\Chapter;
use BookStack\Entities\ExportService;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Repos\BookRepo;
use Throwable;
@ -13,7 +13,7 @@ class ChapterExportApiController extends ApiController
/**
* ChapterExportController constructor.
*/
public function __construct(BookRepo $chapterRepo, ExportService $exportService)
public function __construct(BookRepo $chapterRepo, ExportFormatter $exportService)
{
$this->chapterRepo = $chapterRepo;
$this->exportService = $exportService;

View File

@ -3,7 +3,7 @@
use Activity;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Tools\ShelfContext;
use BookStack\Entities\Repos\BookRepo;
use BookStack\Exceptions\ImageUploadException;

View File

@ -2,7 +2,7 @@
namespace BookStack\Http\Controllers;
use BookStack\Entities\ExportService;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Repos\BookRepo;
use Throwable;
@ -15,7 +15,7 @@ class BookExportController extends Controller
/**
* BookExportController constructor.
*/
public function __construct(BookRepo $bookRepo, ExportService $exportService)
public function __construct(BookRepo $bookRepo, ExportFormatter $exportService)
{
$this->bookRepo = $bookRepo;
$this->exportService = $exportService;

View File

@ -3,7 +3,7 @@
namespace BookStack\Http\Controllers;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Repos\BookRepo;
use BookStack\Exceptions\SortOperationException;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Http\Controllers;
use Activity;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\ShelfContext;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Exceptions\ImageUploadException;

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Repos\ChapterRepo;
use BookStack\Exceptions\MoveOperationException;

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Entities\ExportService;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Repos\ChapterRepo;
use BookStack\Exceptions\NotFoundException;
use Throwable;
@ -14,7 +14,7 @@ class ChapterExportController extends Controller
/**
* ChapterExportController constructor.
*/
public function __construct(ChapterRepo $chapterRepo, ExportService $exportService)
public function __construct(ChapterRepo $chapterRepo, ExportFormatter $exportService)
{
$this->chapterRepo = $chapterRepo;
$this->exportService = $exportService;

View File

@ -3,7 +3,7 @@
use Activity;
use BookStack\Actions\ActivityType;
use BookStack\Actions\CommentRepo;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

View File

@ -1,9 +1,9 @@
<?php namespace BookStack\Http\Controllers;
use Activity;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\BookRepo;
use BookStack\Entities\Repos\BookshelfRepo;
use Illuminate\Http\Response;

View File

@ -3,7 +3,7 @@
use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditActivity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo;
use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\NotifyException;

View File

@ -2,7 +2,7 @@
namespace BookStack\Http\Controllers;
use BookStack\Entities\ExportService;
use BookStack\Entities\Tools\ExportFormatter;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Repos\PageRepo;
use BookStack\Exceptions\NotFoundException;
@ -17,7 +17,7 @@ class PageExportController extends Controller
/**
* PageExportController constructor.
*/
public function __construct(PageRepo $pageRepo, ExportService $exportService)
public function __construct(PageRepo $pageRepo, ExportFormatter $exportService)
{
$this->pageRepo = $pageRepo;
$this->exportService = $exportService;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Actions\ActivityType;
use BookStack\Entities\Deletion;
use BookStack\Entities\Models\Deletion;
use BookStack\Entities\Tools\TrashCan;
class RecycleBinController extends Controller

View File

@ -1,30 +1,27 @@
<?php namespace BookStack\Http\Controllers;
use BookStack\Actions\ViewService;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Tools\SearchRunner;
use BookStack\Entities\Tools\ShelfContext;
use BookStack\Entities\SearchService;
use BookStack\Entities\SearchOptions;
use BookStack\Entities\Tools\SearchOptions;
use Illuminate\Http\Request;
class SearchController extends Controller
{
protected $viewService;
protected $searchService;
protected $searchRunner;
protected $entityContextManager;
/**
* SearchController constructor.
*/
public function __construct(
ViewService $viewService,
SearchService $searchService,
SearchRunner $searchRunner,
ShelfContext $entityContextManager
) {
$this->viewService = $viewService;
$this->searchService = $searchService;
$this->searchRunner = $searchRunner;
$this->entityContextManager = $entityContextManager;
}
@ -40,7 +37,7 @@ class SearchController extends Controller
$page = intval($request->get('page', '0')) ?: 1;
$nextPageLink = url('/search?term=' . urlencode($fullSearchString) . '&page=' . ($page+1));
$results = $this->searchService->searchEntities($searchOpts, 'all', $page, 20);
$results = $this->searchRunner->searchEntities($searchOpts, 'all', $page, 20);
return view('search.all', [
'entities' => $results['results'],
@ -52,14 +49,13 @@ class SearchController extends Controller
]);
}
/**
* Searches all entities within a book.
*/
public function searchBook(Request $request, int $bookId)
{
$term = $request->get('term', '');
$results = $this->searchService->searchBook($bookId, $term);
$results = $this->searchRunner->searchBook($bookId, $term);
return view('partials.entity-list', ['entities' => $results]);
}
@ -69,7 +65,7 @@ class SearchController extends Controller
public function searchChapter(Request $request, int $chapterId)
{
$term = $request->get('term', '');
$results = $this->searchService->searchChapter($chapterId, $term);
$results = $this->searchRunner->searchChapter($chapterId, $term);
return view('partials.entity-list', ['entities' => $results]);
}
@ -86,7 +82,7 @@ class SearchController extends Controller
// Search for entities otherwise show most popular
if ($searchTerm !== false) {
$searchTerm .= ' {type:'. implode('|', $entityTypes) .'}';
$entities = $this->searchService->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20, $permission)['results'];
$entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20, $permission)['results'];
} else {
$entities = $this->viewService->getPopular(20, 0, $entityTypes, $permission);
}

View File

@ -1,11 +1,11 @@
<?php namespace BookStack\Providers;
use Blade;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\BreadcrumbsViewComposer;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Settings\Setting;
use BookStack\Settings\SettingService;
use Illuminate\Database\Eloquent\Relations\Relation;

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Uploads;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Ownable;
/**

View File

@ -1,6 +1,6 @@
<?php namespace BookStack\Uploads;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Ownable;
use Images;

View File

@ -1,7 +1,7 @@
<?php namespace BookStack\Uploads;
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Exceptions\ImageUploadException;
use Exception;
use Illuminate\Database\Eloquent\Builder;

View File

@ -21,7 +21,7 @@ $factory->define(\BookStack\Auth\User::class, function ($faker) {
];
});
$factory->define(\BookStack\Entities\Bookshelf::class, function ($faker) {
$factory->define(\BookStack\Entities\Models\Bookshelf::class, function ($faker) {
return [
'name' => $faker->sentence,
'slug' => Str::random(10),
@ -29,7 +29,7 @@ $factory->define(\BookStack\Entities\Bookshelf::class, function ($faker) {
];
});
$factory->define(\BookStack\Entities\Book::class, function ($faker) {
$factory->define(\BookStack\Entities\Models\Book::class, function ($faker) {
return [
'name' => $faker->sentence,
'slug' => Str::random(10),
@ -37,7 +37,7 @@ $factory->define(\BookStack\Entities\Book::class, function ($faker) {
];
});
$factory->define(\BookStack\Entities\Chapter::class, function ($faker) {
$factory->define(\BookStack\Entities\Models\Chapter::class, function ($faker) {
return [
'name' => $faker->sentence,
'slug' => Str::random(10),
@ -45,7 +45,7 @@ $factory->define(\BookStack\Entities\Chapter::class, function ($faker) {
];
});
$factory->define(\BookStack\Entities\Page::class, function ($faker) {
$factory->define(\BookStack\Entities\Models\Page::class, function ($faker) {
$html = '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>';
return [
'name' => $faker->sentence,

View File

@ -119,11 +119,11 @@ class CreateBookshelvesTable extends Migration
Schema::dropIfExists('bookshelves');
// Drop related polymorphic items
DB::table('activities')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('views')->where('viewable_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('entity_permissions')->where('restrictable_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('tags')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('search_terms')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('comments')->where('entity_type', '=', 'BookStack\Entities\Bookshelf')->delete();
DB::table('activities')->where('entity_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
DB::table('views')->where('viewable_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
DB::table('entity_permissions')->where('restrictable_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
DB::table('tags')->where('entity_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
DB::table('search_terms')->where('entity_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
DB::table('comments')->where('entity_type', '=', 'BookStack\Entities\Models\Bookshelf')->delete();
}
}

View File

@ -5,10 +5,10 @@ use BookStack\Auth\Permissions\PermissionService;
use BookStack\Auth\Permissions\RolePermission;
use BookStack\Auth\Role;
use BookStack\Auth\User;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\SearchService;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Tools\SearchIndex;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
@ -33,7 +33,7 @@ class DummyContentSeeder extends Seeder
$byData = ['created_by' => $editorUser->id, 'updated_by' => $editorUser->id];
factory(\BookStack\Entities\Book::class, 5)->create($byData)
factory(\BookStack\Entities\Models\Book::class, 5)->create($byData)
->each(function($book) use ($editorUser, $byData) {
$chapters = factory(Chapter::class, 3)->create($byData)
->each(function($chapter) use ($editorUser, $book, $byData){
@ -45,7 +45,7 @@ class DummyContentSeeder extends Seeder
$book->pages()->saveMany($pages);
});
$largeBook = factory(\BookStack\Entities\Book::class)->create(array_merge($byData, ['name' => 'Large book' . Str::random(10)]));
$largeBook = factory(\BookStack\Entities\Models\Book::class)->create(array_merge($byData, ['name' => 'Large book' . Str::random(10)]));
$pages = factory(Page::class, 200)->make($byData);
$chapters = factory(Chapter::class, 50)->make($byData);
$largeBook->pages()->saveMany($pages);
@ -67,6 +67,6 @@ class DummyContentSeeder extends Seeder
$token->save();
app(PermissionService::class)->buildJointPermissions();
app(SearchService::class)->indexAllEntities();
app(SearchIndex::class)->indexAllEntities();
}
}

View File

@ -3,9 +3,9 @@
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Auth\Role;
use BookStack\Auth\User;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\SearchService;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Tools\SearchIndex;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
@ -23,12 +23,12 @@ class LargeContentSeeder extends Seeder
$editorRole = Role::getRole('editor');
$editorUser->attachRole($editorRole);
$largeBook = factory(\BookStack\Entities\Book::class)->create(['name' => 'Large book' . Str::random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$largeBook = factory(\BookStack\Entities\Models\Book::class)->create(['name' => 'Large book' . Str::random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$pages = factory(Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$chapters = factory(Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$largeBook->pages()->saveMany($pages);
$largeBook->chapters()->saveMany($chapters);
app(PermissionService::class)->buildJointPermissions();
app(SearchService::class)->indexAllEntities();
app(SearchIndex::class)->indexAllEntities();
}
}

View File

@ -29,7 +29,7 @@
<div class="links text-center">
@if (hasAppAccess())
<a class="hide-over-l" href="{{ url('/search') }}">@icon('search'){{ trans('common.search') }}</a>
@if(userCanOnAny('view', \BookStack\Entities\Bookshelf::class) || userCan('bookshelf-view-all') || userCan('bookshelf-view-own'))
@if(userCanOnAny('view', \BookStack\Entities\Models\Bookshelf::class) || userCan('bookshelf-view-all') || userCan('bookshelf-view-own'))
<a href="{{ url('/shelves') }}">@icon('bookshelf'){{ trans('entities.shelves') }}</a>
@endif
<a href="{{ url('/books') }}">@icon('books'){{ trans('entities.books') }}</a>

View File

@ -3,7 +3,7 @@
<div page-picker>
<div class="input-base">
<span @if($value) style="display: none" @endif page-picker-default class="text-muted italic">{{ $placeholder }}</span>
<a @if(!$value) style="display: none" @endif href="{{ url('/link/' . $value) }}" target="_blank" class="text-page" page-picker-display>#{{$value}}, {{$value ? \BookStack\Entities\Page::find($value)->name : '' }}</a>
<a @if(!$value) style="display: none" @endif href="{{ url('/link/' . $value) }}" target="_blank" class="text-page" page-picker-display>#{{$value}}, {{$value ? \BookStack\Entities\Models\Page::find($value)->name : '' }}</a>
</div>
<br>
<input type="hidden" value="{{$value}}" name="{{$name}}" id="{{$name}}">

View File

@ -2,7 +2,7 @@
<?php $breadcrumbCount = 0; ?>
{{-- Show top level books item --}}
@if (count($crumbs) > 0 && ($crumbs[0] ?? null) instanceof \BookStack\Entities\Book)
@if (count($crumbs) > 0 && ($crumbs[0] ?? null) instanceof \BookStack\Entities\Models\Book)
<a href="{{ url('/books') }}" class="text-book icon-list-item outline-hover">
<span>@icon('books')</span>
<span>{{ trans('entities.books') }}</span>
@ -11,7 +11,7 @@
@endif
{{-- Show top level shelves item --}}
@if (count($crumbs) > 0 && ($crumbs[0] ?? null) instanceof \BookStack\Entities\Bookshelf)
@if (count($crumbs) > 0 && ($crumbs[0] ?? null) instanceof \BookStack\Entities\Models\Bookshelf)
<a href="{{ url('/shelves') }}" class="text-bookshelf icon-list-item outline-hover">
<span>@icon('bookshelf')</span>
<span>{{ trans('entities.shelves') }}</span>
@ -20,7 +20,7 @@
@endif
@foreach($crumbs as $key => $crumb)
<?php $isEntity = ($crumb instanceof \BookStack\Entities\Entity); ?>
<?php $isEntity = ($crumb instanceof \BookStack\Entities\Models\Entity); ?>
@if (is_null($crumb))
<?php continue; ?>

View File

@ -19,7 +19,7 @@
<button type="submit" class="button">{{ trans('common.delete_confirm') }}</button>
</form>
@if($deletion->deletable instanceof \BookStack\Entities\Entity)
@if($deletion->deletable instanceof \BookStack\Entities\Models\Entity)
<hr class="mt-m">
<h5>{{ trans('settings.recycle_bin_destroy_list') }}</h5>
@include('settings.recycle-bin.deletable-entity-list', ['entity' => $deletion->deletable])

View File

@ -62,17 +62,17 @@
{{ $deletion->deletable->name }}
</div>
</div>
@if($deletion->deletable instanceof \BookStack\Entities\Book || $deletion->deletable instanceof \BookStack\Entities\Chapter)
@if($deletion->deletable instanceof \BookStack\Entities\Models\Book || $deletion->deletable instanceof \BookStack\Entities\Models\Chapter)
<div class="mb-m"></div>
@endif
@if($deletion->deletable instanceof \BookStack\Entities\Book)
@if($deletion->deletable instanceof \BookStack\Entities\Models\Book)
<div class="pl-xl block inline">
<div class="text-chapter">
@icon('chapter') {{ trans_choice('entities.x_chapters', $deletion->deletable->chapters()->withTrashed()->count()) }}
</div>
</div>
@endif
@if($deletion->deletable instanceof \BookStack\Entities\Book || $deletion->deletable instanceof \BookStack\Entities\Chapter)
@if($deletion->deletable instanceof \BookStack\Entities\Models\Book || $deletion->deletable instanceof \BookStack\Entities\Models\Chapter)
<div class="pl-xl block inline">
<div class="text-page">
@icon('page') {{ trans_choice('entities.x_pages', $deletion->deletable->pages()->withTrashed()->count()) }}

View File

@ -18,7 +18,7 @@
<button type="submit" class="button">{{ trans('settings.recycle_bin_restore') }}</button>
</form>
@if($deletion->deletable instanceof \BookStack\Entities\Entity)
@if($deletion->deletable instanceof \BookStack\Entities\Models\Entity)
<hr class="mt-m">
<h5>{{ trans('settings.recycle_bin_restore_list') }}</h5>
@if($deletion->deletable->getParent() && $deletion->deletable->getParent()->trashed())

View File

@ -1,7 +1,7 @@
<?php namespace Tests;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
class ActivityTrackingTest extends BrowserKitTest
{

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Api;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use Tests\TestCase;
class ApiListingTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Api;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use Tests\TestCase;
class BooksApiTest extends TestCase

View File

@ -1,7 +1,7 @@
<?php namespace Tests\Api;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use Tests\TestCase;
class ChaptersApiTest extends TestCase

View File

@ -1,7 +1,7 @@
<?php namespace Tests\Api;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use Tests\TestCase;
class ShelvesApiTest extends TestCase

View File

@ -5,7 +5,7 @@ use BookStack\Actions\ActivityService;
use BookStack\Actions\ActivityType;
use BookStack\Auth\UserRepo;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo;
use Carbon\Carbon;

View File

@ -2,7 +2,7 @@
use BookStack\Auth\Role;
use BookStack\Auth\User;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Notifications\ConfirmEmail;
use BookStack\Notifications\ResetPassword;
use BookStack\Settings\SettingService;

View File

@ -1,6 +1,6 @@
<?php namespace Tests;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Entity;
use BookStack\Auth\Role;
use BookStack\Auth\Permissions\PermissionService;
use BookStack\Settings\SettingService;
@ -71,9 +71,9 @@ abstract class BrowserKitTest extends TestCase
protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false)
{
if ($updaterUser === false) $updaterUser = $creatorUser;
$book = factory(\BookStack\Entities\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]);
$chapter = factory(\BookStack\Entities\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]);
$page = factory(\BookStack\Entities\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id, 'chapter_id' => $chapter->id]);
$book = factory(\BookStack\Entities\Models\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]);
$chapter = factory(\BookStack\Entities\Models\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]);
$page = factory(\BookStack\Entities\Models\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id, 'chapter_id' => $chapter->id]);
$restrictionService = $this->app[PermissionService::class];
$restrictionService->buildJointPermissionsForEntity($book);
return [

View File

@ -4,8 +4,8 @@ use BookStack\Actions\ActivityType;
use BookStack\Actions\Comment;
use BookStack\Actions\CommentRepo;
use BookStack\Auth\Permissions\JointPermission;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Page;
use BookStack\Auth\User;
use BookStack\Entities\Repos\PageRepo;
use Symfony\Component\Console\Exception\RuntimeException;

View File

@ -1,8 +1,8 @@
<?php namespace Tests\Entity;
use BookStack\Auth\User;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Uploads\Image;
use Illuminate\Support\Str;
use Tests\TestCase;

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use Tests\TestCase;
class BookTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Chapter;
use BookStack\Entities\Models\Chapter;
use Tests\TestCase;
class ChapterTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Tests\BrowserKitTest;
class CommentSettingTest extends BrowserKitTest

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Actions\Comment;
use Tests\TestCase;

View File

@ -1,10 +1,10 @@
<?php namespace Tests\Entity;
use BookStack\Actions\Tag;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use Tests\TestCase;
class EntitySearchTest extends TestCase

View File

@ -1,9 +1,9 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Auth\UserRepo;
use BookStack\Entities\Repos\PageRepo;
use Carbon\Carbon;

View File

@ -1,8 +1,8 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Uploads\HttpFetcher;
use Illuminate\Support\Str;
use Tests\TestCase;

View File

@ -9,7 +9,7 @@ class MarkdownTest extends BrowserKitTest
public function setUp(): void
{
parent::setUp();
$this->page = \BookStack\Entities\Page::first();
$this->page = \BookStack\Entities\Models\Page::first();
}
protected function setMarkdownEditor()

View File

@ -1,7 +1,7 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Tests\TestCase;
class PageContentTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo;
use Tests\BrowserKitTest;
@ -16,7 +16,7 @@ class PageDraftTest extends BrowserKitTest
public function setUp(): void
{
parent::setUp();
$this->page = \BookStack\Entities\Page::first();
$this->page = \BookStack\Entities\Models\Page::first();
$this->pageRepo = app(PageRepo::class);
}
@ -56,7 +56,7 @@ class PageDraftTest extends BrowserKitTest
public function test_alert_message_shows_if_someone_else_editing()
{
$nonEditedPage = \BookStack\Entities\Page::take(10)->get()->last();
$nonEditedPage = \BookStack\Entities\Models\Page::take(10)->get()->last();
$addedContent = '<p>test message content</p>';
$this->asAdmin()->visit($this->page->getUrl('/edit'))
->dontSeeInField('html', $addedContent);
@ -75,7 +75,7 @@ class PageDraftTest extends BrowserKitTest
public function test_draft_pages_show_on_homepage()
{
$book = \BookStack\Entities\Book::first();
$book = \BookStack\Entities\Models\Book::first();
$this->asAdmin()->visit('/')
->dontSeeInElement('#recent-drafts', 'New Page')
->visit($book->getUrl() . '/create-page')
@ -85,7 +85,7 @@ class PageDraftTest extends BrowserKitTest
public function test_draft_pages_not_visible_by_others()
{
$book = \BookStack\Entities\Book::first();
$book = \BookStack\Entities\Models\Book::first();
$chapter = $book->chapters->first();
$newUser = $this->getEditor();

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo;
use Tests\TestCase;

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Tests\TestCase;
class PageTemplateTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Tests\TestCase;
class PageTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests\Entity;
use BookStack\Entities\SearchOptions;
use BookStack\Entities\Tools\SearchOptions;
use Tests\TestCase;
class SearchOptionsTest extends TestCase

View File

@ -1,8 +1,8 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Entities\Repos\PageRepo;
use Tests\TestCase;

View File

@ -1,10 +1,10 @@
<?php namespace Tests\Entity;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Actions\Tag;
use BookStack\Entities\Entity;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Auth\Permissions\PermissionService;
use Tests\BrowserKitTest;

View File

@ -1,6 +1,6 @@
<?php namespace Tests;
use BookStack\Entities\Book;
use BookStack\Entities\Models\Book;
use Illuminate\Support\Facades\Log;
class ErrorTest extends TestCase

View File

@ -1,6 +1,6 @@
<?php namespace Tests;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Models\Bookshelf;
class HomepageTest extends TestCase
{

View File

@ -1,11 +1,11 @@
<?php namespace Tests\Permissions;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Entity;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Entity;
use BookStack\Auth\User;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Page;
use Tests\BrowserKitTest;
class RestrictionsTest extends BrowserKitTest

View File

@ -2,10 +2,10 @@
use BookStack\Actions\Comment;
use BookStack\Auth\User;
use BookStack\Entities\Book;
use BookStack\Entities\Bookshelf;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
use BookStack\Auth\Role;
use BookStack\Uploads\Image;
use Laravel\BrowserKitTesting\HttpException;

View File

@ -5,9 +5,9 @@ use BookStack\Auth\Permissions\PermissionService;
use BookStack\Auth\Permissions\RolePermission;
use BookStack\Auth\Role;
use BookStack\Auth\User;
use BookStack\Entities\Book;
use BookStack\Entities\Chapter;
use BookStack\Entities\Page;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Page;
class PublicActionTest extends BrowserKitTest
{

Some files were not shown because too many files have changed in this diff Show More