diff --git a/app/Repos/BookRepo.php b/app/Repos/BookRepo.php
index 816db4cf0..2ec9a4c25 100644
--- a/app/Repos/BookRepo.php
+++ b/app/Repos/BookRepo.php
@@ -1,31 +1,25 @@
book = $book;
$this->pageRepo = $pageRepo;
$this->chapterRepo = $chapterRepo;
- $this->restrictionService = $restrictionService;
+ parent::__construct();
}
/**
@@ -90,7 +84,6 @@ class BookRepo
*/
public function getRecentlyViewed($count = 10, $page = 0)
{
- // TODO restrict
return Views::getUserRecentlyViewed($count, $page, $this->book);
}
@@ -102,7 +95,6 @@ class BookRepo
*/
public function getPopular($count = 10, $page = 0)
{
- // TODO - Restrict
return Views::getPopular($count, $page, $this->book);
}
@@ -241,16 +233,7 @@ class BookRepo
*/
public function getBySearch($term, $count = 20, $paginationAppends = [])
{
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
+ $terms = $this->prepareSearchTerms($term);
$books = $this->restrictionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
@@ -262,27 +245,4 @@ class BookRepo
return $books;
}
- /**
- * Updates books restrictions from a request
- * @param $request
- * @param $book
- */
- public function updateRestrictionsFromRequest($request, $book)
- {
- // TODO - extract into shared repo
- $book->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $book->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach ($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $book->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $book->save();
- }
-
}
\ No newline at end of file
diff --git a/app/Repos/BookRepo.php.orig b/app/Repos/BookRepo.php.orig
deleted file mode 100644
index 4b9709fe6..000000000
--- a/app/Repos/BookRepo.php.orig
+++ /dev/null
@@ -1,295 +0,0 @@
-book = $book;
- $this->pageRepo = $pageRepo;
- $this->chapterRepo = $chapterRepo;
- $this->restrictionService = $restrictionService;
- }
-
- /**
- * Base query for getting books.
- * Takes into account any restrictions.
- * @return mixed
- */
- private function bookQuery()
- {
- return $this->restrictionService->enforceBookRestrictions($this->book, 'view');
- }
-
- /**
- * Get the book that has the given id.
- * @param $id
- * @return mixed
- */
- public function getById($id)
- {
- return $this->bookQuery()->findOrFail($id);
- }
-
- /**
- * Get all books, Limited by count.
- * @param int $count
- * @return mixed
- */
- public function getAll($count = 10)
- {
- $bookQuery = $this->bookQuery()->orderBy('name', 'asc');
- if (!$count) return $bookQuery->get();
- return $bookQuery->take($count)->get();
- }
-
- /**
- * Get all books paginated.
- * @param int $count
- * @return mixed
- */
- public function getAllPaginated($count = 10)
- {
- return $this->bookQuery()
- ->orderBy('name', 'asc')->paginate($count);
- }
-
-
- /**
- * Get the latest books.
- * @param int $count
- * @return mixed
- */
- public function getLatest($count = 10)
- {
- return $this->bookQuery()->orderBy('created_at', 'desc')->take($count)->get();
- }
-
- /**
- * Gets the most recently viewed for a user.
- * @param int $count
- * @param int $page
- * @return mixed
- */
- public function getRecentlyViewed($count = 10, $page = 0)
- {
- // TODO restrict
- return Views::getUserRecentlyViewed($count, $page, $this->book);
- }
-
- /**
- * Gets the most viewed books.
- * @param int $count
- * @param int $page
- * @return mixed
- */
- public function getPopular($count = 10, $page = 0)
- {
- // TODO - Restrict
- return Views::getPopular($count, $page, $this->book);
- }
-
- /**
- * Get a book by slug
- * @param $slug
- * @return mixed
- * @throws NotFoundException
- */
- public function getBySlug($slug)
- {
- $book = $this->bookQuery()->where('slug', '=', $slug)->first();
- if ($book === null) throw new NotFoundException('Book not found');
- return $book;
- }
-
- /**
- * Checks if a book exists.
- * @param $id
- * @return bool
- */
- public function exists($id)
- {
- return $this->bookQuery()->where('id', '=', $id)->exists();
- }
-
- /**
- * Get a new book instance from request input.
- * @param $input
- * @return Book
- */
- public function newFromInput($input)
- {
- return $this->book->newInstance($input);
- }
-
- /**
- * Destroy a book identified by the given slug.
- * @param $bookSlug
- */
- public function destroyBySlug($bookSlug)
- {
- $book = $this->getBySlug($bookSlug);
- foreach ($book->pages as $page) {
- $this->pageRepo->destroy($page);
- }
- foreach ($book->chapters as $chapter) {
- $this->chapterRepo->destroy($chapter);
- }
- $book->views()->delete();
- $book->restrictions()->delete();
- $book->delete();
- }
-
- /**
- * Get the next child element priority.
- * @param Book $book
- * @return int
- */
- public function getNewPriority($book)
- {
- $lastElem = $this->getChildren($book)->pop();
- return $lastElem ? $lastElem->priority + 1 : 0;
- }
-
- /**
- * @param string $slug
- * @param bool|false $currentId
- * @return bool
- */
- public function doesSlugExist($slug, $currentId = false)
- {
- $query = $this->book->where('slug', '=', $slug);
- if ($currentId) {
- $query = $query->where('id', '!=', $currentId);
- }
- return $query->count() > 0;
- }
-
- /**
- * Provides a suitable slug for the given book name.
- * Ensures the returned slug is unique in the system.
- * @param string $name
- * @param bool|false $currentId
- * @return string
- */
- public function findSuitableSlug($name, $currentId = false)
- {
- $originalSlug = Str::slug($name);
- $slug = $originalSlug;
- $count = 2;
- while ($this->doesSlugExist($slug, $currentId)) {
- $slug = $originalSlug . '-' . $count;
- $count++;
- }
- return $slug;
- }
-
- /**
- * Get all child objects of a book.
- * Returns a sorted collection of Pages and Chapters.
- * Loads the bookslug onto child elements to prevent access database access for getting the slug.
- * @param Book $book
- * @return mixed
- */
- public function getChildren(Book $book)
- {
- $pageQuery = $book->pages()->where('chapter_id', '=', 0);
- $pageQuery = $this->restrictionService->enforcePageRestrictions($pageQuery, 'view');
- $pages = $pageQuery->get();
-
- $chapterQuery = $book->chapters()->with(['pages' => function($query) {
- $this->restrictionService->enforcePageRestrictions($query, 'view');
- }]);
- $chapterQuery = $this->restrictionService->enforceChapterRestrictions($chapterQuery, 'view');
- $chapters = $chapterQuery->get();
- $children = $pages->merge($chapters);
- $bookSlug = $book->slug;
- $children->each(function ($child) use ($bookSlug) {
- $child->setAttribute('bookSlug', $bookSlug);
- if ($child->isA('chapter')) {
- $child->pages->each(function ($page) use ($bookSlug) {
- $page->setAttribute('bookSlug', $bookSlug);
- });
- }
- });
- return $children->sortBy('priority');
- }
-
- /**
- * Get books by search term.
- * @param $term
- * @param int $count
- * @param array $paginationAppends
- * @return mixed
- */
- public function getBySearch($term, $count = 20, $paginationAppends = [])
- {
-<<<<<<< HEAD
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
- $books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
-=======
- $terms = explode(' ', $term);
- $books = $this->restrictionService->enforceBookRestrictions($this->book->fullTextSearchQuery(['name', 'description'], $terms))
->>>>>>> custom_role_system
- ->paginate($count)->appends($paginationAppends);
- $words = join('|', explode(' ', preg_quote(trim($term), '/')));
- foreach ($books as $book) {
- //highlight
- $result = preg_replace('#' . $words . '#iu', "\$0", $book->getExcerpt(100));
- $book->searchSnippet = $result;
- }
- return $books;
- }
-
- /**
- * Updates books restrictions from a request
- * @param $request
- * @param $book
- */
- public function updateRestrictionsFromRequest($request, $book)
- {
- // TODO - extract into shared repo
- $book->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $book->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach ($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $book->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $book->save();
- }
-
-}
\ No newline at end of file
diff --git a/app/Repos/ChapterRepo.php b/app/Repos/ChapterRepo.php
index 6868bbf89..5d1d6437f 100644
--- a/app/Repos/ChapterRepo.php
+++ b/app/Repos/ChapterRepo.php
@@ -3,27 +3,11 @@
use Activity;
use BookStack\Exceptions\NotFoundException;
-use BookStack\Services\RestrictionService;
use Illuminate\Support\Str;
use BookStack\Chapter;
-class ChapterRepo
+class ChapterRepo extends EntityRepo
{
-
- protected $chapter;
- protected $restrictionService;
-
- /**
- * ChapterRepo constructor.
- * @param Chapter $chapter
- * @param RestrictionService $restrictionService
- */
- public function __construct(Chapter $chapter, RestrictionService $restrictionService)
- {
- $this->chapter = $chapter;
- $this->restrictionService = $restrictionService;
- }
-
/**
* Base query for getting chapters, Takes restrictions into account.
* @return mixed
@@ -148,7 +132,7 @@ class ChapterRepo
/**
* Get chapters by the given search term.
- * @param $term
+ * @param string $term
* @param array $whereTerms
* @param int $count
* @param array $paginationAppends
@@ -156,16 +140,7 @@ class ChapterRepo
*/
public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
+ $terms = $this->prepareSearchTerms($term);
$chapters = $this->restrictionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
@@ -195,27 +170,4 @@ class ChapterRepo
return $chapter;
}
- /**
- * Updates pages restrictions from a request
- * @param $request
- * @param $chapter
- */
- public function updateRestrictionsFromRequest($request, $chapter)
- {
- // TODO - extract into shared repo
- $chapter->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $chapter->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $chapter->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $chapter->save();
- }
-
}
\ No newline at end of file
diff --git a/app/Repos/ChapterRepo.php.orig b/app/Repos/ChapterRepo.php.orig
deleted file mode 100644
index be4a4e6b5..000000000
--- a/app/Repos/ChapterRepo.php.orig
+++ /dev/null
@@ -1,226 +0,0 @@
-chapter = $chapter;
- $this->restrictionService = $restrictionService;
- }
-
- /**
- * Base query for getting chapters, Takes restrictions into account.
- * @return mixed
- */
- private function chapterQuery()
- {
- return $this->restrictionService->enforceChapterRestrictions($this->chapter, 'view');
- }
-
- /**
- * Check if an id exists.
- * @param $id
- * @return bool
- */
- public function idExists($id)
- {
- return $this->chapterQuery()->where('id', '=', $id)->count() > 0;
- }
-
- /**
- * Get a chapter by a specific id.
- * @param $id
- * @return mixed
- */
- public function getById($id)
- {
- return $this->chapterQuery()->findOrFail($id);
- }
-
- /**
- * Get all chapters.
- * @return \Illuminate\Database\Eloquent\Collection|static[]
- */
- public function getAll()
- {
- return $this->chapterQuery()->all();
- }
-
- /**
- * Get a chapter that has the given slug within the given book.
- * @param $slug
- * @param $bookId
- * @return mixed
- * @throws NotFoundException
- */
- public function getBySlug($slug, $bookId)
- {
- $chapter = $this->chapterQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
- if ($chapter === null) throw new NotFoundException('Chapter not found');
- return $chapter;
- }
-
- /**
- * Get the child items for a chapter
- * @param Chapter $chapter
- */
- public function getChildren(Chapter $chapter)
- {
- return $this->restrictionService->enforcePageRestrictions($chapter->pages())->get();
- }
-
- /**
- * Create a new chapter from request input.
- * @param $input
- * @return $this
- */
- public function newFromInput($input)
- {
- return $this->chapter->fill($input);
- }
-
- /**
- * Destroy a chapter and its relations by providing its slug.
- * @param Chapter $chapter
- */
- public function destroy(Chapter $chapter)
- {
- if (count($chapter->pages) > 0) {
- foreach ($chapter->pages as $page) {
- $page->chapter_id = 0;
- $page->save();
- }
- }
- Activity::removeEntity($chapter);
- $chapter->views()->delete();
- $chapter->restrictions()->delete();
- $chapter->delete();
- }
-
- /**
- * Check if a chapter's slug exists.
- * @param $slug
- * @param $bookId
- * @param bool|false $currentId
- * @return bool
- */
- public function doesSlugExist($slug, $bookId, $currentId = false)
- {
- $query = $this->chapter->where('slug', '=', $slug)->where('book_id', '=', $bookId);
- if ($currentId) {
- $query = $query->where('id', '!=', $currentId);
- }
- return $query->count() > 0;
- }
-
- /**
- * Finds a suitable slug for the provided name.
- * Checks database to prevent duplicate slugs.
- * @param $name
- * @param $bookId
- * @param bool|false $currentId
- * @return string
- */
- public function findSuitableSlug($name, $bookId, $currentId = false)
- {
- $slug = Str::slug($name);
- while ($this->doesSlugExist($slug, $bookId, $currentId)) {
- $slug .= '-' . substr(md5(rand(1, 500)), 0, 3);
- }
- return $slug;
- }
-
- /**
- * Get chapters by the given search term.
- * @param $term
- * @param array $whereTerms
- * @param int $count
- * @param array $paginationAppends
- * @return mixed
- */
- public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
- {
-<<<<<<< HEAD
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
- $chapters = $this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms)
-=======
- $terms = explode(' ', $term);
- $chapters = $this->restrictionService->enforceChapterRestrictions($this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms))
->>>>>>> custom_role_system
- ->paginate($count)->appends($paginationAppends);
- $words = join('|', explode(' ', preg_quote(trim($term), '/')));
- foreach ($chapters as $chapter) {
- //highlight
- $result = preg_replace('#' . $words . '#iu', "\$0", $chapter->getExcerpt(100));
- $chapter->searchSnippet = $result;
- }
- return $chapters;
- }
-
- /**
- * Changes the book relation of this chapter.
- * @param $bookId
- * @param Chapter $chapter
- * @return Chapter
- */
- public function changeBook($bookId, Chapter $chapter)
- {
- $chapter->book_id = $bookId;
- foreach ($chapter->activity as $activity) {
- $activity->book_id = $bookId;
- $activity->save();
- }
- $chapter->slug = $this->findSuitableSlug($chapter->name, $bookId, $chapter->id);
- $chapter->save();
- return $chapter;
- }
-
- /**
- * Updates pages restrictions from a request
- * @param $request
- * @param $chapter
- */
- public function updateRestrictionsFromRequest($request, $chapter)
- {
- // TODO - extract into shared repo
- $chapter->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $chapter->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $chapter->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $chapter->save();
- }
-
-}
\ No newline at end of file
diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php
index 46e1d98a5..9c5184e2f 100644
--- a/app/Repos/EntityRepo.php
+++ b/app/Repos/EntityRepo.php
@@ -1,32 +1,43 @@
book = $book;
- $this->chapter = $chapter;
- $this->page = $page;
- $this->restrictionService = $restrictionService;
+ $this->book = app(Book::class);
+ $this->chapter = app(Chapter::class);
+ $this->page = app(Page::class);
+ $this->restrictionService = app(RestrictionService::class);
}
/**
@@ -37,7 +48,7 @@ class EntityRepo
public function getRecentlyCreatedBooks($count = 20, $page = 0)
{
return $this->restrictionService->enforceBookRestrictions($this->book)
- ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ ->orderBy('created_at', 'desc')->skip($page * $count)->take($count)->get();
}
/**
@@ -49,7 +60,7 @@ class EntityRepo
public function getRecentlyUpdatedBooks($count = 20, $page = 0)
{
return $this->restrictionService->enforceBookRestrictions($this->book)
- ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ ->orderBy('updated_at', 'desc')->skip($page * $count)->take($count)->get();
}
/**
@@ -60,7 +71,7 @@ class EntityRepo
public function getRecentlyCreatedPages($count = 20, $page = 0)
{
return $this->restrictionService->enforcePageRestrictions($this->page)
- ->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ ->orderBy('created_at', 'desc')->skip($page * $count)->take($count)->get();
}
/**
@@ -72,7 +83,49 @@ class EntityRepo
public function getRecentlyUpdatedPages($count = 20, $page = 0)
{
return $this->restrictionService->enforcePageRestrictions($this->page)
- ->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ ->orderBy('updated_at', 'desc')->skip($page * $count)->take($count)->get();
+ }
+
+ /**
+ * Updates entity restrictions from a request
+ * @param $request
+ * @param Entity $entity
+ */
+ public function updateRestrictionsFromRequest($request, Entity $entity)
+ {
+ $entity->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
+ $entity->restrictions()->delete();
+ if ($request->has('restrictions')) {
+ foreach ($request->get('restrictions') as $roleId => $restrictions) {
+ foreach ($restrictions as $action => $value) {
+ $entity->restrictions()->create([
+ 'role_id' => $roleId,
+ 'action' => strtolower($action)
+ ]);
+ }
+ }
+ }
+ $entity->save();
+ }
+
+ /**
+ * Prepare a string of search terms by turning
+ * it into an array of terms.
+ * Keeps quoted terms together.
+ * @param $termString
+ * @return array
+ */
+ protected function prepareSearchTerms($termString)
+ {
+ preg_match_all('/"(.*?)"/', $termString, $matches);
+ if (count($matches[1]) > 0) {
+ $terms = $matches[1];
+ $termString = trim(preg_replace('/"(.*?)"/', '', $termString));
+ } else {
+ $terms = [];
+ }
+ if (!empty($termString)) $terms = array_merge($terms, explode(' ', $termString));
+ return $terms;
}
diff --git a/app/Repos/PageRepo.php b/app/Repos/PageRepo.php
index 3d675183e..4784ad407 100644
--- a/app/Repos/PageRepo.php
+++ b/app/Repos/PageRepo.php
@@ -3,34 +3,23 @@
use Activity;
use BookStack\Book;
-use BookStack\Chapter;
use BookStack\Exceptions\NotFoundException;
-use BookStack\Services\RestrictionService;
-use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Auth;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use BookStack\Page;
use BookStack\PageRevision;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-class PageRepo
+class PageRepo extends EntityRepo
{
- protected $page;
protected $pageRevision;
- protected $restrictionService;
/**
* PageRepo constructor.
- * @param Page $page
* @param PageRevision $pageRevision
- * @param RestrictionService $restrictionService
*/
- public function __construct(Page $page, PageRevision $pageRevision, RestrictionService $restrictionService)
+ public function __construct(PageRevision $pageRevision)
{
- $this->page = $page;
$this->pageRevision = $pageRevision;
- $this->restrictionService = $restrictionService;
+ parent::__construct();
}
/**
@@ -200,16 +189,7 @@ class PageRepo
*/
public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
+ $terms = $this->prepareSearchTerms($term);
$pages = $this->restrictionService->enforcePageRestrictions($this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms))
->paginate($count)->appends($paginationAppends);
@@ -416,27 +396,4 @@ class PageRepo
return $this->pageQuery()->orderBy('updated_at', 'desc')->paginate($count);
}
- /**
- * Updates pages restrictions from a request
- * @param $request
- * @param $page
- */
- public function updateRestrictionsFromRequest($request, $page)
- {
- // TODO - extract into shared repo
- $page->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $page->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $page->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $page->save();
- }
-
}
diff --git a/app/Repos/PageRepo.php.orig b/app/Repos/PageRepo.php.orig
deleted file mode 100644
index c1e02b501..000000000
--- a/app/Repos/PageRepo.php.orig
+++ /dev/null
@@ -1,437 +0,0 @@
-page = $page;
- $this->pageRevision = $pageRevision;
- $this->restrictionService = $restrictionService;
- }
-
- /**
- * Base query for getting pages, Takes restrictions into account.
- * @return mixed
- */
- private function pageQuery()
- {
- return $this->restrictionService->enforcePageRestrictions($this->page, 'view');
- }
-
- /**
- * Get a page via a specific ID.
- * @param $id
- * @return mixed
- */
- public function getById($id)
- {
- return $this->pageQuery()->findOrFail($id);
- }
-
- /**
- * Get a page identified by the given slug.
- * @param $slug
- * @param $bookId
- * @return mixed
- * @throws NotFoundException
- */
- public function getBySlug($slug, $bookId)
- {
- $page = $this->pageQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
- if ($page === null) throw new NotFoundException('Page not found');
- return $page;
- }
-
- /**
- * Search through page revisions and retrieve
- * the last page in the current book that
- * has a slug equal to the one given.
- * @param $pageSlug
- * @param $bookSlug
- * @return null | Page
- */
- public function findPageUsingOldSlug($pageSlug, $bookSlug)
- {
- $revision = $this->pageRevision->where('slug', '=', $pageSlug)
- ->whereHas('page', function($query) {
- $this->restrictionService->enforcePageRestrictions($query);
- })
- ->where('book_slug', '=', $bookSlug)->orderBy('created_at', 'desc')
- ->with('page')->first();
- return $revision !== null ? $revision->page : null;
- }
-
- /**
- * Get a new Page instance from the given input.
- * @param $input
- * @return Page
- */
- public function newFromInput($input)
- {
- $page = $this->page->fill($input);
- return $page;
- }
-
-
- /**
- * Save a new page into the system.
- * Input validation must be done beforehand.
- * @param array $input
- * @param Book $book
- * @param int $chapterId
- * @return Page
- */
- public function saveNew(array $input, Book $book, $chapterId = null)
- {
- $page = $this->newFromInput($input);
- $page->slug = $this->findSuitableSlug($page->name, $book->id);
-
- if ($chapterId) $page->chapter_id = $chapterId;
-
- $page->html = $this->formatHtml($input['html']);
- $page->text = strip_tags($page->html);
- $page->created_by = auth()->user()->id;
- $page->updated_by = auth()->user()->id;
-
- $book->pages()->save($page);
- return $page;
- }
-
- /**
- * 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;
- }
-
-
- /**
- * Gets pages by a search term.
- * Highlights page content for showing in results.
- * @param string $term
- * @param array $whereTerms
- * @param int $count
- * @param array $paginationAppends
- * @return mixed
- */
- public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
- {
-<<<<<<< HEAD
- preg_match_all('/"(.*?)"/', $term, $matches);
- if (count($matches[1]) > 0) {
- $terms = $matches[1];
- $term = trim(preg_replace('/"(.*?)"/', '', $term));
- } else {
- $terms = [];
- }
- if (!empty($term)) {
- $terms = array_merge($terms, explode(' ', $term));
- }
- $pages = $this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms)
-=======
- $terms = explode(' ', $term);
- $pages = $this->restrictionService->enforcePageRestrictions($this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms))
->>>>>>> custom_role_system
- ->paginate($count)->appends($paginationAppends);
-
- // Add highlights to page text.
- $words = join('|', explode(' ', preg_quote(trim($term), '/')));
- //lookahead/behind assertions ensures cut between words
- $s = '\s\x00-/:-@\[-`{-~'; //character set for start/end of words
-
- foreach ($pages as $page) {
- preg_match_all('#(?<=[' . $s . ']).{1,30}((' . $words . ').{1,30})+(?=[' . $s . '])#uis', $page->text, $matches, PREG_SET_ORDER);
- //delimiter between occurrences
- $results = [];
- foreach ($matches as $line) {
- $results[] = htmlspecialchars($line[0], 0, 'UTF-8');
- }
- $matchLimit = 6;
- if (count($results) > $matchLimit) {
- $results = array_slice($results, 0, $matchLimit);
- }
- $result = join('... ', $results);
-
- //highlight
- $result = preg_replace('#' . $words . '#iu', "\$0", $result);
- if (strlen($result) < 5) {
- $result = $page->getExcerpt(80);
- }
- $page->searchSnippet = $result;
- }
- return $pages;
- }
-
- /**
- * Search for image usage.
- * @param $imageString
- * @return mixed
- */
- public function searchForImage($imageString)
- {
- $pages = $this->pageQuery()->where('html', 'like', '%' . $imageString . '%')->get();
- foreach ($pages as $page) {
- $page->url = $page->getUrl();
- $page->html = '';
- $page->text = '';
- }
- return count($pages) > 0 ? $pages : false;
- }
-
- /**
- * Updates a page with any fillable data and saves it into the database.
- * @param Page $page
- * @param int $book_id
- * @param string $input
- * @return Page
- */
- public function updatePage(Page $page, $book_id, $input)
- {
- // Save a revision before updating
- if ($page->html !== $input['html'] || $page->name !== $input['name']) {
- $this->saveRevision($page);
- }
-
- // Prevent slug being updated if no name change
- if ($page->name !== $input['name']) {
- $page->slug = $this->findSuitableSlug($input['name'], $book_id, $page->id);
- }
-
- // Update with new details
- $page->fill($input);
- $page->html = $this->formatHtml($input['html']);
- $page->text = strip_tags($page->html);
- $page->updated_by = auth()->user()->id;
- $page->save();
- return $page;
- }
-
- /**
- * Restores a revision's content back into a page.
- * @param Page $page
- * @param Book $book
- * @param int $revisionId
- * @return Page
- */
- public function restoreRevision(Page $page, Book $book, $revisionId)
- {
- $this->saveRevision($page);
- $revision = $this->getRevisionById($revisionId);
- $page->fill($revision->toArray());
- $page->slug = $this->findSuitableSlug($page->name, $book->id, $page->id);
- $page->text = strip_tags($page->html);
- $page->updated_by = auth()->user()->id;
- $page->save();
- return $page;
- }
-
- /**
- * Saves a page revision into the system.
- * @param Page $page
- * @return $this
- */
- public function saveRevision(Page $page)
- {
- $revision = $this->pageRevision->fill($page->toArray());
- $revision->page_id = $page->id;
- $revision->slug = $page->slug;
- $revision->book_slug = $page->book->slug;
- $revision->created_by = auth()->user()->id;
- $revision->created_at = $page->updated_at;
- $revision->save();
- // Clear old revisions
- if ($this->pageRevision->where('page_id', '=', $page->id)->count() > 50) {
- $this->pageRevision->where('page_id', '=', $page->id)
- ->orderBy('created_at', 'desc')->skip(50)->take(5)->delete();
- }
- return $revision;
- }
-
- /**
- * Gets a single revision via it's id.
- * @param $id
- * @return mixed
- */
- public function getRevisionById($id)
- {
- return $this->pageRevision->findOrFail($id);
- }
-
- /**
- * Checks if a slug exists within a book already.
- * @param $slug
- * @param $bookId
- * @param bool|false $currentId
- * @return bool
- */
- public function doesSlugExist($slug, $bookId, $currentId = false)
- {
- $query = $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId);
- if ($currentId) $query = $query->where('id', '!=', $currentId);
- return $query->count() > 0;
- }
-
- /**
- * Changes the related book for the specified page.
- * Changes the book id of any relations to the page that store the book id.
- * @param int $bookId
- * @param Page $page
- * @return Page
- */
- public function changeBook($bookId, Page $page)
- {
- $page->book_id = $bookId;
- foreach ($page->activity as $activity) {
- $activity->book_id = $bookId;
- $activity->save();
- }
- $page->slug = $this->findSuitableSlug($page->name, $bookId, $page->id);
- $page->save();
- return $page;
- }
-
- /**
- * Gets a suitable slug for the resource
- * @param $name
- * @param $bookId
- * @param bool|false $currentId
- * @return string
- */
- public function findSuitableSlug($name, $bookId, $currentId = false)
- {
- $slug = Str::slug($name);
- while ($this->doesSlugExist($slug, $bookId, $currentId)) {
- $slug .= '-' . substr(md5(rand(1, 500)), 0, 3);
- }
- return $slug;
- }
-
- /**
- * Destroy a given page along with its dependencies.
- * @param $page
- */
- public function destroy($page)
- {
- Activity::removeEntity($page);
- $page->views()->delete();
- $page->revisions()->delete();
- $page->restrictions()->delete();
- $page->delete();
- }
-
- /**
- * Get the latest pages added to the system.
- * @param $count
- */
- public function getRecentlyCreatedPaginated($count = 20)
- {
- return $this->pageQuery()->orderBy('created_at', 'desc')->paginate($count);
- }
-
- /**
- * Get the latest pages added to the system.
- * @param $count
- */
- public function getRecentlyUpdatedPaginated($count = 20)
- {
- return $this->pageQuery()->orderBy('updated_at', 'desc')->paginate($count);
- }
-
- /**
- * Updates pages restrictions from a request
- * @param $request
- * @param $page
- */
- public function updateRestrictionsFromRequest($request, $page)
- {
- // TODO - extract into shared repo
- $page->restricted = $request->has('restricted') && $request->get('restricted') === 'true';
- $page->restrictions()->delete();
- if ($request->has('restrictions')) {
- foreach($request->get('restrictions') as $roleId => $restrictions) {
- foreach ($restrictions as $action => $value) {
- $page->restrictions()->create([
- 'role_id' => $roleId,
- 'action' => strtolower($action)
- ]);
- }
- }
- }
- $page->save();
- }
-
-}
diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php
index a57210b8d..118bd6d9c 100644
--- a/app/Services/ActivityService.php
+++ b/app/Services/ActivityService.php
@@ -1,6 +1,5 @@