]> BookStack Code Mirror - bookstack/blob - app/Entity.php
Fixed issue with searching invalid chars and page-content compiliation
[bookstack] / app / Entity.php
1 <?php
2
3 namespace BookStack;
4
5 use Illuminate\Database\Eloquent\Model;
6
7 abstract class Entity extends Model
8 {
9
10     use Ownable;
11
12     /**
13      * Compares this entity to another given entity.
14      * Matches by comparing class and id.
15      * @param $entity
16      * @return bool
17      */
18     public function matches($entity)
19     {
20         return [get_class($this), $this->id] === [get_class($entity), $entity->id];
21     }
22
23     /**
24      * Checks if an entity matches or contains another given entity.
25      * @param Entity $entity
26      * @return bool
27      */
28     public function matchesOrContains(Entity $entity)
29     {
30         $matches = [get_class($this), $this->id] === [get_class($entity), $entity->id];
31
32         if ($matches) return true;
33
34         if ($entity->isA('chapter') && $this->isA('book')) {
35             return $entity->book_id === $this->id;
36         }
37
38         if ($entity->isA('page') && $this->isA('book')) {
39             return $entity->book_id === $this->id;
40         }
41
42         if ($entity->isA('page') && $this->isA('chapter')) {
43             return $entity->chapter_id === $this->id;
44         }
45
46         return false;
47     }
48
49     /**
50      * Gets the activity objects for this entity.
51      * @return \Illuminate\Database\Eloquent\Relations\MorphMany
52      */
53     public function activity()
54     {
55         return $this->morphMany('BookStack\Activity', 'entity')->orderBy('created_at', 'desc');
56     }
57
58     /**
59      * Get View objects for this entity.
60      * @return mixed
61      */
62     public function views()
63     {
64         return $this->morphMany('BookStack\View', 'viewable');
65     }
66
67     /**
68      * Get just the views for the current user.
69      * @return mixed
70      */
71     public function userViews()
72     {
73         return $this->views()->where('user_id', '=', auth()->user()->id);
74     }
75
76     /**
77      * Allows checking of the exact class, Used to check entity type.
78      * Cleaner method for is_a.
79      * @param $type
80      * @return bool
81      */
82     public static function isA($type)
83     {
84         return static::getClassName() === strtolower($type);
85     }
86
87     /**
88      * Gets the class name.
89      * @return string
90      */
91     public static function getClassName()
92     {
93         return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]);
94     }
95
96     /**
97      *Gets a limited-length version of the entities name.
98      * @param int $length
99      * @return string
100      */
101     public function getShortName($length = 25)
102     {
103         if(strlen($this->name) <= $length) return $this->name;
104         return substr($this->name, 0, $length-3) . '...';
105     }
106
107     /**
108      * Perform a full-text search on this entity.
109      * @param string[] $fieldsToSearch
110      * @param string[] $terms
111      * @param string[] array $wheres
112      * @return mixed
113      */
114     public static function fullTextSearch($fieldsToSearch, $terms, $wheres = [])
115     {
116         $termString = '';
117         foreach ($terms as $term) {
118             $termString .= htmlentities($term) . '* ';
119         }
120         $fields = implode(',', $fieldsToSearch);
121         $termStringEscaped = \DB::connection()->getPdo()->quote($termString);
122         $search = static::addSelect(\DB::raw('*, MATCH(name) AGAINST('.$termStringEscaped.' IN BOOLEAN MODE) AS title_relevance'));
123         $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termStringEscaped]);
124
125         // Add additional where terms
126         foreach ($wheres as $whereTerm) {
127             $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
128         }
129
130         // Load in relations
131         if (!static::isA('book')) $search = $search->with('book');
132         if (static::isA('page'))  $search = $search->with('chapter');
133
134         return $search->orderBy('title_relevance', 'desc')->get();
135     }
136
137     /**
138      * Get the url for this item.
139      * @return string
140      */
141     abstract public function getUrl();
142
143 }