diff --git a/app/Entity.php b/app/Entity.php
index 705444959..42323628a 100644
--- a/app/Entity.php
+++ b/app/Entity.php
@@ -98,7 +98,7 @@ abstract class Entity extends Model
* @param string[] array $wheres
* @return mixed
*/
- public static function fullTextSearch($fieldsToSearch, $terms, $wheres = [])
+ public static function fullTextSearchQuery($fieldsToSearch, $terms, $wheres = [])
{
$termString = '';
foreach ($terms as $term) {
@@ -107,7 +107,7 @@ abstract class Entity extends Model
$fields = implode(',', $fieldsToSearch);
$termStringEscaped = \DB::connection()->getPdo()->quote($termString);
$search = static::addSelect(\DB::raw('*, MATCH(name) AGAINST('.$termStringEscaped.' IN BOOLEAN MODE) AS title_relevance'));
- $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termStringEscaped]);
+ $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
// Add additional where terms
foreach ($wheres as $whereTerm) {
@@ -115,10 +115,13 @@ abstract class Entity extends Model
}
// Load in relations
- if (!static::isA('book')) $search = $search->with('book');
- if (static::isA('page')) $search = $search->with('chapter');
+ if (static::isA('page')) {
+ $search = $search->with('book', 'chapter', 'createdBy', 'updatedBy');
+ } else if (static::isA('chapter')) {
+ $search = $search->with('book');
+ }
- return $search->orderBy('title_relevance', 'desc')->get();
+ return $search->orderBy('title_relevance', 'desc');
}
/**
diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php
index a4365d605..d577a85b1 100644
--- a/app/Http/Controllers/BookController.php
+++ b/app/Http/Controllers/BookController.php
@@ -157,7 +157,7 @@ class BookController extends Controller
$this->checkPermission('book-update');
$book = $this->bookRepo->getBySlug($bookSlug);
$bookChildren = $this->bookRepo->getChildren($book);
- $books = $this->bookRepo->getAll();
+ $books = $this->bookRepo->getAll(false);
$this->setPageTitle('Sort Book ' . $book->getShortName());
return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
}
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 8fd1c1009..e20c89e06 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -3,25 +3,21 @@
namespace BookStack\Http\Controllers;
use Activity;
-use Illuminate\Http\Request;
-
+use BookStack\Repos\EntityRepo;
use BookStack\Http\Requests;
-use BookStack\Repos\BookRepo;
use Views;
class HomeController extends Controller
{
-
- protected $activityService;
- protected $bookRepo;
+ protected $entityRepo;
/**
* HomeController constructor.
- * @param BookRepo $bookRepo
+ * @param EntityRepo $entityRepo
*/
- public function __construct(BookRepo $bookRepo)
+ public function __construct(EntityRepo $entityRepo)
{
- $this->bookRepo = $bookRepo;
+ $this->entityRepo = $entityRepo;
parent::__construct();
}
@@ -33,9 +29,16 @@ class HomeController extends Controller
*/
public function index()
{
- $activity = Activity::latest();
- $recents = $this->signedIn ? Views::getUserRecentlyViewed(10, 0) : $this->bookRepo->getLatest(10);
- return view('home', ['activity' => $activity, 'recents' => $recents]);
+ $activity = Activity::latest(10);
+ $recents = $this->signedIn ? Views::getUserRecentlyViewed(12, 0) : $this->entityRepo->getRecentlyCreatedBooks(10);
+ $recentlyCreatedPages = $this->entityRepo->getRecentlyCreatedPages(5);
+ $recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdatedPages(5);
+ return view('home', [
+ 'activity' => $activity,
+ 'recents' => $recents,
+ 'recentlyCreatedPages' => $recentlyCreatedPages,
+ 'recentlyUpdatedPages' => $recentlyUpdatedPages
+ ]);
}
}
diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php
index b4ab9682b..e78ae13e4 100644
--- a/app/Http/Controllers/PageController.php
+++ b/app/Http/Controllers/PageController.php
@@ -11,6 +11,7 @@ use BookStack\Http\Requests;
use BookStack\Repos\BookRepo;
use BookStack\Repos\ChapterRepo;
use BookStack\Repos\PageRepo;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Views;
class PageController extends Controller
@@ -81,6 +82,8 @@ class PageController extends Controller
/**
* Display the specified page.
+ * If the page is not found via the slug the
+ * revisions are searched for a match.
*
* @param $bookSlug
* @param $pageSlug
@@ -89,7 +92,15 @@ class PageController extends Controller
public function show($bookSlug, $pageSlug)
{
$book = $this->bookRepo->getBySlug($bookSlug);
- $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
+
+ try {
+ $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
+ } catch (NotFoundHttpException $e) {
+ $page = $this->pageRepo->findPageUsingOldSlug($pageSlug, $bookSlug);
+ if ($page === null) abort(404);
+ return redirect($page->getUrl());
+ }
+
$sidebarTree = $this->bookRepo->getChildren($book);
Views::add($page);
$this->setPageTitle($page->getShortName());
@@ -278,4 +289,30 @@ class PageController extends Controller
]);
}
+ /**
+ * Show a listing of recently created pages
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function showRecentlyCreated()
+ {
+ $pages = $this->pageRepo->getRecentlyCreatedPaginated(20);
+ return view('pages/detailed-listing', [
+ 'title' => 'Recently Created Pages',
+ 'pages' => $pages
+ ]);
+ }
+
+ /**
+ * Show a listing of recently created pages
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function showRecentlyUpdated()
+ {
+ $pages = $this->pageRepo->getRecentlyUpdatedPaginated(20);
+ return view('pages/detailed-listing', [
+ 'title' => 'Recently Updated Pages',
+ 'pages' => $pages
+ ]);
+ }
+
}
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 035de9fe6..e198dc767 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -42,11 +42,77 @@ class SearchController extends Controller
return redirect()->back();
}
$searchTerm = $request->get('term');
- $pages = $this->pageRepo->getBySearch($searchTerm);
- $books = $this->bookRepo->getBySearch($searchTerm);
- $chapters = $this->chapterRepo->getBySearch($searchTerm);
+ $paginationAppends = $request->only('term');
+ $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
+ $books = $this->bookRepo->getBySearch($searchTerm, 10, $paginationAppends);
+ $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 10, $paginationAppends);
$this->setPageTitle('Search For ' . $searchTerm);
- return view('search/all', ['pages' => $pages, 'books' => $books, 'chapters' => $chapters, 'searchTerm' => $searchTerm]);
+ return view('search/all', [
+ 'pages' => $pages,
+ 'books' => $books,
+ 'chapters' => $chapters,
+ 'searchTerm' => $searchTerm
+ ]);
+ }
+
+ /**
+ * Search only the pages in the system.
+ * @param Request $request
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
+ */
+ public function searchPages(Request $request)
+ {
+ if (!$request->has('term')) return redirect()->back();
+
+ $searchTerm = $request->get('term');
+ $paginationAppends = $request->only('term');
+ $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
+ $this->setPageTitle('Page Search For ' . $searchTerm);
+ return view('search/entity-search-list', [
+ 'entities' => $pages,
+ 'title' => 'Page Search Results',
+ 'searchTerm' => $searchTerm
+ ]);
+ }
+
+ /**
+ * Search only the chapters in the system.
+ * @param Request $request
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
+ */
+ public function searchChapters(Request $request)
+ {
+ if (!$request->has('term')) return redirect()->back();
+
+ $searchTerm = $request->get('term');
+ $paginationAppends = $request->only('term');
+ $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
+ $this->setPageTitle('Chapter Search For ' . $searchTerm);
+ return view('search/entity-search-list', [
+ 'entities' => $chapters,
+ 'title' => 'Chapter Search Results',
+ 'searchTerm' => $searchTerm
+ ]);
+ }
+
+ /**
+ * Search only the books in the system.
+ * @param Request $request
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
+ */
+ public function searchBooks(Request $request)
+ {
+ if (!$request->has('term')) return redirect()->back();
+
+ $searchTerm = $request->get('term');
+ $paginationAppends = $request->only('term');
+ $books = $this->bookRepo->getBySearch($searchTerm, 20, $paginationAppends);
+ $this->setPageTitle('Book Search For ' . $searchTerm);
+ return view('search/entity-search-list', [
+ 'entities' => $books,
+ 'title' => 'Book Search Results',
+ 'searchTerm' => $searchTerm
+ ]);
}
/**
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index bf25eafb2..55ca5be19 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -2,6 +2,7 @@
namespace BookStack\Http\Controllers;
+use BookStack\Activity;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
@@ -92,10 +93,9 @@ class UserController extends Controller
$user->save();
}
- return redirect('/users');
+ return redirect('/settings/users');
}
-
/**
* Show the form for editing the specified user.
* @param int $id
@@ -159,7 +159,7 @@ class UserController extends Controller
}
$user->save();
- return redirect('/users');
+ return redirect('/settings/users');
}
/**
@@ -197,6 +197,25 @@ class UserController extends Controller
}
$this->userRepo->destroy($user);
- return redirect('/users');
+ return redirect('/settings/users');
+ }
+
+ /**
+ * Show the user profile page
+ * @param $id
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
+ public function showProfilePage($id)
+ {
+ $user = $this->userRepo->getById($id);
+ $userActivity = $this->userRepo->getActivity($user);
+ $recentlyCreated = $this->userRepo->getRecentlyCreated($user, 5, 0);
+ $assetCounts = $this->userRepo->getAssetCounts($user);
+ return view('users/profile', [
+ 'user' => $user,
+ 'activity' => $userActivity,
+ 'recentlyCreated' => $recentlyCreated,
+ 'assetCounts' => $assetCounts
+ ]);
}
}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 6ac322122..36cf2a19f 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -3,6 +3,11 @@
// Authenticated routes...
Route::group(['middleware' => 'auth'], function () {
+ Route::group(['prefix' => 'pages'], function() {
+ Route::get('/recently-created', 'PageController@showRecentlyCreated');
+ Route::get('/recently-updated', 'PageController@showRecentlyUpdated');
+ });
+
Route::group(['prefix' => 'books'], function () {
// Books
@@ -47,14 +52,8 @@ Route::group(['middleware' => 'auth'], function () {
});
- // Users
- Route::get('/users', 'UserController@index');
- Route::get('/users/create', 'UserController@create');
- Route::get('/users/{id}/delete', 'UserController@delete');
- Route::post('/users/create', 'UserController@store');
- Route::get('/users/{id}', 'UserController@edit');
- Route::put('/users/{id}', 'UserController@update');
- Route::delete('/users/{id}', 'UserController@destroy');
+ // User Profile routes
+ Route::get('/user/{userId}', 'UserController@showProfilePage');
// Image routes
Route::group(['prefix' => 'images'], function() {
@@ -75,6 +74,9 @@ Route::group(['middleware' => 'auth'], function () {
// Search
Route::get('/search/all', 'SearchController@searchAll');
+ Route::get('/search/pages', 'SearchController@searchPages');
+ Route::get('/search/books', 'SearchController@searchBooks');
+ Route::get('/search/chapters', 'SearchController@searchChapters');
Route::get('/search/book/{bookId}', 'SearchController@searchBook');
// Other Pages
@@ -82,8 +84,18 @@ Route::group(['middleware' => 'auth'], function () {
Route::get('/home', 'HomeController@index');
// Settings
- Route::get('/settings', 'SettingController@index');
- Route::post('/settings', 'SettingController@update');
+ Route::group(['prefix' => 'settings'], function() {
+ Route::get('/', 'SettingController@index');
+ Route::post('/', 'SettingController@update');
+ // Users
+ Route::get('/users', 'UserController@index');
+ Route::get('/users/create', 'UserController@create');
+ Route::get('/users/{id}/delete', 'UserController@delete');
+ Route::post('/users/create', 'UserController@store');
+ Route::get('/users/{id}', 'UserController@edit');
+ Route::put('/users/{id}', 'UserController@update');
+ Route::delete('/users/{id}', 'UserController@destroy');
+ });
});
diff --git a/app/Page.php b/app/Page.php
index bd5f3bafe..53724ec20 100644
--- a/app/Page.php
+++ b/app/Page.php
@@ -45,7 +45,8 @@ class Page extends Entity
public function getExcerpt($length = 100)
{
- return strlen($this->text) > $length ? substr($this->text, 0, $length-3) . '...' : $this->text;
+ $text = strlen($this->text) > $length ? substr($this->text, 0, $length-3) . '...' : $this->text;
+ return mb_convert_encoding($text, 'UTF-8');
}
}
diff --git a/app/Repos/BookRepo.php b/app/Repos/BookRepo.php
index a57050ce2..d8a24c099 100644
--- a/app/Repos/BookRepo.php
+++ b/app/Repos/BookRepo.php
@@ -14,8 +14,8 @@ class BookRepo
/**
* BookRepo constructor.
- * @param Book $book
- * @param PageRepo $pageRepo
+ * @param Book $book
+ * @param PageRepo $pageRepo
* @param ChapterRepo $chapterRepo
*/
public function __construct(Book $book, PageRepo $pageRepo, ChapterRepo $chapterRepo)
@@ -42,7 +42,9 @@ class BookRepo
*/
public function getAll($count = 10)
{
- return $this->book->orderBy('name', 'asc')->take($count)->get();
+ $bookQuery = $this->book->orderBy('name', 'asc');
+ if (!$count) return $bookQuery->get();
+ return $bookQuery->take($count)->get();
}
/**
@@ -159,7 +161,7 @@ class BookRepo
}
/**
- * @param string $slug
+ * @param string $slug
* @param bool|false $currentId
* @return bool
*/
@@ -175,7 +177,7 @@ class BookRepo
/**
* Provides a suitable slug for the given book name.
* Ensures the returned slug is unique in the system.
- * @param string $name
+ * @param string $name
* @param bool|false $currentId
* @return string
*/
@@ -218,12 +220,15 @@ class BookRepo
/**
* Get books by search term.
* @param $term
+ * @param int $count
+ * @param array $paginationAppends
* @return mixed
*/
- public function getBySearch($term)
+ public function getBySearch($term, $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $books = $this->book->fullTextSearch(['name', 'description'], $terms);
+ $books = $this->book->fullTextSearchQuery(['name', 'description'], $terms)
+ ->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
foreach ($books as $book) {
//highlight
diff --git a/app/Repos/ChapterRepo.php b/app/Repos/ChapterRepo.php
index 3824e6982..bba6cbe7a 100644
--- a/app/Repos/ChapterRepo.php
+++ b/app/Repos/ChapterRepo.php
@@ -125,12 +125,15 @@ class ChapterRepo
* 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 = [])
+ public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $chapters = $this->chapter->fullTextSearch(['name', 'description'], $terms, $whereTerms);
+ $chapters = $this->chapter->fullTextSearchQuery(['name', 'description'], $terms, $whereTerms)
+ ->paginate($count)->appends($paginationAppends);
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
foreach ($chapters as $chapter) {
//highlight
diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php
new file mode 100644
index 000000000..28942d94a
--- /dev/null
+++ b/app/Repos/EntityRepo.php
@@ -0,0 +1,71 @@
+book = $book;
+ $this->chapter = $chapter;
+ $this->page = $page;
+ }
+
+ /**
+ * Get the latest books added to the system.
+ * @param $count
+ * @param $page
+ */
+ public function getRecentlyCreatedBooks($count = 20, $page = 0)
+ {
+ return $this->book->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ }
+
+ /**
+ * Get the most recently updated books.
+ * @param $count
+ * @param int $page
+ * @return mixed
+ */
+ public function getRecentlyUpdatedBooks($count = 20, $page = 0)
+ {
+ return $this->book->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ }
+
+ /**
+ * Get the latest pages added to the system.
+ * @param $count
+ * @param $page
+ */
+ public function getRecentlyCreatedPages($count = 20, $page = 0)
+ {
+ return $this->page->orderBy('created_at', 'desc')->skip($page*$count)->take($count)->get();
+ }
+
+ /**
+ * Get the most recently updated pages.
+ * @param $count
+ * @param int $page
+ * @return mixed
+ */
+ public function getRecentlyUpdatedPages($count = 20, $page = 0)
+ {
+ return $this->page->orderBy('updated_at', 'desc')->skip($page*$count)->take($count)->get();
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/Repos/PageRepo.php b/app/Repos/PageRepo.php
index 05052432e..f028a1fcc 100644
--- a/app/Repos/PageRepo.php
+++ b/app/Repos/PageRepo.php
@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use BookStack\Page;
use BookStack\PageRevision;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class PageRepo
{
@@ -65,11 +66,28 @@ class PageRepo
public function getBySlug($slug, $bookId)
{
$page = $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
- if ($page === null) abort(404);
+ if ($page === null) throw new NotFoundHttpException('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)
+ ->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
*/
@@ -125,21 +143,20 @@ class PageRepo
if($htmlText == '') return $htmlText;
libxml_use_internal_errors(true);
$doc = new \DOMDocument();
- $doc->loadHTML($htmlText);
+ $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
- $lastId = false;
$idArray = [];
foreach ($childNodes as $index => $childNode) {
/** @var \DOMElement $childNode */
if (get_class($childNode) !== 'DOMElement') continue;
- // Overwrite id if not a bookstack custom id
+ // Overwrite id if not a BookStack custom id
if ($childNode->hasAttribute('id')) {
$id = $childNode->getAttribute('id');
if (strpos($id, 'bkmrk') === 0 && array_search($id, $idArray) === false) {
@@ -149,13 +166,18 @@ class PageRepo
}
// Create an unique id for the element
- do {
- $id = 'bkmrk-' . substr(uniqid(), -5);
- } while ($id == $lastId);
- $lastId = $id;
+ // 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', $id);
- $idArray[] = $id;
+ $childNode->setAttribute('id', $newId);
+ $idArray[] = $newId;
}
// Generate inner html as a string
@@ -171,14 +193,17 @@ class PageRepo
/**
* Gets pages by a search term.
* Highlights page content for showing in results.
- * @param string $term
+ * @param string $term
* @param array $whereTerms
+ * @param int $count
+ * @param array $paginationAppends
* @return mixed
*/
- public function getBySearch($term, $whereTerms = [])
+ public function getBySearch($term, $whereTerms = [], $count = 20, $paginationAppends = [])
{
$terms = explode(' ', $term);
- $pages = $this->page->fullTextSearch(['name', 'text'], $terms, $whereTerms);
+ $pages = $this->page->fullTextSearchQuery(['name', 'text'], $terms, $whereTerms)
+ ->paginate($count)->appends($paginationAppends);
// Add highlights to page text.
$words = join('|', explode(' ', preg_quote(trim($term), '/')));
@@ -238,9 +263,13 @@ class PageRepo
$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->slug = $this->findSuitableSlug($page->name, $book_id, $page->id);
$page->html = $this->formatHtml($input['html']);
$page->text = strip_tags($page->html);
$page->updated_by = auth()->user()->id;
@@ -276,6 +305,8 @@ class PageRepo
{
$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();
@@ -358,5 +389,22 @@ class PageRepo
$page->delete();
}
+ /**
+ * Get the latest pages added to the system.
+ * @param $count
+ */
+ public function getRecentlyCreatedPaginated($count = 20)
+ {
+ return $this->page->orderBy('created_at', 'desc')->paginate($count);
+ }
-}
\ No newline at end of file
+ /**
+ * Get the latest pages added to the system.
+ * @param $count
+ */
+ public function getRecentlyUpdatedPaginated($count = 20)
+ {
+ return $this->page->orderBy('updated_at', 'desc')->paginate($count);
+ }
+
+}
diff --git a/app/Repos/UserRepo.php b/app/Repos/UserRepo.php
index d02ffe929..48541a51a 100644
--- a/app/Repos/UserRepo.php
+++ b/app/Repos/UserRepo.php
@@ -1,6 +1,5 @@
user = $user;
$this->role = $role;
+ $this->entityRepo = $entityRepo;
}
/**
@@ -112,4 +115,49 @@ class UserRepo
$user->socialAccounts()->delete();
$user->delete();
}
+
+ /**
+ * Get the latest activity for a user.
+ * @param User $user
+ * @param int $count
+ * @param int $page
+ * @return array
+ */
+ public function getActivity(User $user, $count = 20, $page = 0)
+ {
+ return \Activity::userActivity($user, $count, $page);
+ }
+
+ /**
+ * Get the recently created content for this given user.
+ * @param User $user
+ * @param int $count
+ * @return mixed
+ */
+ public function getRecentlyCreated(User $user, $count = 20)
+ {
+ return [
+ 'pages' => $this->entityRepo->page->where('created_by', '=', $user->id)->orderBy('created_at', 'desc')
+ ->take($count)->get(),
+ 'chapters' => $this->entityRepo->chapter->where('created_by', '=', $user->id)->orderBy('created_at', 'desc')
+ ->take($count)->get(),
+ 'books' => $this->entityRepo->book->where('created_by', '=', $user->id)->orderBy('created_at', 'desc')
+ ->take($count)->get()
+ ];
+ }
+
+ /**
+ * Get asset created counts for the give user.
+ * @param User $user
+ * @return array
+ */
+ public function getAssetCounts(User $user)
+ {
+ return [
+ 'pages' => $this->entityRepo->page->where('created_by', '=', $user->id)->count(),
+ 'chapters' => $this->entityRepo->chapter->where('created_by', '=', $user->id)->count(),
+ 'books' => $this->entityRepo->book->where('created_by', '=', $user->id)->count(),
+ ];
+ }
+
}
\ No newline at end of file
diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php
index 2ef5f9cfe..a065ae01f 100644
--- a/app/Services/ActivityService.php
+++ b/app/Services/ActivityService.php
@@ -29,18 +29,19 @@ class ActivityService
*/
public function add(Entity $entity, $activityKey, $bookId = 0, $extra = false)
{
- $this->activity->user_id = $this->user->id;
- $this->activity->book_id = $bookId;
- $this->activity->key = strtolower($activityKey);
+ $activity = $this->activity->newInstance();
+ $activity->user_id = $this->user->id;
+ $activity->book_id = $bookId;
+ $activity->key = strtolower($activityKey);
if ($extra !== false) {
- $this->activity->extra = $extra;
+ $activity->extra = $extra;
}
- $entity->activity()->save($this->activity);
+ $entity->activity()->save($activity);
$this->setNotification($activityKey);
}
/**
- * Adds a activity history with a message & without binding to a entitiy.
+ * Adds a activity history with a message & without binding to a entity.
* @param $activityKey
* @param int $bookId
* @param bool|false $extra
@@ -91,14 +92,14 @@ class ActivityService
}
/**
- * Gets the latest activity for an entitiy, Filtering out similar
+ * Gets the latest activity for an entity, Filtering out similar
* items to prevent a message activity list.
* @param Entity $entity
* @param int $count
* @param int $page
* @return array
*/
- function entityActivity($entity, $count = 20, $page = 0)
+ public function entityActivity($entity, $count = 20, $page = 0)
{
$activity = $entity->hasMany('BookStack\Activity')->orderBy('created_at', 'desc')
->skip($count * $page)->take($count)->get();
@@ -107,15 +108,30 @@ class ActivityService
}
/**
- * Filters out similar activity.
- * @param Activity[] $activity
+ * Get latest activity for a user, Filtering out similar
+ * items.
+ * @param $user
+ * @param int $count
+ * @param int $page
* @return array
*/
- protected function filterSimilar($activity)
+ public function userActivity($user, $count = 20, $page = 0)
+ {
+ $activity = $this->activity->where('user_id', '=', $user->id)
+ ->orderBy('created_at', 'desc')->skip($count * $page)->take($count)->get();
+ return $this->filterSimilar($activity);
+ }
+
+ /**
+ * Filters out similar activity.
+ * @param Activity[] $activities
+ * @return array
+ */
+ protected function filterSimilar($activities)
{
$newActivity = [];
$previousItem = false;
- foreach ($activity as $activityItem) {
+ foreach ($activities as $activityItem) {
if ($previousItem === false) {
$previousItem = $activityItem;
$newActivity[] = $activityItem;
diff --git a/app/User.php b/app/User.php
index 4a5914afd..c55102078 100644
--- a/app/User.php
+++ b/app/User.php
@@ -164,6 +164,6 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getEditUrl()
{
- return '/users/' . $this->id;
+ return '/settings/users/' . $this->id;
}
}
diff --git a/composer.lock b/composer.lock
index ad399b973..9951362c1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -9,16 +9,16 @@
"packages": [
{
"name": "aws/aws-sdk-php",
- "version": "3.14.2",
+ "version": "3.15.1",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "2970cb63e7b7b37dd8c07a4fa4e4e18a110ed4e2"
+ "reference": "5e6078913293576de969703481994b77c380ca30"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2970cb63e7b7b37dd8c07a4fa4e4e18a110ed4e2",
- "reference": "2970cb63e7b7b37dd8c07a4fa4e4e18a110ed4e2",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5e6078913293576de969703481994b77c380ca30",
+ "reference": "5e6078913293576de969703481994b77c380ca30",
"shasum": ""
},
"require": {
@@ -40,7 +40,8 @@
"ext-simplexml": "*",
"ext-spl": "*",
"nette/neon": "^2.3",
- "phpunit/phpunit": "~4.0|~5.0"
+ "phpunit/phpunit": "~4.0|~5.0",
+ "psr/cache": "^1.0"
},
"suggest": {
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
@@ -84,7 +85,7 @@
"s3",
"sdk"
],
- "time": "2016-01-28 21:33:18"
+ "time": "2016-02-11 23:23:31"
},
{
"name": "barryvdh/laravel-debugbar",
@@ -918,16 +919,16 @@
},
{
"name": "laravel/framework",
- "version": "v5.2.12",
+ "version": "v5.2.16",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "6b6255ad7bfbdb721b8d00b09d52b146c5d363d7"
+ "reference": "39e89553c124dce266da03ee3c0260bdd62f1848"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/6b6255ad7bfbdb721b8d00b09d52b146c5d363d7",
- "reference": "6b6255ad7bfbdb721b8d00b09d52b146c5d363d7",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/39e89553c124dce266da03ee3c0260bdd62f1848",
+ "reference": "39e89553c124dce266da03ee3c0260bdd62f1848",
"shasum": ""
},
"require": {
@@ -1042,7 +1043,7 @@
"framework",
"laravel"
],
- "time": "2016-01-26 04:15:37"
+ "time": "2016-02-15 17:46:58"
},
{
"name": "laravel/socialite",
@@ -1629,16 +1630,16 @@
},
{
"name": "paragonie/random_compat",
- "version": "1.1.6",
+ "version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
- "reference": "e6f80ab77885151908d0ec743689ca700886e8b0"
+ "reference": "b0e69d10852716b2ccbdff69c75c477637220790"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/e6f80ab77885151908d0ec743689ca700886e8b0",
- "reference": "e6f80ab77885151908d0ec743689ca700886e8b0",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/b0e69d10852716b2ccbdff69c75c477637220790",
+ "reference": "b0e69d10852716b2ccbdff69c75c477637220790",
"shasum": ""
},
"require": {
@@ -1673,7 +1674,7 @@
"pseudorandom",
"random"
],
- "time": "2016-01-29 16:19:52"
+ "time": "2016-02-06 03:52:05"
},
{
"name": "phenx/php-font-lib",
@@ -2024,16 +2025,16 @@
},
{
"name": "symfony/console",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "ebcdc507829df915f4ca23067bd59ee4ef61f6c3"
+ "reference": "5a02eaadaa285e2bb727eb6bbdfb8201fcd971b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/ebcdc507829df915f4ca23067bd59ee4ef61f6c3",
- "reference": "ebcdc507829df915f4ca23067bd59ee4ef61f6c3",
+ "url": "https://api.github.com/repos/symfony/console/zipball/5a02eaadaa285e2bb727eb6bbdfb8201fcd971b0",
+ "reference": "5a02eaadaa285e2bb727eb6bbdfb8201fcd971b0",
"shasum": ""
},
"require": {
@@ -2080,20 +2081,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2015-12-22 10:39:06"
+ "time": "2016-02-02 13:44:19"
},
{
"name": "symfony/debug",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "73612266ac709769effdbfc0762e5b07cfd2ac2a"
+ "reference": "29606049ced1ec715475f88d1bbe587252a3476e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/73612266ac709769effdbfc0762e5b07cfd2ac2a",
- "reference": "73612266ac709769effdbfc0762e5b07cfd2ac2a",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/29606049ced1ec715475f88d1bbe587252a3476e",
+ "reference": "29606049ced1ec715475f88d1bbe587252a3476e",
"shasum": ""
},
"require": {
@@ -2137,20 +2138,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2015-12-26 13:39:53"
+ "time": "2016-01-27 05:14:46"
},
{
"name": "symfony/event-dispatcher",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf"
+ "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d36355e026905fa5229e1ed7b4e9eda2e67adfcf",
- "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa",
+ "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa",
"shasum": ""
},
"require": {
@@ -2197,20 +2198,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2015-10-30 23:35:59"
+ "time": "2016-01-27 05:14:46"
},
{
"name": "symfony/finder",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "8617895eb798b6bdb338321ce19453dc113e5675"
+ "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/8617895eb798b6bdb338321ce19453dc113e5675",
- "reference": "8617895eb798b6bdb338321ce19453dc113e5675",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723",
+ "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723",
"shasum": ""
},
"require": {
@@ -2246,20 +2247,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2015-12-05 11:13:14"
+ "time": "2016-01-27 05:14:46"
},
{
"name": "symfony/http-foundation",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "939c8c28a5b1e4ab7317bc30c1f9aa881c4b06b5"
+ "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/939c8c28a5b1e4ab7317bc30c1f9aa881c4b06b5",
- "reference": "939c8c28a5b1e4ab7317bc30c1f9aa881c4b06b5",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9344a87ceedfc50354a39653e54257ee9aa6a77d",
+ "reference": "9344a87ceedfc50354a39653e54257ee9aa6a77d",
"shasum": ""
},
"require": {
@@ -2298,20 +2299,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2015-12-18 15:43:53"
+ "time": "2016-02-02 13:44:19"
},
{
"name": "symfony/http-kernel",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "f7933e9f19e26e7baba7ec04735b466fedd3a6db"
+ "reference": "cec02604450481ac26710ca4249cc61b57b23942"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f7933e9f19e26e7baba7ec04735b466fedd3a6db",
- "reference": "f7933e9f19e26e7baba7ec04735b466fedd3a6db",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cec02604450481ac26710ca4249cc61b57b23942",
+ "reference": "cec02604450481ac26710ca4249cc61b57b23942",
"shasum": ""
},
"require": {
@@ -2380,7 +2381,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2015-12-26 16:46:13"
+ "time": "2016-02-03 12:38:44"
},
{
"name": "symfony/polyfill-mbstring",
@@ -2551,16 +2552,16 @@
},
{
"name": "symfony/process",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "f4794f1d00f0746621be3020ffbd8c5e0b217ee3"
+ "reference": "dfecef47506179db2501430e732adbf3793099c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/f4794f1d00f0746621be3020ffbd8c5e0b217ee3",
- "reference": "f4794f1d00f0746621be3020ffbd8c5e0b217ee3",
+ "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8",
+ "reference": "dfecef47506179db2501430e732adbf3793099c8",
"shasum": ""
},
"require": {
@@ -2596,20 +2597,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2015-12-23 11:04:02"
+ "time": "2016-02-02 13:44:19"
},
{
"name": "symfony/routing",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "3b1bac52f42cb0f54df1a2dbabd55a1d214e2a59"
+ "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/3b1bac52f42cb0f54df1a2dbabd55a1d214e2a59",
- "reference": "3b1bac52f42cb0f54df1a2dbabd55a1d214e2a59",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/4686baa55a835e1c1ede9b86ba02415c8c8d6166",
+ "reference": "4686baa55a835e1c1ede9b86ba02415c8c8d6166",
"shasum": ""
},
"require": {
@@ -2670,20 +2671,20 @@
"uri",
"url"
],
- "time": "2015-12-23 08:00:11"
+ "time": "2016-01-27 05:14:46"
},
{
"name": "symfony/translation",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "dff0867826a7068d673801b7522f8e2634016ef9"
+ "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/dff0867826a7068d673801b7522f8e2634016ef9",
- "reference": "dff0867826a7068d673801b7522f8e2634016ef9",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91",
+ "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91",
"shasum": ""
},
"require": {
@@ -2734,20 +2735,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2015-12-05 17:45:07"
+ "time": "2016-02-02 13:44:19"
},
{
"name": "symfony/var-dumper",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "87db8700deb12ba2b65e858f656a1f885530bcb0"
+ "reference": "24bb94807eff00db49374c37ebf56a0304e8aef3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/87db8700deb12ba2b65e858f656a1f885530bcb0",
- "reference": "87db8700deb12ba2b65e858f656a1f885530bcb0",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/24bb94807eff00db49374c37ebf56a0304e8aef3",
+ "reference": "24bb94807eff00db49374c37ebf56a0304e8aef3",
"shasum": ""
},
"require": {
@@ -2797,7 +2798,7 @@
"debug",
"dump"
],
- "time": "2015-12-05 11:13:14"
+ "time": "2016-01-07 13:38:51"
},
{
"name": "vlucas/phpdotenv",
@@ -3182,22 +3183,24 @@
},
{
"name": "phpspec/prophecy",
- "version": "v1.5.0",
+ "version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
+ "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
- "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
+ "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "~2.0",
- "sebastian/comparator": "~1.1"
+ "sebastian/comparator": "~1.1",
+ "sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpspec/phpspec": "~2.0"
@@ -3205,7 +3208,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4.x-dev"
+ "dev-master": "1.5.x-dev"
}
},
"autoload": {
@@ -3238,7 +3241,7 @@
"spy",
"stub"
],
- "time": "2015-08-13 10:07:40"
+ "time": "2016-02-15 07:46:21"
},
{
"name": "phpunit/php-code-coverage",
@@ -3482,16 +3485,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "4.8.21",
+ "version": "4.8.23",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "ea76b17bced0500a28098626b84eda12dbcf119c"
+ "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea76b17bced0500a28098626b84eda12dbcf119c",
- "reference": "ea76b17bced0500a28098626b84eda12dbcf119c",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483",
+ "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483",
"shasum": ""
},
"require": {
@@ -3550,7 +3553,7 @@
"testing",
"xunit"
],
- "time": "2015-12-12 07:45:58"
+ "time": "2016-02-11 14:56:33"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -3981,16 +3984,16 @@
},
{
"name": "symfony/css-selector",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "4613311fd46e146f506403ce2f8a0c71d402d2a3"
+ "reference": "6605602690578496091ac20ec7a5cbd160d4dff4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/4613311fd46e146f506403ce2f8a0c71d402d2a3",
- "reference": "4613311fd46e146f506403ce2f8a0c71d402d2a3",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/6605602690578496091ac20ec7a5cbd160d4dff4",
+ "reference": "6605602690578496091ac20ec7a5cbd160d4dff4",
"shasum": ""
},
"require": {
@@ -4030,20 +4033,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2015-12-05 17:45:07"
+ "time": "2016-01-27 05:14:46"
},
{
"name": "symfony/dom-crawler",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "7c622b0c9fb8bdb146d6dfa86c5f91dcbfdbc11d"
+ "reference": "b693a9650aa004576b593ff2e91ae749dc90123d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/7c622b0c9fb8bdb146d6dfa86c5f91dcbfdbc11d",
- "reference": "7c622b0c9fb8bdb146d6dfa86c5f91dcbfdbc11d",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b693a9650aa004576b593ff2e91ae749dc90123d",
+ "reference": "b693a9650aa004576b593ff2e91ae749dc90123d",
"shasum": ""
},
"require": {
@@ -4086,20 +4089,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2015-12-26 13:42:31"
+ "time": "2016-01-25 09:56:57"
},
{
"name": "symfony/yaml",
- "version": "v3.0.1",
+ "version": "v3.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691"
+ "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/3df409958a646dad2bc5046c3fb671ee24a1a691",
- "reference": "3df409958a646dad2bc5046c3fb671ee24a1a691",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a",
+ "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a",
"shasum": ""
},
"require": {
@@ -4135,7 +4138,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2015-12-26 13:39:53"
+ "time": "2016-02-02 13:44:19"
}
],
"aliases": [],
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
index aa6cfee42..5e060006e 100644
--- a/database/migrations/2014_10_12_000000_create_users_table.php
+++ b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -18,7 +18,7 @@ class CreateUsersTable extends Migration
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
- $table->timestamps();
+ $table->nullableTimestamps();
});
\BookStack\User::forceCreate([
diff --git a/database/migrations/2015_07_12_114933_create_books_table.php b/database/migrations/2015_07_12_114933_create_books_table.php
index 1f8fae685..51fb55c48 100644
--- a/database/migrations/2015_07_12_114933_create_books_table.php
+++ b/database/migrations/2015_07_12_114933_create_books_table.php
@@ -17,7 +17,7 @@ class CreateBooksTable extends Migration
$table->string('name');
$table->string('slug')->indexed();
$table->text('description');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_07_12_190027_create_pages_table.php b/database/migrations/2015_07_12_190027_create_pages_table.php
index b7b1dc130..b3b2b9244 100644
--- a/database/migrations/2015_07_12_190027_create_pages_table.php
+++ b/database/migrations/2015_07_12_190027_create_pages_table.php
@@ -21,7 +21,7 @@ class CreatePagesTable extends Migration
$table->longText('html');
$table->longText('text');
$table->integer('priority');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_07_13_172121_create_images_table.php b/database/migrations/2015_07_13_172121_create_images_table.php
index ecd074a9b..61beaa7c3 100644
--- a/database/migrations/2015_07_13_172121_create_images_table.php
+++ b/database/migrations/2015_07_13_172121_create_images_table.php
@@ -16,7 +16,7 @@ class CreateImagesTable extends Migration
$table->increments('id');
$table->string('name');
$table->string('url');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_07_27_172342_create_chapters_table.php b/database/migrations/2015_07_27_172342_create_chapters_table.php
index 5467e63f2..7974759f2 100644
--- a/database/migrations/2015_07_27_172342_create_chapters_table.php
+++ b/database/migrations/2015_07_27_172342_create_chapters_table.php
@@ -19,7 +19,7 @@ class CreateChaptersTable extends Migration
$table->text('name');
$table->text('description');
$table->integer('priority');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_08_09_093534_create_page_revisions_table.php b/database/migrations/2015_08_09_093534_create_page_revisions_table.php
index b55097f0b..9c0693309 100644
--- a/database/migrations/2015_08_09_093534_create_page_revisions_table.php
+++ b/database/migrations/2015_08_09_093534_create_page_revisions_table.php
@@ -19,7 +19,7 @@ class CreatePageRevisionsTable extends Migration
$table->longText('html');
$table->longText('text');
$table->integer('created_by');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_08_16_142133_create_activities_table.php b/database/migrations/2015_08_16_142133_create_activities_table.php
index a0e177ddb..f8d9064f2 100644
--- a/database/migrations/2015_08_16_142133_create_activities_table.php
+++ b/database/migrations/2015_08_16_142133_create_activities_table.php
@@ -20,7 +20,7 @@ class CreateActivitiesTable extends Migration
$table->integer('user_id');
$table->integer('entity_id');
$table->string('entity_type');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_08_29_105422_add_roles_and_permissions.php b/database/migrations/2015_08_29_105422_add_roles_and_permissions.php
index 7247a0a38..4389dc32e 100644
--- a/database/migrations/2015_08_29_105422_add_roles_and_permissions.php
+++ b/database/migrations/2015_08_29_105422_add_roles_and_permissions.php
@@ -28,7 +28,7 @@ class AddRolesAndPermissions extends Migration
$table->string('name')->unique();
$table->string('display_name')->nullable();
$table->string('description')->nullable();
- $table->timestamps();
+ $table->nullableTimestamps();
});
// Create table for associating roles to users (Many-to-Many)
@@ -50,7 +50,7 @@ class AddRolesAndPermissions extends Migration
$table->string('name')->unique();
$table->string('display_name')->nullable();
$table->string('description')->nullable();
- $table->timestamps();
+ $table->nullableTimestamps();
});
// Create table for associating permissions to roles (Many-to-Many)
diff --git a/database/migrations/2015_08_30_125859_create_settings_table.php b/database/migrations/2015_08_30_125859_create_settings_table.php
index 8437668f7..2cef3e6e7 100644
--- a/database/migrations/2015_08_30_125859_create_settings_table.php
+++ b/database/migrations/2015_08_30_125859_create_settings_table.php
@@ -15,7 +15,7 @@ class CreateSettingsTable extends Migration
Schema::create('settings', function (Blueprint $table) {
$table->string('setting_key')->primary()->indexed();
$table->text('value');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_09_04_165821_create_social_accounts_table.php b/database/migrations/2015_09_04_165821_create_social_accounts_table.php
index 3933e728f..700d7f90f 100644
--- a/database/migrations/2015_09_04_165821_create_social_accounts_table.php
+++ b/database/migrations/2015_09_04_165821_create_social_accounts_table.php
@@ -18,7 +18,7 @@ class CreateSocialAccountsTable extends Migration
$table->string('driver')->index();
$table->string('driver_id');
$table->string('avatar');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_09_05_164707_add_email_confirmation_table.php b/database/migrations/2015_09_05_164707_add_email_confirmation_table.php
index 2f20cf0cf..105bda49e 100644
--- a/database/migrations/2015_09_05_164707_add_email_confirmation_table.php
+++ b/database/migrations/2015_09_05_164707_add_email_confirmation_table.php
@@ -20,7 +20,7 @@ class AddEmailConfirmationTable extends Migration
$table->increments('id');
$table->integer('user_id')->index();
$table->string('token')->index();
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2015_11_21_145609_create_views_table.php b/database/migrations/2015_11_21_145609_create_views_table.php
index 2baef7317..90c350864 100644
--- a/database/migrations/2015_11_21_145609_create_views_table.php
+++ b/database/migrations/2015_11_21_145609_create_views_table.php
@@ -18,7 +18,7 @@ class CreateViewsTable extends Migration
$table->integer('viewable_id');
$table->string('viewable_type');
$table->integer('views');
- $table->timestamps();
+ $table->nullableTimestamps();
});
}
diff --git a/database/migrations/2016_02_25_184030_add_slug_to_revisions.php b/database/migrations/2016_02_25_184030_add_slug_to_revisions.php
new file mode 100644
index 000000000..0be6c7940
--- /dev/null
+++ b/database/migrations/2016_02_25_184030_add_slug_to_revisions.php
@@ -0,0 +1,35 @@
+string('slug');
+ $table->index('slug');
+ $table->string('book_slug');
+ $table->index('book_slug');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('page_revisions', function (Blueprint $table) {
+ $table->dropColumn('slug');
+ $table->dropColumn('book_slug');
+ });
+ }
+}
diff --git a/phpunit.xml b/phpunit.xml
index 48c0dde22..762fc2da7 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -25,8 +25,13 @@
{{ $chapter->getExcerpt() }}
@endif - @if(count($chapter->pages) > 0 && !isset($hidePages)) + @if(!isset($hidePages) && count($chapter->pages) > 0){{ count($chapter->pages) }} Pages
{!! $page->searchSnippet !!}
@else{{ $page->getExcerpt() }}
@endif + + @if(isset($style) && $style === 'detailed') + + @endif + +- No items available -
-@endif \ No newline at end of file + @endforeach + @else ++ No items available +
+ @endif ++ View all matched pages + + @if(count($chapters) > 0) + + View all matched chapters + @endif + + @if(count($books) > 0) + + View all matched books + @endif +
No pages matched this search
- @endif -This will fully delete this user with the name '{{$user->name}}' from the system.
Are you sure you want to delete this user?
-