Dan Brown

Added indexes, Reduced queries on pages

...@@ -12,3 +12,4 @@ Homestead.yaml ...@@ -12,3 +12,4 @@ Homestead.yaml
12 /public/build 12 /public/build
13 /storage/images 13 /storage/images
14 _ide_helper.php 14 _ide_helper.php
15 +/storage/debugbar
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -27,16 +27,6 @@ class Book extends Entity ...@@ -27,16 +27,6 @@ class Book extends Entity
27 return $this->hasMany('BookStack\Chapter'); 27 return $this->hasMany('BookStack\Chapter');
28 } 28 }
29 29
30 - public function children()
31 - {
32 - $pages = $this->pages()->where('chapter_id', '=', 0)->get();
33 - $chapters = $this->chapters()->get();
34 - foreach($chapters as $chapter) {
35 - $pages->push($chapter);
36 - }
37 - return $pages->sortBy('priority');
38 - }
39 -
40 public function getExcerpt($length = 100) 30 public function getExcerpt($length = 100)
41 { 31 {
42 return strlen($this->description) > $length ? substr($this->description, 0, $length-3) . '...' : $this->description; 32 return strlen($this->description) > $length ? substr($this->description, 0, $length-3) . '...' : $this->description;
......
...@@ -18,7 +18,8 @@ class Chapter extends Entity ...@@ -18,7 +18,8 @@ class Chapter extends Entity
18 18
19 public function getUrl() 19 public function getUrl()
20 { 20 {
21 - return '/books/' . $this->book->slug . '/chapter/' . $this->slug; 21 + $bookSlug = isset($this->bookSlug) ? $this->bookSlug : $this->book->slug;
22 + return '/books/' . $bookSlug. '/chapter/' . $this->slug;
22 } 23 }
23 24
24 public function getExcerpt($length = 100) 25 public function getExcerpt($length = 100)
......
...@@ -89,7 +89,8 @@ class BookController extends Controller ...@@ -89,7 +89,8 @@ class BookController extends Controller
89 { 89 {
90 $book = $this->bookRepo->getBySlug($slug); 90 $book = $this->bookRepo->getBySlug($slug);
91 Views::add($book); 91 Views::add($book);
92 - return view('books/show', ['book' => $book, 'current' => $book]); 92 + $bookChildren = $this->bookRepo->getChildren($book);
93 + return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
93 } 94 }
94 95
95 /** 96 /**
......
...@@ -80,8 +80,9 @@ class ChapterController extends Controller ...@@ -80,8 +80,9 @@ class ChapterController extends Controller
80 { 80 {
81 $book = $this->bookRepo->getBySlug($bookSlug); 81 $book = $this->bookRepo->getBySlug($bookSlug);
82 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 82 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
83 + $sidebarTree = $this->bookRepo->getChildren($book);
83 Views::add($chapter); 84 Views::add($chapter);
84 - return view('chapters/show', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); 85 + return view('chapters/show', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter, 'sidebarTree' => $sidebarTree]);
85 } 86 }
86 87
87 /** 88 /**
......
...@@ -87,8 +87,9 @@ class PageController extends Controller ...@@ -87,8 +87,9 @@ class PageController extends Controller
87 { 87 {
88 $book = $this->bookRepo->getBySlug($bookSlug); 88 $book = $this->bookRepo->getBySlug($bookSlug);
89 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 89 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
90 + $sidebarTree = $this->bookRepo->getChildren($book);
90 Views::add($page); 91 Views::add($page);
91 - return view('pages/show', ['page' => $page, 'book' => $book, 'current' => $page]); 92 + return view('pages/show', ['page' => $page, 'book' => $book, 'current' => $page, 'sidebarTree' => $sidebarTree]);
92 } 93 }
93 94
94 /** 95 /**
......
...@@ -40,7 +40,9 @@ class Page extends Entity ...@@ -40,7 +40,9 @@ class Page extends Entity
40 40
41 public function getUrl() 41 public function getUrl()
42 { 42 {
43 - return '/books/' . $this->book->slug . '/page/' . $this->slug; 43 + // TODO - Extract this and share with chapters
44 + $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
45 + return '/books/' . $bookSlug . '/page/' . $this->slug;
44 } 46 }
45 47
46 public function getExcerpt($length = 100) 48 public function getExcerpt($length = 100)
......
...@@ -179,6 +179,30 @@ class BookRepo ...@@ -179,6 +179,30 @@ class BookRepo
179 } 179 }
180 180
181 /** 181 /**
182 + * Get all child objects of a book.
183 + * Returns a sorted collection of Pages and Chapters.
184 + * Loads the bookslug onto child elements to prevent access database access for getting the slug.
185 + * @param Book $book
186 + * @return mixed
187 + */
188 + public function getChildren(Book $book)
189 + {
190 + $pages = $book->pages()->where('chapter_id', '=', 0)->get();
191 + $chapters = $book->chapters()->with('pages')->get();
192 + $children = $pages->merge($chapters);
193 + $bookSlug = $book->slug;
194 + $children->each(function ($child) use ($bookSlug) {
195 + $child->setAttribute('bookSlug', $bookSlug);
196 + if ($child->isA('chapter')) {
197 + $child->pages->each(function ($page) use ($bookSlug) {
198 + $page->setAttribute('bookSlug', $bookSlug);
199 + });
200 + }
201 + });
202 + return $children->sortBy('priority');
203 + }
204 +
205 + /**
182 * Get books by search term. 206 * Get books by search term.
183 * @param $term 207 * @param $term
184 * @return mixed 208 * @return mixed
......
...@@ -34,6 +34,12 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon ...@@ -34,6 +34,12 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
34 protected $hidden = ['password', 'remember_token']; 34 protected $hidden = ['password', 'remember_token'];
35 35
36 /** 36 /**
37 + * This holds the user's permissions when loaded.
38 + * @var array
39 + */
40 + protected $permissions;
41 +
42 + /**
37 * Returns a default guest user. 43 * Returns a default guest user.
38 */ 44 */
39 public static function getDefault() 45 public static function getDefault()
...@@ -58,7 +64,19 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon ...@@ -58,7 +64,19 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
58 64
59 public function getRoleAttribute() 65 public function getRoleAttribute()
60 { 66 {
61 - return $this->roles()->first(); 67 + return $this->roles()->with('permissions')->first();
68 + }
69 +
70 + /**
71 + * Loads the user's permissions from thier role.
72 + */
73 + private function loadPermissions()
74 + {
75 + if (isset($this->permissions)) return;
76 + $this->load('roles.permissions');
77 + $permissions = $this->roles[0]->permissions;
78 + $permissionsArray = $permissions->pluck('name')->all();
79 + $this->permissions = $permissionsArray;
62 } 80 }
63 81
64 /** 82 /**
...@@ -68,14 +86,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon ...@@ -68,14 +86,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
68 */ 86 */
69 public function can($permissionName) 87 public function can($permissionName)
70 { 88 {
71 - if($this->email == 'guest') { 89 + if ($this->email == 'guest') {
72 return false; 90 return false;
73 } 91 }
74 - $permissions = $this->role->permissions()->get(); 92 + $this->loadPermissions();
75 - $permissionSearch = $permissions->search(function ($item, $key) use ($permissionName) { 93 + return array_search($permissionName, $this->permissions) !== false;
76 - return $item->name == $permissionName;
77 - });
78 - return $permissionSearch !== false;
79 } 94 }
80 95
81 /** 96 /**
...@@ -114,7 +129,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon ...@@ -114,7 +129,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
114 */ 129 */
115 public function hasSocialAccount($socialDriver = false) 130 public function hasSocialAccount($socialDriver = false)
116 { 131 {
117 - if($socialDriver === false) { 132 + if ($socialDriver === false) {
118 return $this->socialAccounts()->count() > 0; 133 return $this->socialAccounts()->count() > 0;
119 } 134 }
120 135
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
9 "laravel/framework": "5.1.*", 9 "laravel/framework": "5.1.*",
10 "intervention/image": "^2.3", 10 "intervention/image": "^2.3",
11 "barryvdh/laravel-ide-helper": "^2.1", 11 "barryvdh/laravel-ide-helper": "^2.1",
12 - "laravel/socialite": "^2.0" 12 + "laravel/socialite": "^2.0",
13 + "barryvdh/laravel-debugbar": "^2.0"
13 }, 14 },
14 "require-dev": { 15 "require-dev": {
15 "fzaninotto/faker": "~1.4", 16 "fzaninotto/faker": "~1.4",
......
...@@ -4,9 +4,64 @@ ...@@ -4,9 +4,64 @@
4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 "This file is @generated automatically" 5 "This file is @generated automatically"
6 ], 6 ],
7 - "hash": "7d7e80e9f1c13417c35195f79e41c038", 7 + "hash": "c216d0bcb72b4f2008d7fa8067da2f77",
8 + "content-hash": "3c421ae5b8e5c11792249142cb96ff25",
8 "packages": [ 9 "packages": [
9 { 10 {
11 + "name": "barryvdh/laravel-debugbar",
12 + "version": "v2.0.6",
13 + "source": {
14 + "type": "git",
15 + "url": "https://github.com/barryvdh/laravel-debugbar.git",
16 + "reference": "23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c"
17 + },
18 + "dist": {
19 + "type": "zip",
20 + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c",
21 + "reference": "23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c",
22 + "shasum": ""
23 + },
24 + "require": {
25 + "illuminate/support": "~5.0.17|5.1.*",
26 + "maximebf/debugbar": "~1.10.2",
27 + "php": ">=5.4.0",
28 + "symfony/finder": "~2.6"
29 + },
30 + "type": "library",
31 + "extra": {
32 + "branch-alias": {
33 + "dev-master": "2.1-dev"
34 + }
35 + },
36 + "autoload": {
37 + "psr-4": {
38 + "Barryvdh\\Debugbar\\": "src/"
39 + },
40 + "files": [
41 + "src/helpers.php"
42 + ]
43 + },
44 + "notification-url": "https://packagist.org/downloads/",
45 + "license": [
46 + "MIT"
47 + ],
48 + "authors": [
49 + {
50 + "name": "Barry vd. Heuvel",
51 + "email": "barryvdh@gmail.com"
52 + }
53 + ],
54 + "description": "PHP Debugbar integration for Laravel",
55 + "keywords": [
56 + "debug",
57 + "debugbar",
58 + "laravel",
59 + "profiler",
60 + "webprofiler"
61 + ],
62 + "time": "2015-09-09 11:39:27"
63 + },
64 + {
10 "name": "barryvdh/laravel-ide-helper", 65 "name": "barryvdh/laravel-ide-helper",
11 "version": "v2.1.0", 66 "version": "v2.1.0",
12 "source": { 67 "source": {
...@@ -1079,6 +1134,62 @@ ...@@ -1079,6 +1134,62 @@
1079 "time": "2015-08-22 09:49:14" 1134 "time": "2015-08-22 09:49:14"
1080 }, 1135 },
1081 { 1136 {
1137 + "name": "maximebf/debugbar",
1138 + "version": "v1.10.5",
1139 + "source": {
1140 + "type": "git",
1141 + "url": "https://github.com/maximebf/php-debugbar.git",
1142 + "reference": "30e53e8a28284b69dd223c9f5ee8957befd72636"
1143 + },
1144 + "dist": {
1145 + "type": "zip",
1146 + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/30e53e8a28284b69dd223c9f5ee8957befd72636",
1147 + "reference": "30e53e8a28284b69dd223c9f5ee8957befd72636",
1148 + "shasum": ""
1149 + },
1150 + "require": {
1151 + "php": ">=5.3.0",
1152 + "psr/log": "~1.0",
1153 + "symfony/var-dumper": "~2.6"
1154 + },
1155 + "require-dev": {
1156 + "phpunit/phpunit": "~4.0"
1157 + },
1158 + "suggest": {
1159 + "kriswallsmith/assetic": "The best way to manage assets",
1160 + "monolog/monolog": "Log using Monolog",
1161 + "predis/predis": "Redis storage"
1162 + },
1163 + "type": "library",
1164 + "extra": {
1165 + "branch-alias": {
1166 + "dev-master": "1.10-dev"
1167 + }
1168 + },
1169 + "autoload": {
1170 + "psr-0": {
1171 + "DebugBar": "src/"
1172 + }
1173 + },
1174 + "notification-url": "https://packagist.org/downloads/",
1175 + "license": [
1176 + "MIT"
1177 + ],
1178 + "authors": [
1179 + {
1180 + "name": "Maxime Bouroumeau-Fuseau",
1181 + "email": "maxime.bouroumeau@gmail.com",
1182 + "homepage": "http://maximebf.com"
1183 + }
1184 + ],
1185 + "description": "Debug bar in the browser for php application",
1186 + "homepage": "https://github.com/maximebf/php-debugbar",
1187 + "keywords": [
1188 + "debug"
1189 + ],
1190 + "time": "2015-10-19 20:35:12"
1191 + },
1192 + {
1082 "name": "monolog/monolog", 1193 "name": "monolog/monolog",
1083 "version": "1.16.0", 1194 "version": "1.16.0",
1084 "source": { 1195 "source": {
...@@ -1556,12 +1667,12 @@ ...@@ -1556,12 +1667,12 @@
1556 "version": "v2.7.3", 1667 "version": "v2.7.3",
1557 "source": { 1668 "source": {
1558 "type": "git", 1669 "type": "git",
1559 - "url": "https://github.com/symfony/ClassLoader.git", 1670 + "url": "https://github.com/symfony/class-loader.git",
1560 "reference": "2fccbc544997340808801a7410cdcb96dd12edc4" 1671 "reference": "2fccbc544997340808801a7410cdcb96dd12edc4"
1561 }, 1672 },
1562 "dist": { 1673 "dist": {
1563 "type": "zip", 1674 "type": "zip",
1564 - "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/2fccbc544997340808801a7410cdcb96dd12edc4", 1675 + "url": "https://api.github.com/repos/symfony/class-loader/zipball/2fccbc544997340808801a7410cdcb96dd12edc4",
1565 "reference": "2fccbc544997340808801a7410cdcb96dd12edc4", 1676 "reference": "2fccbc544997340808801a7410cdcb96dd12edc4",
1566 "shasum": "" 1677 "shasum": ""
1567 }, 1678 },
...@@ -1606,12 +1717,12 @@ ...@@ -1606,12 +1717,12 @@
1606 "version": "v2.7.3", 1717 "version": "v2.7.3",
1607 "source": { 1718 "source": {
1608 "type": "git", 1719 "type": "git",
1609 - "url": "https://github.com/symfony/Console.git", 1720 + "url": "https://github.com/symfony/console.git",
1610 "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e" 1721 "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e"
1611 }, 1722 },
1612 "dist": { 1723 "dist": {
1613 "type": "zip", 1724 "type": "zip",
1614 - "url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e", 1725 + "url": "https://api.github.com/repos/symfony/console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e",
1615 "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e", 1726 "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e",
1616 "shasum": "" 1727 "shasum": ""
1617 }, 1728 },
...@@ -1663,12 +1774,12 @@ ...@@ -1663,12 +1774,12 @@
1663 "version": "v2.7.3", 1774 "version": "v2.7.3",
1664 "source": { 1775 "source": {
1665 "type": "git", 1776 "type": "git",
1666 - "url": "https://github.com/symfony/CssSelector.git", 1777 + "url": "https://github.com/symfony/css-selector.git",
1667 "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092" 1778 "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092"
1668 }, 1779 },
1669 "dist": { 1780 "dist": {
1670 "type": "zip", 1781 "type": "zip",
1671 - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092", 1782 + "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092",
1672 "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092", 1783 "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092",
1673 "shasum": "" 1784 "shasum": ""
1674 }, 1785 },
...@@ -1716,12 +1827,12 @@ ...@@ -1716,12 +1827,12 @@
1716 "version": "v2.7.3", 1827 "version": "v2.7.3",
1717 "source": { 1828 "source": {
1718 "type": "git", 1829 "type": "git",
1719 - "url": "https://github.com/symfony/Debug.git", 1830 + "url": "https://github.com/symfony/debug.git",
1720 "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3" 1831 "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3"
1721 }, 1832 },
1722 "dist": { 1833 "dist": {
1723 "type": "zip", 1834 "type": "zip",
1724 - "url": "https://api.github.com/repos/symfony/Debug/zipball/9daa1bf9f7e615fa2fba30357e479a90141222e3", 1835 + "url": "https://api.github.com/repos/symfony/debug/zipball/9daa1bf9f7e615fa2fba30357e479a90141222e3",
1725 "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3", 1836 "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3",
1726 "shasum": "" 1837 "shasum": ""
1727 }, 1838 },
...@@ -1776,12 +1887,12 @@ ...@@ -1776,12 +1887,12 @@
1776 "version": "v2.7.3", 1887 "version": "v2.7.3",
1777 "source": { 1888 "source": {
1778 "type": "git", 1889 "type": "git",
1779 - "url": "https://github.com/symfony/DomCrawler.git", 1890 + "url": "https://github.com/symfony/dom-crawler.git",
1780 "reference": "9dabece63182e95c42b06967a0d929a5df78bc35" 1891 "reference": "9dabece63182e95c42b06967a0d929a5df78bc35"
1781 }, 1892 },
1782 "dist": { 1893 "dist": {
1783 "type": "zip", 1894 "type": "zip",
1784 - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/9dabece63182e95c42b06967a0d929a5df78bc35", 1895 + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/9dabece63182e95c42b06967a0d929a5df78bc35",
1785 "reference": "9dabece63182e95c42b06967a0d929a5df78bc35", 1896 "reference": "9dabece63182e95c42b06967a0d929a5df78bc35",
1786 "shasum": "" 1897 "shasum": ""
1787 }, 1898 },
...@@ -1829,12 +1940,12 @@ ...@@ -1829,12 +1940,12 @@
1829 "version": "v2.7.3", 1940 "version": "v2.7.3",
1830 "source": { 1941 "source": {
1831 "type": "git", 1942 "type": "git",
1832 - "url": "https://github.com/symfony/EventDispatcher.git", 1943 + "url": "https://github.com/symfony/event-dispatcher.git",
1833 "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3" 1944 "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3"
1834 }, 1945 },
1835 "dist": { 1946 "dist": {
1836 "type": "zip", 1947 "type": "zip",
1837 - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", 1948 + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
1838 "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", 1949 "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
1839 "shasum": "" 1950 "shasum": ""
1840 }, 1951 },
...@@ -1936,12 +2047,12 @@ ...@@ -1936,12 +2047,12 @@
1936 "version": "v2.7.3", 2047 "version": "v2.7.3",
1937 "source": { 2048 "source": {
1938 "type": "git", 2049 "type": "git",
1939 - "url": "https://github.com/symfony/HttpFoundation.git", 2050 + "url": "https://github.com/symfony/http-foundation.git",
1940 "reference": "863af6898081b34c65d42100c370b9f3c51b70ca" 2051 "reference": "863af6898081b34c65d42100c370b9f3c51b70ca"
1941 }, 2052 },
1942 "dist": { 2053 "dist": {
1943 "type": "zip", 2054 "type": "zip",
1944 - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca", 2055 + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca",
1945 "reference": "863af6898081b34c65d42100c370b9f3c51b70ca", 2056 "reference": "863af6898081b34c65d42100c370b9f3c51b70ca",
1946 "shasum": "" 2057 "shasum": ""
1947 }, 2058 },
...@@ -1989,12 +2100,12 @@ ...@@ -1989,12 +2100,12 @@
1989 "version": "v2.7.3", 2100 "version": "v2.7.3",
1990 "source": { 2101 "source": {
1991 "type": "git", 2102 "type": "git",
1992 - "url": "https://github.com/symfony/HttpKernel.git", 2103 + "url": "https://github.com/symfony/http-kernel.git",
1993 "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98" 2104 "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98"
1994 }, 2105 },
1995 "dist": { 2106 "dist": {
1996 "type": "zip", 2107 "type": "zip",
1997 - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98", 2108 + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98",
1998 "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98", 2109 "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98",
1999 "shasum": "" 2110 "shasum": ""
2000 }, 2111 },
......
...@@ -143,6 +143,7 @@ return [ ...@@ -143,6 +143,7 @@ return [
143 */ 143 */
144 Intervention\Image\ImageServiceProvider::class, 144 Intervention\Image\ImageServiceProvider::class,
145 Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class, 145 Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
146 + Barryvdh\Debugbar\ServiceProvider::class,
146 147
147 148
148 /* 149 /*
...@@ -207,6 +208,7 @@ return [ ...@@ -207,6 +208,7 @@ return [
207 */ 208 */
208 209
209 'ImageTool' => Intervention\Image\Facades\Image::class, 210 'ImageTool' => Intervention\Image\Facades\Image::class,
211 + 'Debugbar' => Barryvdh\Debugbar\Facade::class,
210 212
211 /** 213 /**
212 * Custom 214 * Custom
......
...@@ -23,6 +23,7 @@ $factory->define(BookStack\User::class, function ($faker) { ...@@ -23,6 +23,7 @@ $factory->define(BookStack\User::class, function ($faker) {
23 $factory->define(BookStack\Book::class, function ($faker) { 23 $factory->define(BookStack\Book::class, function ($faker) {
24 return [ 24 return [
25 'name' => $faker->sentence, 25 'name' => $faker->sentence,
26 + 'slug' => str_random(10),
26 'description' => $faker->paragraph 27 'description' => $faker->paragraph
27 ]; 28 ];
28 }); 29 });
...@@ -30,6 +31,7 @@ $factory->define(BookStack\Book::class, function ($faker) { ...@@ -30,6 +31,7 @@ $factory->define(BookStack\Book::class, function ($faker) {
30 $factory->define(BookStack\Chapter::class, function ($faker) { 31 $factory->define(BookStack\Chapter::class, function ($faker) {
31 return [ 32 return [
32 'name' => $faker->sentence, 33 'name' => $faker->sentence,
34 + 'slug' => str_random(10),
33 'description' => $faker->paragraph 35 'description' => $faker->paragraph
34 ]; 36 ];
35 }); 37 });
...@@ -37,6 +39,7 @@ $factory->define(BookStack\Chapter::class, function ($faker) { ...@@ -37,6 +39,7 @@ $factory->define(BookStack\Chapter::class, function ($faker) {
37 $factory->define(BookStack\Page::class, function ($faker) { 39 $factory->define(BookStack\Page::class, function ($faker) {
38 return [ 40 return [
39 'name' => $faker->sentence, 41 'name' => $faker->sentence,
42 + 'slug' => str_random(10),
40 'html' => '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>' 43 'html' => '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>'
41 ]; 44 ];
42 }); 45 });
......
1 +<?php
2 +
3 +use Illuminate\Database\Schema\Blueprint;
4 +use Illuminate\Database\Migrations\Migration;
5 +
6 +class AddEntityIndexes extends Migration
7 +{
8 + /**
9 + * Run the migrations.
10 + *
11 + * @return void
12 + */
13 + public function up()
14 + {
15 + Schema::table('books', function (Blueprint $table) {
16 + $table->index('slug');
17 + $table->index('created_by');
18 + $table->index('updated_by');
19 + });
20 + Schema::table('pages', function (Blueprint $table) {
21 + $table->index('slug');
22 + $table->index('book_id');
23 + $table->index('chapter_id');
24 + $table->index('priority');
25 + $table->index('created_by');
26 + $table->index('updated_by');
27 + });
28 + Schema::table('page_revisions', function (Blueprint $table) {
29 + $table->index('page_id');
30 + });
31 + Schema::table('chapters', function (Blueprint $table) {
32 + $table->index('slug');
33 + $table->index('book_id');
34 + $table->index('priority');
35 + $table->index('created_by');
36 + $table->index('updated_by');
37 + });
38 + Schema::table('activities', function (Blueprint $table) {
39 + $table->index('book_id');
40 + $table->index('user_id');
41 + $table->index('entity_id');
42 + });
43 + Schema::table('views', function (Blueprint $table) {
44 + $table->index('user_id');
45 + $table->index('viewable_id');
46 + });
47 + }
48 +
49 + /**
50 + * Reverse the migrations.
51 + *
52 + * @return void
53 + */
54 + public function down()
55 + {
56 + Schema::table('books', function (Blueprint $table) {
57 + $table->dropIndex('slug');
58 + $table->dropIndex('created_by');
59 + $table->dropIndex('updated_by');
60 + });
61 + Schema::table('pages', function (Blueprint $table) {
62 + $table->dropIndex('slug');
63 + $table->dropIndex('book_id');
64 + $table->dropIndex('chapter_id');
65 + $table->dropIndex('priority');
66 + $table->dropIndex('created_by');
67 + $table->dropIndex('updated_by');
68 + });
69 + Schema::table('page_revisions', function (Blueprint $table) {
70 + $table->dropIndex('page_id');
71 + });
72 + Schema::table('chapters', function (Blueprint $table) {
73 + $table->dropIndex('slug');
74 + $table->dropIndex('book_id');
75 + $table->dropIndex('priority');
76 + $table->dropIndex('created_by');
77 + $table->dropIndex('updated_by');
78 + });
79 + Schema::table('activities', function (Blueprint $table) {
80 + $table->dropIndex('book_id');
81 + $table->dropIndex('user_id');
82 + $table->dropIndex('entity_id');
83 + });
84 + Schema::table('views', function (Blueprint $table) {
85 + $table->dropIndex('user_id');
86 + $table->dropIndex('entity_id');
87 + });
88 + }
89 +}
1 +<?php
2 +
3 +use Illuminate\Database\Seeder;
4 +
5 +class DummyContentSeeder extends Seeder
6 +{
7 + /**
8 + * Run the database seeds.
9 + *
10 + * @return void
11 + */
12 + public function run()
13 + {
14 + $user = factory(BookStack\User::class, 1)->create();
15 + $role = \BookStack\Role::where('name', '=', 'admin')->first();
16 + $user->attachRole($role);
17 +
18 +
19 + $books = factory(BookStack\Book::class, 20)->create(['created_by' => $user->id, 'updated_by' => $user->id])
20 + ->each(function($book) use ($user) {
21 + $chapters = factory(BookStack\Chapter::class, 5)->create(['created_by' => $user->id, 'updated_by' => $user->id])
22 + ->each(function($chapter) use ($user, $book){
23 + $pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
24 + $chapter->pages()->saveMany($pages);
25 + });
26 + $book->chapters()->saveMany($chapters);
27 + });
28 + }
29 +}
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
37 37
38 <div class="page-list"> 38 <div class="page-list">
39 <hr> 39 <hr>
40 - @if(count($book->children()) > 0) 40 + @if(count($bookChildren) > 0)
41 - @foreach($book->children() as $childElement) 41 + @foreach($bookChildren as $childElement)
42 @if($childElement->isA('chapter')) 42 @if($childElement->isA('chapter'))
43 @include('chapters/list-item', ['chapter' => $childElement]) 43 @include('chapters/list-item', ['chapter' => $childElement])
44 @else 44 @else
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
60 </p> 60 </p>
61 </div> 61 </div>
62 <div class="col-md-3 col-md-offset-1"> 62 <div class="col-md-3 col-md-offset-1">
63 - @include('pages/sidebar-tree-list', ['book' => $book]) 63 + @include('pages/sidebar-tree-list', ['book' => $book, 'sidebarTree' => $sidebarTree])
64 </div> 64 </div>
65 </div> 65 </div>
66 </div> 66 </div>
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
60 </div> 60 </div>
61 <div class="col-md-3 print-hidden"> 61 <div class="col-md-3 print-hidden">
62 62
63 - @include('pages/sidebar-tree-list', ['book' => $book]) 63 + @include('pages/sidebar-tree-list', ['book' => $book, 'sidebarTree' => $sidebarTree])
64 64
65 </div> 65 </div>
66 </div> 66 </div>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 <h6 class="text-muted">Book Navigation</h6> 3 <h6 class="text-muted">Book Navigation</h6>
4 <ul class="sidebar-page-list menu"> 4 <ul class="sidebar-page-list menu">
5 <li class="book-header"><a href="{{$book->getUrl()}}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li> 5 <li class="book-header"><a href="{{$book->getUrl()}}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li>
6 - @foreach($book->children() as $bookChild) 6 + @foreach($sidebarTree as $bookChild)
7 <li class="list-item-{{ $bookChild->getName() }}"> 7 <li class="list-item-{{ $bookChild->getName() }}">
8 <a href="{{$bookChild->getUrl()}}" class="{{ $bookChild->getName() }} {{ $current->matches($bookChild)? 'selected' : '' }}"> 8 <a href="{{$bookChild->getUrl()}}" class="{{ $bookChild->getName() }} {{ $current->matches($bookChild)? 'selected' : '' }}">
9 @if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }} 9 @if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }}
......