| 
									
										
										
										
											2018-09-25 19:30:50 +08:00
										 |  |  | <?php namespace BookStack\Entities; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Actions\Activity; | 
					
						
							|  |  |  | use BookStack\Actions\Comment; | 
					
						
							| 
									
										
										
										
											2018-09-25 23:58:03 +08:00
										 |  |  | use BookStack\Actions\Tag; | 
					
						
							|  |  |  | use BookStack\Actions\View; | 
					
						
							| 
									
										
										
										
											2018-09-25 19:30:50 +08:00
										 |  |  | use BookStack\Auth\Permissions\EntityPermission; | 
					
						
							|  |  |  | use BookStack\Auth\Permissions\JointPermission; | 
					
						
							|  |  |  | use BookStack\Ownable; | 
					
						
							| 
									
										
										
										
											2018-09-26 01:00:40 +08:00
										 |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2017-09-03 23:37:51 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Relations\MorphMany; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-26 01:00:40 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Class Entity | 
					
						
							|  |  |  |  * The base class for book-like items such as pages, chapters & books. | 
					
						
							|  |  |  |  * This is not a database model in itself but extended. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @property integer $id | 
					
						
							|  |  |  |  * @property string $name | 
					
						
							|  |  |  |  * @property string $slug | 
					
						
							|  |  |  |  * @property Carbon $created_at | 
					
						
							|  |  |  |  * @property Carbon $updated_at | 
					
						
							|  |  |  |  * @property int $created_by | 
					
						
							|  |  |  |  * @property int $updated_by | 
					
						
							|  |  |  |  * @property boolean $restricted | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @package BookStack\Entities | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-05-07 21:29:43 +08:00
										 |  |  | class Entity extends Ownable | 
					
						
							| 
									
										
										
										
											2015-08-16 21:51:45 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-11-22 01:22:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 02:46:31 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @var string - Name of property where the main text content is found | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-03-27 18:57:33 +08:00
										 |  |  |     public $textField = 'description'; | 
					
						
							| 
									
										
										
										
											2017-01-02 00:57:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 02:46:31 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * @var float - Multiplier for search indexing. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public $searchFactor = 1.0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:30:50 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the morph class for this model. | 
					
						
							|  |  |  |      * Set here since, due to folder changes, the namespace used | 
					
						
							|  |  |  |      * in the database no longer matches the class namespace. | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getMorphClass() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return 'BookStack\\Entity'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-16 21:51:45 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Compares this entity to another given entity. | 
					
						
							|  |  |  |      * Matches by comparing class and id. | 
					
						
							|  |  |  |      * @param $entity | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matches($entity) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return [get_class($this), $this->id] === [get_class($entity), $entity->id]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-17 01:59:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-30 02:06:55 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Checks if an entity matches or contains another given entity. | 
					
						
							|  |  |  |      * @param Entity $entity | 
					
						
							|  |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function matchesOrContains(Entity $entity) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $matches = [get_class($this), $this->id] === [get_class($entity), $entity->id]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  |         if ($matches) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-30 02:06:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-02 22:48:35 +08:00
										 |  |  |         if (($entity->isA('chapter') || $entity->isA('page')) && $this->isA('book')) { | 
					
						
							| 
									
										
										
										
											2015-11-30 02:06:55 +08:00
										 |  |  |             return $entity->book_id === $this->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($entity->isA('page') && $this->isA('chapter')) { | 
					
						
							|  |  |  |             return $entity->chapter_id === $this->id; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-17 01:59:23 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2015-11-22 01:22:14 +08:00
										 |  |  |      * Gets the activity objects for this entity. | 
					
						
							| 
									
										
										
										
											2015-08-17 01:59:23 +08:00
										 |  |  |      * @return \Illuminate\Database\Eloquent\Relations\MorphMany | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function activity() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         return $this->morphMany(Activity::class, 'entity')->orderBy('created_at', 'desc'); | 
					
						
							| 
									
										
										
										
											2015-08-17 01:59:23 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-22 01:22:14 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get View objects for this entity. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function views() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         return $this->morphMany(View::class, 'viewable'); | 
					
						
							| 
									
										
										
										
											2015-11-22 01:22:14 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-08 02:33:32 +08:00
										 |  |  |     public function viewCountQuery() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->views()->selectRaw('viewable_id, sum(views) as view_count')->groupBy('viewable_id'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |      * Get the Tag models that have been user assigned to this entity. | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |      * @return \Illuminate\Database\Eloquent\Relations\MorphMany | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-14 04:20:21 +08:00
										 |  |  |     public function tags() | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-15 03:02:00 +08:00
										 |  |  |         return $this->morphMany(Tag::class, 'entity')->orderBy('order', 'asc'); | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-03 23:37:51 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the comments for an entity | 
					
						
							| 
									
										
										
										
											2017-09-09 22:56:24 +08:00
										 |  |  |      * @param bool $orderByCreated | 
					
						
							|  |  |  |      * @return MorphMany | 
					
						
							| 
									
										
										
										
											2017-09-03 23:37:51 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-09-09 22:56:24 +08:00
										 |  |  |     public function comments($orderByCreated = true) | 
					
						
							| 
									
										
										
										
											2017-09-03 23:37:51 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-09-09 22:56:24 +08:00
										 |  |  |         $query = $this->morphMany(Comment::class, 'entity'); | 
					
						
							|  |  |  |         return $orderByCreated ? $query->orderBy('created_at', 'asc') : $query; | 
					
						
							| 
									
										
										
										
											2017-09-03 23:37:51 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-19 20:48:44 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the related search terms. | 
					
						
							|  |  |  |      * @return \Illuminate\Database\Eloquent\Relations\MorphMany | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function searchTerms() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->morphMany(SearchTerm::class, 'entity'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-02-28 18:49:41 +08:00
										 |  |  |      * Get this entities restrictions. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function permissions() | 
					
						
							| 
									
										
										
										
											2016-02-28 18:49:41 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         return $this->morphMany(EntityPermission::class, 'restrictable'); | 
					
						
							| 
									
										
										
										
											2016-02-28 18:49:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Check if this entity has a specific restriction set against it. | 
					
						
							|  |  |  |      * @param $role_id | 
					
						
							|  |  |  |      * @param $action | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |      * @return bool | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-28 18:49:41 +08:00
										 |  |  |     public function hasRestriction($role_id, $action) | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         return $this->permissions()->where('role_id', '=', $role_id) | 
					
						
							| 
									
										
										
										
											2016-04-24 23:54:20 +08:00
										 |  |  |             ->where('action', '=', $action)->count() > 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |      * Get the entity jointPermissions this is connected to. | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |      * @return \Illuminate\Database\Eloquent\Relations\MorphMany | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |     public function jointPermissions() | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-05-02 04:20:50 +08:00
										 |  |  |         return $this->morphMany(JointPermission::class, 'entity'); | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 03:11:44 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |      * Allows checking of the exact class, Used to check entity type. | 
					
						
							|  |  |  |      * Cleaner method for is_a. | 
					
						
							|  |  |  |      * @param $type | 
					
						
							|  |  |  |      * @return bool | 
					
						
							| 
									
										
										
										
											2015-09-01 03:11:44 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2015-11-30 01:33:25 +08:00
										 |  |  |     public static function isA($type) | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-04-24 01:14:26 +08:00
										 |  |  |         return static::getType() === strtolower($type); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get entity type. | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getType() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return strtolower(static::getClassName()); | 
					
						
							| 
									
										
										
										
											2015-08-31 18:43:28 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get an instance of an entity of the given type. | 
					
						
							|  |  |  |      * @param $type | 
					
						
							|  |  |  |      * @return Entity | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getEntityInstance($type) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-09-17 02:34:09 +08:00
										 |  |  |         $types = ['Page', 'Book', 'Chapter', 'Bookshelf']; | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |         $className = str_replace([' ', '-', '_'], '', ucwords($type)); | 
					
						
							|  |  |  |         if (!in_array($className, $types)) { | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 19:30:50 +08:00
										 |  |  |         return app('BookStack\\Entities\\' . $className); | 
					
						
							| 
									
										
										
										
											2016-05-07 03:33:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-05 22:41:51 +08:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2016-02-28 03:24:42 +08:00
										 |  |  |      * Gets a limited-length version of the entities name. | 
					
						
							| 
									
										
										
										
											2015-12-05 22:41:51 +08:00
										 |  |  |      * @param int $length | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getShortName($length = 25) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-09-12 02:42:25 +08:00
										 |  |  |         if (mb_strlen($this->name) <= $length) { | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  |             return $this->name; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-09-12 02:42:25 +08:00
										 |  |  |         return mb_substr($this->name, 0, $length - 3) . '...'; | 
					
						
							| 
									
										
										
										
											2015-12-05 22:41:51 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-19 20:48:44 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the body text of this entity. | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getText() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->{$this->textField}; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-17 01:49:16 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get an excerpt of this entity's descriptive content to the specified length. | 
					
						
							|  |  |  |      * @param int $length | 
					
						
							|  |  |  |      * @return mixed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getExcerpt(int $length = 100) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $text = $this->getText(); | 
					
						
							|  |  |  |         if (mb_strlen($text) > $length) { | 
					
						
							|  |  |  |             $text = mb_substr($text, 0, $length-3) . '...'; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-07 01:47:27 +08:00
										 |  |  |         return trim($text); | 
					
						
							| 
									
										
										
										
											2018-10-17 01:49:16 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-19 20:48:44 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Return a generalised, common raw query that can be 'unioned' across entities. | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  |     public function entityRawQuery() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ''; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-03-19 20:48:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 05:01:43 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the url of this entity | 
					
						
							|  |  |  |      * @param $path | 
					
						
							|  |  |  |      * @return string | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-04-15 01:00:16 +08:00
										 |  |  |     public function getUrl($path = '/') | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-04-15 01:00:16 +08:00
										 |  |  |         return $path; | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-16 21:51:45 +08:00
										 |  |  | } |