]> BookStack Code Mirror - bookstack/blob - app/Entities/Entity.php
Use joint_permissions to determine is a user has an available page or chapter to...
[bookstack] / app / Entities / Entity.php
1 <?php namespace BookStack\Entities;
2
3 use BookStack\Actions\Activity;
4 use BookStack\Actions\Comment;
5 use BookStack\Actions\Tag;
6 use BookStack\Actions\View;
7 use BookStack\Auth\Permissions\EntityPermission;
8 use BookStack\Auth\Permissions\JointPermission;
9 use BookStack\Ownable;
10 use Carbon\Carbon;
11 use Illuminate\Database\Eloquent\Relations\MorphMany;
12
13 /**
14  * Class Entity
15  * The base class for book-like items such as pages, chapters & books.
16  * This is not a database model in itself but extended.
17  *
18  * @property integer $id
19  * @property string $name
20  * @property string $slug
21  * @property Carbon $created_at
22  * @property Carbon $updated_at
23  * @property int $created_by
24  * @property int $updated_by
25  * @property boolean $restricted
26  *
27  * @package BookStack\Entities
28  */
29 class Entity extends Ownable
30 {
31
32     /**
33      * @var string - Name of property where the main text content is found
34      */
35     public $textField = 'description';
36
37     /**
38      * @var float - Multiplier for search indexing.
39      */
40     public $searchFactor = 1.0;
41
42     /**
43      * Get the morph class for this model.
44      * Set here since, due to folder changes, the namespace used
45      * in the database no longer matches the class namespace.
46      * @return string
47      */
48     public function getMorphClass()
49     {
50         return 'BookStack\\Entity';
51     }
52
53     /**
54      * Compares this entity to another given entity.
55      * Matches by comparing class and id.
56      * @param $entity
57      * @return bool
58      */
59     public function matches($entity)
60     {
61         return [get_class($this), $this->id] === [get_class($entity), $entity->id];
62     }
63
64     /**
65      * Checks if an entity matches or contains another given entity.
66      * @param Entity $entity
67      * @return bool
68      */
69     public function matchesOrContains(Entity $entity)
70     {
71         $matches = [get_class($this), $this->id] === [get_class($entity), $entity->id];
72
73         if ($matches) {
74             return true;
75         }
76
77         if (($entity->isA('chapter') || $entity->isA('page')) && $this->isA('book')) {
78             return $entity->book_id === $this->id;
79         }
80
81         if ($entity->isA('page') && $this->isA('chapter')) {
82             return $entity->chapter_id === $this->id;
83         }
84
85         return false;
86     }
87
88     /**
89      * Gets the activity objects for this entity.
90      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
91      */
92     public function activity()
93     {
94         return $this->morphMany(Activity::class, 'entity')->orderBy('created_at', 'desc');
95     }
96
97     /**
98      * Get View objects for this entity.
99      */
100     public function views()
101     {
102         return $this->morphMany(View::class, 'viewable');
103     }
104
105     /**
106      * Get the Tag models that have been user assigned to this entity.
107      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
108      */
109     public function tags()
110     {
111         return $this->morphMany(Tag::class, 'entity')->orderBy('order', 'asc');
112     }
113
114     /**
115      * Get the comments for an entity
116      * @param bool $orderByCreated
117      * @return MorphMany
118      */
119     public function comments($orderByCreated = true)
120     {
121         $query = $this->morphMany(Comment::class, 'entity');
122         return $orderByCreated ? $query->orderBy('created_at', 'asc') : $query;
123     }
124
125     /**
126      * Get the related search terms.
127      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
128      */
129     public function searchTerms()
130     {
131         return $this->morphMany(SearchTerm::class, 'entity');
132     }
133
134     /**
135      * Get this entities restrictions.
136      */
137     public function permissions()
138     {
139         return $this->morphMany(EntityPermission::class, 'restrictable');
140     }
141
142     /**
143      * Check if this entity has a specific restriction set against it.
144      * @param $role_id
145      * @param $action
146      * @return bool
147      */
148     public function hasRestriction($role_id, $action)
149     {
150         return $this->permissions()->where('role_id', '=', $role_id)
151             ->where('action', '=', $action)->count() > 0;
152     }
153
154     /**
155      * Get the entity jointPermissions this is connected to.
156      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
157      */
158     public function jointPermissions()
159     {
160         return $this->morphMany(JointPermission::class, 'entity');
161     }
162
163     /**
164      * Allows checking of the exact class, Used to check entity type.
165      * Cleaner method for is_a.
166      * @param $type
167      * @return bool
168      */
169     public static function isA($type)
170     {
171         return static::getType() === strtolower($type);
172     }
173
174     /**
175      * Get entity type.
176      * @return mixed
177      */
178     public static function getType()
179     {
180         return strtolower(static::getClassName());
181     }
182
183     /**
184      * Get an instance of an entity of the given type.
185      * @param $type
186      * @return Entity
187      */
188     public static function getEntityInstance($type)
189     {
190         $types = ['Page', 'Book', 'Chapter', 'Bookshelf'];
191         $className = str_replace([' ', '-', '_'], '', ucwords($type));
192         if (!in_array($className, $types)) {
193             return null;
194         }
195
196         return app('BookStack\\Entities\\' . $className);
197     }
198
199     /**
200      * Gets a limited-length version of the entities name.
201      * @param int $length
202      * @return string
203      */
204     public function getShortName($length = 25)
205     {
206         if (mb_strlen($this->name) <= $length) {
207             return $this->name;
208         }
209         return mb_substr($this->name, 0, $length - 3) . '...';
210     }
211
212     /**
213      * Get the body text of this entity.
214      * @return mixed
215      */
216     public function getText()
217     {
218         return $this->{$this->textField};
219     }
220
221     /**
222      * Return a generalised, common raw query that can be 'unioned' across entities.
223      * @return string
224      */
225     public function entityRawQuery()
226     {
227         return '';
228     }
229
230     /**
231      * Get the url of this entity
232      * @param $path
233      * @return string
234      */
235     public function getUrl($path = '/')
236     {
237         return $path;
238     }
239 }